PerceptionSearch.cc
Go to the documentation of this file.00001
00002
00003 #include "DualCoding/AprilTagData.h"
00004 using namespace DualCoding;
00005
00006
00007 #include "Kodu/Primitives/PerceptionSearch.h"
00008
00009 namespace Kodu {
00010
00011 bool HasAprilTagID::operator()(const ShapeRoot& kShape) const {
00012 return (kShape->getType() == aprilTagDataType
00013 && static_cast<const AprilTagData&>(kShape.getData()).getTagID() == id);
00014 }
00015
00016 bool IsMatchForTargetObject::operator()(const ShapeRoot& kShape) const {
00017
00018 return (targetObject->isMatchFor(kShape));
00019 }
00020
00021
00022
00023
00024
00025
00026 bool IsNotWorldShape::operator()(const ShapeRoot& kWShape) const {
00027 switch (kWShape->getType()) {
00028
00029 case cylinderDataType: {
00030 const Shape<CylinderData>& kCyl = ShapeRootTypeConst(kWShape, CylinderData);
00031 if ((kCyl->getRadius() < 40.0f) || (kCyl->getRadius() > 75.0f))
00032 return true;
00033 break;
00034 }
00035
00036
00037 case aprilTagDataType:
00038 return (!IsStar()(kWShape));
00039
00040
00041 case localizationParticleDataType:
00042 case polygonDataType:
00043 case agentDataType:
00044 return false;
00045
00046 default:
00047 return true;
00048 }
00049 return false;
00050 }
00051
00052 bool IsStar::operator()(const ShapeRoot& kWShape) const {
00053 return (kWShape.isValid() && kWShape->getType() == aprilTagDataType
00054 && static_cast<const AprilTagData&>(kWShape.getData()).getTagID() >= 24);
00055 }
00056
00057 bool IsShapeOfType::operator()(const ShapeRoot& kShape) const {
00058 return (kShape->getType() == targetShapeType);
00059 }
00060
00061 bool IsNotExcludedShape::operator()(const ShapeRoot& kShape) const {
00062 return ( kShape.getId() != excludedShape.getId() && (kShape->getName() != "AgentData") &&
00063 ( kShape->getType() == cylinderDataType || kShape->getType() == agentDataType ) );
00064 }
00065
00066 bool ClearSelfShape::operator()(const ShapeRoot& kShape) const {
00067 return (kShape->getName() != "AgentData");
00068 }
00069
00070 bool IsLeftOfAgent::operator()(const ShapeRoot& kShape) const {
00071
00072 return (bearingFromAgentToObject(kShape) > 0.0f ? true : false);
00073 }
00074
00075 bool IsRightOfAgent::operator()(const ShapeRoot& kShape) const {
00076
00077 return (!(IsLeftOfAgent()(kShape)));
00078 }
00079
00080 bool IsInFrontAgent::operator()(const ShapeRoot& kShape) const {
00081
00082 AngSignPi dtheta = bearingFromAgentToObject(kShape);
00083
00084
00085
00086 dtheta += AngSignPi(M_PI / 2.0f);
00087
00088 return (dtheta > 0.0f ? true : false);
00089 }
00090
00091 bool IsBehindAgent::operator()(const ShapeRoot& kShape) const {
00092
00093 return (!(IsInFrontAgent()(kShape)));
00094 }
00095
00096 bool IsCloseByAgent::operator()(const ShapeRoot& kShape) const {
00097
00098 return (distanceFromAgentToObject(kShape) <= 700.0f);
00099 }
00100
00101 bool IsFarAwayFromAgent::operator()(const ShapeRoot& kShape) const {
00102
00103 return (distanceFromAgentToObject(kShape) >= 1050.0f);
00104 }
00105
00106 float bearingFromAgentToPoint(const Point& kPoint) {
00107 float dtheta = 0.0f;
00108 switch (kPoint.getRefFrameType()) {
00109
00110 case allocentric:
00111 {
00112
00113
00114 const Point& kAgentPt = VRmixin::theAgent->getCentroid();
00115 AngSignPi bearing2ThisPoint = (kPoint - kAgentPt).atanYX();
00116
00117
00118 dtheta = bearing2ThisPoint - AngSignPi(VRmixin::theAgent->getOrientation());
00119 break;
00120 }
00121
00122 case egocentric:
00123 {
00124 dtheta = kPoint.atanYX();
00125 break;
00126 }
00127
00128 default:
00129 std::cout << "WARNING: Used unhandled reference frame in bearingFromAgentToPoint(...)\n";
00130 break;
00131 }
00132
00133 return dtheta;
00134 }
00135
00136 float bearingFromAgentToObject(const ShapeRoot& kShape) {
00137 return bearingFromAgentToPoint(kShape->getCentroid());
00138 }
00139
00140 float distanceFromAgentToPoint(const Point& kPoint) {
00141 float dx = kPoint.coordX();
00142 float dy = kPoint.coordY();
00143 switch (kPoint.getRefFrameType()) {
00144
00145 case allocentric:
00146 {
00147
00148 Point agentPoint = VRmixin::theAgent->getCentroid();
00149
00150 dx = dx - agentPoint.coordX();
00151 dy = dy - agentPoint.coordY();
00152 break;
00153 }
00154
00155
00156 case egocentric:
00157 break;
00158
00159
00160 default:
00161 std::cout << "WARNING: Used unhandled reference frame in distanceFromAgentToPoint(...)\n";
00162 return (0.0f);
00163 }
00164
00165 return sqrt((dx * dx) + (dy * dy));
00166 }
00167
00168 float distanceFromAgentToObject(const ShapeRoot& kShape) {
00169 return distanceFromAgentToPoint(kShape->getCentroid());
00170 }
00171
00172 float distanceInBetweenAgentAndObject(const ShapeRoot& kShape) {
00173
00174 static float const kRobotInflatedRadius = 205.0f;
00175 float distBtwObjects = 0.0f;
00176 switch(kShape->getType()) {
00177 case cylinderDataType:
00178 {
00179
00180 float radius = objectRadius(kShape);
00181
00182 float distBetweenCentroids = distanceFromAgentToObject(kShape);
00183 distBtwObjects = distBetweenCentroids - kRobotInflatedRadius - radius;
00184 break;
00185 }
00186 case agentDataType:
00187 {
00188
00189 float distBetweenCentroids = distanceFromAgentToObject(kShape);
00190 distBtwObjects = distBetweenCentroids - 2*kRobotInflatedRadius;
00191 break;
00192 }
00193 default:
00194 std::cout << "WARNING: Used unhandled shape type " << kShape << " in "
00195 << "distanceInBetweenAgentAndObject(...)\n";
00196 return (0.0f);
00197 }
00198 return (distBtwObjects > 0.0f ? distBtwObjects : 0.0f);
00199 }
00200
00201 float objectRadius(const ShapeRoot& kShape) {
00202 static float const kErrValue = -1.0f;
00203 float radius = 0.0f;
00204 switch(kShape->getType()) {
00205 case cylinderDataType:
00206 radius = ShapeRootTypeConst(kShape, CylinderData)->getRadius();
00207 break;
00208
00209 case agentDataType:
00210 radius = 205.0f;
00211 break;
00212
00213 default:
00214 std::cout << "WARNING: Used unhandled shape type in objectRadius(...)\n";
00215 return kErrValue;
00216 }
00217 return radius;
00218 }
00219
00220 ShapeRoot getClosestObject(const std::vector<ShapeRoot>& kObjects) {
00221 const std::size_t kSize = kObjects.size();
00222
00223 if (kSize == 0) {
00224 return ShapeRoot();
00225 }
00226
00227
00228 else if (kSize == 1) {
00229 return kObjects[0];
00230 }
00231
00232
00233 else {
00234 ShapeRoot nearestObject = kObjects[0];
00235 float nearestObjectDist = distanceFromAgentToObject(nearestObject);
00236
00237
00238 for (std::size_t index = 1; index < kSize; index++) {
00239 float currentObjectDist = distanceFromAgentToObject(kObjects[index]);
00240 if (currentObjectDist < nearestObjectDist) {
00241 nearestObjectDist = currentObjectDist;
00242 nearestObject = kObjects[index];
00243 }
00244 }
00245 return nearestObject;
00246 }
00247 }
00248
00249 ShapeRoot getClosestObjectToPoint(const std::vector<ShapeRoot>& kShapes,
00250 const Point& kComparisonPoint)
00251 {
00252 const std::size_t kSize = kShapes.size();
00253
00254 if (kSize == 0) {
00255 return ShapeRoot();
00256 }
00257
00258 else {
00259 ShapeRoot closestMatch = kShapes[0];
00260 float minCenDiff = closestMatch->getCentroid().xyDistanceFrom(kComparisonPoint);
00261
00262 for (std::size_t i = 1; i < kSize; i++) {
00263 float cenDiff = kShapes[i]->getCentroid().xyDistanceFrom(kComparisonPoint);
00264 if (cenDiff < minCenDiff) {
00265 closestMatch = kShapes[i];
00266 minCenDiff = cenDiff;
00267 }
00268 }
00269 return closestMatch;
00270 }
00271 }
00272
00273 std::vector<ShapeRoot> getObjectsLocated(const std::vector<ShapeRoot>& kObjects, SearchLocation_t location) {
00274
00275 std::vector<ShapeRoot> result = kObjects;
00276 std::cout << "Checking map for objects:";
00277
00278
00279 if (location & SL_IN_FRONT) {
00280 std::cout << " [in front]";
00281 result = subset(result, IsInFrontAgent());
00282 } else if (location & SL_BEHIND) {
00283 std::cout << " [behind]";
00284 result = subset(result, IsBehindAgent());
00285 }
00286
00287
00288 if (location & SL_TO_LEFT) {
00289 std::cout << " [to the left]";
00290 result = subset(result, IsLeftOfAgent());
00291 } else if (location & SL_TO_RIGHT) {
00292 std::cout << " [to the right]";
00293 result = subset(result, IsRightOfAgent());
00294 }
00295
00296
00297 if (location & SL_CLOSE_BY) {
00298 std::cout << " [close by]";
00299 result = subset(result, IsCloseByAgent());
00300 }
00301 else if (location & SL_FAR_AWAY) {
00302 std::cout << " [far away]";
00303 result = subset(result, IsFarAwayFromAgent());
00304 }
00305 std::cout << std::endl;
00306 return result;
00307 }
00308
00309 std::vector<ShapeRoot> getMatchingObjects(const std::vector<ShapeRoot>& kObjects,
00310 const std::string& kColor, const std::string& kType) {
00311 std::string rcolor = "";
00312 if (kType == "apple") {
00313 rcolor = "red";
00314 } else if (kType == "rock") {
00315 rcolor = "blue";
00316 } else if (kType == "tree") {
00317 rcolor = "green";
00318 }
00319 if (rcolor != "")
00320 return subset(subset(kObjects, IsType(cylinderDataType)), IsColor(rcolor));
00321 else if(kType == "robot")
00322 return subset(kObjects, IsType(agentDataType));
00323 else
00324 return subset(kObjects, IsName(kType));
00325
00326 }
00327
00328 ShapeRoot getClosestObjectMatching(const std::string& color, const std::string& type, SearchLocation_t location,
00329 const ShapeRoot& kExcludedShape) {
00330
00331
00332 ShapeRoot closestMatch;
00333
00334
00335 NEW_SHAPEROOTVEC(matchingObjects, subset(VRmixin::worldShS, ClearSelfShape()));
00336 if ( ! matchingObjects.empty() && kExcludedShape.isValid() )
00337 matchingObjects = subset(matchingObjects, IsNotExcludedShape(kExcludedShape));
00338
00339
00340 if ( ! matchingObjects.empty() )
00341 matchingObjects = getMatchingObjects(matchingObjects, color, type);
00342
00343
00344
00345 if ( ! matchingObjects.empty() && (location != SL_UNRESTRICTED) )
00346 matchingObjects = getObjectsLocated(matchingObjects, location);
00347
00348
00349 if ( ! matchingObjects.empty() )
00350 closestMatch = getClosestObject(matchingObjects);
00351
00352
00353 return closestMatch;
00354 }
00355 }