/*  BSD-License:

Copyright (c) 2010 by Matthias Bunte, Germany

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
  * Neither the names of the authors the name nicai-systems nor
    the names of its contributors may be used to endorse or promote products
    derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/*! @file    motorpid.h
 *  @brief   Regulating the motor speed with PID
 *  @author  Matthias Bunte (m_bunte@arcor.de)
 *  @date    2010-04-02
 */

#ifndef _BEELIB_MOTORPID_H_
#define _BEELIB_MOTORPID_H_

#include "scheduler.h"

#ifdef __cplusplus
extern "C" {
#endif

// Pointer auf Eventfunktion und zugehoeriger Event-Parameter
typedef _ptarget pMotorPID_EventFkt_t;
typedef enum
{
  MotorPID_EventInvalid,  // System wurde noch nie genutzt / ungueltig
  MotorPID_EventStarted,  // Regelung wurde gestartet
  MotorPID_EventFinished, // Vorgegebene Wegstrecke ist zurueckgelegt
  MotorPID_Event_LR_Blocked,  // Motoren sind blockiert
  MotorPID_Event_L_Blocked,  // Motoren sind blockiert
  MotorPID_Event_R_Blocked,  // Motoren sind blockiert
}
MotorPID_Event_t;

// Initialisierungsfunktion mit Eventfunktion als Parameter.
// Diese Eventfunktion wird aufgerufen, sobald eine Strecke gestartet und zu
// Ende gefahren ist. Diese Funktion wird auch aufgerufen, sobald ein Motor
// fuer ca. 1 s angehalten wurde.
void MotorPID_Init(pMotorPID_EventFkt_t pEventFkt);

// Initialisierungszustand auslesen
uint8_t MotorPID_Initialized(void);

// Pruefe, ob schon initialisiert wurde und wenn nicht, initialisiere
#define MotorPID_CheckAndInit(P_EVENT_FKT) do { \
  if (!MotorPID_Initialized()) MotorPID_Init(P_EVENT_FKT); \
} while (0)

// Liefert das zuletzt aufgetretene Event, falls keine Eventfunktion
// bei der Init-Funktion uebergeben wurde. Sonst liefert die Funktion immer
// EventInvalid.
uint16_t MotorPID_GetLastEvent(void);

// Starte Regler
//
// Speed: Von -100 (Vollgas rueckwaerts) ueber 0 (Stillstand) bis +100 (Vollgas)
//
// Steering: Von  -100 (Dreht sich auf der Stelle linksherum) 
//           ueber -50 (Dreht sich linksherum, das linke Rad steht)
//           ueber   0 (Faehrt geradeaus)
//           ueber +50 (Dreht sich rechtsherum, das rechte Rad steht)
//           bis  +100 (Dreht sich auf der Stelle rechtsherum)
//
// WayCm: Ungefaehre Strecke in cm, die gefahren werden soll
//
// pNextEventFkt: Zeiger auf die Funktion, die aufgerufen wird,
//                wenn ein Ereignis eintritt.
//                Ein Ereignis tritt ein, sobald Count Radsensorticks gefahren
//                wurde. So koennen mehrere Bewegungen aneinander gereiht
//                werden.
//                Ein Ereignis tritt ebenfalls ein, sobald ein Rad fuer eine
//                Sekunde steht, obwohl es fahren sollte.
//                Wenn diese Funktion NULL ist, wird statt dessen die Funktion
//                aufgerufen, die bei der Initialisierung uebergeben wurde.

//void MotorPID_Start(int8_t Speed, int8_t Steering, uint8_t WayCm, pMotorPID_EventFkt_t pNextEventFkt);
void MotorPID_Start(int8_t Speed, int8_t Steering, uint8_t WayCm);

// Starte Geradeauslauf
#define MotorPID_StartGerade(SPEED) do { \
  MotorPID_Start( (SPEED), 0, 0 ); \
} while (0)

// Starte Geradeauslauf fuer eine Strecke
#define MotorPID_StartStrecke(SPEED, WAYCM) do { \
  MotorPID_Start( (SPEED), 0, (WAYCM) ); \
} while (0)

// Starte Kurvenfahrt
#define MotorPID_StartKurve(SPEED, STEERING) do { \
  MotorPID_Start( (SPEED), (STEERING), 0 ); \
} while (0)

// Starte Kurvenfahrt fuer eine Strecke
#define MotorPID_StartKurvenStrecke(SPEED, STEERING, WAYCM) do { \
  MotorPID_Start( (SPEED), (STEERING), (WAYCM) ); \
} while (0)

// Stoppe Motor
void MotorPID_Stopp(void);


#ifdef __cplusplus
} // extern "C"
#endif

#endif // _NIBOBEE_MOTORPID_H_

