00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Tools/Streams/InOut.h"
00011 #include "Tools/FieldDimensions.h"
00012 #include "LandmarksPercept.h"
00013
00014
00015 enum FlagType
00016 {
00017 pinkAboveYellow, pinkAboveSkyblue,
00018 yellowAbovePink, skyblueAbovePink
00019 };
00020
00021 colorClass Flag::getLowerColor() const
00022 {
00023 switch(type)
00024 {
00025 case pinkAboveYellow:
00026 return yellow;
00027 case pinkAboveSkyblue:
00028 return skyblue;
00029 default:
00030 return pink;
00031 }
00032 }
00033
00034 colorClass Flag::getUpperColor() const
00035 {
00036 switch(type)
00037 {
00038 case yellowAbovePink:
00039 return yellow;
00040 case skyblueAbovePink:
00041 return skyblue;
00042 default:
00043 return pink;
00044 }
00045 }
00046
00047 LandmarksPercept::LandmarksPercept()
00048 {
00049 reset(0);
00050 }
00051
00052 void LandmarksPercept::reset(unsigned long frameNumber)
00053 {
00054 this->frameNumber = frameNumber;
00055 numberOfFlags = numberOfGoals = 0;
00056 }
00057
00058 void LandmarksPercept::addFlag(Flag::FlagType type,
00059 const Vector2<double>& position,
00060 const ConditionalBoundary& boundary)
00061 {
00062 if(numberOfFlags < 4)
00063 {
00064 flags[numberOfFlags].type = type;
00065 flags[numberOfFlags].position = position;
00066 (ConditionalBoundary&) flags[numberOfFlags++] = boundary;
00067 }
00068 }
00069
00070
00071
00072 void LandmarksPercept::addFlag
00073 (
00074 Flag::FlagType type,
00075 bool ownTeamColorIsBlue,
00076 const ConditionalBoundary& boundary
00077 )
00078 {
00079 if(numberOfFlags < 4)
00080 {
00081 Vector2<double> flagPosition;
00082
00083 int flip = ownTeamColorIsBlue ? -1 : 1;
00084
00085 switch (type)
00086 {
00087 case Flag::pinkAboveYellow:
00088 flagPosition.x = xPosBackFlags * flip;
00089 flagPosition.y = yPosRightFlags * flip;
00090 break;
00091 case Flag::pinkAboveSkyblue:
00092 flagPosition.x = xPosFrontFlags * flip;
00093 flagPosition.y = yPosRightFlags * flip;
00094 break;
00095 case Flag::yellowAbovePink:
00096 flagPosition.x = xPosBackFlags * flip;
00097 flagPosition.y = yPosLeftFlags * flip;
00098 break;
00099 case Flag::skyblueAbovePink:
00100 flagPosition.x = xPosFrontFlags * flip;
00101 flagPosition.y = yPosLeftFlags * flip;
00102 break;
00103 }
00104
00105 flags[numberOfFlags].type = type;
00106 flags[numberOfFlags].position = flagPosition;
00107 (ConditionalBoundary&) flags[numberOfFlags++] = boundary;
00108 }
00109 }
00110
00111 void LandmarksPercept::estimateOffsetForFlags
00112 (
00113 const Vector2<double>& cameraOffset
00114 )
00115 {
00116 for(int i = 0; i < numberOfFlags; ++i)
00117 {
00118 Flag& flag = flags[i];
00119
00120
00121 double distance;
00122 double direction = flag.x.getCenter();
00123
00124 if(!flag.isOnBorder(flag.y.min) && !flag.isOnBorder(flag.y.max))
00125 {
00126 if(flag.y.min != flag.y.max)
00127 {
00128 distance = flagHeight / (tan(flag.y.max) - tan(flag.y.min)) + flagRadius;
00129 flag.distanceValidity = 0.8;
00130 }
00131 else
00132 {
00133 distance = 4500;
00134 flag.distanceValidity = 0.05;
00135 }
00136 }
00137 else
00138 {
00139 distance = flagRadius / sin(flag.x.getSize() / 2);
00140 if(!flag.isOnBorder(flag.x.min) && !flag.isOnBorder(flag.x.max))
00141 flag.distanceValidity = 0.7;
00142 else
00143 flag.distanceValidity = 0.2;
00144 }
00145
00146 if(!flag.isOnBorder(flag.x.min) && !flag.isOnBorder(flag.x.max))
00147 flag.angleValidity = 0.8;
00148 else
00149 flag.angleValidity = 0.7;
00150
00151 Pose2D p = Pose2D(cameraOffset) + Pose2D(direction)
00152 + Pose2D(Vector2<double>(distance,0));
00153
00154
00155
00156 flag.distance = p.translation.abs();
00157 flag.angle = direction;
00158
00159
00160 if (flag.distance > 6000)
00161 {
00162 flag.distance = 6000;
00163 flag.distanceValidity=0;
00164 }
00165 else if (flag.distance > 3000)
00166 flag.distanceValidity*=0.5;
00167 }
00168 }
00169
00170 void LandmarksPercept::addGoal(colorClass color,
00171 const Vector2<double>& leftPost,
00172 const Vector2<double>& rightPost,
00173 const ConditionalBoundary& boundary)
00174 {
00175 if(numberOfGoals < 2)
00176 {
00177 goals[numberOfGoals].color = color;
00178 goals[numberOfGoals].leftPost = leftPost;
00179 goals[numberOfGoals].rightPost = rightPost;
00180 (ConditionalBoundary&) goals[numberOfGoals++] = boundary;
00181 }
00182 }
00183
00184 void LandmarksPercept::addGoal
00185 (
00186 colorClass color,
00187 bool ownTeamColorIsBlue,
00188 const ConditionalBoundary& boundary
00189 )
00190 {
00191 if(numberOfGoals < 2)
00192 {
00193 int flip = ownTeamColorIsBlue ? -1 : 1;
00194 Vector2<double>leftGoalPost, rightGoalPost;
00195 switch (color)
00196 {
00197 case yellow:
00198 leftGoalPost.x = xPosOwnGoalpost * flip;
00199 leftGoalPost.y = yPosRightGoal * flip;
00200 rightGoalPost.x = xPosOwnGoalpost * flip;
00201 rightGoalPost.y = yPosLeftGoal * flip;
00202 break;
00203 case skyblue:
00204 leftGoalPost.x = xPosOpponentGoalpost * flip;
00205 leftGoalPost.y = yPosLeftGoal * flip;
00206 rightGoalPost.x = xPosOpponentGoalpost * flip;
00207 rightGoalPost.y = yPosRightGoal* flip;
00208 break;
00209 }
00210 goals[numberOfGoals].color = color;
00211 goals[numberOfGoals].leftPost = leftGoalPost;
00212 goals[numberOfGoals].rightPost = rightGoalPost;
00213 (ConditionalBoundary&) goals[numberOfGoals++] = boundary;
00214 }
00215 }
00216
00217 void LandmarksPercept::estimateOffsetForGoals
00218 (
00219 const Vector2<double>& cameraOffset
00220 )
00221 {
00222 for (int i = 0; i < numberOfGoals; i++)
00223 {
00224 if(i >= 2)
00225 {
00226 OUTPUT(idText,text,"to many Goals");
00227 numberOfGoals = 2;
00228 return;
00229 }
00230 Goal& goal = goals[i];
00231
00232
00233
00234
00235 double distance;
00236 if(goal.y.max != goal.y.min)
00237 distance = goalHeight / (tan(goal.y.max) - tan(goal.y.min));
00238 else
00239 distance = 10000;
00240 double direction = goal.x.getCenter();
00241 Pose2D p = Pose2D(cameraOffset) + Pose2D(direction)
00242 + Pose2D(Vector2<double>(distance,0));
00243 goal.distance = p.translation.abs();
00244
00245 goal.angle = direction;
00246 goal.rotation = 0;
00247 if(!goal.isOnBorder(goal.x.min) && !goal.isOnBorder(goal.x.max))
00248 {
00249 goal.angleValidity = 0.80;
00250 goal.distanceValidity = 0.50;
00251 }
00252 else
00253 if (goal.isOnBorder(goal.x.min) && goal.isOnBorder(goal.x.max))
00254 {
00255 goal.angleValidity = 0.20;
00256 goal.distanceValidity = 0.10;
00257 }
00258 else
00259 {
00260 goal.angleValidity = 0.5;
00261 goal.distanceValidity = 0.15;
00262 }
00263
00264 if (goal.distance > 6000)
00265 {
00266 goal.distance = 6000;
00267 goal.distanceValidity=0;
00268 }
00269 else if (goal.distance > 3000)
00270 goal.distanceValidity*=0.5;
00271
00272 }
00273 }
00274
00275
00276 In& operator>>(In& stream,LandmarksPercept& landmarksPercept)
00277 {
00278 stream >> landmarksPercept.frameNumber;
00279 stream.read(&landmarksPercept.numberOfFlags,sizeof(int));
00280 stream.read(&landmarksPercept.flags,sizeof(Flag) * landmarksPercept.numberOfFlags);
00281 stream.read(&landmarksPercept.numberOfGoals,sizeof(int));
00282 stream.read(&landmarksPercept.goals,sizeof(Goal) * landmarksPercept.numberOfGoals);
00283 stream.read(&landmarksPercept.cameraOffset,sizeof(landmarksPercept.cameraOffset));
00284 return stream;
00285 }
00286
00287 Out& operator<<(Out& stream, const LandmarksPercept& landmarksPercept)
00288 {
00289 stream << landmarksPercept.frameNumber;
00290 stream.write(&landmarksPercept.numberOfFlags,sizeof(int));
00291 stream.write(&landmarksPercept.flags,sizeof(Flag) * landmarksPercept.numberOfFlags);
00292 stream.write(&landmarksPercept.numberOfGoals,sizeof(int));
00293 stream.write(&landmarksPercept.goals,sizeof(Goal) * landmarksPercept.numberOfGoals);
00294 stream.write(&landmarksPercept.cameraOffset,sizeof(landmarksPercept.cameraOffset));
00295
00296 return stream;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384