00001 00002 /** 00003 * @file RFieldStateMachine.cpp 00004 * Implementation of class RFieldStateMachine. 00005 * 00006 * @author <A href=mailto:sadprofessor@web.de>Bernd Schmidt</A> 00007 */ 00008 00009 #include "RFieldStateMachine.h" 00010 00011 RFieldStateMachine::RFieldStateMachine() 00012 :state(START) 00013 { 00014 reset(0,0); 00015 } 00016 00017 RFieldStateMachine::~RFieldStateMachine(){} 00018 00019 void RFieldStateMachine::reset(int x,int y){ 00020 start.x = x; 00021 start.y = y; 00022 numberOfEdges = 0; 00023 obstacleFarPoint = -1; 00024 obstacleNearPoint = -1; 00025 state = START; 00026 isUnknownBot = false; 00027 } 00028 00029 void RFieldStateMachine::update(int x,int y,REdgeDetection& scanner){ 00030 //follow the scan and update the states 00031 if (numberOfEdges == 20) return; 00032 rangeSum = 0; 00033 greenRange = 0; 00034 whiteRange = 0; 00035 grayRange = 0; 00036 00037 edgeBuffer[numberOfEdges].x = x; 00038 edgeBuffer[numberOfEdges].y = y; 00039 00040 types[numberOfEdges] = nothing; 00041 for (int i = 0; i<scanner.getBufferSize();i++){ 00042 color = scanner.getColor(i); 00043 range = scanner.getRange(i); 00044 rangeSum = rangeSum + range; 00045 if (color == green) greenRange = greenRange + range; 00046 else if (color == white) whiteRange = whiteRange + range; 00047 else if (color == gray) grayRange = grayRange + range; 00048 00049 if (greenRange > 2){ 00050 if (obstacleNearPoint == 0) obstacleFarPoint = 0; 00051 obstacleNearPoint = numberOfEdges; 00052 } 00053 00054 findNextState(); 00055 executeState(); 00056 } 00057 numberOfEdges++; 00058 } 00059 00060 // TODO: implement state-array for state machine 00061 //(f.e. states[state]->findNextState()) 00062 void RFieldStateMachine::findNextState(){ 00063 switch(state){ 00064 case START: 00065 switch(color){ 00066 case white: 00067 if (whiteRange > 3) state = FOUND_WHITE; 00068 break; 00069 case green: 00070 state = FOUND_FIELD; 00071 break; 00072 case red: 00073 state = FOUND_RED_ROBOT; 00074 break; 00075 case blue: 00076 state = FOUND_BLUE_ROBOT; 00077 break; 00078 case skyblue: 00079 state = SKYBLUE_GOAL; 00080 break; 00081 case yellow: 00082 state = YELLOW_GOAL; 00083 break; 00084 } 00085 break; 00086 case FOUND_WHITE: 00087 switch(color){ 00088 case green: 00089 state = FOUND_BORDER; 00090 break; 00091 case red: 00092 state = FOUND_RED_ROBOT; 00093 break; 00094 case blue: 00095 state = FOUND_BLUE_ROBOT; 00096 break; 00097 case orange: 00098 state = FOUND_BALL; 00099 break; 00100 case gray: 00101 if (grayRange > 3) state = FOUND_UNKNOWN; 00102 } 00103 break; 00104 case FOUND_BORDER: 00105 break; 00106 case FOUND_FIELD: 00107 switch(color){ 00108 case orange: 00109 state = FOUND_BALL; 00110 break; 00111 case red: 00112 state = FOUND_RED_ROBOT; 00113 break; 00114 case blue: 00115 state = FOUND_BLUE_ROBOT; 00116 break; 00117 case white: 00118 state = LINE_IN; 00119 } 00120 break; 00121 case LINE_IN: 00122 switch(color){ 00123 case green: 00124 state = LINE_OUT; 00125 break; 00126 case red: 00127 state = FOUND_RED_ROBOT; 00128 break; 00129 case blue: 00130 state = FOUND_BLUE_ROBOT; 00131 break; 00132 case orange: 00133 state = FOUND_BALL; 00134 break; 00135 case gray: 00136 if (grayRange > 3) state = FOUND_UNKNOWN; 00137 } 00138 break; 00139 case LINE_OUT: break; 00140 case YELLOW_GOAL: 00141 switch(color){ 00142 case green: 00143 state = YELLOW_FINISHED; 00144 break; 00145 case red: 00146 state = FOUND_RED_ROBOT; 00147 break; 00148 case blue: 00149 state = FOUND_BLUE_ROBOT; 00150 break; 00151 case orange: 00152 state = FOUND_BALL; 00153 break; 00154 case white: 00155 state = FOUND_UNKNOWN; 00156 break; 00157 } 00158 break; 00159 case YELLOW_FINISHED: break; 00160 case SKYBLUE_GOAL: 00161 switch(color){ 00162 case green: 00163 state = SKYBLUE_FINISHED; 00164 break; 00165 case red: 00166 state = FOUND_RED_ROBOT; 00167 break; 00168 case blue: 00169 state = FOUND_BLUE_ROBOT; 00170 break; 00171 case orange: 00172 state = FOUND_BALL; 00173 break; 00174 case white: 00175 state = FOUND_UNKNOWN; 00176 break; 00177 } 00178 break; 00179 case SKYBLUE_FINISHED: break; 00180 case FOUND_RED_ROBOT: 00181 switch(color){ 00182 case green: 00183 state = FINISHED_RED_ROBOT; 00184 break; 00185 case blue: 00186 state = FOUND_UNKNOWN; 00187 isUnknownBot = true; 00188 break; 00189 case orange: 00190 state = FOUND_BALL; 00191 break; 00192 } 00193 break; 00194 case FOUND_BLUE_ROBOT: 00195 switch(color){ 00196 case green: 00197 state = FINISHED_BLUE_ROBOT; 00198 break; 00199 case red: 00200 state = FOUND_UNKNOWN; 00201 isUnknownBot = true; 00202 break; 00203 } 00204 break; 00205 case FINISHED_BLUE_ROBOT: break; 00206 case FINISHED_RED_ROBOT: break; 00207 case FOUND_BALL: 00208 if (color == green) state = FINISHED_BALL; 00209 break; 00210 case FINISHED_BALL: break; 00211 case FOUND_UNKNOWN: 00212 if (isUnknownBot){ 00213 if (color == green) 00214 state = FINISHED_UNKNOWN; 00215 } 00216 else{ 00217 switch(color){ 00218 case blue: 00219 state = FOUND_BLUE_ROBOT; 00220 break; 00221 case red: 00222 state = FOUND_RED_ROBOT; 00223 break; 00224 case orange: 00225 state = FOUND_BALL; 00226 break; 00227 case skyblue: 00228 state = SKYBLUE_GOAL; 00229 break; 00230 case yellow: 00231 state = YELLOW_GOAL; 00232 break; 00233 } 00234 } 00235 break; 00236 case FINISHED_UNKNOWN: 00237 break; 00238 default: break; //machine is in undefined state 00239 } 00240 } 00241 00242 // A little bit like XABSL-CODE but it seems to be efficient 00243 void RFieldStateMachine::executeState(){ 00244 switch(state){ 00245 case START: break; 00246 case FOUND_WHITE: break; 00247 case FOUND_FIELD: break; 00248 case FOUND_BORDER: 00249 state = FOUND_FIELD; 00250 if(greenRange<3){ 00251 types[numberOfEdges] = border; 00252 obstacleFarPoint = numberOfEdges; 00253 } 00254 else if (numberOfEdges>0){ 00255 types[numberOfEdges-1] = border; 00256 obstacleFarPoint = numberOfEdges-1; 00257 } 00258 break; 00259 case LINE_IN: break; 00260 case LINE_OUT: 00261 state = FOUND_FIELD; 00262 if (numberOfEdges<1) break; 00263 if (greenRange<3){ 00264 types[numberOfEdges] = line; 00265 //types[numberOfEdges-1] = line; 00266 } 00267 else{ 00268 types[numberOfEdges-1] = line; 00269 //types[numberOfEdges-2] = line; 00270 } 00271 break; 00272 case YELLOW_GOAL: break; 00273 case YELLOW_FINISHED: 00274 state = FOUND_FIELD; 00275 if(greenRange<3){ 00276 types[numberOfEdges] = yellowGoal; 00277 obstacleFarPoint = numberOfEdges; 00278 } 00279 else if (numberOfEdges>0){ 00280 types[numberOfEdges-1] = yellowGoal; 00281 obstacleFarPoint = numberOfEdges-1; 00282 } 00283 break; 00284 case SKYBLUE_GOAL: break; 00285 case SKYBLUE_FINISHED: 00286 state = FOUND_FIELD; 00287 if(greenRange<3){ 00288 types[numberOfEdges] = skyblueGoal; 00289 obstacleFarPoint = numberOfEdges; 00290 } 00291 else if (numberOfEdges>0){ 00292 types[numberOfEdges-1] = skyblueGoal; 00293 obstacleFarPoint = numberOfEdges-1; 00294 } 00295 break; 00296 case FOUND_RED_ROBOT: break; 00297 case FOUND_BLUE_ROBOT: break; 00298 case FINISHED_BLUE_ROBOT: 00299 if(greenRange<3){ 00300 types[numberOfEdges] = blueRobot; 00301 obstacleFarPoint = numberOfEdges; 00302 } 00303 else if (numberOfEdges>0){ 00304 types[numberOfEdges-1] = blueRobot; 00305 obstacleFarPoint = numberOfEdges-1; 00306 } 00307 state = FOUND_FIELD; 00308 break; 00309 case FINISHED_RED_ROBOT: 00310 state = FOUND_FIELD; 00311 if(greenRange<3){ 00312 types[numberOfEdges] = redRobot; 00313 obstacleFarPoint = numberOfEdges; 00314 } 00315 else if (numberOfEdges>0){ 00316 types[numberOfEdges-1] = redRobot; 00317 obstacleFarPoint = numberOfEdges-1; 00318 } 00319 break; 00320 case FOUND_BALL: break; 00321 case FINISHED_BALL: 00322 state = FOUND_FIELD; 00323 //TODO(schmidtb): Integrate BallSpecialist into Field-Scan 00324 break; 00325 case FOUND_UNKNOWN: break; 00326 case FINISHED_UNKNOWN: 00327 state = FOUND_FIELD; 00328 if(greenRange<3){ 00329 types[numberOfEdges] = unknown; 00330 obstacleFarPoint = numberOfEdges; 00331 } 00332 else if (numberOfEdges>0){ 00333 types[numberOfEdges-1] = unknown; 00334 obstacleFarPoint = numberOfEdges-1; 00335 } 00336 break; 00337 default: break; //machine is in undefined state 00338 } 00339 } 00340 /* 00341 * Change log : 00342 * 00343 * $Log: RFieldStateMachine.cpp,v $ 00344 * Revision 1.6 2004/09/09 11:08:04 spranger 00345 * renamed GT2004EdgeDetection to REdgeDetection for consistency 00346 * 00347 * Revision 1.5 2004/09/09 10:15:55 spranger 00348 * fixed doxygen-errors 00349 * 00350 * Revision 1.4 2004/09/06 12:02:26 schmidtb 00351 * commented almost all members, removed warnings in documentation 00352 00353 * did further code clean up 00354 * 00355 * Revision 1.3 2004/09/02 07:59:29 schmidtb 00356 * Added RasterImageProcessor to repository, because we used it for the OpenChallenge. 00357 * 00358 * Revision 1.3 2004/05/25 13:27:34 schmidtb 00359 * modified version of rip for open-challenge 00360 * 00361 * Revision 1.3 2004/04/15 19:08:34 pg_besc 00362 * merged code 00363 * 00364 * Revision 1.2 2004/03/25 15:29:04 pg_besc 00365 * made some changes 00366 * 00367 * Revision 1.1 2004/03/17 22:12:39 schmidtb 00368 * established RFieldStateMachine 00369 * 00370 * 00371 */