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 void Flag::setBottomColor()
00022 {
00023 switch(type)
00024 {
00025 case pinkAboveYellow:
00026 bottomColor = yellow;
00027 return;
00028 case pinkAboveSkyblue:
00029 bottomColor = skyblue;
00030 return;
00031 default:
00032 bottomColor = pink;
00033 }
00034 }
00035
00036 void Flag::setTopColor()
00037 {
00038 switch(type)
00039 {
00040 case yellowAbovePink:
00041 topColor = yellow;
00042 return;
00043 case skyblueAbovePink:
00044 topColor = skyblue;
00045 return;
00046 default:
00047 topColor = pink;
00048 }
00049 }
00050
00051 LandmarksPercept::LandmarksPercept()
00052 {
00053 reset(0);
00054 }
00055
00056 void LandmarksPercept::reset(unsigned long frameNumber)
00057 {
00058 this->frameNumber = frameNumber;
00059 numberOfFlags = numberOfGoals = 0;
00060 viewAngle = 0;
00061 viewAngleValid = false;
00062 }
00063
00064 void LandmarksPercept::addFlag(Flag::FlagType type,
00065 const Vector2<double>& position,
00066 const ConditionalBoundary& boundary,
00067 const Vector2<int>& topLeft,
00068 const Vector2<int>& topRight,
00069 const Vector2<int>& bottomLeft,
00070 const Vector2<int>& bottomRight)
00071 {
00072 if(numberOfFlags < 4)
00073 {
00074 flags[numberOfFlags].type = type;
00075 flags[numberOfFlags].position = position;
00076 flags[numberOfFlags].topLeft = topLeft;
00077 flags[numberOfFlags].topRight = topRight;
00078 flags[numberOfFlags].bottomLeft = bottomLeft;
00079 flags[numberOfFlags].bottomRight = bottomRight;
00080 flags[numberOfFlags].setBottomColor();
00081 flags[numberOfFlags].setTopColor();
00082 (ConditionalBoundary&) flags[numberOfFlags++] = boundary;
00083 }
00084 }
00085
00086
00087
00088 void LandmarksPercept::addFlag
00089 (
00090 Flag::FlagType type,
00091 bool ownTeamColorIsBlue,
00092 const ConditionalBoundary& boundary,
00093 const Vector2<int>& topLeft,
00094 const Vector2<int>& topRight,
00095 const Vector2<int>& bottomLeft,
00096 const Vector2<int>& bottomRight
00097 )
00098 {
00099 if(numberOfFlags < 4)
00100 {
00101 Vector2<double> flagPosition;
00102
00103 int flip = ownTeamColorIsBlue ? -1 : 1;
00104
00105 switch (type)
00106 {
00107 case Flag::pinkAboveYellow:
00108 flagPosition.x = xPosBackFlags * flip;
00109 flagPosition.y = yPosRightFlags * flip;
00110 break;
00111 case Flag::pinkAboveSkyblue:
00112 flagPosition.x = xPosFrontFlags * flip;
00113 flagPosition.y = yPosRightFlags * flip;
00114 break;
00115 case Flag::yellowAbovePink:
00116 flagPosition.x = xPosBackFlags * flip;
00117 flagPosition.y = yPosLeftFlags * flip;
00118 break;
00119 case Flag::skyblueAbovePink:
00120 flagPosition.x = xPosFrontFlags * flip;
00121 flagPosition.y = yPosLeftFlags * flip;
00122 break;
00123 }
00124
00125 flags[numberOfFlags].type = type;
00126 flags[numberOfFlags].position = flagPosition;
00127 flags[numberOfFlags].topLeft = topLeft;
00128 flags[numberOfFlags].topRight = topRight;
00129 flags[numberOfFlags].bottomLeft = bottomLeft;
00130 flags[numberOfFlags].bottomRight = bottomRight;
00131 flags[numberOfFlags].setBottomColor();
00132 flags[numberOfFlags].setTopColor();
00133 (ConditionalBoundary&) flags[numberOfFlags++] = boundary;
00134 }
00135 }
00136
00137 void LandmarksPercept::estimateOffsetForFlags
00138 (
00139 const Vector2<double>& cameraOffset
00140 )
00141 {
00142 for(int i = 0; i < numberOfFlags; ++i)
00143 {
00144 Flag& flag = flags[i];
00145
00146
00147 double distance;
00148 double direction = flag.x.getCenter();
00149
00150 if(!flag.isOnBorder(flag.y.min) && !flag.isOnBorder(flag.y.max))
00151 {
00152 if(flag.y.min != flag.y.max)
00153 {
00154
00155 distance = flagHeight / (tan(flag.y.max) - tan(flag.y.min)) + flagRadius;
00156 flag.distanceValidity = 0.8;
00157 }
00158 else
00159 {
00160 distance = 4500;
00161 flag.distanceValidity = 0.05;
00162 }
00163 }
00164 else
00165 {
00166 distance = flagRadius / sin(flag.x.getSize() / 2);
00167 if(!flag.isOnBorder(flag.x.min) && !flag.isOnBorder(flag.x.max))
00168 flag.distanceValidity = 0.7;
00169 else
00170 flag.distanceValidity = 0.2;
00171 }
00172
00173 if(!flag.isOnBorder(flag.x.min) && !flag.isOnBorder(flag.x.max))
00174 flag.angleValidity = 0.8;
00175 else
00176 flag.angleValidity = 0.7;
00177
00178 Pose2D p = Pose2D(cameraOffset) + Pose2D(direction)
00179 + Pose2D(Vector2<double>(distance,0));
00180
00181
00182
00183 flag.distance = p.translation.abs();
00184 flag.angle = direction;
00185
00186
00187 if (flag.distance > 6000)
00188 {
00189 flag.distance = 6000;
00190 flag.distanceValidity=0;
00191 }
00192 else if (flag.distance > 3000)
00193 flag.distanceValidity*=0.5;
00194 }
00195 }
00196
00197 void LandmarksPercept::addGoal(colorClass color,
00198 const ConditionalBoundary& boundary,
00199 const Vector2<int>& topLeft, const Vector2<int>& topRight,
00200 const Vector2<int>& bottomLeft, const Vector2<int>& bottomRight,
00201 double distance, double angle, double rotation,
00202 double distanceValidity, double angleValidity)
00203 {
00204
00205 if(numberOfGoals >= 2)
00206 return;
00207
00208
00209 Vector2<double> leftGoalpost, rightGoalpost;
00210 colorClass ownGoalColor = (getPlayer().getTeamColor() == Player::blue) ? skyblue : yellow;
00211 if (color==ownGoalColor)
00212 {
00213 leftGoalpost.x = xPosOwnGoalpost;
00214 leftGoalpost.y = yPosRightGoal;
00215 rightGoalpost.x = xPosOwnGoalpost;
00216 rightGoalpost.y = yPosLeftGoal;
00217 }
00218 else
00219 {
00220 leftGoalpost.x = xPosOpponentGoalpost;
00221 leftGoalpost.y = yPosLeftGoal;
00222 rightGoalpost.x = xPosOpponentGoalpost;
00223 rightGoalpost.y = yPosRightGoal;
00224 }
00225
00226
00227 Goal& goal = goals[numberOfGoals++];
00228
00229 goal.color = color;
00230 goal.leftPost = leftGoalpost;
00231 goal.rightPost = rightGoalpost;
00232 goal.topLeft = topLeft;
00233 goal.topRight = topRight;
00234 goal.bottomLeft = bottomLeft;
00235 goal.bottomRight = bottomRight;
00236 (ConditionalBoundary&) goal = boundary;
00237 goal.distance = distance;
00238 goal.angle = angle;
00239 goal.rotation = rotation;
00240 goal.angleValidity = angleValidity;
00241 goal.distanceValidity = distanceValidity;
00242 }
00243
00244 void LandmarksPercept::addGoal(colorClass color,
00245 const ConditionalBoundary& boundary,
00246 const Vector2<int>& topLeft,
00247 const Vector2<int>& topRight,
00248 const Vector2<int>& bottomLeft,
00249 const Vector2<int>& bottomRight,
00250 const CameraMatrix& cameraMatrix)
00251 {
00252 if (numberOfGoals < 2)
00253 {
00254 addGoal(color, boundary, topLeft, topRight, bottomLeft, bottomRight, 0, 0, 0, 0, 0);
00255 estimateOffsetAndValiditiesForGoal(goals[numberOfGoals-1], cameraMatrix);
00256 }
00257 }
00258
00259 void LandmarksPercept::estimateOffsetAndValiditiesForGoal(Goal& goal, const CameraMatrix& cameraMatrix)
00260 {
00261 Vector2<double> cameraOffset(cameraMatrix.translation.x, cameraMatrix.translation.y);
00262
00263 double distance, distanceByHeight,distanceByWidth;
00264 if(goal.y.max != goal.y.min)
00265
00266 distanceByHeight = goalHeight / (tan(goal.y.max) - tan(goal.y.min));
00267 else
00268 distanceByHeight = 10000;
00269
00270 if(goal.x.max != goal.x.min)
00271
00272 distanceByWidth = goalWidth / (2 * (tan((goal.x.max - goal.x.min)/2)));
00273 else
00274 distanceByWidth = 10000;
00275
00276 if( distanceByHeight < distanceByWidth)
00277 distance = distanceByHeight;
00278 else
00279 distance = distanceByWidth;
00280
00281 double direction = goal.x.getCenter();
00282 Pose2D p = Pose2D(cameraOffset) + Pose2D(direction)
00283 + Pose2D(Vector2<double>(distance,0));
00284 goal.distance = p.translation.abs();
00285
00286 goal.angle = direction;
00287 goal.rotation = 0;
00288 if(!goal.isOnBorder(goal.x.min) && !goal.isOnBorder(goal.x.max))
00289 {
00290 goal.angleValidity = 0.80;
00291 goal.distanceValidity = 0.50;
00292 }
00293 else
00294 if (goal.isOnBorder(goal.x.min) && goal.isOnBorder(goal.x.max))
00295 {
00296 goal.angleValidity = 0.20;
00297 goal.distanceValidity = 0.10;
00298 }
00299 else
00300 {
00301 goal.angleValidity = 0.5;
00302 goal.distanceValidity = 0.15;
00303 }
00304
00305 if (goal.distance > xPosOpponentFieldBorder * 1.2)
00306 {
00307 goal.distanceValidity=0;
00308 }
00309 else if (goal.distance > xPosOpponentFieldBorder * 0.5)
00310 goal.distanceValidity*=0.5;
00311
00312 }