/// @file control_behaviors.hh /// @author Stefan Schmitt /// @version 1.0 /// @date 2003-07 /// /// Declares behavior for controlling the actors. #ifndef CONTROL_BEHAVIORS_HH #define CONTROL_BEHAVIORS_HH #include "behavior/behavior.hh" #include "behavior/stdc_linktypes.hh" #include "output/eyebot_actors.hh" #include "input/eyebot_sensors.hh" #include "mind/mind.hh" #include "eyebot_behavior_types.h" namespace EyeMind { /// Motor velocity controller (PID). /// @arg Input: SpeedLink (last) /// @arg Output: FloatLink (all) class MotorControl : public Behavior { friend MotorControl& operator>>(FloatLink& l, MotorControl& o); friend FloatLink& operator<<(MotorControl& n, FloatLink& i); private: DCMotor& motor; ///< Motor to be controlled. // the symbols for the control values are taken from a German DIN // standard, one might want to change this. float y_min; ///< Min controller output. float y_max; ///< Max controller output. float w_min; ///< Max desired value. float w_max; ///< Min desired value. float x_d[3]; ///< Controller input and previous values. float y[2]; ///< Controller output and previous values. float K_P; ///< Proportional gain. float T_N; ///< Reset time. float T_V; ///< Rate time. unsigned time_stalled; ///< count number of time-units that velocity has been 0.0 unsigned time_limit; ///< maximum number of time-units before we declare that we are stalled. float dband; protected: FloatLink* velocity; ///< Desired velocity link. /// Call this in your derived class and make it \c public. MotorControl(DCMotor& m); virtual int Execute(); virtual void Feed(SignalLink& l); public: /// @name Attribute manipulation functions //@{ /// Set the controller parameters. /// @param p Proportional gain /// @param re Reset time /// @param ra Rate time void Params(float p, float re, float ra); /// Set the limits of the desired value. void Limits(float lower, float upper); /// Returns the actual motor velocity. float Velocity(){ return motor.Velocity(); } //@} /// Returns TRUE if the motor is in a stall. bool Stalled() { if (time_stalled > time_limit) { time_stalled=0; return true; } else return false; } }; MotorControl& operator>>(FloatLink& l, MotorControl& o); FloatLink& operator<<(MotorControl& n, FloatLink& i); MotorControl& operator<<(FloatLink& l, MotorControl& i); FloatLink& operator>>(MotorControl& n, FloatLink& o); /// MotorControl for left driving motor. class MotorControlLeft : public MotorControl { private: NO_COPYING(MotorControlLeft); public: SINGLETON(MotorControlLeft); MotorControlLeft() : MotorControl(DCMotorLeft::I()){} }; /// MotorControl for right driving motor. class MotorControlRight : public MotorControl { private: NO_COPYING(MotorControlRight); public: SINGLETON(MotorControlRight); MotorControlRight() : MotorControl(DCMotorRight::I()){} }; }; // namespace EyeMind #endif //CONTROL_BEHAVIORS_HH