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

# Tools/PotentialFields/PfcParser.cpp

Go to the documentation of this file.

    00001 /**
    00002 * @file PfcParser.cpp
    00003 *
    00004 * Implementation of class Parser
    00005 *
    00006 * @author <a href="mailto:timlaue@informatik.uni-bremen.de">Tim Laue</a>
    00007 */
    00008
    00009
    00010 #include "PfcParser.h"
    00011 #include "Actionfield.h"
    00012 #include "Motionfield.h"
    00013 #include "PfieldDatatypes.h"
    00014 #include "PotentialFunctions.h"
    00015 #include "PfieldGeometry.h"
    00016 #include "FieldObject.h"
    00017 #include "FormationObject.h"
    00018 #include "RandomMotionGenerator.h"
    00019 #include "AStarSearch.h"
    00020 #include <cassert>
    00021 #include <iostream>
    00022
    00023
    00024 inline double toDouble(const std::string& s)
    00025 {
    00026   return atof(s.c_str());
    00027 }
    00028
    00029
    00030 inline int toInt(const std::string& s)
    00031 {
    00032   return atoi(s.c_str());
    00033 }
    00034
    00035
    00036 inline bool toBool(const std::string& s)
    00037 {
    00038   if(s=="true")
    00039   {
    00040     return true;
    00041   }
    00042   else
    00043   {
    00044     return false;
    00045   }
    00046 }
    00047
    00048
    00049 inline ChangeType toChangeType(const std::string& s)
    00050 {
    00051   if(s == "calls")
    00052   {
    00053     return CALLS;
    00054   }
    00055   else
    00056   {
    00057     return MILLISECONDS;
    00058   }
    00059 }
    00060
    00061
    00062
    00063 Parser::~Parser()
    00064 {
    00065   std::vector < PotentialFieldsObject* >::iterator object;
    00066   for (object = objects.begin (); object != objects.end (); ++object)
    00067   {
    00068     delete (*object);
    00069   }
    00070   objects.clear();
    00071   instanceGroups.clear();
    00072 }
    00073
    00074
    00075 inline char Parser::nextChar()
    00076 {
    00077   char ch;
    00078 #ifdef POTENTIALFIELDS_FOR_GT2004_
    00079   (*file) >> ch;
    00080 #else
    00081   ch = file.get();
    00082 #endif //POTENTIALFIELDS_FOR_GT2004_
    00083   return ch;
    00084 }
    00085
    00086
    00087 inline bool Parser::endOfFile()
    00088 {
    00089 #ifdef POTENTIALFIELDS_FOR_GT2004_
    00090   return file->eof();
    00091 #else
    00092   return file.eof();
    00093 #endif //POTENTIALFIELDS_FOR_GT2004_
    00094 }
    00095
    00096
    00097 std::string Parser::nextToken()
    00098 {
    00099   std::string token="";
    00100   char ch;
    00101   do
    00102   {
    00103     ch = nextChar();
    00104   } while (((ch == ' ') || (ch == '\t') || (ch == '\n') ||
    00105            (ch == 0x0A) || (ch == 0x0D) || (ch == ';')) && !endOfFile());
    00106   while ((ch != ';') && !endOfFile())
    00107   {
    00108     token += ch;
    00109     ch = nextChar();
    00110   }
    00111   return token;
    00112 }
    00113
    00114
    00115 inline double Parser::parseAngle()
    00116 {
    00117   return (toDouble(nextToken()) * pi_180);
    00118 }
    00119
    00120
    00121 void Parser::parseGeometricObject(PfieldGeometricObject*& geometricObject,
    00122                                   const std::string& preparsedToken)
    00123 {
    00124   std::string geometryType;
    00125   if(preparsedToken == "")
    00126   {
    00127     geometryType = nextToken();
    00128   }
    00129   else
    00130   {
    00131     geometryType = preparsedToken;
    00132   }
    00133   if(geometryType == "line")
    00134   {
    00135     Line* line= new Line();
    00136     line->intersectable = toBool(nextToken());
    00137     line->p1.x = toDouble(nextToken());
    00138     line->p1.y = toDouble(nextToken());
    00139     line->p2.x = toDouble(nextToken());
    00140     line->p2.y = toDouble(nextToken());
    00141     line->initRadiusOfCollisionCircle();
    00142     geometricObject = line;
    00143   }
    00144   else if(geometryType == "polygon")
    00145   {
    00146     Polygon* polygon = new Polygon();
    00147     polygon->intersectable = toBool(nextToken());
    00148     std::string x;
    00149     PfVec p;
    00150     x = nextToken();
    00151     while(x != "EOL")
    00152     {
    00153       p.x = toDouble(x);
    00154       p.y = toDouble(nextToken());
    00155       polygon->addPoint(p);
    00156       x = nextToken();
    00157     }
    00158     polygon->initRadiusOfCollisionCircle();
    00159     geometricObject = polygon;
    00160   }
    00161   else if(geometryType == "circle")
    00162   {
    00163     Circle* circle = new Circle();
    00164     circle->radius = toDouble(nextToken());
    00165     circle->intersectable = toBool(nextToken());
    00166     circle->initRadiusOfCollisionCircle();
    00167     geometricObject = circle;
    00168   }
    00169   else if(geometryType == "no-geometry")
    00170   {
    00171     NoGeometry* noGeometry = new NoGeometry();
    00172     noGeometry->intersectable = false;
    00173     noGeometry->initRadiusOfCollisionCircle();
    00174     geometricObject = noGeometry;
    00175   }
    00176 }
    00177
    00178
    00179 void Parser::parseFunction(PotentialfieldFunction*& function)
    00180 {
    00181   std::string functionType = nextToken();
    00182   if(functionType == "linear-function")
    00183   {
    00184     double range = toDouble(nextToken());
    00185     double atZero = toDouble(nextToken());
    00186     LinearFunction* linearFunction = new LinearFunction(range, atZero);
    00187     function = linearFunction;
    00188   }
    00189   else if(functionType == "parabolic-function")
    00190   {
    00191     double range = toDouble(nextToken());
    00192     double atZero = toDouble(nextToken());
    00193     ParabolicFunction* parabolicFunction = new ParabolicFunction(range, atZero);
    00194     function = parabolicFunction;
    00195   }
    00196   if(functionType == "no-function")
    00197   {
    00198     NoFunction* noFunction = new NoFunction();
    00199     function = noFunction;
    00200   }
    00201   else if(functionType == "asymptotic-function")
    00202   {
    00203     double range = toDouble(nextToken());
    00204     double atZero = toDouble(nextToken());
    00205     double solidCenter = toDouble(nextToken());
    00206     assert(solidCenter > 0.0);
    00207     AsymptoticFunction* asymptoticFunction = new AsymptoticFunction(range, atZero, solidCenter);
    00208     function = asymptoticFunction;
    00209   }
    00210   else if(functionType == "social-function")
    00211   {
    00212     double cRep(toDouble(nextToken()));
    00213     double omRep(toDouble(nextToken()));
    00214     double cAtt(toDouble(nextToken()));
    00215     double omAtt(toDouble(nextToken()));
    00216     double epsilon(toDouble(nextToken()));
    00217     double k(toDouble(nextToken()));
    00218     assert((cRep >= 0.0) && (cAtt >= 0.0) && (omRep > omAtt) && (omAtt >= 0.0) && (epsilon >= 0.0));
    00219     SocialFunction* socialFunction = new SocialFunction(cRep,omRep,cAtt,omAtt, epsilon, k);
    00220     function = socialFunction;
    00221   }
    00222   if((functionType == "asymptotic-function") ||
    00223      (functionType == "linear-function") ||
    00224      (functionType == "parabolic-function"))
    00225   {
    00226     double smoothingAtObject(toDouble(nextToken())/100.0);
    00227     double smoothingAtBorder(toDouble(nextToken())/100.0);
    00228     double gradientAtObject(toDouble(nextToken()));
    00229     double gradientAtBorder(toDouble(nextToken()));
    00230     assert((smoothingAtObject >= 0.0) && (smoothingAtBorder >=0.0) &&
    00231            (smoothingAtObject <= 1.0) && (smoothingAtBorder <=1.0));
    00232     function->setSmoothingParameters(smoothingAtObject, smoothingAtBorder,
    00233                                      gradientAtObject, gradientAtBorder);
    00234   }
    00235 }
    00236
    00237
    00238 inline PotentialFieldsObject* Parser::getInstance(const std::string& name)
    00239 {
    00240   NameToIndexMap::const_iterator pos;
    00241   pos = composition->objectMap.find(name);
    00242   assert(pos != composition->objectMap.end());
    00243   return composition->objects[pos->second];
    00244 }
    00245
    00246
    00247 void Parser::parseObjectsForField(const std::string& nameOfFirst,Potentialfield* field)
    00248 {
    00249   std::string objectName = nameOfFirst;
    00250   PotentialFieldsObject* object;
    00251   while(objectName != "EOL")
    00252   {
    00253     if(objectName == "include-group")
    00254     {
    00255       objectName = nextToken();
    00256       addGroupToField(objectName, field);
    00257       objectName = nextToken();
    00258     }
    00259     else
    00260     {
    00261       if(objectName == "include-formation")
    00262       {
    00263         objectName = nextToken();
    00264       }
    00265       object = getInstance(objectName);
    00266       assert(object != 0);
    00267       field->addObject(object);
    00268       objectName = nextToken();
    00269     }
    00270   }
    00271 }
    00272
    00273
    00274 void Parser::addGroupToField(const std::string& groupName, Potentialfield* field)
    00275 {
    00276   bool groupFound = false;
    00277   for(unsigned int i=0; i<instanceGroups.size(); i++)
    00278   {
    00279     if(instanceGroups[i].name == groupName)
    00280     {
    00281       for(unsigned int j=0; j<instanceGroups[i].objects.size(); j++)
    00282       {
    00283         field->addObject(instanceGroups[i].objects[j]);
    00284       }
    00285       groupFound = true;
    00286       break;
    00287     }
    00288   }
    00289   assert(groupFound);
    00290 }
    00291
    00292
    00293 void Parser::parseObjectStateSymbol()
    00294 {
    00295   std::string symbol(nextToken());
    00296   composition->addDynamicObjectState(symbol);
    00297 }
    00298
    00299
    00300 void Parser::parseInstanceGroup()
    00301 {
    00302   InstanceGroup newGroup;
    00303   newGroup.name = nextToken();
    00304   std::string objectName = nextToken();
    00305   PotentialFieldsObject* object;
    00306   while(objectName != "EOL")
    00307   {
    00308     object = getInstance(objectName);
    00309     assert(object != 0);
    00310     newGroup.objects.push_back(object);
    00311     objectName = nextToken();
    00312   }
    00313   instanceGroups.push_back(newGroup);
    00314 }
    00315
    00316
    00317 PotentialFieldsObject* Parser::parseObject()
    00318 {
    00319   std::string name(nextToken());
    00320   std::string type(nextToken());
    00321   ObjectType objectType;
    00322   if(type=="attractive")
    00323   {
    00324     objectType = ATTRACTIVE;
    00325   }
    00326   else
    00327   {
    00328     objectType = REPULSIVE;
    00329   }
    00330   PotentialFieldsObject* object = new PotentialFieldsObject(name, objectType);
    00331   std::string tangentialField = nextToken();
    00332   if(tangentialField == "clockwise")
    00333   {
    00334     object->setTangentialField(CLOCKWISE);
    00335   }
    00336   else if(tangentialField == "counter-clockwise")
    00337   {
    00338     object->setTangentialField(COUNTER_CLOCKWISE);
    00339   }
    00340   object->setPfieldCompositionRef(composition);
    00341   PotentialfieldFunction* function;
    00342   parseFunction(function);
    00343   object->setFunction(function);
    00344   delete function;
    00345   std::string fieldType = nextToken();
    00346   if(fieldType == "point-field")
    00347   {
    00348     object->setField(POINT_FIELD);
    00349   }
    00350   else if(fieldType == "shape-field")
    00351   {
    00352     object->setField(SHAPE_FIELD);
    00353   }
    00354   else if(fieldType == "sector-field")
    00355   {
    00356     Sector sector;
    00357     sector.openingAngle = parseAngle();
    00358     std::string crossFunctionString = nextToken();
    00359     if(crossFunctionString == "linear-function")
    00360     {
    00361       sector.crossFunction = new LinearFunction(1.0,1.0);
    00362     }
    00363     else if(crossFunctionString == "parabolic-function")
    00364     {
    00365       sector.crossFunction = new ParabolicFunction(1.0,1.0);
    00366     }
    00367     else if(crossFunctionString == "asymptotic-function")
    00368     {
    00369       sector.crossFunction = new AsymptoticFunction(1.0,1.0,0.0001);
    00370     }
    00371     sector.crossFunction->setSmoothingParameters(
    00372         toDouble(nextToken()), toDouble(nextToken()),
    00373         toDouble(nextToken()), toDouble(nextToken()));
    00374     object->setField(SECTOR_FIELD, sector);
    00375   }
    00376   PfieldGeometricObject* geometricObject;
    00377   parseGeometricObject(geometricObject);
    00378   object->setGeometry(geometricObject);
    00379   delete geometricObject;
    00380   return object;
    00381 }
    00382
    00383
    00384 void Parser::parseAndInsertObject()
    00385 {
    00386   PotentialFieldsObject* object = parseObject();
    00387   objectMap[object->getName()] = objects.size();
    00388   objects.push_back(object);
    00389 }
    00390
    00391
    00392 void Parser::parseInstance()
    00393 {
    00394   PotentialFieldsObject* instance = 0;
    00395   std::string type = nextToken();
    00396   std::string name = nextToken();
    00397   NameToIndexMap::iterator pos;
    00398   pos = objectMap.find(type);
    00399   assert(pos != objectMap.end());
    00400   instance = objects[pos->second]->createInstance(name);
    00401   std::string pose = nextToken();
    00402   if(pose=="static-pose")
    00403   {
    00404     PfPose pose;
    00405     pose.pos.x = toDouble(nextToken());
    00406     pose.pos.y = toDouble(nextToken());
    00407     pose.rotation = parseAngle();
    00408     instance->setPose(pose);
    00409     instance->setStatic(true);
    00410     instance->setActivation(true);
    00411   }
    00412   else if(pose=="dynamic-pose")
    00413   {
    00414     std::string poseSymbol = nextToken();
    00415     unsigned int dynamicPoseId = composition->getIdFromObjectStateSymbol(poseSymbol);
    00416     instance->setStatic(false, dynamicPoseId);
    00417     instance->setActivation(false);
    00418   }
    00419   composition->addObject(instance);
    00420 }
    00421
    00422
    00423 void Parser::parseSingleFormation(SingleFormation*& formation,
    00424                                   const std::string& formationToken)
    00425 {
    00426   if(formationToken == "between")
    00427   {
    00428     BetweenFormation* betweenFormation = new BetweenFormation();
    00429     betweenFormation->addObject(getInstance(nextToken()));
    00430     betweenFormation->addObject(getInstance(nextToken()));
    00431     formation = betweenFormation;
    00432   }
    00433   else if(formationToken == "among")
    00434   {
    00435     AmongFormation* amongFormation = new AmongFormation();
    00436     std::string groupName(nextToken());
    00437     bool groupFound = false;
    00438     for(unsigned int i=0; i<instanceGroups.size(); i++)
    00439     {
    00440       if(instanceGroups[i].name == groupName)
    00441       {
    00442         for(unsigned int j=0; j<instanceGroups[i].objects.size(); j++)
    00443         {
    00444           amongFormation->addObject(instanceGroups[i].objects[j]);
    00445         }
    00446         groupFound = true;
    00447         break;
    00448       }
    00449     }
    00450     assert(groupFound);
    00451     formation = amongFormation;
    00452   }
    00453   else if(formationToken == "relative-to")
    00454   {
    00455     RelativeFormation* relativeFormation = new RelativeFormation();
    00456     relativeFormation->addObject(getInstance(nextToken()));
    00457     double angle(parseAngle());
    00458     std::string coordinateString(nextToken());
    00459     if(coordinateString == "relative")
    00460     {
    00461       relativeFormation->setParameters(angle, RELATIVE_FORMATION);
    00462     }
    00463     else //coordinateString == "absolute"
    00464     {
    00465       relativeFormation->setParameters(angle, ABSOLUTE_FORMATION);
    00466     }
    00467     formation = relativeFormation;
    00468   }
    00469   formation->setPriority(toDouble(nextToken()));
    00470   PotentialfieldFunction* function;
    00471   parseFunction(function);
    00472   formation->setFunction(function);
    00473   delete function;
    00474   formation->init();
    00475 }
    00476
    00477
    00478 void Parser::parseFormationObject()
    00479 {
    00480   FormationObject* object;
    00481   std::string name(nextToken());
    00482   object = new FormationObject(name);
    00483   std::string formationToken(nextToken());
    00484   while(formationToken != "EOL")
    00485   {
    00486     if(formationToken != "best-fit")
    00487     {
    00488       SingleFormation* singleFormation;
    00489       parseSingleFormation(singleFormation, formationToken);
    00490       object->addSingleFormation(singleFormation);
    00491     }
    00492     else
    00493     {
    00494       BestFitFormation* bestFitFormation = new BestFitFormation();
    00495       std::string selectionString(nextToken());
    00496       if(selectionString == "max-gradient")
    00497       {
    00498         bestFitFormation->setBestFitSelection(SELECT_MAX_GRADIENT);
    00499       }
    00500       else if(selectionString == "min-gradient")
    00501       {
    00502         bestFitFormation->setBestFitSelection(SELECT_MIN_GRADIENT);
    00503       }
    00504       else if(selectionString == "min-distance")
    00505       {
    00506         bestFitFormation->setBestFitSelection(SELECT_MIN_DISTANCE);
    00507       }
    00508       else //selectionString == "max-priority"
    00509       {
    00510         bestFitFormation->setBestFitSelection(SELECT_MAX_PRIORITY);
    00511       }
    00512       formationToken = nextToken();
    00513       while(formationToken != "EOL")
    00514       {
    00515         SingleFormation* singleFormation;
    00516         parseSingleFormation(singleFormation, formationToken);
    00517         bestFitFormation->addFormation(singleFormation);
    00518         formationToken = nextToken();
    00519       }
    00520       object->addSingleFormation(bestFitFormation);
    00521     }
    00522     formationToken = nextToken();
    00523   }
    00524   composition->addObject(object);
    00525 }
    00526
    00527
    00528 void Parser::parseTimeConstraintsForField(Potentialfield* field)
    00529 {
    00530   std::string whatToKeepStr(nextToken());
    00531   KeepType whatToKeep;
    00532   if(whatToKeepStr == "result")
    00533   {
    00534     whatToKeep = KEEP_RESULT;
    00535   }
    00536   else
    00537   {
    00538     whatToKeep = KEEP_FIELD;
    00539   }
    00540   ChangeType changeTypeN(toChangeType(nextToken()));
    00541   int n(toInt(nextToken()));
    00542   ChangeType changeTypeM(toChangeType(nextToken()));
    00543   int m(toInt(nextToken()));
    00544   ChangeType changeTypeO(toChangeType(nextToken()));
    00545   int o(toInt(nextToken()));
    00546   field->setTimeConstraints(whatToKeep, changeTypeN, n, changeTypeM, m,
    00547                             changeTypeO, o);
    00548 }
    00549
    00550
    00551 void Parser::parseMotionfield()
    00552 {
    00553   std::string name = nextToken();
    00554   Motionfield* motionField = new Motionfield(name);
    00555   bool disableTranslation(toBool(nextToken()));
    00556   bool disableRotation(toBool(nextToken()));
    00557   motionField->disableDegreesOfFreedom(disableTranslation, disableRotation);
    00558   double maxAccel(toDouble(nextToken()));
    00559   double maxGradientDifference(parseAngle());
    00560   motionField->setAccelerationLimits(maxAccel, maxGradientDifference);
    00561   parseTimeConstraintsForField(motionField);
    00562   std::string criterion = nextToken();
    00563   if(criterion == "gradient")
    00564   {
    00565     motionField->setCriterion(CRITERION_GRADIENT);
    00566   }
    00567   else if(criterion == "const")
    00568   {
    00569     motionField->setCriterion(CRITERION_CONST,toDouble(nextToken()));
    00570   }
    00571   std::string combinedField(nextToken());
    00572   while(combinedField != "EOL")
    00573   {
    00574     motionField->addCombinedField(combinedField);
    00575     combinedField = nextToken();
    00576   }
    00577   std::string nameOfFirstObject(nextToken());
    00578   if(nameOfFirstObject == "avoid-local-minima")
    00579   {
    00580     std::string pathPlannerUsage(nextToken());
    00581     bool alwaysPlanning(pathPlannerUsage == "always");
    00582     double gradientLength(toDouble(nextToken()));
    00583     PotentialFieldsObject* goalObject = getInstance(nextToken());
    00584     PotentialfieldAStarParameterSet parameterSet;
    00585     parameterSet.distanceToGoal = toDouble(nextToken());
    00586     parameterSet.minExpansionRadius = toDouble(nextToken());
    00587     parameterSet.maxExpansionRadius = toDouble(nextToken());
    00588     parameterSet.minBranchingFactor = toInt(nextToken());
    00589     parameterSet.maxBranchingFactor = toInt(nextToken());
    00590     parameterSet.endOfNear = toDouble(nextToken());
    00591     parameterSet.endOfFar = toDouble(nextToken());
    00592     parameterSet.standardGradientLength = toDouble(nextToken());
    00593     parameterSet.numberOfCalls = 0;
    00594     int maxNumberOfSearchNodes(toInt(nextToken()));
    00595     int minCacheSize(toInt(nextToken()));
    00596     nameOfFirstObject = nextToken();
    00597     if(nameOfFirstObject == "stabilization-element")
    00598     {
    00599       parameterSet.useStabilization = true;
    00600       parameterSet.stabilizationDistance = toDouble(nextToken());
    00601       nameOfFirstObject = nextToken();
    00602       parameterSet.stabilizationObject = parseObject();
    00603       nameOfFirstObject = nextToken();
    00604     }
    00605     AStarSearch<PotentialfieldAStarNode, PotentialfieldAStarParameterSet,double>* pathPlanner =
    00606       new AStarSearch<PotentialfieldAStarNode, PotentialfieldAStarParameterSet,double>(minCacheSize,maxNumberOfSearchNodes,parameterSet);
    00607     motionField->addPathPlanner(pathPlanner, alwaysPlanning,
    00608                                 goalObject, parameterSet, gradientLength);
    00609   }
    00610   if(nameOfFirstObject == "include-random-motion-generator")
    00611   {
    00612     double minValue(toDouble(nextToken()));
    00613     double maxValue(toDouble(nextToken()));
    00614     double valueDx(toDouble(nextToken()));
    00615     double directionDx(parseAngle());
    00616     assert(minValue <= maxValue);
    00617     assert(maxValue >= 0.0);
    00618     assert(valueDx >= 0.0);
    00619     assert(directionDx >= 0.0);
    00620     ChangeType changeType;
    00621     std::string changeString(nextToken());
    00622     if(changeString == "calls") changeType = CALLS;
    00623     else changeType = MILLISECONDS;
    00624     unsigned long n = toInt(nextToken());
    00625     RandomMotionGenerator* rmg = new RandomMotionGenerator
    00626                           (minValue, maxValue, valueDx, directionDx, changeType,n);
    00627     motionField->addRandomMotionGenerator(rmg);
    00628     nameOfFirstObject = nextToken();
    00629   }
    00630   parseObjectsForField(nameOfFirstObject,motionField);
    00631   composition->addField(motionField);
    00632 }
    00633
    00634
    00635 void Parser::parseTransformation(PotentialfieldTransformation*& transformation,
    00636                                  const std::string& typeToken)
    00637 {
    00638   if (typeToken == "translation")
    00639   {
    00640     Translation* translation = new Translation();
    00641     translation->translation.x = toDouble(nextToken());
    00642     translation->translation.y = toDouble(nextToken());
    00643     translation->time = toDouble(nextToken())/1000.0;
    00644     translation->speed = 0.0;
    00645     translation->alongGradient = false;
    00646     translation->stepLength = 0.0;
    00647     translation->maxGradientDeviation = 0.0;
    00648     translation->toObject = 0;
    00649     transformation = translation;
    00650   }
    00651   else if (typeToken == "translation-to-object")
    00652   {
    00653     Translation* translation = new Translation();
    00654     translation->alongGradient = false;
    00655     translation->stepLength = 0.0;
    00656     translation->maxGradientDeviation = 0.0;
    00657     translation->toObject = getInstance(nextToken());
    00658     translation->speed = toDouble(nextToken());
    00659     translation->time = 0.0;
    00660     transformation = translation;
    00661   }
    00662   else if (typeToken == "translation-along-gradient")
    00663   {
    00664     Translation* translation = new Translation();
    00665     translation->alongGradient = true;
    00666     translation->stepLength = toDouble(nextToken());
    00667     translation->maxGradientDeviation = parseAngle();
    00668     translation->maxLength = toDouble(nextToken());
    00669     translation->speed = toDouble(nextToken());
    00670     translation->time = 0.0;
    00671     translation->toObject = 0;
    00672     transformation = translation;
    00673   }
    00674   else if (typeToken == "rotation")
    00675   {
    00676     Rotation* rotation = new Rotation();
    00677     rotation->toGradient = false;
    00678     rotation->angle = parseAngle();
    00679     rotation->speed = 0.0;
    00680     rotation->time = toDouble(nextToken())/1000.0;
    00681     rotation->toObject = 0;
    00682     transformation = rotation;
    00683   }
    00684   else if (typeToken == "rotation-to-gradient")
    00685   {
    00686     Rotation* rotationToGradient = new Rotation();
    00687     rotationToGradient->toGradient = true;
    00688     rotationToGradient->toObject = 0;
    00689     rotationToGradient->speed = parseAngle();
    00690     rotationToGradient->time = 0.0;
    00691     transformation = rotationToGradient;
    00692   }
    00693   else if (typeToken == "rotation-to-object")
    00694   {
    00695     Rotation* rotationToObject = new Rotation();
    00696     rotationToObject->toGradient = false;
    00697     rotationToObject->toObject = getInstance(nextToken());
    00698     rotationToObject->speed = parseAngle();
    00699     rotationToObject->time = 0.0;
    00700     transformation = rotationToObject;
    00701   }
    00702   else if(typeToken == "no-transformation")
    00703   {
    00704     transformation = new NoTransformation();
    00705     transformation->time = toDouble(nextToken());
    00706     assert(transformation->time != 0.0);
    00707   }
    00708 }
    00709
    00710
    00711 void Parser::parseAction(Action& action)
    00712 {
    00713   std::string manipulationType = nextToken();
    00714   if(manipulationType == "move-object")
    00715   {
    00716     action.actionType = MOVE_OBJECT;
    00717     action.joinAction = toBool(nextToken());
    00718     action.manipulatedObject = getInstance(nextToken());
    00719     std::string polygonString = nextToken();
    00720     PfieldGeometricObject* geoObj;
    00721     while(polygonString == "polygon")
    00722     {
    00723       parseGeometricObject(geoObj, polygonString);
    00724       Polygon* polygon;
    00725       polygon = (Polygon*)(geoObj);
    00726       action.impactAreas.push_back(*polygon);
    00727       delete geoObj;
    00728       polygonString = nextToken();
    00729     }
    00730   }
    00731   else if(manipulationType == "move-self")
    00732   {
    00733     action.actionType = MOVE_SELF;
    00734     action.manipulatedObject = 0;
    00735     action.joinAction = false;
    00736   }
    00737   else if(manipulationType == "measure-object")
    00738   {
    00739     action.actionType = MEASURE_OBJECT;
    00740     action.manipulatedObject = getInstance(nextToken());
    00741     action.joinAction = false;
    00742   }
    00743   else // (manipulationType == "measure-self")
    00744   {
    00745     action.actionType = MEASURE_SELF;
    00746     action.manipulatedObject = 0;
    00747     action.joinAction = false;
    00748   }
    00749   if((manipulationType == "move-object") || (manipulationType == "move-self"))
    00750   {
    00751     std::string transformationToken(nextToken());
    00752     PotentialfieldTransformation* transformation;
    00753     if(transformationToken == "probability-distribution")
    00754     {
    00755       transformationToken = nextToken();
    00756       while(transformationToken != "EOL")
    00757       {
    00758         double probability = toDouble(transformationToken);
    00759         transformationToken = nextToken();
    00760         parseTransformation(transformation, transformationToken);
    00761         transformation->probability = probability;
    00762         action.transformations.push_back(transformation);
    00763         transformationToken = nextToken();
    00764       }
    00765     }
    00766     else
    00767     {
    00768       parseTransformation(transformation, transformationToken);
    00769       transformation->probability = 1.0;
    00770       action.transformations.push_back(transformation);
    00771     }
    00772   }
    00773   else
    00774   {
    00775     PotentialfieldTransformation* transformation = new NoTransformation();
    00776     transformation->time = 1.0;
    00777     action.transformations.push_back(transformation);
    00778   }
    00779 }
    00780
    00781
    00782 void Parser::parseActionfield()
    00783 {
    00784   std::string name = nextToken();
    00785   Actionfield* actionField = new Actionfield(name);
    00786   actionField->setConsiderTime(toBool(nextToken()));
    00787   parseTimeConstraintsForField(actionField);
    00788   std::string criterion = nextToken();
    00789   if(criterion == "gain")
    00790   {
    00791     actionField->setCriterion(CRITERION_GAIN);
    00792   }
    00793   else if(criterion == "gradient")
    00794   {
    00795     actionField->setCriterion(CRITERION_GRADIENT);
    00796   }
    00797   else if(criterion == "absolute")
    00798   {
    00799     actionField->setCriterion(CRITERION_ABSOLUTE);
    00800   }
    00801   else if(criterion == "const")
    00802   {
    00803     actionField->setCriterion(CRITERION_CONST,toDouble(nextToken()));
    00804   }
    00805   std::string nextAction(nextToken());
    00806   if(nextAction == "fixed-sequence")
    00807   {
    00808     actionField->setActionfieldType(FIXED_SEQUENCE_FIELD);
    00809     nextAction = nextToken();
    00810   }
    00811   else if(nextAction == "find-best-sequence")
    00812   {
    00813     unsigned int depth(toInt(nextToken()));
    00814     bool decreasingValuesOnly(toBool(nextToken()));
    00815     actionField->setActionfieldType(BEST_SEQUENCE_FIELD,
    00816                                     decreasingValuesOnly, depth);
    00817     nextAction = nextToken();
    00818   }
    00819   else
    00820   {
    00821     actionField->setActionfieldType(SINGLE_ACTION_FIELD);
    00822   }
    00823   while (nextAction != "EOL")
    00824   {
    00825     Action action;
    00826     action.name = nextToken();
    00827     parseAction(action);
    00828     actionField->addAction(action);
    00829     nextAction = nextToken();
    00830   }
    00831   std::string combinedField = nextToken();
    00832   while(combinedField != "EOL")
    00833   {
    00834     actionField->addCombinedField(combinedField);
    00835     combinedField = nextToken();
    00836   }
    00837   std::string nameOfFirstObject(nextToken());
    00838   parseObjectsForField(nameOfFirstObject, actionField);
    00839   composition->addField(actionField);
    00840 }
    00841
    00842
    00843 void Parser::parseComposition()
    00844 {
    00845   std::string selectionProcedure(nextToken());
    00846   int n = toInt(nextToken());
    00847   if(selectionProcedure == "best-of-n")
    00848   {
    00849     composition->setFieldSelectionParameters(BEST_OF_N, n);
    00850   }
    00851   else
    00852   {
    00853     composition->setFieldSelectionParameters(SUCCESSIVE_N_TIMES, n);
    00854   }
    00855 }
    00856
    00857
    00858 void Parser::parse(PotentialfieldComposition* composition, std::string filename)
    00859 {
    00860   setlocale(LC_NUMERIC, "C");
    00861   this->composition = composition;
    00862 #ifdef POTENTIALFIELDS_FOR_GT2004_
    00863   std::string relativeFileName("Pfield/"+filename);
    00864   file = new InBinaryFile(relativeFileName.c_str());
    00865   assert(file->exists());
    00866 #else
    00867   file.open(filename.c_str());
    00868 #endif //POTENTIALFIELDS_FOR_GT2004_
    00869   std::string mainToken;
    00870   while(!endOfFile())
    00871   {
    00872     mainToken = nextToken();
    00873     if(mainToken == "object")
    00874     {
    00875       parseAndInsertObject();
    00876     }
    00877     else if(mainToken == "object-state-symbol")
    00878     {
    00879       parseObjectStateSymbol();
    00880     }
    00881     else if(mainToken == "instance-group")
    00882     {
    00883       parseInstanceGroup();
    00884     }
    00885     else if(mainToken == "formation-object")
    00886     {
    00887       parseFormationObject();
    00888     }
    00889     else if(mainToken == "object-instance")
    00890     {
    00891       parseInstance();
    00892     }
    00893     else if(mainToken == "motionfield")
    00894     {
    00895       parseMotionfield();
    00896     }
    00897     else if(mainToken == "actionfield")
    00898     {
    00899       parseActionfield();
    00900     }
    00901     else if(mainToken == "composition")
    00902     {
    00903       parseComposition();
    00904     }
    00905     else
    00906     {
    00907       assert(mainToken == ""); //Unknown element has been read
    00908     }
    00909   }
    00910 #ifdef POTENTIALFIELDS_FOR_GT2004_
    00911   delete file;
    00912 #else
    00913   file.close();
    00914 #endif //POTENTIALFIELDS_FOR_GT2004_
    00915 }