#ifndef QRK_M_DIFFERENTIAL_DRIVE_H
#define QRK_M_DIFFERENTIAL_DRIVE_H

/*!
  \file
  \brief モニタ対応の走行制御クラス

  \author Satofumi KAMIMURA

  $Id: mDifferentialDrive.h 783 2009-05-05 08:56:26Z satofumi $
*/

#include "DifferentialDrive.h"


namespace qrk
{
  /*!
    \brief モニタ対応の走行制御クラス
  */
  class mDifferentialDrive : public Running
  {
    mDifferentialDrive(void);
    mDifferentialDrive(const mDifferentialDrive& rhs);
    mDifferentialDrive& operator = (const mDifferentialDrive& rhs);

    struct pImpl;
    std::auto_ptr<pImpl> pimpl;

  public:
    enum {
      DefaultBaudrate = 115200,
    };
    explicit mDifferentialDrive(int argc, char *argv[]);
    ~mDifferentialDrive(void);

    const char* what(void) const;

    void pushState(void);
    void popState(void);

    bool connect(const char* device, long baudrate = DefaultBaudrate);
    void setConnection(Connection* con);
    Connection* connection(void);
    void disconnect(void);
    bool isConnected(void);

    bool setTimestamp(int ticks = 0,
                      int* response_msec = NULL, int* force_delay_msec = NULL);

    void setServo(bool on);

    void followLine(const Position<long>& position);
    void followCircle(const Grid<long>& point, const int radius);

    void stopToLine(const Grid<long>& point, const Angle& angle);
    void stopToDirection(const Angle& angle);

    void rotateAngle(const Angle& angle);
    void rotate(const Angle& angle_sec);

    void stop(void);

    Position<long> position(Coordinate* coordinate = NULL,
                           int* timestamp = NULL);
    void setRobotPosition(const Position<long>& position);
    bool isStable(void);

    void setStraightVelocity(int mm_sec);
    int straightVelocity(void);

    void setStraightAcceleration(int mm_sec2);

    void setRotateVelocity(const Angle& angle_sec);
    Angle rotateVelocity(void);
    void setRotateAcceleration(const Angle& angle_sec2);

    // !!! 削除予定
    void setWheelVel(int id, int mm_vel);
  };
}

#endif /* !QRK_M_DIFFERENTIAL_DRIVE_H */
