00001 #include "GT2005StableSampleTemplateGenerator.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 GT2005StableSampleTemplateGenerator::GT2005StableSampleTemplateGenerator()
00015 {
00016 numberOfTemplates = 0;
00017 numberOfFlags = 0;
00018 nextTemplate = 0;
00019 randomFactor = 0;
00020 }
00021
00022
00023
00024
00025
00026
00027 GT2005StableSelfLocatorSample GT2005StableSampleTemplateGenerator::getTemplate()
00028 {
00029 if(nextTemplate >= numberOfTemplates)
00030 {
00031 nextTemplate = 0;
00032 ++randomFactor;
00033 }
00034
00035 while(nextTemplate < numberOfTemplates)
00036 {
00037 const Pose2D& t = templates[nextTemplate++];
00038
00039
00040 if(field.isInside(t.translation))
00041 {
00042 return GT2005StableSelfLocatorSample(Pose2D::random(Range<double>(t.translation.x - randomFactor * 50,
00043 t.translation.x + randomFactor * 50),
00044 Range<double>(t.translation.y - randomFactor * 50,
00045 t.translation.y + randomFactor * 50),
00046 Range<double>(t.getAngle() - randomFactor * 0.1,
00047 t.getAngle() + randomFactor * 0.1)));
00048 }
00049 }
00050 return GT2005StableSelfLocatorSample(field.randomPose());
00051 }
00052
00053
00054
00055
00056
00057
00058 bool GT2005StableSampleTemplateGenerator::poseFromBearings(double dir0,double dir1,double dir2,
00059 const Vector2<double>& mark0,
00060 const Vector2<double>& mark1,
00061 const Vector2<double>& mark2,
00062 const Vector2<double>& cameraOffset,
00063 Pose2D& resultingPose)
00064 {
00065 double w1 = dir1 - dir0,
00066 w2 = dir2 - dir1;
00067
00068 if(sin(w1) != 0 && sin(w2) != 0)
00069 {
00070 Vector2<double> p = mark2 - mark1;
00071 double a2 = p.abs();
00072 p = (Pose2D(mark0) - Pose2D(atan2(p.y,p.x),mark1)).translation;
00073 double a1 = p.abs();
00074 if(a1 > 0 && a2 > 0)
00075 {
00076 double w3 = pi2 - w1 - w2 - atan2(p.y,p.x);
00077 double t = a1 * sin(w2) / (a2 * sin(w1)) + cos(w3);
00078 if(t != 0)
00079 {
00080 double w = atan(sin(w3) / t);
00081 double b = a1 * sin(w) / sin(w1);
00082 w = pi - w1 - w;
00083 p = mark0 - mark1;
00084 resultingPose = Pose2D(atan2(p.y,p.x) - w,mark1)
00085 + Pose2D(Vector2<double>(b,0));
00086 p = (Pose2D(mark1) - resultingPose).translation;
00087 resultingPose += Pose2D(atan2(p.y,p.x) - dir1);
00088 resultingPose += Pose2D(Vector2<double>(-cameraOffset.x,
00089 -cameraOffset.y));
00090 return true;
00091 }
00092 }
00093 }
00094 return false;
00095 }
00096
00097
00098
00099
00100
00101 int GT2005StableSampleTemplateGenerator::poseFromBearingsAndDistance(
00102 double dir0,double dir1,double dist,
00103 const Vector2<double>& mark0,
00104 const Vector2<double>& mark1,
00105 const Vector2<double>& cameraOffset,
00106 Pose2D& resultingPose1,
00107 Pose2D& resultingPose2)
00108 {
00109 double alpha = dir0 - dir1;
00110 Vector2<double> diff = mark0 - mark1;
00111 double dir10 = atan2(diff.y,diff.x);
00112 double f = dist * sin(alpha) / diff.abs();
00113 if(fabs(f) <= 1)
00114 {
00115 double gamma = asin(f),
00116 beta = pi - alpha - gamma;
00117
00118 resultingPose1 = Pose2D(dir10 + beta,mark1) +
00119 Pose2D(pi - dir1,Vector2<double>(dist,0)) +
00120 Pose2D(Vector2<double>(-cameraOffset.x,
00121 -cameraOffset.y));
00122
00123 if(fabs(alpha) < pi_2 || fabs(alpha) > 3 * pi_2)
00124 {
00125 if(gamma > 0)
00126 gamma = pi - gamma;
00127 else
00128 gamma = -pi - gamma;
00129 beta = pi - alpha - gamma;
00130 resultingPose2 = Pose2D(dir10 + beta,mark1) +
00131 Pose2D(pi - dir1,Vector2<double>(dist,0)) +
00132 Pose2D(Vector2<double>(-cameraOffset.x,
00133 -cameraOffset.y));
00134 return 2;
00135 }
00136 else
00137 return 1;
00138 }
00139 else
00140 return 0;
00141 }
00142
00143
00144 bool GT2005StableSampleTemplateGenerator::getBearing(const LandmarksPercept& landmarksPercept,int i,
00145 Vector2<double>& mark,
00146 double& dir,double& dist)
00147 {
00148 if(i < numberOfFlags)
00149 {
00150 const Flag& flag = flags[i];
00151 mark = flag.position;
00152 dir = flag.angle;
00153 dist = flag.distance;
00154 return true;
00155 }
00156 else
00157 {
00158 i -= numberOfFlags;
00159 const Goal& goal = landmarksPercept.goals[i >> 1];
00160 if((i & 1) == 0 && !goal.isOnBorder(goal.x.min))
00161 {
00162 mark = goal.rightPost;
00163 dir = goal.x.min;
00164 dist = goal.distance;
00165 return true;
00166 }
00167 else if((i & 1) == 1 && !goal.isOnBorder(goal.x.max))
00168 {
00169 mark = goal.leftPost;
00170 dir = goal.x.max;
00171 dist = goal.distance;
00172 return true;
00173 }
00174 else
00175 return false;
00176 }
00177 }
00178
00179
00180
00181
00182
00183 void GT2005StableSampleTemplateGenerator::addFlag(const Flag& flag)
00184 {
00185 if(!flag.isOnBorder(flag.x.min) && !flag.isOnBorder(flag.x.max))
00186 {
00187 int i;
00188 for(i = 0; i < numberOfFlags && flags[i].type != flag.type; ++i)
00189 ;
00190
00191 if(i < numberOfFlags)
00192 --numberOfFlags;
00193
00194 if(i < FLAGS_MAX)
00195 ++i;
00196
00197 while(--i > 0)
00198 flags[i] = flags[i - 1];
00199
00200 flags[0] = flag;
00201
00202 if(numberOfFlags < FLAGS_MAX)
00203 ++numberOfFlags;
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212 void GT2005StableSampleTemplateGenerator::generateTemplates(const LandmarksPercept& landmarksPercept,
00213 const LinesPercept& linesPercept,
00214 const Pose2D& odometry,
00215 int numberOfPerceptTypes,
00216 const LinesPercept::LineType types[LinesPercept::numberOfLineTypes])
00217 {
00218 randomFactor = 0;
00219
00220
00221
00222 int i;
00223 for(i = 0; i < numberOfFlags; ++i)
00224 {
00225 Flag& flag = flags[i];
00226 Vector2<double> p = ( Pose2D(flag.angle) + Pose2D(Vector2<double>(flag.distance,0)) - odometry).translation;
00227 flag.angle = atan2(p.y,p.x);
00228 flag.distance = p.abs();
00229 }
00230
00231 for (i=0;i<landmarksPercept.numberOfFlags;i++){
00232 addFlag(landmarksPercept.flags[i]);
00233 }
00234
00235 numberOfTemplates = 0;
00236 nextTemplate = 0;
00237 double dir0,
00238 dir1,
00239 dir2;
00240 double dist0,
00241 dist1;
00242 Vector2<double> mark0,
00243 mark1,
00244 mark2,
00245 cameraOffset(landmarksPercept.cameraOffset.x,
00246 landmarksPercept.cameraOffset.y);
00247
00248
00249 int n = numberOfFlags + 2 * landmarksPercept.numberOfGoals;
00250 for(i = 0; i < n - 2; ++i)
00251
00252 if(getBearing(landmarksPercept,i,mark0,dir0,dist0))
00253 for(int j = i + 1; j < n - 1; ++j)
00254
00255 if(getBearing(landmarksPercept,j,mark1,dir1,dist1))
00256 {
00257 if(numberOfTemplates >= TEMPLATES_MAX - 4)
00258 return;
00259 numberOfTemplates += poseFromBearingsAndDistance(dir0,dir1,dist1,mark0,mark1,cameraOffset,
00260 templates[numberOfTemplates],templates[numberOfTemplates + 1]);
00261 numberOfTemplates += poseFromBearingsAndDistance(dir1,dir0,dist0,mark1,mark0,cameraOffset,
00262 templates[numberOfTemplates],templates[numberOfTemplates + 1]);
00263
00264 for(int k = j + 1; k < n; ++k)
00265 if(getBearing(landmarksPercept,k,mark2,dir2,dist0))
00266 if(poseFromBearings(dir0,dir1,dir2,mark0,mark1,mark2,cameraOffset,
00267 templates[numberOfTemplates]))
00268 if(++numberOfTemplates == TEMPLATES_MAX)
00269 return;
00270
00271 }
00272
00273
00274
00275
00276
00277 for(i = LinesPercept::yellowGoal; i <= LinesPercept::skyblueGoal; ++i)
00278 {
00279 for(int j = 0; j < linesPercept.points[i].numberOfPoints; ++j)
00280 {
00281 const Vector2<int>& point = linesPercept.points[i].pointsOnField[j];
00282 Pose2D t = templateTable->sample(point.abs());
00283 if((getPlayer().getTeamColor() == Player::blue && i == LinesPercept::yellowGoal) ||
00284 (getPlayer().getTeamColor() == Player::red && i == LinesPercept::skyblueGoal))
00285 {
00286
00287 t = Pose2D(pi) + t;
00288 }
00289 templates[numberOfTemplates++] = t + Pose2D(-atan2((double)point.y,(double)point.x));
00290 if(numberOfTemplates == TEMPLATES_MAX)
00291 return;
00292 }
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 }
00312
00313 int GT2005StableSampleTemplateGenerator::getNumberOfTemplates(){
00314 return numberOfTemplates;
00315 }
00316
00317
00318
00319
00320
00321