Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/PotentialFields/Motionfield.cpp

Go to the documentation of this file.
00001 /**
00002 * @file Motionfield.cpp
00003 * 
00004 * Implementation of class Motionfield
00005 *
00006 * @author <a href="mailto:timlaue@informatik.uni-bremen.de">Tim Laue</a>
00007 */
00008 
00009 #include "Motionfield.h"
00010 #include "FieldObject.h"
00011 #include "PfieldDatatypes.h"
00012 #include "RandomMotionGenerator.h"
00013 #include "AStarSearch.h"
00014 #include "PotentialfieldComposition.h"
00015 #ifdef POTENTIALFIELDS_FOR_GT2004_
00016 #include "Tools/Debugging/Debugging.h"
00017 #include "Tools/Debugging/DebugDrawings.h"
00018 #endif //POTENTIALFIELDS_FOR_GT2004_
00019 
00020 
00021 Motionfield::Motionfield(const std::string& name)
00022 {
00023   this->name = name;
00024   randomMotionGenerator = 0;
00025   pathPlanner = 0;
00026   pathPlannerActive = false;
00027   alwaysUsePathPlanner = false;
00028   translationDisabled = false;
00029   rotationDisabled = false;
00030   lastMotionVector.x = 0.0;
00031   lastMotionVector.y = 0.0;
00032 }
00033 
00034 
00035 Motionfield::~Motionfield()
00036 {
00037   if(randomMotionGenerator)
00038   {
00039     delete randomMotionGenerator;
00040   }
00041   if(pathPlanner)
00042   {
00043     delete pathPlanner;
00044   }
00045   if(aStarParameterSet.stabilizationObject)
00046   {
00047     delete aStarParameterSet.stabilizationObject;
00048   }
00049 }
00050 
00051 
00052 void Motionfield::execute(const PfPose& pose, PotentialfieldResult& result)
00053 {
00054   result.actionPossible = true;
00055   result.subAction = "";
00056   PfVec gradientVec;
00057   if(pathPlanner == 0)
00058   {
00059     gradientVec = getFieldVecAt(pose);
00060   }
00061   else if(alwaysUsePathPlanner)
00062   {
00063     gradientVec = getFieldVecFromAStarSearch(pose);
00064   }
00065   else if(pathPlannerActive)
00066   {
00067     gradientVec = getFieldVecFromAStarSearch(pose);
00068     pathPlannerActive = pathPlanningStillNeeded(pose);
00069   }
00070   else
00071   {
00072     gradientVec = getFieldVecAt(pose);
00073     pathPlannerActive = reachedLocalMinimum(gradientVec.length());
00074   }
00075   correctMotionVector(gradientVec);
00076   lastMotionVector = gradientVec;
00077   gradientVec.rotate(-pose.rotation);
00078   if(translationDisabled) 
00079   {
00080     result.motion.pos.x = 0.0;
00081     result.motion.pos.y = 0.0;
00082   }
00083   else 
00084   {
00085     result.motion.pos = gradientVec;
00086     result.motion.pos.normalize();
00087   }
00088   if(rotationDisabled || (gradientVec.length() == 0)) 
00089   {
00090     result.motion.rotation = 0.0;
00091   }
00092   else 
00093   {
00094     result.motion.rotation = gradientVec.getAngle();
00095   }
00096   result.motion.speed = gradientVec.length();
00097   if(criterion == CRITERION_CONST)
00098   {
00099     result.value = criterionParameter;
00100   }
00101   else if(criterion == CRITERION_GRADIENT)
00102   {
00103     result.value = -result.motion.speed;
00104   } 
00105 }
00106 
00107 
00108 PfVec Motionfield::getFieldVecFromAStarSearch(const PfPose& pose)
00109 {
00110   PotentialfieldAStarNode start;
00111   PfPose goalPose(this->goal->getPose(pose));
00112   PfPose startPose(pose);
00113   startPose.probabilityDistribution.clear();
00114   startPose.hasProbabilityDistribution = false;
00115   start.setPose(pose);
00116   start.setFunctionValues(0,0);
00117   start.setValueAtPos(aStarParameterSet);
00118   aStarParameterSet.startPosition = start.getPose().pos;
00119   PotentialfieldAStarNode goal;
00120   goal.setPose(goalPose);
00121   if(aStarParameterSet.useStabilization && aStarParameterSet.numberOfCalls)
00122   {
00123     PfVec stabilizationPosition(-lastMotionVector.x,-lastMotionVector.y);
00124     stabilizationPosition.normalize();
00125     stabilizationPosition *= aStarParameterSet.stabilizationDistance;
00126     stabilizationPosition += pose.pos;
00127     PfPose stabObjectPose;
00128     stabObjectPose.pos = stabilizationPosition;
00129     stabObjectPose.rotation = (pose.pos - stabilizationPosition).getAngle();
00130     aStarParameterSet.stabilizationObject->setPose(stabObjectPose);
00131   }
00132   PotentialfieldAStarNode nextPosition = 
00133       pathPlanner->search(start, goal, aStarParameterSet, plannedPathLengthToGoal);
00134   PfVec result(nextPosition.getPose().pos-pose.pos);
00135   result.normalize();
00136   result *= aStarParameterSet.standardGradientLength;
00137   aStarParameterSet.numberOfCalls++;
00138   return result;
00139 }
00140 
00141 
00142 bool Motionfield::reachedLocalMinimum(double currentGradientLength)
00143 {
00144   return (currentGradientLength <= maxGradientLengthForLocalMinimum);
00145 }
00146 
00147 
00148 bool Motionfield::pathPlanningStillNeeded(const PfPose& pose)
00149 {
00150   PfPose currentPose(pose);
00151   PfPose goalPose(this->goal->getPose());
00152   PfVec nextStep;
00153   double gradientTrajectoryLength(0.0);
00154   double stepLength(aStarParameterSet.minExpansionRadius);
00155   double maxLength(plannedPathLengthToGoal*2.0);
00156   while(gradientTrajectoryLength < maxLength)
00157   {
00158     if((currentPose.pos - goalPose.pos).length() < aStarParameterSet.distanceToGoal)
00159     {
00160       aStarParameterSet.numberOfCalls = 0; //reset call counter
00161 #ifdef POTENTIALFIELDS_FOR_GT2004_
00162       DEBUG_DRAWING_FINISHED(behavior_aStarSearch); 
00163 #endif //POTENTIALFIELDS_FOR_GT2004_
00164       return false;
00165     }
00166     nextStep = getFieldVecAt(currentPose);
00167     nextStep.normalize();
00168     nextStep *= stepLength;
00169     currentPose.addAbsVector(nextStep);
00170     gradientTrajectoryLength += stepLength;
00171   }
00172   return true;
00173 }
00174 
00175 
00176 void Motionfield::correctMotionVector(PfVec& motionVector) const
00177 {
00178   double secondsSinceLastResult(((double)(getSystemTime()-lastResult.timeStamp))/1000.0);
00179   if(maxAccel > 0.0)
00180   {
00181     double currentSpeed(motionVector.length());
00182     double lastSpeed(lastMotionVector.length());
00183     double speedDiff((currentSpeed - lastSpeed)/secondsSinceLastResult);
00184     if(speedDiff > maxAccel)
00185     {
00186       motionVector.normalize();
00187       motionVector *= (lastSpeed + maxAccel*secondsSinceLastResult);
00188     }
00189     else if(speedDiff < -maxAccel)
00190     {
00191       motionVector.normalize();
00192       motionVector *= (lastSpeed - maxAccel*secondsSinceLastResult);
00193     }
00194   }
00195   if(maxGradientDifference > 0.0)
00196   {
00197     double currentAngle(motionVector.getAngle());
00198     double lastAngle(lastMotionVector.getAngle());
00199     double diffAngle(currentAngle-lastAngle);
00200     PfPose dummyPose; dummyPose.rotation = diffAngle; dummyPose.normRotation();
00201     diffAngle = dummyPose.rotation;
00202     double currentRotAccel(diffAngle / secondsSinceLastResult);
00203     if(currentRotAccel > maxGradientDifference)
00204     {
00205       motionVector.rotate(-diffAngle + maxGradientDifference*secondsSinceLastResult);
00206     }
00207     else if(currentRotAccel < -maxGradientDifference)
00208     {
00209       motionVector.rotate(-diffAngle - maxGradientDifference*secondsSinceLastResult);
00210     }
00211   }
00212 }
00213 
00214 
00215 
00216 /*
00217 * $Log: Motionfield.cpp,v $
00218 * Revision 1.1.1.1  2004/05/22 17:37:27  cvsadm
00219 * created new repository GT2004_WM
00220 *
00221 * Revision 1.1  2004/01/20 15:42:19  tim
00222 * Added potential fields implementation
00223 *
00224 * Revision 1.7  2003/06/13 14:27:58  tim
00225 * added random generator and tangential fields
00226 *
00227 * Revision 1.6  2003/06/09 20:00:04  tim
00228 * Changed potentialfield architecture
00229 *
00230 * Revision 1.5  2003/04/22 14:35:17  tim
00231 * Merged changes from GO
00232 *
00233 * Revision 1.5  2003/04/12 06:21:17  tim
00234 * Stand vor dem Spiel gegen Dortmund
00235 *
00236 * Revision 1.4  2003/04/02 14:39:11  tim
00237 * Changed Bremen Byters Behavior
00238 *
00239 * Revision 1.3  2003/03/30 15:32:09  tim
00240 * several minor changes
00241 *
00242 * Revision 1.2  2003/03/23 20:32:37  loetzsch
00243 * removed green compiler warning: no newline at end of file
00244 *
00245 * Revision 1.1  2003/03/23 17:51:27  tim
00246 * Added potentialfields
00247 *
00248 */

Generated on Thu Sep 23 19:57:40 2004 for GT2004 by doxygen 1.3.6