00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "Actionfield.h"
00010 #include "FutureWorldModelGenerator.h"
00011 #include "FieldObject.h"
00012 #include "PotentialfieldComposition.h"
00013 #include "FormationObject.h"
00014
00015
00016
00017 Action::Action()
00018 {
00019 manipulatedObject = 0;
00020 name = "";
00021 }
00022
00023
00024 Action::~Action()
00025 {
00026 impactAreas.clear();
00027 std::vector < PotentialfieldTransformation* >::iterator t;
00028 for(t = transformations.begin(); t != transformations.end(); ++t)
00029 {
00030 delete (*t);
00031 }
00032 transformations.clear();
00033 }
00034
00035
00036 Action::Action(const Action& a)
00037 {
00038 name = a.name;
00039 manipulatedObject = a.manipulatedObject;
00040 joinAction = a.joinAction;
00041 actionType = a.actionType;
00042 impactAreas = a.impactAreas;
00043 std::vector < PotentialfieldTransformation* >::const_iterator t;
00044 for(t = a.transformations.begin(); t != a.transformations.end(); ++t)
00045 {
00046 transformations.push_back((*t)->copy());
00047 }
00048 }
00049
00050
00051 bool Action::canBeApplied(const PfPose& robotPose,
00052 const std::vector<Object*>& objects)
00053 {
00054 if((actionType == MOVE_SELF) || (actionType == MEASURE_SELF))
00055 {
00056 return true;
00057 }
00058 if(actionType == MEASURE_OBJECT)
00059 {
00060 return objects[objectIdx]->isActive();
00061 }
00062 else
00063 {
00064 if(!(objects[objectIdx]->isActive()))
00065 {
00066 return false;
00067 }
00068 unsigned int i,j;
00069 PfPose manipulatedObjectPose(objects[objectIdx]->getPose());
00070 PfPose objPose, robPose;
00071 if(manipulatedObjectPose.hasProbabilityDistribution)
00072 {
00073 if(robotPose.hasProbabilityDistribution)
00074 {
00075 for(j=0; j<robotPose.probabilityDistribution.size(); j++)
00076 {
00077 for(i=0; i<manipulatedObjectPose.probabilityDistribution.size(); i++)
00078 {
00079 if(poseInsideImpactArea(robotPose.probabilityDistribution[j],
00080 manipulatedObjectPose.probabilityDistribution[i]))
00081 {
00082 return true;
00083 }
00084 }
00085 }
00086 }
00087 else
00088 {
00089 for(i=0; i<manipulatedObjectPose.probabilityDistribution.size(); i++)
00090 {
00091 if(poseInsideImpactArea(robotPose,
00092 manipulatedObjectPose.probabilityDistribution[i]))
00093 {
00094 return true;
00095 }
00096 }
00097 }
00098 }
00099 else
00100 {
00101 if(robotPose.hasProbabilityDistribution)
00102 {
00103 for(i=0; i<robotPose.probabilityDistribution.size(); i++)
00104 {
00105 if(poseInsideImpactArea(robotPose.probabilityDistribution[i],
00106 manipulatedObjectPose))
00107 {
00108 return true;
00109 }
00110 }
00111 }
00112 else
00113 {
00114 return poseInsideImpactArea(robotPose, manipulatedObjectPose);
00115 }
00116 }
00117 }
00118 return false;
00119 }
00120
00121
00122 inline bool Action::poseInsideImpactArea(const PfPose& robPose, const PfPose& objPose)
00123 {
00124 PfVec relPosition(objPose.pos);
00125 relPosition -= robPose.pos;
00126 relPosition.rotate(-robPose.rotation);
00127 std::vector< Polygon >::const_iterator polygon;
00128 for(polygon = impactAreas.begin(); polygon != impactAreas.end(); ++polygon)
00129 {
00130 if((*polygon).pointInside(relPosition))
00131 {
00132 return true;
00133 }
00134 }
00135 return false;
00136 }
00137
00138
00139
00140 Actionfield::Actionfield(const std::string& name)
00141 {
00142 this->name = name;
00143 futureWorldModelGenerator = FutureWorldModelGenerator::getFutureWorldModelGenerator();
00144 }
00145
00146
00147 Actionfield::~Actionfield()
00148 {
00149 actions.clear();
00150 unsigned int numOfObjects(dynamicObjects.size());
00151 for(unsigned int i=0; i<worldStateDepth; i++)
00152 {
00153 for(unsigned int j=0; j<numOfObjects; j++)
00154 {
00155 delete futureWorldStates[i][j];
00156 }
00157 }
00158 futureWorldStates.clear();
00159 }
00160
00161
00162 void Actionfield::init()
00163 {
00164
00165 std::vector < Action >::iterator action;
00166 for (action = actions.begin(); action != actions.end(); ++action)
00167 {
00168 if(((*action).actionType == MOVE_OBJECT) || ((*action).actionType == MEASURE_OBJECT))
00169 {
00170 addManipulatedObject((*action));
00171 }
00172 }
00173
00174 if(actionfieldType == SINGLE_ACTION_FIELD)
00175 {
00176 worldStateDepth = 1;
00177 }
00178 else if(actionfieldType == FIXED_SEQUENCE_FIELD)
00179 {
00180 worldStateDepth = actions.size();
00181 }
00182
00183
00184
00185 futureWorldStates.clear();
00186 futureWorldStates.resize(worldStateDepth);
00187 unsigned int numOfObjects(dynamicObjects.size());
00188 for(unsigned int i=0; i<worldStateDepth; i++)
00189 {
00190 futureWorldStates[i].resize(numOfObjects);
00191 for(unsigned int j=0; j<numOfObjects; j++)
00192 {
00193 futureWorldStates[i][j] = dynamicObjects[j]->getCopy();
00194 }
00195 }
00196 futureRobotPoses.resize(worldStateDepth);
00197 }
00198
00199
00200 void Actionfield::addObject(Object* object)
00201 {
00202 Potentialfield::addObject(object);
00203 if(object->isStatic())
00204 {
00205 staticObjects.push_back(object);
00206 }
00207 else
00208 {
00209 dynamicObjects.push_back(object);
00210 }
00211 }
00212
00213
00214 void Actionfield::addManipulatedObject(Action& action)
00215 {
00216 for(unsigned int i=0; i<dynamicObjects.size(); i++)
00217 {
00218 if(dynamicObjects[i] == action.manipulatedObject)
00219 {
00220 action.objectIdx = i;
00221 return;
00222 }
00223 }
00224 action.objectIdx = dynamicObjects.size();
00225 dynamicObjects.push_back(action.manipulatedObject);
00226 objects.push_back(action.manipulatedObject);
00227 }
00228
00229
00230 void Actionfield::addAction(const Action& action)
00231 {
00232 actions.push_back(action);
00233 }
00234
00235
00236 void Actionfield::execute(const PfPose& pose, PotentialfieldResult& result)
00237 {
00238 result.value = 0.0;
00239 result.motion.speed = 42;
00240 result.actionPossible = false;
00241 if((actionfieldType == SINGLE_ACTION_FIELD) || (actionfieldType == FIXED_SEQUENCE_FIELD))
00242 {
00243 unsigned int currentAction(0);
00244 double time(0.0);
00245 if(actions[currentAction].canBeApplied(pose, dynamicObjects))
00246 {
00247 result.actionPossible = true;
00248 result.subAction = actions[0].name;
00249 futureWorldModelGenerator->transformWorldState(
00250 pose, futureRobotPoses[0], actions[0], this,
00251 dynamicObjects, futureWorldStates[0], staticObjects);
00252 time += actions[0].time;
00253 currentAction++;
00254 while(currentAction < actions.size())
00255 {
00256 if(actions[currentAction].canBeApplied(futureRobotPoses[currentAction-1],
00257 futureWorldStates[currentAction-1]))
00258 {
00259 futureWorldModelGenerator->transformWorldState(
00260 futureRobotPoses[currentAction-1], futureRobotPoses[currentAction],
00261 actions[currentAction], this,
00262 futureWorldStates[currentAction-1], futureWorldStates[currentAction],
00263 staticObjects);
00264 time += actions[currentAction].time;
00265 currentAction++;
00266 }
00267 else
00268 {
00269 break;
00270 }
00271 }
00272 if(criterion == CRITERION_CONST)
00273 {
00274 result.value = criterionParameter;
00275 }
00276 else
00277 {
00278 bool dummy;
00279 result.value = computeActionValue(actions[currentAction-1], time, pose,
00280 futureRobotPoses[currentAction-1],
00281 dynamicObjects, futureWorldStates[currentAction-1], dummy);
00282 }
00283 result.motion = actions[0].motionParameters;
00284 }
00285 }
00286 else
00287 {
00288 double time(0.0);
00289 std::vector<unsigned int> actionSequenceList;
00290 for(unsigned int currentAction=0; currentAction<actions.size(); currentAction++)
00291 {
00292 if(actions[currentAction].canBeApplied(pose, dynamicObjects))
00293 {
00294 futureWorldModelGenerator->transformWorldState(
00295 pose, futureRobotPoses[0], actions[currentAction], this,
00296 dynamicObjects, futureWorldStates[0], staticObjects);
00297 time = actions[currentAction].time;
00298 bool pruningCheckPassed;
00299 double value = computeActionValue(actions[currentAction], time, pose,
00300 futureRobotPoses[0], dynamicObjects,
00301 futureWorldStates[0], pruningCheckPassed);
00302 if(!pruningCheckPassed)
00303 {
00304 continue;
00305 }
00306 if(!result.actionPossible)
00307 {
00308 result.actionPossible = true;
00309 result.value = value;
00310 result.motion = actions[currentAction].motionParameters;
00311 result.subAction = actions[currentAction].name;
00312 }
00313 else if(value < result.value)
00314 {
00315 result.value = value;
00316 result.motion = actions[currentAction].motionParameters;
00317 result.subAction = actions[currentAction].name;
00318 }
00319 if(worldStateDepth > 1)
00320 {
00321 actionSequenceList.push_back(currentAction);
00322 findBestSequence(1, pose, actionSequenceList, time, value, result);
00323 actionSequenceList.pop_back();
00324 }
00325 }
00326 }
00327 }
00328 }
00329
00330
00331 void Actionfield::findBestSequence(unsigned int depth, const PfPose& robotPose,
00332 std::vector<unsigned int>& actionSequenceList,
00333 double time, double previousValue,
00334 PotentialfieldResult& result)
00335 {
00336 double currentTime(0);
00337 for(unsigned int currentAction=0; currentAction<actions.size(); currentAction++)
00338 {
00339 if(actions[currentAction].canBeApplied(futureRobotPoses[depth-1],
00340 futureWorldStates[depth-1]))
00341 {
00342 futureWorldModelGenerator->transformWorldState(
00343 futureRobotPoses[depth-1], futureRobotPoses[depth],
00344 actions[currentAction], this, futureWorldStates[depth-1],
00345 futureWorldStates[depth], staticObjects);
00346 currentTime = actions[currentAction].time + time;
00347 bool pruningCheckPassed;
00348 double value = computeActionValue(actions[currentAction], currentTime,
00349 robotPose, futureRobotPoses[depth], dynamicObjects,
00350 futureWorldStates[depth], pruningCheckPassed);
00351 if(!pruningCheckPassed)
00352 {
00353 continue;
00354 }
00355 if(value < result.value)
00356 {
00357 result.value = value;
00358 result.motion = actions[currentAction].motionParameters;
00359 result.subAction = actions[actionSequenceList[0]].name;
00360 }
00361 if(depth+1 < worldStateDepth)
00362 {
00363 actionSequenceList.push_back(currentAction);
00364 findBestSequence(depth+1, robotPose, actionSequenceList,
00365 currentTime, value, result);
00366 actionSequenceList.pop_back();
00367 }
00368 }
00369 }
00370 }
00371
00372
00373 double Actionfield::computeValueAtPose(const PfPose& pose,
00374 const std::vector<Object*>& dynamicObjects,
00375 int excludedDynamicObject)
00376 {
00377 unsigned int skip;
00378 if(excludedDynamicObject == -1)
00379 {
00380 skip = dynamicObjects.size();
00381 }
00382 else
00383 {
00384 skip = static_cast<unsigned int>(excludedDynamicObject);
00385 }
00386 double value(0.0);
00387 std::vector < Object* >::const_iterator object;
00388 for (object = staticObjects.begin(); object != staticObjects.end(); ++object)
00389 {
00390 value += (*object)->computeChargeAt(pose);
00391 }
00392 for (unsigned int i=0; i<dynamicObjects.size(); i++)
00393 {
00394 if(i != skip)
00395 {
00396 value += dynamicObjects[i]->computeChargeAt(pose);
00397 }
00398 }
00399 return value;
00400 }
00401
00402
00403 PfVec Actionfield::getFutureFieldVecAt(const PfPose& pose,
00404 const std::vector<Object*>& dynamicObjects,
00405 int excludedDynamicObject)
00406 {
00407 unsigned int skip;
00408 if(excludedDynamicObject == -1)
00409 {
00410 skip = dynamicObjects.size();
00411 }
00412 else
00413 {
00414 skip = static_cast<unsigned int>(excludedDynamicObject);
00415 }
00416 PfVec gradient(0.0,0.0);
00417 std::vector < Object* >::const_iterator object;
00418 for (object = staticObjects.begin(); object != staticObjects.end(); ++object)
00419 {
00420 gradient += (*object)->computeAbsFieldVecAt(pose);
00421 }
00422 for (unsigned int i=0; i<dynamicObjects.size(); i++)
00423 {
00424 if(i != skip)
00425 {
00426 gradient += dynamicObjects[i]->computeAbsFieldVecAt(pose);
00427 }
00428 }
00429 return gradient;
00430 }
00431
00432
00433 double Actionfield::computeActionValue(const Action& action, double time,
00434 const PfPose& ownPoseBefore,
00435 const PfPose& ownPoseAfter,
00436 const std::vector<Object*>& objectsBefore,
00437 const std::vector<Object*>& objectsAfter,
00438 bool& passedPruningCheck)
00439 {
00440 passedPruningCheck = true;
00441 double valueAfterAction(0.0), valueBeforeAction(0.0), actionValue(0.0);
00442 switch(action.actionType)
00443 {
00444 case MOVE_SELF:
00445 case MEASURE_SELF: valueAfterAction = computeValueAtPose(ownPoseAfter, objectsAfter);
00446 break;
00447 case MOVE_OBJECT:
00448 case MEASURE_OBJECT: valueAfterAction = computeValueAtPose(
00449 objectsAfter[action.objectIdx]->getPose(),
00450 objectsAfter, action.objectIdx);
00451 break;
00452 }
00453 if((criterion != CRITERION_ABSOLUTE) || decreasingValuesOnly)
00454 {
00455 switch(action.actionType)
00456 {
00457 case MOVE_SELF:
00458 case MEASURE_SELF: valueBeforeAction = computeValueAtPose(ownPoseAfter, objectsBefore);
00459 break;
00460 case MOVE_OBJECT:
00461 case MEASURE_OBJECT: valueBeforeAction = computeValueAtPose(
00462 objectsBefore[action.objectIdx]->getPose(),
00463 objectsBefore, action.objectIdx);
00464 break;
00465 }
00466 }
00467 if(decreasingValuesOnly)
00468 {
00469 passedPruningCheck = (valueAfterAction < valueBeforeAction);
00470 }
00471 if(criterion == CRITERION_GAIN)
00472 {
00473 actionValue = (valueAfterAction - valueBeforeAction);
00474 }
00475 else if(criterion == CRITERION_ABSOLUTE)
00476 {
00477 actionValue = valueAfterAction;
00478 }
00479 else
00480 {
00481 double dist((objectsAfter[action.objectIdx]->getPose().pos -
00482 objectsBefore[action.objectIdx]->getPose().pos).length());
00483 if(fabs(dist) < EPSILON)
00484 {
00485 return 0.0;
00486 }
00487 else
00488 {
00489 actionValue = ((valueBeforeAction - valueAfterAction) / dist);
00490 }
00491 }
00492 if(considerTime)
00493 {
00494 if(time < EPSILON)
00495 {
00496 return actionValue;
00497 }
00498 else
00499 {
00500 return actionValue/time;
00501 }
00502 }
00503 else
00504 {
00505 return actionValue;
00506 }
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552