#include "unused_soccer_behaviors.hh" namespace Soccer03 { #if 0 /** * Function to map image co-ordinates (x,y) to polar co-ordinates * (R, theta). Polar co-ordinates are relative to the centre of the * kicker mechanism of the robot. * * Inputs: x,y INT * Outputs: R,theta *INT * * Initial Implementation: * Equations to map to polar have been derived from experiments * which yeilded relationships between image co-ords and * polar co-ords. * * @author: Jarrod Bassan * @date: 11/04/03 * */ int FindBall::image_to_polar(int x, int y) { // theta = 0.613*x - 25.6 //ball.phi = (float)( ((20*x)>>5) - 26 ); // this line cause a problem when x = 43 ball.phi = ((20.0*x)/(1<<5)) - 26.0; ball.r = (float)( (y<20) ? lookup_range[y] : div(512,y) ); ball.phi = -1 * ball.phi * M_PI / 180.0; //DEBUG_PRINTF("r=%3.1f,",ball.r); //DEBUG_PRINTF("phi=%3.1f\n",ball.phi); return 0; } FindBall::FindBall() { ball.r = 0; ball.phi = 0; ball_found = 0; findball_bt *fd = (findball_bt*) HDTFindEntry(B_FINDBALL,0); if(fd==NULL) OSPanic("Cannot find\n findball data\n"); /* threshold_green = fd->threshold_green; threshold_blue = fd->threshold_blue; threshold_intensity_lo = fd->threshold_intensity_lo; threshold_intensity_hi = fd->threshold_intensity_hi; */ // threshold_r = fd->threshold_close_range; // threshold_phi = fd->threshold_close_phi * M_PI / 180; } int FindBall::Execute() { int i, j, k; //int r_norm; int g_norm, b_norm, intensity[5]; int ball_x; int ball_y; int north, south, east, west; int rows_to_scan; int num_matches; BYTE* I; num_matches = 0; ball_found = 1; //nominal signal to say we have run, but didn't find the ball. ball.r = -1; // set the distance to the ball <0 so know if didn't find the ball. I = (BYTE*) buffer; ImageLink *l = (ImageLink*) inlinks.Begin(); //// Save one level of indentation by returning here or using goto. //// It's ok in that case. if(l!=NULL) { LCDPutColorGraphic(l->Image()); rows_to_scan = 2; /* Scan image */ for (i=imagerows-2;i>rows_to_scan;(i>30) ? (i-=2) : (i-=1)) //for (i=imagerows-2;i>rows_to_scan;i-=1) { k=i*imagecolumns*3; for (j=k+3;j<(k+(3*(imagecolumns-1)));(i>40) ? (j+=6) : (j+=3)) //for (j=k+3;j<(k+(3*(imagecolumns-1)));j+=6) { g_norm=I[j+GREEN]; b_norm=I[j+BLUE]; intensity[0]=I[j+RED]+I[j+GREEN]+I[j+BLUE]; if((intensity[0] > threshold_intensity_lo)&&(intensity[0] < threshold_intensity_hi)) { g_norm = div(I[j+GREEN]*100,intensity[0]); b_norm = div(I[j+BLUE]*100,intensity[0]); } if ((ball_found==1)&&(g_norm > threshold_green)&&(b_norm < threshold_blue)) { // Now check the 4 neighbouring pixels // north = NORTH(j); south = SOUTH(j); east = EAST(j); west = WEST(j); intensity[1]=I[east+RED]+I[east+GREEN]+I[east+BLUE]; ((div(I[east+GREEN]*100,intensity[1]) > threshold_green)&&(intensity[1]>threshold_intensity_lo)&&(intensity[1] threshold_green)&&(intensity[2]>threshold_intensity_lo)&&(intensity[2] threshold_green)&&(intensity[3]>threshold_intensity_lo)&&(intensity[3] threshold_green)&&(intensity[4]>threshold_intensity_lo)&&(intensity[4] 3) { num_matches = 1; (div(I[east+BLUE]*100,intensity[1]) < threshold_blue) ? num_matches++ : 1; (div(I[west+BLUE]*100,intensity[2]) < threshold_blue) ? num_matches++ : 1; (div(I[north+BLUE]*100,intensity[3]) < threshold_blue) ? num_matches++ : 1; (div(I[south+BLUE]*100,intensity[4]) < threshold_blue) ? num_matches++ : 1; if (num_matches > 3) { ball_y = (int)(j/(imagecolumns*3)); ball_x = (int)((j - (ball_y * imagecolumns * 3))/3.0); //DEBUG_PRINTF("%4d ",ball_x); //DEBUG_PRINTF("%4d\n",ball_y); image_to_polar(ball_x, ball_y); if ((ball.r < threshold_r)&&(ball.phi < threshold_phi)&&(ball.phi > -threshold_phi)) { //DEBUG_PRINTF("close %5.4f\n", ball.phi); return EXCITE_HI_AVG; // ball is close, return a high excitation } else { //DEBUG_PRINTF("far %5.4f\n", ball.phi); return EXCITE_MED_AVG; // ball is far, return a medium excitation } } } } } } } //.DEBUG_PRINTF("b:%d\n",ball_found); return EXCITE_LOW_MIN; } void FindBall::Feed(SignalLink &l) { if (!l.Generic()) reinterpret_cast(l).Polar(ball); Behavior::Feed(l); } /** Behaviour to turn the head */ int TurnHeadTo::Execute() { PolarType dQ; PolarLink* pl = reinterpret_cast(FindMaxNonGenericInputSignal()); if(pl==NULL) return 0; dQ = pl->Polar(); // get the coordinates if(dQ.r < 0) { angle.r = 0.0; angle.phi = 0.0; // reset back to zero } else { angle.r = dQ.r; angle.phi += dQ.phi; } //DEBUG_PRINTF("Q: %f\n",angle.phi); // set the head angle head.AngleRad( angle.phi ); angle.phi = head.AngleRad(); head.Update(); return pl->Signal(); } /** Feed the signal */ void TurnHeadTo::Feed(SignalLink &l) { if (!l.Generic()) { reinterpret_cast(l).Polar(angle); } Behavior::Feed(l); } TurnHeadTo& operator>>(PolarLink& l, TurnHeadTo& o) { SignalLinkOutputToBehavior(l,o); return o; } TurnHeadTo& operator<<(PolarLink& l, TurnHeadTo& i) { SignalLinkInputToBehavior(l,i); return i; } PolarLink& operator>>(TurnHeadTo& n, PolarLink& o) { BehaviorOutputToSignalLink(n,o); return o; } PolarLink& operator<<(TurnHeadTo& n, PolarLink& i) { BehaviorInputToSignalLink(n,i); return i; } int Predict::Execute() { int max_signal; float temp; //int return_val; SignalLink* i = inlinks.Begin(); max_signal = 0; //phi = 0.0; //command.v = 0.0; //command.w = 0.0; // find the maximum input signal while (i!=NULL) { if (!i->Generic()) { PolarLink* pl = reinterpret_cast(i); if (i->Signal()>max_signal) { actual = pl->Polar(); max_signal = i->Signal(); } } i = ++inlinks; } if (max_signal>ball_not_found_signal) { frames_held++; if (frames_held == 1) { predicted.r = actual.r; predicted.phi = actual.phi; Ep.phi = 0.0; Ei.phi = 0.0; Ed.phi = 0.0; Ep.r = 0.0; Ei.r = 0.0; Ed.r = 0.0; } temp = Ep.phi; Ep.phi = actual.phi - predicted.phi; Ed.phi = Ep.phi - temp; Ei.phi += Ep.phi; predicted.phi = Kp*Ep.phi + Ki*Ei.phi + Kd*Ed.phi; temp = Ep.r; Ep.r = actual.r - predicted.r; Ed.r = Ep.r - temp; Ei.r += Ep.r; //predicted.r = Kp*Ep.r + Ki*Ei.r + Kd*Ed.r; predicted.r = actual.r; } else { frames_held = 0; predicted.r = 0.0; predicted.phi = 0.0; } //DEBUG_PRINTF("rp= %3.1f,", predicted.r); //DEBUG_PRINTF("%3.1f\n", predicted.phi); //DEBUG_PRINTF("max_sig= %d\n", max_signal); //avg_ticks_per_frame=(avg_ticks_per_frame>>1) + (ticks_since_frame>>1); //ticks_since_frame=0; return max_signal; } void Predict::Feed(SignalLink &l) { if (!l.Generic()) { reinterpret_cast(l).Polar(predicted); } Behavior::Feed(l); } void Predict::Params(float Kproportional, float Kintegral, float Kdifferential) { Kp = Kproportional; Ki = Kintegral; Kd = Kdifferential; } /**Connect PolarLink output with target Predict. */ Predict& operator>>(PolarLink& l, Predict& o) { SignalLinkOutputToBehavior(l,o); return o; } /**Connect PolarLink input with source Predict. */ Predict& operator<<(PolarLink& l, Predict& i) { SignalLinkInputToBehavior(l,i); return i; } /**Add output SpeedLink to Predicte. */ PolarLink& operator>>(Predict& n, PolarLink& o) { BehaviorOutputToSignalLink(n,o); return o; } /**Add input PolarLink to Predict. */ PolarLink& operator<<(Predict& n, PolarLink& i) { BehaviorInputToSignalLink(n,i); return i; } int TrackCloseObjects::Execute() { int i=0; int min=0; int min_i=0; float min_Q; float Q; if(anglelink==NULL) return 0; // store current servo angle Q = anglelink->Polar().phi; // update the psd psd->Update(); //DEBUG_PRINTF("d=%4d\n",psd->X()); // store i = (int)((Q+(50.0*M_PI/180.0))/dQ); dist[i] = psd->X(); //DEBUG_PRINTF("i=",i); //DEBUG_PRINTF("%d\n",dist[i]); //DEBUG_WAIT(100); // turn head to point with minimum distance // and decrement each distance value min = dist[0]; dist[0]-=decrement; for(i=1;i Q + dQ) { angle.phi = dQ; } else if ( min_Q < Q - dQ) { angle.phi = -dQ; } //DEBUG_PRINTF("%4.3f ",anglelink->Polar().phi); //DEBUG_PRINTF("%d\n",min_i); return 1; } void TrackCloseObjects::Feed(SignalLink &l) { if (!l.Generic()) { reinterpret_cast(l).Polar(angle); } Behavior::Feed(l); } TrackCloseObjects& operator>>(PolarLink& l, TrackCloseObjects& o) { o.anglelink = &l; SignalLinkOutputToBehavior(l,o); return o; } TrackCloseObjects& operator<<(PolarLink& l, TrackCloseObjects& i) { SignalLinkInputToBehavior(l,i); return i; } PolarLink& operator>>(TrackCloseObjects& n, PolarLink& o) { BehaviorOutputToSignalLink(n,o); return o; } PolarLink& operator<<(TrackCloseObjects& n, PolarLink& i) { n.anglelink = &i; BehaviorInputToSignalLink(n,i); return i; } #endif }; // namespace Soccer03