/// @file soccer_behaviors.hh /// @author Jarrod Bassan /// @author Joshua Petitt #ifndef SOCCER_BEHAVIORS_HH #define SOCCER_BEHAVIORS_HH #include "behavior/behavior.hh" #include "behavior/stdc_linktypes.hh" #include "behavior/linktypes.hh" #include "output/soccer_actors.hh" #include "input/eyebot_sensors.hh" #include "eyebot_behavior_types.h" #define ALLPIXELS imagerows*imagecolumns*3 #define RED 0 #define GREEN 1 #define BLUE 2 /* macros for referencing a pixels in relation to the current pixel eg: NORTH(k) is the memory address within the image BYTE array for the pixel above pixel k */ //// Use inline functions if you really need it. #define SOUTH(x) ((x)+(imagecolumns*3)) #define NORTH(x) ((x)-(imagecolumns*3)) #define EAST(x) ((x)-3) #define WEST(x) ((x)+3) #define div(x,y) (x/y) namespace Soccer03 { #if 0 using namespace EyeMind; //// didn't you mean unsigned? static const int lookup_range[19] = {164,108,85,71,62,56,51,47,44,41,39,37,35,33,32,31,30,29,28}; /** * Filter the image */ class FindBall : public Behavior { private: PolarType ball; int ball_found; colimage* buffer; float threshold_phi; float threshold_r; int threshold_green; int threshold_blue; int threshold_intensity_lo; int threshold_intensity_hi; int image_to_polar(int x, int y); public: FindBall(); int Execute(); void Image(colimage* buf){buffer=buf;} void Feed(SignalLink &l); void TargetCloseThresh(float r,float phi) { threshold_phi = phi; threshold_r = r; } // PolarType BallPosition(){ return ball; } // int FoundBall(){ return ball_found; } }; inline FindBall& operator>>(ImageLink& l, FindBall& o) { o.Image(l.Image()); SignalLinkOutputToBehavior(l,o); return o; } inline ImageLink& operator<<(FindBall& n, ImageLink& i) { n.Image(i.Image()); BehaviorInputToSignalLink(n,i); return i; } inline FindBall& operator<<(PolarLink& l, FindBall& i) { SignalLinkInputToBehavior(l,i); return i; } inline PolarLink& operator>>(FindBall& n, PolarLink& o) { BehaviorOutputToSignalLink(n,o); return o; } /// A behavior for turning the head of the robot. /// Takes raw polar co-ordinates from the camera, corrects the co-ordinates /// @arg Input: PolarLink (highest) /// @arg Output: PolarLink (all) class TurnHeadTo: public Behavior { private: HeadServo& head; float dband; // deadband region PolarType angle; protected: virtual int Execute(); void Feed(SignalLink &l); public: TurnHeadTo(): Behavior(), head(HeadServo::I()) { head.CalibrateRange(-50.0, 50.0); dband = 0.1; memset(&angle,0,sizeof(angle)); } }; TurnHeadTo& operator>>(PolarLink& l, TurnHeadTo& o); TurnHeadTo& operator<<(PolarLink& l, TurnHeadTo& i); PolarLink& operator>>(TurnHeadTo& n, PolarLink& o); PolarLink& operator<<(TurnHeadTo& n, PolarLink& i); /// Predict the position of the ball at the next image frame. /// The prediction algorithm uses a PID controller to estimate /// the next position of the ball. /// @arg Input: PolarLink (?) /// @arg Output: PolarLink (?) class Predict : public Behavior { private: int ticks; PolarType actual; PolarType predicted; int ball_not_found_signal; int max_delay; int frames_held; // Number of consecutive frames we have seen the ball float Kp, Kd, Ki; // Gains PolarType Ep, Ed, Ei; // Errors protected: void Feed(SignalLink &l); virtual int Execute(); public: void Params(float Kproportional, float Kintegral, float Kdifferential); Predict(): Behavior() { max_delay = 10; ticks = max_delay; ball_not_found_signal = 1; memset(&actual, 0, sizeof(PolarType)); memset(&predicted, 0, sizeof(PolarType)); memset(&Ep, 0, sizeof(PolarType)); memset(&Ei, 0, sizeof(PolarType)); memset(&Ed, 0, sizeof(PolarType)); actual.r = 0.0; actual.phi = 0.0; predicted.r = 0.0; predicted.phi = 0.0; Ep.phi = 0.0; Ei.phi = 0.0; Ed.phi = 0.0; Ep.r = 0.0; Ei.r = 0.0; Ed.r = 0.0; Kp = 0.2; Ki = 0.1; Kd = 0.3; frames_held = 0; //Set the behavior parameters //MaxExcitation(1000); } }; Predict& operator>>(PolarLink& l, Predict& o); Predict& operator<<(PolarLink& l, Predict& i); PolarLink& operator>>(Predict& n, PolarLink& o); PolarLink& operator<<(Predict& n, PolarLink& i); /** * A behavior for tracking a close object using the PSD sensors * */ /* class TrackClose : public Behavior */ /* { */ /* private: */ /* Psd* psd; */ /* MotorControl* motor[2]; */ /* float K[4]; */ /* public: */ /* TrackClose(Psd* p, MotorControl* left, MotorControl* right) */ /* { */ /* psd = p; */ /* motor[0] = left; */ /* motor[1] = right; */ /* K[0] = (0.4370)*2; */ /* K[1] = -3.2772; */ /* K[2] = 0.002; */ /* K[3] = 0; */ /* } */ /* int Execute() */ /* { */ /* int x, dx, dq; */ /* int v; */ /* psd->Update(); */ /* x = psd->X(); */ /* dx = psd->DX(); */ /* dq = (motor[0]->Velocity() + motor[1]->Velocity())>>1; */ /* v = (int)(K[0]*x + K[1]*dx + K[2]*dq + K[3]); */ /* if(x>140) */ /* v = -80; */ /* if(dq > 20 || dq < -20) */ /* v = 0; */ /* motor[0]->Velocity(v); */ /* motor[1]->Velocity(v); */ /* return 1; */ /* } */ /* }; */ /** * A Behavior for turning head towards the closest object to the robot. * * Input: PolarLink from TurnHeadTo Behavior * * Output: PolarLink for TurnHeadTo Behavior */ #define SCAN_POINTS 31 class TrackCloseObjects: public Behavior { friend TrackCloseObjects& operator>>(PolarLink& l, TrackCloseObjects& o); friend PolarLink& operator<<(TrackCloseObjects& n, PolarLink& i); private: PsdFront* psd; PolarLink* anglelink; PolarType angle; float dQ; // angle between scan points int dist[SCAN_POINTS]; int decrement; protected: virtual int Execute(); void Feed(SignalLink &l); public: TrackCloseObjects():Behavior() { //MaxExcitation(3); Threshold(2); //Exhaustion(2); psd = &PsdFront::I(); anglelink=NULL; memset(&angle,0,sizeof(PolarType)); dQ = 100.0*M_PI/(SCAN_POINTS*180.0); decrement = 1; for(int i=0;i>(PolarLink& l, TrackCloseObjects& o); TrackCloseObjects& operator<<(PolarLink& l, TrackCloseObjects& i); PolarLink& operator>>(TrackCloseObjects& n, PolarLink& o); PolarLink& operator<<(TrackCloseObjects& n, PolarLink& i); #endif }; // namespace Soccer03 #endif // SOCCER_BEHAVIORS_HH