/** * This class defines some basic states which apply to the robots movement. */ #ifndef MOTION_STATES_H #define MOTION_STATES_H #include "state.hh" #include "behavior/linktypes.hh" using namespace EyeMind; /** * A state for making the robot go to a position (x,y,q) */ class PositionState : public State { friend SpeedLink& operator>>(PositionState& n, SpeedLink& o); friend PositionLink& operator<<(PositionState& n, PositionLink& i); private: SpeedLink *speed; PositionLink *position; PositionType goal; // desired position float dband; // distance deadband float qband; // angle deadband SpeedType m; // output speeds public: PositionState() { dband = 0.001; // meters^2 qband = 0.1; // radians^2 m.v = 0.2; m.w = 0.1; } tristate Evaluate() { double d,dx,dy,dq; PositionType pos; if(!position) return TRISTATE_UNKNOWN; pos = position->Position(); dx = goal.x - pos.x; dy = goal.y - pos.y; dq = goal.phi - pos.phi; d = dx*dx + dy*dy; // calculate norm-squared error if(d>dband) { //DEBUG_PRINT("Too far\n"); value = TRISTATE_FALSE; } else if(dq>qband || dq<-dband) { //DEBUG_PRINT("Not oriented\n"); value = TRISTATE_FALSE; } else { if(speed!=NULL) { //DEBUG_PRINT("At goal\n"); SpeedType temp = {0,0}; speed->Speed(temp); speed->Signal(EXCITE_HI_MIN); value = TRISTATE_TRUE; } } return value; } tristate Resolve() { float d,dx,dy,dq,p; PositionType pos; // Check the distance if(position==NULL || speed==NULL) return 0; pos = position->Position(); dx = goal.x - pos.x; dy = goal.y - pos.y; dq = goal.phi - pos.phi; d = dx*dx + dy*dy; // Distance is too great if(d>dband) { // Calculate heading to point p = atan2(dy,dx) - pos.phi; DEBUG_PRINTF("%6.5f ",d); DEBUG_PRINTF("%4.3f\n",p); if(p>qband || p<-qband) { // Turn towards point if(p>0) { speed->Speed(m); speed->Signal(EXCITE_HI_MIN); speed->Update(); } else { SpeedType temp = m; m.w *= -1.0; speed->Speed(m); speed->Signal(EXCITE_HI_MIN); speed->Update(); } } else { // Drive straight //DEBUG_PRINT("driving\n"); SpeedType temp = {2 * m.v, 0}; speed->Speed(m); speed->Signal(EXCITE_HI_MIN); speed->Update(); } } return 0; } inline float X(){return goal.x;} inline void X(float v){goal.x=v;} inline float Y(){return goal.y;} inline void Y(float v){goal.y=v;} inline float Q(){return goal.phi;} inline void Q(float v){goal.phi=v;} inline void Speed(const SpeedType& s){m=s;} void Speed(SpeedLink* l){speed = l;} void Position(PositionLink* l){position = l;} }; inline SpeedLink& operator>>(PositionState& n, SpeedLink& o) { n.speed = &o; StateOutputToSignalLink(n,o); return o; } inline PositionLink& operator<<(PositionState& n, PositionLink& i) { n.position = &i; StateInputToSignalLink(n,i); return i; } #endif //MOTION_STATES_H