Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Pilot.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_Pilot_h_
00003 #define INCLUDED_Pilot_h_
00004 
00005 // Using a single WaypointWalkMC causes problems if we chain a couple
00006 // of WaypointWalkNodes together because some of the LocomotionEvents
00007 // indicating termination of the first one may not arrive until after
00008 // the second node has been activated, causing the second node to
00009 // terminate prematurely.  The only reason to use shared MCs is for
00010 // the Chiara's XWalk, which runs through an elaborate (slow) leg
00011 // initialization sequence on every start().  No other robots have
00012 // this problem, so the Pilot will only use shared motion commands for
00013 // the Chiara.  For everyone else, waypointwalk_id will be invalid_MC_ID.
00014 #ifdef TGT_IS_CHIARA
00015 #  define PILOT_USES_SHARED_MOTION_COMMANDS
00016 #endif
00017 
00018 #include <queue>
00019 #include <deque>
00020 
00021 // Have to do all our #includes explicitly; can't rely on
00022 // StateMachine.h because of circular dependencies with the Pilot.
00023 
00024 #include "Behaviors/Nodes/HeadPointerNode.h"
00025 #include "Behaviors/Nodes/PostMachine.h"
00026 #include "Behaviors/Nodes/SpeechNode.h"
00027 #include "Behaviors/Nodes/WaypointWalkNode.h"
00028 #include "Behaviors/Nodes/WalkNode.h"
00029 
00030 #include "Behaviors/Transitions/CompletionTrans.h"
00031 #include "Behaviors/Transitions/EventTrans.h"
00032 #include "Behaviors/Transitions/NullTrans.h"
00033 #include "Behaviors/Transitions/PilotTrans.h"
00034 #include "Behaviors/Transitions/SignalTrans.h"
00035 #include "Behaviors/Transitions/TextMsgTrans.h"
00036 #include "Behaviors/Transitions/TimeOutTrans.h"
00037 
00038 #include "Crew/MapBuilderNode.h"
00039 #include "Crew/PilotRequest.h"
00040 
00041 #include "Motion/MMAccessor.h"
00042 #include "Motion/WaypointWalkMC.h"
00043 #include "Motion/WaypointEngine.h"
00044 #include "Motion/WaypointList.h"
00045 #include "Planners/Navigation/ShapeSpacePlannerXY.h"
00046 #include "Planners/Navigation/ShapeSpacePlannerXYTheta.h"
00047 
00048 #include "DualCoding/DualCoding.h"
00049 
00050 using namespace std;
00051 
00052 namespace DualCoding {
00053 
00054 class Pilot : public StateNode {
00055  public:
00056   Pilot(const std::string &nodename="Pilot") : StateNode(nodename), requests(), curReq(NULL), idCounter(0), walk_id(MotionManager::invalid_MC_ID), waypointwalk_id(MotionManager::invalid_MC_ID), dispatch_(NULL), defaultLandmarks(), defaultLandmarkExtractor(NULL), initPos(), initHead(), planReq(), plan(), maxTurn(M_PI), pushingObj() {}
00057 
00058   typedef unsigned int PilotVerbosity_t;
00059   static const PilotVerbosity_t PVstart =     1<<0;
00060   static const PilotVerbosity_t PVevents =    1<<1;
00061   static const PilotVerbosity_t PVexecute =   1<<2;
00062   static const PilotVerbosity_t PVsuccess =   1<<3;
00063   static const PilotVerbosity_t PVfailure =   1<<4;
00064   static const PilotVerbosity_t PVcomplete =  1<<5;
00065   static const PilotVerbosity_t PVabort =     1<<6;
00066   static const PilotVerbosity_t PVpop =       1<<7;
00067   static const PilotVerbosity_t PVqueued =    1<<8;
00068   static const PilotVerbosity_t PVcollision = 1<<9;
00069   static const PilotVerbosity_t PVnavStep =   1<<10;
00070   static const PilotVerbosity_t PVshowPath =  1<<11;
00071 
00072   static PilotVerbosity_t getVerbosity() { return verbosity; }
00073   static void setVerbosity(PilotVerbosity_t v) { verbosity = v; }
00074 
00075   /*! @cond INTERNAL */
00076 
00077   enum NavigationStepType_t {
00078     localizeStep,     //!< localize during path following
00079     travelStep,       //!< travel forward during path following
00080     turnStep,         //!< turn to next heading on path
00081     turnObjStep,      //!< turn while pushing an object
00082     acquireObjStep    //!< move to acquire contact with object
00083   };
00084 
00085   struct NavigationStep {
00086     NavigationStep(NavigationStepType_t _type, DualCoding::Point _waypoint): type(_type), waypoint(_waypoint), visibleLandmarks() {};
00087     NavigationStepType_t type;
00088     DualCoding::Point waypoint;
00089     std::vector<DualCoding::ShapeRoot> visibleLandmarks;
00090     std::string toString() const;
00091   };
00092 
00093   //! Stores and indexes into a sequence of actions to complete a navigation task
00094   struct NavigationPlan {
00095     NavigationPlan() : path(), steps(), currentStep() {};
00096     std::vector<DualCoding::Point> path;   //!< Path returned by path planner, from which the plan is generated
00097     std::vector<NavigationStep> steps;     //!< The plan is a sequence of navigation steps
00098     std::vector<NavigationStep>::const_iterator currentStep;   //!< Index into the plan
00099     std::string toString() const;
00100     void addNavigationStep(NavigationStepType_t type, const DualCoding::Point &waypoint, AngTwoPi orientation);
00101 
00102     void clear() {
00103       path.clear();
00104       steps.clear();
00105       currentStep = steps.begin();
00106     }
00107   };
00108 
00109   struct BearingLessThan {
00110     AngTwoPi hdg;
00111     BearingLessThan(const AngTwoPi heading) : hdg(heading) {}
00112 
00113     bool operator()(AngTwoPi a, AngTwoPi b) {
00114       AngTwoPi aBearing = a - hdg;
00115       AngTwoPi bBearing = b - hdg;
00116       return aBearing < bBearing;
00117     }
00118   };
00119 
00120 
00121   virtual void doStart();
00122   virtual void doStop();
00123   virtual void doEvent();
00124   void unwindForNextRequest();
00125   unsigned int executeRequest(BehaviorBase* requestingBehavior, const PilotRequest& req);
00126   void executeRequest();
00127   void requestComplete(PilotTypes::ErrorType_t errorType);
00128   void requestComplete(const PilotEvent &e);
00129   void pilotPop();
00130   void pilotAbort();
00131   void cancelVelocity(); // forces completion of a setVelocity operation
00132   void setWorldBounds(const Shape<PolygonData> &bounds);
00133 
00134   void setDefaultLandmarks(const std::vector<ShapeRoot> &landmarks);
00135   const std::vector<ShapeRoot>& getDefaultLandmarks() { return defaultLandmarks; }
00136 
00137   void setDefaultLandmarkExtractor(const MapBuilderRequest &mapreq);
00138   MapBuilderRequest* getDefaultLandmarkExtractor() const { return defaultLandmarkExtractor; }
00139 
00140   MotionManager::MC_ID getWalk_id() const { return walk_id; }
00141   MotionManager::MC_ID getWaypointwalk_id() const { return waypointwalk_id; }
00142 
00143   void setupLandmarkExtractor();
00144   //! Find the landmarks that should be visible from current location
00145   static std::vector<ShapeRoot> calculateVisibleLandmarks(const DualCoding::Point &currentLocation, 
00146                 AngTwoPi currentOrientation, AngTwoPi maxTurn,
00147                 const std::vector<DualCoding::ShapeRoot> &possibleLandmarks);
00148   static bool isLandmarkViewable(const DualCoding::ShapeRoot &selectedLandmark,
00149          const DualCoding::Point &currentLocation, AngTwoPi currentOrientation, AngTwoPi maxTurn);
00150 
00151   //! Returns true if we have enough landmarks to localize.
00152   /*! This could be much more sophisticated: taking landmark geometry
00153    into account so we don't settle for two adjacent landmarks if a
00154    more widely dispersed set is available.
00155   */
00156   static bool defaultLandmarkExitTest();
00157 
00158   //! Pilot's setAgent is called by its RunMotionModel behavior.  Or user can call directly.
00159   /* If @a quiet is false, the new agent position will be announced on
00160      cout. If @a updateWayPoint is true, the Pilot's WaypointWalk
00161      engine's position will also be updated.  This doesn't seem to be a good idea,
00162      as it leads to fights due to the particle filter preventing the Waypoint Walk
00163      engine from reaching its destination.  Needs further study.
00164    */
00165   void setAgent(const Point &loc, AngTwoPi heading, bool quiet=false, bool updateWaypoint=true);
00166 
00167   //================ Background processes ================
00168 
00169   //! Run the particle filter's motion model every few hundred milliseconds to provide odometry
00170   class RunMotionModel : public StateNode {
00171    public:
00172     RunMotionModel(const std::string &nodename="RunMotionModel") : StateNode(nodename) {}
00173     virtual void doStart();
00174     virtual void doEvent();
00175   };
00176 
00177   //! Collision checker service; its behavior is model-dependent.
00178   /*! On the Create and Calliope it uses the bump switches and motor torques
00179    */
00180   class CollisionChecker : public StateNode {
00181    public:
00182     CollisionChecker(const std::string &nodename="CollisionChecker") : StateNode(nodename), overcurrentCounter(0) {}
00183     virtual void doStart();
00184     virtual void doEvent();
00185     virtual void enableDetection();
00186     virtual void disableDetection(unsigned int howlong);
00187     virtual void reportCollision();
00188     int overcurrentCounter; //!< count Create overcurrent button events to eliminate transients
00189     static unsigned int const collisionEnableTimer = 1;
00190     static unsigned int const overcurrentResetTimer = 2;
00191   };
00192 
00193   //================ Utility Classes Used By Pilot State Machines ================
00194 
00195   class ReportCompletion : public StateNode {
00196    public:
00197     ReportCompletion(const std::string &nodename, PilotTypes::ErrorType_t _errorType=noError) : StateNode(nodename), errorType(_errorType) {}
00198     PilotTypes::ErrorType_t errorType;  // cache the constructor's parameter
00199     virtual void doStart() {
00200       VRmixin::pilot->requestComplete(errorType);
00201     }
00202   };
00203 
00204   //! Used by Pilot walk machines to decide how to respond to a collision
00205   class CollisionDispatch : public StateNode {
00206    public:
00207     CollisionDispatch(const std::string &nodename="CollisionDispatch") : StateNode(nodename) {}
00208     virtual void doStart();
00209     virtual void doEvent();
00210   };
00211 
00212   //! Terminate a walk operation and indicate that a collision was responsible
00213   class TerminateDueToCollision : public StateNode {
00214    public:
00215     TerminateDueToCollision(const std::string &nodename="TerminateDueToCollision") : StateNode(nodename) {}
00216     virtual void doStart();
00217   };
00218 
00219   class SetupLandmarkExtractor : public VisualRoutinesStateNode {
00220    public:
00221     SetupLandmarkExtractor(const std::string &nodename="SetupLandmarkExtractor") : VisualRoutinesStateNode(nodename) {}
00222     virtual void doStart() {
00223         VRmixin::pilot->setupLandmarkExtractor();
00224     }
00225   };
00226 
00227   class PlanPath : public VisualRoutinesStateNode {
00228    public:
00229     PlanPath(const std::string &nodename="PlanPath") : VisualRoutinesStateNode(nodename) {}
00230     virtual void doStart() {
00231     NavigationPlan &plan = getAncestor<Pilot>()->plan;
00232     Point &initPos = getAncestor<Pilot>()->initPos;
00233     AngTwoPi &initHead = getAncestor<Pilot>()->initHead;
00234     PilotRequest &planReq = getAncestor<Pilot>()->planReq;
00235       plan.clear();
00236       doPlan(plan, initPos, initHead, planReq);
00237     }
00238     void doPlan(NavigationPlan &plan, Point initPos, AngTwoPi initHead, PilotRequest req);
00239   };
00240 
00241   //! Construct a navigation plan: mixture of moving, turning, and localizing steps
00242   class ConstructNavPlan : public VisualRoutinesStateNode {
00243    public:
00244     ConstructNavPlan(const std::string &nodename="ConstructNavPlan") : VisualRoutinesStateNode(nodename) {}
00245     virtual void doStart() {
00246     NavigationPlan &plan = getAncestor<Pilot>()->plan;
00247     Point &initPos = getAncestor<Pilot>()->initPos;
00248     AngTwoPi &initHead = getAncestor<Pilot>()->initHead;
00249     PilotRequest &planReq = getAncestor<Pilot>()->planReq;
00250       doAnalysis(plan, initPos, initHead, planReq);
00251     }
00252     void doAnalysis(NavigationPlan &plan, Point initPos, AngTwoPi initHead, PilotRequest req);
00253   };
00254 
00255   //! Execute a navigation plan; used for both goToShape and pushObject
00256   class ExecutePlan : public VisualRoutinesStateNode {
00257    public:
00258     ExecutePlan(const std::string &nodename="ExecutePlan") : VisualRoutinesStateNode(nodename), nextDisplacementInstruction(), boxX(), acquireDist() {}
00259 
00260     //! distance in mm we can be from a destination point and be "there"
00261     static const float allowableDistanceError;
00262     static const float allowableAngularError;
00263 
00264     //! Each movement step in a navigation plan is a DisplacementInstruction
00265     struct DisplacementInstruction {
00266       DisplacementInstruction() : nextPoint(), angleToTurn(0) {};
00267       fmat::Column<2> nextPoint;
00268       AngSignPi angleToTurn;
00269     };
00270 
00271     enum TurnAdjustType_t {
00272       collisionAdjust,
00273       localizationAdjust
00274     };
00275 
00276     class NextTask : public VisualRoutinesStateNode {
00277      public:
00278       NextTask(const std::string &nodename="NextTask") : VisualRoutinesStateNode(nodename) {}
00279       virtual void doStart() {
00280         NavigationPlan &plan = getAncestor<Pilot>()->plan;
00281           if ( ++plan.currentStep == plan.steps.end() )
00282             postStateCompletion();  // indicate that we're done
00283           else
00284             postStateSuccess();     // indicate that we have a task to perform
00285       }
00286     };
00287 
00288     class Walk : public WaypointWalkNode {
00289      public:
00290       Walk(const std::string &nodename="Walk") : WaypointWalkNode(nodename) {}
00291       virtual void doStart() {
00292           PilotRequest &req = *VRmixin::pilot->curReq;
00293         DisplacementInstruction &nextDisplacementInstruction = getAncestor<ExecutePlan>()->nextDisplacementInstruction;
00294     
00295           MMAccessor<WaypointWalkMC> wp_acc(getMC());
00296           wp_acc->getWaypointList().clear();
00297     
00298           #ifdef TGT_IS_CREATE
00299           float vx = (req.forwardSpeed > 0) ? req.forwardSpeed : 50.f;
00300           float va = (req.turnSpeed > 0) ? req.turnSpeed : 1.0f;
00301           wp_acc->addEgocentricWaypoint(nextDisplacementInstruction.nextPoint.norm(), 0,  0, true, vx, va);
00302           #else
00303           float vx = (req.forwardSpeed > 0) ? req.forwardSpeed : 15.f;
00304           float va = (req.turnSpeed > 0) ? req.turnSpeed : 0.1f;
00305           wp_acc->addEgocentricWaypoint(nextDisplacementInstruction.nextPoint.norm(), 0,  0, true, vx, va);
00306           #endif
00307     
00308           motman->setPriority(VRmixin::pilot->getWaypointwalk_id(),MotionManager::kStdPriority);        
00309       }
00310     };
00311 
00312     class Turn : public WaypointWalkNode {
00313      public:
00314       Turn(const std::string &nodename="Turn") : WaypointWalkNode(nodename) {}
00315       virtual void doStart() {
00316           PilotRequest &req = *VRmixin::pilot->curReq;
00317         DisplacementInstruction &nextDisplacementInstruction = getAncestor<ExecutePlan>()->nextDisplacementInstruction;
00318     
00319           MMAccessor<WaypointWalkMC> wp_acc(getMC());
00320           wp_acc->getWaypointList().clear();
00321           // std::cout<<"turning \n";
00322     
00323           #ifdef TGT_IS_CREATE
00324           float vx = (req.forwardSpeed > 0) ? req.forwardSpeed : 50.f;
00325           float va = (req.turnSpeed > 0) ? req.turnSpeed : 1.0f;
00326           wp_acc->addEgocentricWaypoint(0, 0, nextDisplacementInstruction.angleToTurn, true, vx, va);
00327           #else
00328           // these values are for Chiara
00329           float vx = (req.forwardSpeed > 0) ? req.forwardSpeed : 15.f;
00330           float va = (req.turnSpeed > 0) ? req.turnSpeed : 0.1f;
00331           wp_acc->addEgocentricWaypoint(0, 0,nextDisplacementInstruction.angleToTurn, true, vx, va);
00332           #endif
00333       }
00334     };
00335 
00336     class TurnObj : public WaypointWalkNode {
00337      public:
00338       TurnObj(const std::string &nodename="TurnObj") : WaypointWalkNode(nodename) {}
00339       virtual void doStart() {
00340         DisplacementInstruction &nextDisplacementInstruction = getAncestor<ExecutePlan>()->nextDisplacementInstruction;
00341         float &acquireDist = getAncestor<ExecutePlan>()->acquireDist;
00342           MMAccessor<WaypointWalkMC> wp_acc(getMC());
00343           wp_acc->getWaypointList().clear();
00344     
00345           const float backup_step_size = 300;  // back up from the box
00346           wp_acc->addEgocentricWaypoint(-backup_step_size, 0, M_PI, true, 50.f, 1.f );
00347     
00348           float theta = nextDisplacementInstruction.angleToTurn;
00349           float abstheta = fabs(theta);
00350           float hyp = (backup_step_size + 100)/cos(abstheta);
00351           float x = (backup_step_size + 100) * tan(abstheta);
00352           float step2 = (backup_step_size/tan(abstheta)) - 100;
00353           float d = 500 / sin(abstheta);
00354     
00355           cout << "*************** TURN PUSH BOX *****************     " << nextDisplacementInstruction.angleToTurn << "  ******************" << endl;
00356           if (theta >= 0) {
00357             //Turn Right
00358             wp_acc->addEgocentricWaypoint(0, 0, -M_PI/2.f, true, 50.f, 1.0f );
00359             if (x > 500) {
00360               wp_acc->addEgocentricWaypoint(500, 0, 0, true, 50.f, 1.0f );
00361               wp_acc->addEgocentricWaypoint(0, 0, M_PI/2.f, true, 50.f, 1.0f );
00362               wp_acc->addEgocentricWaypoint(backup_step_size - step2, 0, 0, true, 50.f, 1.0f );
00363               wp_acc->addEgocentricWaypoint(0, 0, abstheta, true, 50.f, 1.0f );
00364               // wp_acc->addEgocentricWaypoint(d, 0, 0, true, 50.f, 1.0f );
00365               acquireDist = d;
00366             } else {
00367               wp_acc->addEgocentricWaypoint(x, 0, 0, true, 50.f, 1.0f );
00368               wp_acc->addEgocentricWaypoint(0, 0, M_PI/2.f + abstheta, true, 50.f, 1.0f );
00369               //wp_acc->addEgocentricWaypoint(hyp, 0, 0, true, 50.f, 1.0f );
00370               acquireDist = hyp;
00371             }
00372           } else {
00373             wp_acc->addEgocentricWaypoint(0, 0, -abstheta + M_PI/2.f, true, 50.f, 1.0f );
00374             wp_acc->addEgocentricWaypoint(backup_step_size*sin(abstheta), 0, 0, true, 50.f, 1.0f );
00375             wp_acc->addEgocentricWaypoint(0, 0, -M_PI/2.f, true, 50.f, 1.0f );
00376             wp_acc->addEgocentricWaypoint(backup_step_size*cos(abstheta), 0, 0, true, 50.f, 1.0f );
00377           }
00378       }
00379     };
00380 
00381     class AdjustTurn : public WaypointWalkNode {
00382      public:
00383       AdjustTurn(const std::string &nodename, const ExecutePlan::TurnAdjustType_t _adjustmentType) : WaypointWalkNode(nodename), adjustmentType(_adjustmentType) {}
00384       const ExecutePlan::TurnAdjustType_t adjustmentType;  // cache the constructor's parameter
00385       virtual void doStart() {
00386         NavigationPlan &plan = getAncestor<Pilot>()->plan;
00387           MMAccessor<WaypointWalkMC> wp_acc(getMC());
00388           wp_acc->getWaypointList().clear();
00389           DualCoding::Point position = theAgent->getCentroid();
00390           fmat::Column<3> pos = position.getCoords();
00391           fmat::Column<3> next = plan.currentStep->waypoint.getCoords();
00392     
00393           if (adjustmentType == collisionAdjust) {
00394             next = plan.currentStep->waypoint.getCoords();
00395             cout << "*************** ADJUST TURN COLLISION ***********************************" << endl;
00396           }
00397           else {
00398             plan.currentStep++;
00399             next = plan.currentStep->waypoint.getCoords();
00400             plan.currentStep--;
00401             cout << "*************** ADJUST TURN ***********************************" << endl;
00402           }
00403     
00404           fmat::Column<2> disp = fmat::SubVector<2>(next) - fmat::SubVector<2>(pos);
00405           AngSignPi angle = (atan2(disp[1], disp[0]) - theAgent->getOrientation());
00406     
00407           PilotRequest &req = *VRmixin::pilot->curReq;
00408           #ifdef TGT_IS_CREATE
00409           float vx = (req.forwardSpeed > 0) ? req.forwardSpeed : 50.f;
00410           float va = (req.turnSpeed > 0) ? req.turnSpeed : 1.0f;
00411           wp_acc->addEgocentricWaypoint(0, 0, angle, true, vx, va);
00412           #else
00413           // these values are for Chiara
00414           float vx = (req.forwardSpeed > 0) ? req.forwardSpeed : 15.f;
00415           float va = (req.turnSpeed > 0) ? req.turnSpeed : 0.1f;
00416           wp_acc->addEgocentricWaypoint(0, 0, angle, true, vx, va);
00417           #endif
00418       }
00419     };
00420 
00421     class ExecuteStep : public VisualRoutinesStateNode {
00422      public:
00423       ExecuteStep(const std::string &nodename="ExecuteStep") : VisualRoutinesStateNode(nodename) {}
00424         virtual void doStart() {
00425       DisplacementInstruction &nextDisplacementInstruction = getAncestor<ExecutePlan>()->nextDisplacementInstruction;
00426       NavigationPlan &plan = getAncestor<Pilot>()->plan;
00427       bool &pushingObj = getAncestor<Pilot>()->pushingObj;
00428   
00429           doExecute(plan, nextDisplacementInstruction, pushingObj);
00430         }
00431         virtual void doExecute(NavigationPlan &plan, DisplacementInstruction &nextDisplacementInstruction, const bool pushType);
00432     };
00433 
00434     class LookForObject : public MapBuilderNode {
00435      public:
00436       LookForObject(const std::string &nodename="LookForObject") : MapBuilderNode(nodename) {}
00437       virtual void doStart() {
00438           MapBuilderRequest *m = VRmixin::pilot->curReq->objectExtractor;
00439           if ( m == NULL )
00440             cancelThisRequest();
00441           else
00442             mapreq = *m;
00443       }
00444     };
00445 
00446     class SelectObject : public VisualRoutinesStateNode {
00447      public:
00448       SelectObject(const std::string &nodename="SelectObject") : VisualRoutinesStateNode(nodename) {}
00449       virtual void doStart() {
00450         float &boxX = getAncestor<ExecutePlan>()->boxX;
00451           PilotRequest &req = *VRmixin::pilot->curReq;
00452           if ( req.objectMatcher == NULL ) {
00453             cout << "No objectMatcher specified for pushObject in Pilot" << endl;
00454             postStateFailure();
00455           } else {
00456             ShapeRoot localObj = (*req.objectMatcher)(req.objectShape);
00457             if ( ! localObj.isValid() )
00458               postStateFailure();
00459             else {
00460               boxX = localObj->getCentroid().coordX();
00461               postStateCompletion();
00462             }
00463           }
00464       }
00465     };
00466 
00467     class TurnAndMove : public WaypointWalkNode {
00468      public:
00469       TurnAndMove(const std::string &nodename="TurnAndMove") : WaypointWalkNode(nodename) {}
00470       virtual void doStart() {
00471         float &acquireDist = getAncestor<ExecutePlan>()->acquireDist;
00472         float &boxX = getAncestor<ExecutePlan>()->boxX;
00473           float stepSize = min(acquireDist, 100.f);
00474           acquireDist -= stepSize;
00475           float angle;
00476           angle = asin( (160.f - boxX) * sin(M_PI/6.f)/160.f );  // ***HACK based on 320x240 camera image
00477           angle = 0;
00478     
00479           MMAccessor<WaypointWalkMC> wp_acc(getMC());
00480           wp_acc->getWaypointList().clear();
00481     
00482           #ifdef TGT_IS_CREATE
00483           float vx = 50.f;
00484           float va = 1.0f;
00485           #else
00486           float vx = 15.f;
00487           float va = 0.1f;
00488           #endif
00489     
00490           wp_acc->addEgocentricWaypoint(0, 0,  angle, true, vx, va);
00491           wp_acc->addEgocentricWaypoint(stepSize, 0,  0, true, vx, va);
00492           motman->setPriority(VRmixin::pilot->getWaypointwalk_id(),MotionManager::kStdPriority);
00493       }
00494     };
00495 
00496     class DecideNode : public VisualRoutinesStateNode {
00497      public:
00498       DecideNode(const std::string &nodename="DecideNode") : VisualRoutinesStateNode(nodename) {}
00499       virtual void doStart() {
00500         float &acquireDist = getAncestor<ExecutePlan>()->acquireDist;
00501             if (acquireDist < 1.f)
00502                 postStateCompletion();
00503             else
00504                 postStateFailure();
00505       }
00506     };
00507 
00508     class AcquireObj : public VisualRoutinesStateNode {
00509      public:
00510       AcquireObj(const std::string &nodename="AcquireObj") : VisualRoutinesStateNode(nodename) {}
00511       virtual void doStart() {
00512         float &acquireDist = getAncestor<ExecutePlan>()->acquireDist;
00513         DisplacementInstruction &nextDisplacementInstruction = getAncestor<ExecutePlan>()->nextDisplacementInstruction;
00514             acquireDist = nextDisplacementInstruction.nextPoint.norm();
00515       }
00516     };
00517 
00518     virtual void setup() {
00519      ExecuteStep *execute = new ExecuteStep("execute");
00520      addNode(execute);
00521 
00522      PostMachineCompletion *postmachinecompletion1 = new PostMachineCompletion("postmachinecompletion1");
00523      addNode(postmachinecompletion1);
00524 
00525      LocalizationUtility *localizer = new LocalizationUtility("localizer");
00526      addNode(localizer);
00527 
00528      AdjustTurn *adjust = new AdjustTurn("adjust",localizationAdjust);
00529      addNode(adjust);
00530      adjust->setMC(VRmixin::pilot->waypointwalk_id);
00531 
00532      Walk *walker = new Walk("walker");
00533      addNode(walker);
00534      walker->setMC(VRmixin::pilot->waypointwalk_id);
00535 
00536      Turn *turner = new Turn("turner");
00537      addNode(turner);
00538      turner->setMC(VRmixin::pilot->waypointwalk_id);
00539 
00540      TurnObj *boxturner = new TurnObj("boxturner");
00541      addNode(boxturner);
00542      boxturner->setMC(VRmixin::pilot->waypointwalk_id);
00543 
00544      AcquireObj *acquirebox = new AcquireObj("acquirebox");
00545      addNode(acquirebox);
00546 
00547      LookForObject *locatebox = new LookForObject("locatebox");
00548      addNode(locatebox);
00549 
00550      SelectObject *select = new SelectObject("select");
00551      addNode(select);
00552 
00553      TurnAndMove *turnandmove = new TurnAndMove("turnandmove");
00554      addNode(turnandmove);
00555 
00556      DecideNode *decide = new DecideNode("decide");
00557      addNode(decide);
00558 
00559      NextTask *next = new NextTask("next");
00560      addNode(next);
00561 
00562      PostMachineCompletion *postmachinecompletion2 = new PostMachineCompletion("postmachinecompletion2");
00563      addNode(postmachinecompletion2);
00564 
00565      CollisionDispatch *collisionDispatch = new CollisionDispatch("collisionDispatch");
00566      addNode(collisionDispatch);
00567 
00568      TerminateDueToCollision *term = new TerminateDueToCollision("term");
00569      addNode(term);
00570 
00571      startnode = execute;
00572 
00573      execute->addTransition(new SignalTrans<NavigationStepType_t>("signaltrans1",localizer,localizeStep));
00574      execute->addTransition(new SignalTrans<NavigationStepType_t>("signaltrans2",walker,travelStep));
00575      execute->addTransition(new SignalTrans<NavigationStepType_t>("signaltrans3",turner,turnStep));
00576      execute->addTransition(new SignalTrans<NavigationStepType_t>("signaltrans4",turner,turnObjStep));
00577      execute->addTransition(new SignalTrans<NavigationStepType_t>("signaltrans5",acquirebox,acquireObjStep));
00578      execute->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans6",next,StateNode::successSignal));
00579      execute->addTransition(new CompletionTrans("completiontrans1",postmachinecompletion1));
00580      localizer->addTransition(new CompletionTrans("completiontrans2",adjust));
00581      localizer->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans7",adjust,StateNode::failureSignal));
00582      adjust->addTransition(new CompletionTrans("completiontrans3",next));
00583      walker->addTransition(new CompletionTrans("completiontrans4",next));
00584      turner->addTransition(new CompletionTrans("completiontrans5",next));
00585      boxturner->addTransition(new CompletionTrans("completiontrans6",locatebox));
00586      acquirebox->addTransition(new NullTrans("nulltrans1",locatebox));
00587      locatebox->addTransition(new CompletionTrans("completiontrans7",select));
00588      locatebox->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans8",select,StateNode::failureSignal));
00589      select->addTransition(new NullTrans("nulltrans2",turnandmove));
00590      turnandmove->addTransition(new CompletionTrans("completiontrans8",decide));
00591      decide->addTransition(new CompletionTrans("completiontrans9",next));
00592      decide->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans9",locatebox,StateNode::failureSignal));
00593      next->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans10",execute,StateNode::successSignal));
00594      next->addTransition(new CompletionTrans("completiontrans10",postmachinecompletion2));
00595 
00596      PilotTrans *pilottrans1 = new PilotTrans("pilottrans1",term,PilotTypes::collisionDetected);
00597      collisionDispatch->addTransition(pilottrans1);
00598      localizer->addTransition(pilottrans1);
00599      walker->addTransition(pilottrans1);
00600      turner->addTransition(pilottrans1);
00601      boxturner->addTransition(pilottrans1);
00602      turnandmove->addTransition(pilottrans1);
00603 
00604     }
00605     DisplacementInstruction nextDisplacementInstruction;   // from $provide
00606     float boxX;   // from $provide
00607     float acquireDist;   // from $provide
00608   };
00609 
00610   //================ LocalizationUtility ================
00611 
00612   //! State machine called by various Pilot functions to perform a landmark search and localization.
00613   class LocalizationUtility : public VisualRoutinesStateNode {
00614    public:
00615     LocalizationUtility(const std::string &nodename="LocalizationUtility") : VisualRoutinesStateNode(nodename), initialHeading(), gazePoints(), gazeHeadings() {}
00616 
00617 
00618     class TakeInitialPicture : public MapBuilderNode {
00619      public:
00620       TakeInitialPicture(const std::string &nodename="TakeInitialPicture") : MapBuilderNode(nodename,MapBuilderRequest::localMap) {}
00621       virtual void doStart() {
00622         AngTwoPi &initialHeading = getAncestor<LocalizationUtility>()->initialHeading;
00623           initialHeading = VRmixin::theAgent->getOrientation();
00624         AngTwoPi &maxTurn = getAncestor<Pilot>()->maxTurn;
00625           maxTurn = M_PI;
00626           if ( VRmixin::pilot->curReq == NULL // needed to prevent crash if behavior is shut down in the ControllerGUI
00627                || VRmixin::pilot->curReq->landmarkExtractor == NULL ) {
00628             cancelThisRequest();
00629             return;
00630           }
00631           mapreq = *VRmixin::pilot->curReq->landmarkExtractor;
00632           mapreq.clearLocal = true;
00633       }
00634     };
00635 
00636     class CheckEnoughLandmarks : public VisualRoutinesStateNode {
00637      public:
00638       CheckEnoughLandmarks(const std::string &nodename="CheckEnoughLandmarks") : VisualRoutinesStateNode(nodename) {}
00639       virtual void doStart() {
00640           if ( VRmixin::pilot->curReq != NULL // needed to prevent crash if behavior is shut down in the ControllerGUI
00641          && VRmixin::pilot->curReq->landmarkExitTest() )
00642       postStateSuccess();
00643           else
00644       postStateFailure();
00645       }
00646     };
00647 
00648 #ifdef TGT_HAS_HEAD
00649     // Use gazepoints since we have a pan/tilt available
00650 
00651     class ChooseGazePoints : public StateNode {
00652      public:
00653       ChooseGazePoints(const std::string &nodename="ChooseGazePoints") : StateNode(nodename) {}
00654         virtual void doStart() {
00655       std::deque<Point> &gazePoints = getAncestor<LocalizationUtility>()->gazePoints;
00656     setupGazePoints(gazePoints);
00657         }
00658         void setupGazePoints(std::deque<Point> &gazePoints);
00659     };
00660 
00661     class PrepareForNextGazePoint : public StateNode {
00662      public:
00663       PrepareForNextGazePoint(const std::string &nodename="PrepareForNextGazePoint") : StateNode(nodename) {}
00664         virtual void doStart() {
00665     // This node just does a quick check because we'll be using the
00666     // pan/tilt for the actual work.  The no-head version (below)
00667     // will turn the body.
00668       std::deque<Point> &gazePoints = getAncestor<LocalizationUtility>()->gazePoints;
00669     if ( gazePoints.empty() )
00670       postStateFailure();
00671     else
00672       postStateCompletion();
00673         }
00674         void setMC(const MotionManager::MC_ID) {}  // dummy for compatibility with headless case below
00675     };
00676 
00677     class TakeNextPicture : public MapBuilderNode {
00678      public:
00679       TakeNextPicture(const std::string &nodename="TakeNextPicture") : MapBuilderNode(nodename,MapBuilderRequest::localMap) {}
00680       virtual void doStart() {
00681           {
00682       GET_SHAPE(gazePoint, PointData, VRmixin::localShS);
00683       if ( gazePoint.isValid() )
00684         VRmixin::localShS.deleteShape(gazePoint);
00685           }
00686           // send the MapBuilder to the next gaze point
00687         std::deque<Point> &gazePoints = getAncestor<LocalizationUtility>()->gazePoints;
00688           NEW_SHAPE(gazePoint, PointData, new PointData(localShS, gazePoints.front()));
00689           gazePoints.pop_front();
00690           mapreq =  *VRmixin::pilot->curReq->landmarkExtractor;
00691           mapreq.searchArea = gazePoint;
00692           mapreq.clearLocal = false;
00693           
00694       }
00695     };
00696 
00697     class ReturnToInitialHeading : public StateNode {
00698      public:
00699       ReturnToInitialHeading(const std::string &nodename="ReturnToInitialHeading") : StateNode(nodename) {}
00700         virtual void doStart() {
00701           // dummy node since we never moved the body (because we have a pan/tilt)
00702           postStateCompletion();
00703         }
00704         void setMC(const MotionManager::MC_ID) {}  // dummy for compatibility with headless case below
00705     };
00706 
00707 #else
00708     // No pan/tilt available; must turn the body to acquire more landmarks
00709 
00710     class ChooseGazePoints : public StateNode {
00711      public:
00712       ChooseGazePoints(const std::string &nodename="ChooseGazePoints") : StateNode(nodename) {}
00713         virtual void doStart() {
00714       AngTwoPi &initialHeading = getAncestor<LocalizationUtility>()->initialHeading;
00715       std::deque<AngTwoPi> &gazeHeadings = getAncestor<LocalizationUtility>()->gazeHeadings;
00716       AngTwoPi &maxTurn = getAncestor<Pilot>()->maxTurn;
00717   
00718           setupGazeHeadings(initialHeading, gazeHeadings, maxTurn);
00719         }
00720         void setupGazeHeadings(const AngTwoPi initialHeading, std::deque<AngTwoPi> &gazeHeadings, const AngTwoPi maxTurn);
00721     };
00722 
00723     class PrepareForNextGazePoint : public WaypointWalkNode {
00724      public:
00725       PrepareForNextGazePoint(const std::string &nodename="PrepareForNextGazePoint") : WaypointWalkNode(nodename) {}
00726         virtual void doStart() {
00727       std::deque<AngTwoPi> &gazeHeadings = getAncestor<LocalizationUtility>()->gazeHeadings;
00728       AngTwoPi &maxTurn = getAncestor<Pilot>()->maxTurn;
00729           prepareForNext(gazeHeadings, maxTurn);
00730         }
00731         void prepareForNext(std::deque<AngTwoPi> &gazeHeadings, const AngTwoPi maxTurn);
00732     };
00733 
00734     class TakeNextPicture : public MapBuilderNode {
00735      public:
00736       TakeNextPicture(const std::string &nodename="TakeNextPicture") : MapBuilderNode(nodename,MapBuilderRequest::localMap) {}
00737       virtual void doStart() {
00738           mapreq =  *VRmixin::pilot->curReq->landmarkExtractor;
00739           mapreq.clearLocal = false;
00740         AngTwoPi &initialHeading = getAncestor<LocalizationUtility>()->initialHeading;
00741           const AngTwoPi curHeading = VRmixin::theAgent->getOrientation();
00742           const float headingShift = float(curHeading-initialHeading);
00743           mapreq.baseTransform.rotation() = fmat::rotationZ(headingShift);
00744     
00745       }
00746     };
00747 
00748     class ReturnToInitialHeading : public WaypointWalkNode {
00749      public:
00750       ReturnToInitialHeading(const std::string &nodename="ReturnToInitialHeading") : WaypointWalkNode(nodename) {
00751           setMC(VRmixin::pilot->getWaypointwalk_id());
00752       }
00753   
00754         virtual void doStart() {
00755           static const float allowableAngularError = 0.10f;
00756       AngTwoPi &initialHeading = getAncestor<LocalizationUtility>()->initialHeading;
00757           const AngTwoPi curHeading = VRmixin::theAgent->getOrientation();
00758           const AngSignPi turnAmount = AngSignPi(initialHeading - curHeading);
00759           if ( fabs(turnAmount) < allowableAngularError ) {
00760             postStateCompletion();
00761             return;
00762           }
00763           MMAccessor<WaypointWalkMC> wp_acc(getMC());
00764           wp_acc->getWaypointList().clear();
00765   #ifdef TGT_IS_CREATE
00766           float const va = 0.9f;  // optimal turn speed for CREATE odometry
00767           wp_acc->addEgocentricWaypoint(0, 0, turnAmount, true, 0, va);
00768   #else
00769           // no other headless robots supported yet, so just repeat the Create values for now
00770           float const va = 0.9f;
00771           wp_acc->addEgocentricWaypoint(0, 0, turnAmount, true, 0, va);
00772   #endif
00773           motman->setPriority(VRmixin::pilot->getWaypointwalk_id(),MotionManager::kStdPriority);
00774         }
00775     };
00776 
00777 #endif // TGT_HAS_HEAD
00778 
00779     class Localize : public VisualRoutinesStateNode {
00780      public:
00781       Localize(const std::string &nodename="Localize") : VisualRoutinesStateNode(nodename) {}
00782         static float const minConfidentWeight;
00783         virtual void doStart();
00784     };
00785 
00786     virtual void setup() {
00787      TakeInitialPicture *take = new TakeInitialPicture("take");
00788      addNode(take);
00789 
00790      CheckEnoughLandmarks *checkEnough = new CheckEnoughLandmarks("checkEnough");
00791      addNode(checkEnough);
00792 
00793      ChooseGazePoints *choosegazepoints1 = new ChooseGazePoints("choosegazepoints1");
00794      addNode(choosegazepoints1);
00795 
00796      PrepareForNextGazePoint *loop = new PrepareForNextGazePoint("loop");
00797      addNode(loop);
00798      loop->setMC(VRmixin::pilot->getWaypointwalk_id());
00799 
00800      StateNode *statenode1 = new StateNode("statenode1");
00801      addNode(statenode1);
00802 
00803      TakeNextPicture *takenextpic = new TakeNextPicture("takenextpic");
00804      addNode(takenextpic);
00805 
00806      CheckEnoughLandmarks *checkEnough2 = new CheckEnoughLandmarks("checkEnough2");
00807      addNode(checkEnough2);
00808 
00809      ReturnToInitialHeading *returntoinitialheading1 = new ReturnToInitialHeading("returntoinitialheading1");
00810      addNode(returntoinitialheading1);
00811      returntoinitialheading1->setMC(VRmixin::pilot->getWaypointwalk_id());
00812 
00813      Localize *loc = new Localize("loc");
00814      addNode(loc);
00815 
00816      PostMachineSuccess *postmachinesuccess1 = new PostMachineSuccess("postmachinesuccess1");
00817      addNode(postmachinesuccess1);
00818 
00819      PostMachineCompletion *postmachinecompletion3 = new PostMachineCompletion("postmachinecompletion3");
00820      addNode(postmachinecompletion3);
00821 
00822      ReturnToInitialHeading *outofoptions = new ReturnToInitialHeading("outofoptions");
00823      addNode(outofoptions);
00824 
00825      PostMachineFailure *postmachinefailure1 = new PostMachineFailure("postmachinefailure1");
00826      addNode(postmachinefailure1);
00827 
00828      PostMachineCompletion *postmachinecompletion4 = new PostMachineCompletion("postmachinecompletion4");
00829      addNode(postmachinecompletion4);
00830 
00831      startnode = take;
00832 
00833      take->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans11",outofoptions,StateNode::failureSignal));
00834      take->addTransition(new EventTrans("eventtrans1",checkEnough,EventBase::mapbuilderEGID,(size_t)take,EventBase::statusETID));
00835      checkEnough->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans12",loc,StateNode::successSignal));
00836      checkEnough->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans13",choosegazepoints1,StateNode::failureSignal));
00837      choosegazepoints1->addTransition(new NullTrans("nulltrans3",loop));
00838      loop->addTransition(new CompletionTrans("completiontrans11",statenode1));
00839      statenode1->addTransition(new TimeOutTrans("timeouttrans1",takenextpic,1000));
00840      loop->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans14",loop,StateNode::successSignal));
00841      loop->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans15",outofoptions,StateNode::failureSignal));
00842      takenextpic->addTransition(new EventTrans("eventtrans2",checkEnough2,EventBase::mapbuilderEGID,(size_t)takenextpic,EventBase::statusETID));
00843      checkEnough2->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans16",returntoinitialheading1,StateNode::successSignal));
00844      returntoinitialheading1->addTransition(new CompletionTrans("completiontrans12",loc));
00845      checkEnough2->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans17",loop,StateNode::failureSignal));
00846      loc->addTransition(new NullTrans("nulltrans4",postmachinesuccess1));
00847      postmachinesuccess1->addTransition(new NullTrans("nulltrans5",postmachinecompletion3));
00848      outofoptions->addTransition(new CompletionTrans("completiontrans13",postmachinefailure1));
00849      postmachinefailure1->addTransition(new NullTrans("nulltrans6",postmachinecompletion4));
00850     }
00851     AngTwoPi initialHeading;   // from $provide
00852     std::deque<Point> gazePoints;   // from $provide
00853     std::deque<AngTwoPi> gazeHeadings;   // from $provide
00854   };
00855 
00856   //================ LocalizationMachine ================
00857 
00858   class LocalizationMachine : public StateNode {
00859    public:
00860     LocalizationMachine(const std::string &nodename="LocalizationMachine") : StateNode(nodename) {}
00861     virtual void setup() {
00862      SetupLandmarkExtractor *setuplandmarkextractor1 = new SetupLandmarkExtractor("setuplandmarkextractor1");
00863      addNode(setuplandmarkextractor1);
00864 
00865      LocalizationUtility *loc = new LocalizationUtility("loc");
00866      addNode(loc);
00867 
00868      PostMachineSuccess *postmachinesuccess2 = new PostMachineSuccess("postmachinesuccess2");
00869      addNode(postmachinesuccess2);
00870 
00871      PostMachineFailure *postmachinefailure2 = new PostMachineFailure("postmachinefailure2");
00872      addNode(postmachinefailure2);
00873 
00874      startnode = setuplandmarkextractor1;
00875 
00876      setuplandmarkextractor1->addTransition(new NullTrans("nulltrans7",loc));
00877      loc->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans18",postmachinesuccess2,StateNode::successSignal));
00878      loc->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans19",postmachinefailure2,StateNode::failureSignal));
00879     }
00880   };
00881 
00882   //================ WalkMachine ================
00883 
00884   class WalkMachine : public StateNode {
00885    public:
00886     WalkMachine(const std::string &nodename="WalkMachine") : StateNode(nodename) {}
00887 
00888     class WalkMachine_WaypointWalker : public WaypointWalkNode {
00889      public:
00890       WalkMachine_WaypointWalker(const std::string &nodename="WalkMachine_WaypointWalker") : WaypointWalkNode(nodename) {}
00891         virtual void doStart();
00892     };
00893 
00894     virtual void setup() {
00895      startnode = new StateNode("startnode");
00896      addNode(startnode);
00897 
00898      WalkMachine_WaypointWalker *walker = new WalkMachine_WaypointWalker("walker");
00899      addNode(walker);
00900      walker->setMC(VRmixin::pilot->getWaypointwalk_id());
00901 
00902      ReportCompletion *reportcompletion1 = new ReportCompletion("reportcompletion1");
00903      addNode(reportcompletion1);
00904 
00905      CollisionDispatch *collisionDispatch = new CollisionDispatch("collisionDispatch");
00906      addNode(collisionDispatch);
00907 
00908      TerminateDueToCollision *terminateduetocollision1 = new TerminateDueToCollision("terminateduetocollision1");
00909      addNode(terminateduetocollision1);
00910 
00911      startnode = startnode;
00912 
00913      NullTrans *nulltrans8 = new NullTrans("nulltrans8",walker);
00914      nulltrans8->addDestination(collisionDispatch);
00915      startnode->addTransition(nulltrans8);
00916 
00917      walker->addTransition(new CompletionTrans("completiontrans14",reportcompletion1));
00918 
00919      PilotTrans *pilottrans2 = new PilotTrans("pilottrans2",terminateduetocollision1,PilotTypes::collisionDetected);
00920      collisionDispatch->addTransition(pilottrans2);
00921      walker->addTransition(pilottrans2);
00922 
00923     }
00924 
00925   };
00926 
00927   //================ WaypointWalkMachine ================
00928 
00929   class WaypointWalkMachine : public StateNode {
00930    public:
00931     WaypointWalkMachine(const std::string &nodename="WaypointWalkMachine") : StateNode(nodename) {}
00932 
00933     class WaypointWalkMachine_WaypointWalker : public WaypointWalkNode {
00934      public:
00935       WaypointWalkMachine_WaypointWalker(const std::string &nodename="WaypointWalkMachine_WaypointWalker") : WaypointWalkNode(nodename) {}
00936         virtual void doStart();
00937     };
00938 
00939     virtual void setup() {
00940      startnode = new StateNode("startnode");
00941      addNode(startnode);
00942 
00943      WaypointWalkMachine_WaypointWalker *walker = new WaypointWalkMachine_WaypointWalker("walker");
00944      addNode(walker);
00945      walker->setMC(VRmixin::pilot->getWaypointwalk_id());
00946 
00947      ReportCompletion *reportcompletion2 = new ReportCompletion("reportcompletion2");
00948      addNode(reportcompletion2);
00949 
00950      CollisionDispatch *collisionDispatch = new CollisionDispatch("collisionDispatch");
00951      addNode(collisionDispatch);
00952 
00953      TerminateDueToCollision *terminateduetocollision2 = new TerminateDueToCollision("terminateduetocollision2");
00954      addNode(terminateduetocollision2);
00955 
00956      startnode = startnode;
00957 
00958      NullTrans *nulltrans9 = new NullTrans("nulltrans9",walker);
00959      nulltrans9->addDestination(collisionDispatch);
00960      startnode->addTransition(nulltrans9);
00961 
00962      walker->addTransition(new CompletionTrans("completiontrans15",reportcompletion2));
00963 
00964      PilotTrans *pilottrans3 = new PilotTrans("pilottrans3",terminateduetocollision2,PilotTypes::collisionDetected);
00965      collisionDispatch->addTransition(pilottrans3);
00966      walker->addTransition(pilottrans3);
00967 
00968     }
00969 
00970   };
00971 
00972   //=============== SetVelocityMachine ==================
00973   class SetVelocityMachine : public StateNode {
00974    public:
00975     SetVelocityMachine(const std::string &nodename="SetVelocityMachine") : StateNode(nodename) {}
00976 
00977     class SetVelocityMachine_Walker : public WalkNode {
00978      public:
00979       SetVelocityMachine_Walker(const std::string &nodename="SetVelocityMachine_Walker") : WalkNode(nodename) {}
00980         virtual void doStart();
00981     };
00982 
00983     virtual void setup() {
00984      startnode = new StateNode("startnode");
00985      addNode(startnode);
00986 
00987      SetVelocityMachine_Walker *walker = new SetVelocityMachine_Walker("walker");
00988      addNode(walker);
00989      walker->setMC(VRmixin::pilot->getWalk_id());
00990 
00991      StateNode *statenode2 = new StateNode("statenode2");
00992      addNode(statenode2);
00993 
00994      ReportCompletion *reportcompletion3 = new ReportCompletion("reportcompletion3");
00995      addNode(reportcompletion3);
00996 
00997      CollisionDispatch *collisionDispatch = new CollisionDispatch("collisionDispatch");
00998      addNode(collisionDispatch);
00999 
01000      TerminateDueToCollision *terminateduetocollision3 = new TerminateDueToCollision("terminateduetocollision3");
01001      addNode(terminateduetocollision3);
01002 
01003      startnode = startnode;
01004 
01005      NullTrans *nulltrans10 = new NullTrans("nulltrans10",walker);
01006      nulltrans10->addDestination(collisionDispatch);
01007      startnode->addTransition(nulltrans10);
01008 
01009      walker->addTransition(new CompletionTrans("completiontrans16",statenode2));
01010      statenode2->addTransition(new TimeOutTrans("timeouttrans2",reportcompletion3,2000));
01011 
01012      PilotTrans *pilottrans4 = new PilotTrans("pilottrans4",terminateduetocollision3,PilotTypes::collisionDetected);
01013      collisionDispatch->addTransition(pilottrans4);
01014      walker->addTransition(pilottrans4);
01015 
01016     }
01017 
01018   };
01019 
01020   //================ GoToShapeMachine ================
01021 
01022   class GoToShapeMachine : public VisualRoutinesStateNode {
01023    public:
01024     GoToShapeMachine(const std::string &nodename="GoToShapeMachine") : VisualRoutinesStateNode(nodename) {}
01025 
01026     //! Check that the request's goToShape parameters are valid
01027     class CheckParameters : public StateNode {
01028      public:
01029       CheckParameters(const std::string &nodename="CheckParameters") : StateNode(nodename) {}
01030         virtual void doStart();
01031     };
01032 
01033     class SetUpPlanNode : public StateNode {
01034      public:
01035       SetUpPlanNode(const std::string &nodename="SetUpPlanNode") : StateNode(nodename) {}
01036       virtual void doStart() {
01037         Point &initPos = getAncestor<Pilot>()->initPos;
01038         AngTwoPi &initHead = getAncestor<Pilot>()->initHead;
01039         PilotRequest &planReq = getAncestor<Pilot>()->planReq;
01040         bool &pushingObj = getAncestor<Pilot>()->pushingObj;
01041     
01042             initPos = theAgent->getCentroid();
01043             initHead = theAgent->getOrientation();
01044             planReq = *VRmixin::pilot->curReq;
01045             pushingObj = false;
01046       }
01047     };
01048 
01049     class SetMaxTurn : public StateNode {
01050      public:
01051       SetMaxTurn(const std::string &nodename="SetMaxTurn") : StateNode(nodename) {}
01052       virtual void doStart() {
01053         AngTwoPi &maxTurn = getAncestor<Pilot>()->maxTurn;
01054             maxTurn = M_PI;
01055       }
01056     };
01057 
01058     virtual void  setup() {   // setup GoToShapeMachine
01059 
01060      SetMaxTurn *setmaxturn1 = new SetMaxTurn("setmaxturn1");
01061      addNode(setmaxturn1);
01062 
01063      CheckParameters *check = new CheckParameters("check");
01064      addNode(check);
01065 
01066      ReportCompletion *reportcompletion4 = new ReportCompletion("reportcompletion4",invalidRequest);
01067      addNode(reportcompletion4);
01068 
01069      SetupLandmarkExtractor *setuplandmarkextractor2 = new SetupLandmarkExtractor("setuplandmarkextractor2");
01070      addNode(setuplandmarkextractor2);
01071 
01072      LocalizationUtility *loc = new LocalizationUtility("loc");
01073      addNode(loc);
01074 
01075      SetUpPlanNode *setupplan = new SetUpPlanNode("setupplan");
01076      addNode(setupplan);
01077 
01078      PlanPath *planpath = new PlanPath("planpath");
01079      addNode(planpath);
01080 
01081      ReportCompletion *reportcompletion5 = new ReportCompletion("reportcompletion5",startCollides);
01082      addNode(reportcompletion5);
01083 
01084      ReportCompletion *reportcompletion6 = new ReportCompletion("reportcompletion6",endCollides);
01085      addNode(reportcompletion6);
01086 
01087      ReportCompletion *reportcompletion7 = new ReportCompletion("reportcompletion7",noPath);
01088      addNode(reportcompletion7);
01089 
01090      ReportCompletion *reportcompletion8 = new ReportCompletion("reportcompletion8");
01091      addNode(reportcompletion8);
01092 
01093      CollisionDispatch *collisionDispatch = new CollisionDispatch("collisionDispatch");
01094      addNode(collisionDispatch);
01095 
01096      ConstructNavPlan *constructnavplan = new ConstructNavPlan("constructnavplan");
01097      addNode(constructnavplan);
01098 
01099      ExecutePlan *execute = new ExecutePlan("execute");
01100      addNode(execute);
01101 
01102      PostMachineCompletion *postmachinecompletion5 = new PostMachineCompletion("postmachinecompletion5");
01103      addNode(postmachinecompletion5);
01104 
01105      TerminateDueToCollision *term = new TerminateDueToCollision("term");
01106      addNode(term);
01107 
01108      startnode = setmaxturn1;
01109 
01110      setmaxturn1->addTransition(new NullTrans("nulltrans11",check));
01111      check->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans20",reportcompletion4,StateNode::failureSignal));
01112      check->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans21",setuplandmarkextractor2,StateNode::successSignal));
01113      setuplandmarkextractor2->addTransition(new NullTrans("nulltrans12",loc));
01114      loc->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans22",setupplan,StateNode::successSignal));
01115      loc->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans23",setupplan,StateNode::failureSignal));
01116      setupplan->addTransition(new NullTrans("nulltrans13",planpath));
01117      planpath->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans24",reportcompletion5,GenericRRTBase::START_COLLIDES));
01118      planpath->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans25",reportcompletion6,GenericRRTBase::END_COLLIDES));
01119      planpath->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans26",reportcompletion7,GenericRRTBase::MAX_ITER));
01120      planpath->addTransition(new CompletionTrans("completiontrans17",constructnavplan));
01121      planpath->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans27",reportcompletion8,StateNode::failureSignal));
01122 
01123      CompletionTrans *completiontrans18 = new CompletionTrans("completiontrans18",execute);
01124      completiontrans18->addDestination(collisionDispatch);
01125      constructnavplan->addTransition(completiontrans18);
01126 
01127      execute->addTransition(new CompletionTrans("completiontrans19",postmachinecompletion5));
01128 
01129      PilotTrans *pilottrans5 = new PilotTrans("pilottrans5",term,PilotTypes::collisionDetected);
01130      collisionDispatch->addTransition(pilottrans5);
01131      execute->addTransition(pilottrans5);
01132 
01133     }
01134   };
01135 
01136   //================ PushObjectMachine ================
01137 
01138   class PushObjectMachine : public VisualRoutinesStateNode {
01139    public:
01140     PushObjectMachine(const std::string &nodename="PushObjectMachine") : VisualRoutinesStateNode(nodename), initToObjPlan(), objToDestPlan() {}
01141 
01142 
01143 
01144     class SetMaxTurn : public StateNode {
01145      public:
01146       SetMaxTurn(const std::string &nodename, float _value=M_PI) : StateNode(nodename), value(_value) {}
01147       float value;  // cache the constructor's parameter
01148       virtual void doStart() {
01149         AngTwoPi &maxTurn = getAncestor<Pilot>()->maxTurn;
01150           maxTurn = value;
01151       }
01152     };
01153 
01154     class CheckParameters : public StateNode {
01155      public:
01156       CheckParameters(const std::string &nodename="CheckParameters") : StateNode(nodename) {}
01157         virtual void doStart();
01158     };
01159 
01160     class SetUpObjToDest : public StateNode {
01161      public:
01162       SetUpObjToDest(const std::string &nodename="SetUpObjToDest") : StateNode(nodename) {}
01163       virtual void doStart() {
01164         Point &initPos = getAncestor<Pilot>()->initPos;
01165         PilotRequest &planReq = getAncestor<Pilot>()->planReq;
01166         NavigationPlan &plan = getAncestor<Pilot>()->plan;
01167         bool &pushingObj = getAncestor<Pilot>()->pushingObj;
01168           plan.clear();
01169           initPos = VRmixin::pilot->curReq->objectShape->getCentroid();
01170           planReq = *VRmixin::pilot->curReq;
01171           planReq.objectShape->setObstacle(false);
01172           pushingObj = false;
01173       }
01174     };
01175 
01176     class BackOffDest : public StateNode {
01177      public:
01178       BackOffDest(const std::string &nodename="BackOffDest") : StateNode(nodename) {}
01179       virtual void doStart() {
01180         NavigationPlan &plan = getAncestor<Pilot>()->plan;
01181           size_t s = plan.path.size();
01182           Point final = plan.path[s-1];
01183           Point prev = plan.path[s-2];
01184           Point vec = final-prev;
01185           float len = vec.xyNorm();
01186           float robotDiam = 150;  // *** Should take from bounding box
01187           // *** should also subtract half of object diameter
01188           // back off by robot diameter to leave object at the destination
01189           if ( len > robotDiam )
01190             plan.path[s-1] = prev + vec/len*(len-robotDiam);
01191       }
01192     };
01193 
01194     class AddAcquirePt : public StateNode {
01195      public:
01196       AddAcquirePt(const std::string &nodename="AddAcquirePt") : StateNode(nodename) {}
01197       virtual void doStart() {
01198         NavigationPlan &plan = getAncestor<Pilot>()->plan;
01199           const Point delta = (plan.path[1] - plan.path[0]); 
01200           const Point deltaStep = delta.unitVector() * (-400);  // *** HACK: should compute from robot bounding box
01201           // *** HACK: should check this segment for collisions; don't assume it's safe
01202           const Point acquirePt = plan.path[0] + deltaStep;
01203     
01204           std::vector<DualCoding::Point>::iterator it;
01205           it = plan.path.begin();
01206           plan.path.insert(it, acquirePt);
01207     
01208           // Display path from object to destination
01209           NEW_SHAPE(plannedObjToDestPath, GraphicsData, new GraphicsData(worldShS));
01210           GraphicsData::xyPair U, V;
01211           for ( size_t i = 1; i < plan.path.size(); i++ ) {
01212             U.first = plan.path[i-1].coordX(); U.second = plan.path[i-1].coordY();
01213             V.first = plan.path[i].coordX(); V.second = plan.path[i].coordY();
01214             plannedObjToDestPath->add(new GraphicsData::LineElement(U, V, rgb(0,255,255)));
01215           }
01216       }
01217     };
01218 
01219     class SetUpInitToObj : public StateNode {
01220      public:
01221       SetUpInitToObj(const std::string &nodename="SetUpInitToObj") : StateNode(nodename) {}
01222       virtual void doStart() {
01223         NavigationPlan &plan = getAncestor<Pilot>()->plan;
01224         Point &initPos = getAncestor<Pilot>()->initPos;
01225         AngTwoPi &initHead = getAncestor<Pilot>()->initHead;
01226         PilotRequest &planReq = getAncestor<Pilot>()->planReq;
01227         NavigationPlan &objToDestPlan = getAncestor<PushObjectMachine>()->objToDestPlan;
01228           objToDestPlan.clear();
01229           objToDestPlan.path = plan.path;
01230           plan.clear();
01231     
01232           initPos = theAgent->getCentroid();
01233           initHead = theAgent->getOrientation();
01234           planReq = *VRmixin::pilot->curReq;
01235           planReq.objectShape->setObstacle(true);
01236     
01237           NEW_SHAPE( dest, PointData, new PointData(worldShS, plan.path[0] ) );
01238           dest->setObstacle(false);
01239           planReq.targetShape = dest;
01240       }
01241     };
01242 
01243     class Walk : public WaypointWalkNode {
01244      public:
01245       Walk(const std::string &nodename="Walk") : WaypointWalkNode(nodename) {}
01246       virtual void doStart() {
01247           MMAccessor<WaypointWalkMC> wp_acc(getMC());
01248           wp_acc->getWaypointList().clear();
01249     
01250           #ifdef TGT_IS_CREATE
01251           wp_acc->addEgocentricWaypoint(-300, 0,  0, true, 100.f, 0.f);
01252           #else
01253           wp_acc->addEgocentricWaypoint(-300, 0,  0, true, 100.f, 0.f);
01254           #endif
01255           motman->setPriority(VRmixin::pilot->getWaypointwalk_id(),MotionManager::kStdPriority);        
01256       }
01257     };
01258 
01259     class SetUpExecute2 : public StateNode {
01260      public:
01261       SetUpExecute2(const std::string &nodename="SetUpExecute2") : StateNode(nodename) {}
01262       virtual void doStart() {
01263         NavigationPlan &plan = getAncestor<Pilot>()->plan;
01264         Point &initPos = getAncestor<Pilot>()->initPos;
01265         AngTwoPi &initHead = getAncestor<Pilot>()->initHead;
01266         PilotRequest &planReq = getAncestor<Pilot>()->planReq;
01267         AngTwoPi &maxTurn = getAncestor<Pilot>()->maxTurn;
01268         bool &pushingObj = getAncestor<Pilot>()->pushingObj;
01269         NavigationPlan &objToDestPlan = getAncestor<PushObjectMachine>()->objToDestPlan;
01270         NavigationPlan &initToObjPlan = getAncestor<PushObjectMachine>()->initToObjPlan;
01271     
01272           initToObjPlan.clear();
01273           initToObjPlan.path = plan.path;
01274           initToObjPlan.steps = plan.steps;
01275     
01276           plan.clear();
01277           plan.path = objToDestPlan.path;
01278     
01279           PilotRequest &req = *VRmixin::pilot->curReq;
01280           initPos = theAgent->getCentroid();
01281           initHead = theAgent->getOrientation();
01282           req.turnSpeed = 0.25f;
01283           req.forwardSpeed = 50.f;
01284           planReq = req;
01285           maxTurn = 0.f;
01286           pushingObj = true;
01287           req.collisionAction = PilotTypes::collisionIgnore;
01288       }
01289     };
01290 
01291     class MoveTheObject : public VisualRoutinesStateNode {
01292      public:
01293       MoveTheObject(const std::string &nodename="MoveTheObject") : VisualRoutinesStateNode(nodename) {}
01294       virtual void doStart() {
01295           const Point destination = VRmixin::pilot->curReq->targetShape->getCentroid();
01296           // *** do we need a setLocation method in BaseData?
01297           if ( VRmixin::pilot->curReq->objectShape->isType(ellipseDataType) )
01298             ShapeRootType(VRmixin::pilot->curReq->objectShape,EllipseData)->setCentroidPt(destination);
01299       }
01300     };
01301 
01302     virtual void setup() { // set up PushObjectMachine
01303      SetMaxTurn *setmaxturn2 = new SetMaxTurn("setmaxturn2");
01304      addNode(setmaxturn2);
01305 
01306      CheckParameters *checkparams = new CheckParameters("checkparams");
01307      addNode(checkparams);
01308 
01309      ReportCompletion *reportcompletion9 = new ReportCompletion("reportcompletion9",invalidRequest);
01310      addNode(reportcompletion9);
01311 
01312      SetupLandmarkExtractor *localize = new SetupLandmarkExtractor("localize");
01313      addNode(localize);
01314 
01315      LocalizationUtility *locutil = new LocalizationUtility("locutil");
01316      addNode(locutil);
01317 
01318      SetUpObjToDest *plandelivery = new SetUpObjToDest("plandelivery");
01319      addNode(plandelivery);
01320 
01321      PlanPath *planpath2 = new PlanPath("planpath2");
01322      addNode(planpath2);
01323 
01324      ReportCompletion *reportcompletion10 = new ReportCompletion("reportcompletion10",startCollides);
01325      addNode(reportcompletion10);
01326 
01327      ReportCompletion *reportcompletion11 = new ReportCompletion("reportcompletion11",endCollides);
01328      addNode(reportcompletion11);
01329 
01330      ReportCompletion *reportcompletion12 = new ReportCompletion("reportcompletion12",noPath);
01331      addNode(reportcompletion12);
01332 
01333      ReportCompletion *reportcompletion13 = new ReportCompletion("reportcompletion13");
01334      addNode(reportcompletion13);
01335 
01336      BackOffDest *planacquire = new BackOffDest("planacquire");
01337      addNode(planacquire);
01338 
01339      AddAcquirePt *addacquirept1 = new AddAcquirePt("addacquirept1");
01340      addNode(addacquirept1);
01341 
01342      SetUpInitToObj *setupinittoobj1 = new SetUpInitToObj("setupinittoobj1");
01343      addNode(setupinittoobj1);
01344 
01345      PlanPath *planpath1 = new PlanPath("planpath1");
01346      addNode(planpath1);
01347 
01348      ReportCompletion *reportcompletion14 = new ReportCompletion("reportcompletion14",startCollides);
01349      addNode(reportcompletion14);
01350 
01351      ReportCompletion *reportcompletion15 = new ReportCompletion("reportcompletion15",endCollides);
01352      addNode(reportcompletion15);
01353 
01354      ReportCompletion *reportcompletion16 = new ReportCompletion("reportcompletion16",noPath);
01355      addNode(reportcompletion16);
01356 
01357      ConstructNavPlan *constructnavplan1 = new ConstructNavPlan("constructnavplan1");
01358      addNode(constructnavplan1);
01359 
01360      ReportCompletion *reportcompletion17 = new ReportCompletion("reportcompletion17");
01361      addNode(reportcompletion17);
01362 
01363      ExecutePlan *execute = new ExecutePlan("execute");
01364      addNode(execute);
01365 
01366      SetUpExecute2 *setupexecute21 = new SetUpExecute2("setupexecute21");
01367      addNode(setupexecute21);
01368 
01369      ConstructNavPlan *constructnavplan2 = new ConstructNavPlan("constructnavplan2");
01370      addNode(constructnavplan2);
01371 
01372      ExecutePlan *executeplan1 = new ExecutePlan("executeplan1");
01373      addNode(executeplan1);
01374 
01375      MoveTheObject *movetheobject1 = new MoveTheObject("movetheobject1");
01376      addNode(movetheobject1);
01377 
01378      Walk *walk1 = new Walk("walk1");
01379      addNode(walk1);
01380      walk1->setMC(VRmixin::pilot->waypointwalk_id);
01381 
01382      ReportCompletion *reportcompletion18 = new ReportCompletion("reportcompletion18");
01383      addNode(reportcompletion18);
01384 
01385      startnode = setmaxturn2;
01386 
01387      setmaxturn2->addTransition(new NullTrans("nulltrans14",checkparams));
01388      checkparams->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans28",localize,StateNode::successSignal));
01389      checkparams->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans29",reportcompletion9,StateNode::failureSignal));
01390      localize->addTransition(new NullTrans("nulltrans15",locutil));
01391      locutil->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans30",plandelivery,StateNode::successSignal));
01392      locutil->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans31",plandelivery,StateNode::failureSignal));
01393      plandelivery->addTransition(new NullTrans("nulltrans16",planpath2));
01394      planpath2->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans32",reportcompletion10,GenericRRTBase::START_COLLIDES));
01395      planpath2->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans33",reportcompletion11,GenericRRTBase::END_COLLIDES));
01396      planpath2->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans34",reportcompletion12,GenericRRTBase::MAX_ITER));
01397      planpath2->addTransition(new CompletionTrans("completiontrans20",planacquire));
01398      planpath2->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans35",reportcompletion13,StateNode::failureSignal));
01399      planacquire->addTransition(new NullTrans("nulltrans17",addacquirept1));
01400      addacquirept1->addTransition(new NullTrans("nulltrans18",setupinittoobj1));
01401      setupinittoobj1->addTransition(new NullTrans("nulltrans19",planpath1));
01402      planpath1->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans36",reportcompletion14,GenericRRTBase::START_COLLIDES));
01403      planpath1->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans37",reportcompletion15,GenericRRTBase::END_COLLIDES));
01404      planpath1->addTransition(new SignalTrans<GenericRRTBase::PlanPathResultCode>("signaltrans38",reportcompletion16,GenericRRTBase::MAX_ITER));
01405      planpath1->addTransition(new CompletionTrans("completiontrans21",constructnavplan1));
01406      constructnavplan1->addTransition(new CompletionTrans("completiontrans22",execute));
01407      planpath1->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans39",reportcompletion17,StateNode::failureSignal));
01408      execute->addTransition(new CompletionTrans("completiontrans23",setupexecute21));
01409      setupexecute21->addTransition(new NullTrans("nulltrans20",constructnavplan2));
01410      constructnavplan2->addTransition(new CompletionTrans("completiontrans24",executeplan1));
01411      executeplan1->addTransition(new CompletionTrans("completiontrans25",movetheobject1));
01412      movetheobject1->addTransition(new NullTrans("nulltrans21",walk1));
01413      walk1->addTransition(new CompletionTrans("completiontrans26",reportcompletion18));
01414     }
01415 
01416     NavigationPlan initToObjPlan;   // from $provide
01417     NavigationPlan objToDestPlan;   // from $provide
01418   };
01419 
01420   //================ VisualSearchMachine ================
01421 
01422   class VisualSearchMachine : public StateNode {
01423    public:
01424     VisualSearchMachine(const std::string &nodename="VisualSearchMachine") : StateNode(nodename) {}
01425 
01426     class Search : public MapBuilderNode {
01427      public:
01428       Search(const std::string &nodename="Search") : MapBuilderNode(nodename) {}
01429       virtual void doStart() {
01430           if (VRmixin::pilot->curReq->searchObjectExtractor == NULL) {
01431       cout << "Pilot received visualSearch request with invalid searchObjectExtractor field" << endl;
01432       VRmixin::pilot->requestComplete(invalidRequest);
01433           }
01434           else if (VRmixin::pilot->curReq->searchExitTest == NULL) {
01435       cout << "Pilot received visualSearch request with no exitTest" << endl;
01436       VRmixin::pilot->requestComplete(invalidRequest);
01437           }
01438           mapreq = *VRmixin::pilot->curReq->searchObjectExtractor;
01439       }
01440     };
01441 
01442     class Check : public StateNode {
01443      public:
01444       Check(const std::string &nodename="Check") : StateNode(nodename) {}
01445       virtual void doStart() {
01446           if (VRmixin::pilot->curReq->searchExitTest())
01447       VRmixin::pilot->requestComplete(noError);
01448           else if (VRmixin::pilot->curReq->searchRotationAngle == 0)
01449       VRmixin::pilot->requestComplete(searchFailed);
01450           else
01451       postStateCompletion();
01452       }
01453     };
01454 
01455     class Rotate : public WaypointWalkNode {
01456      public:
01457       Rotate(const std::string &nodename="Rotate") : WaypointWalkNode(nodename) {}
01458       virtual void doStart() {
01459           MMAccessor<WaypointWalkMC> wp_acc(getMC());
01460           wp_acc->getWaypointList().clear();
01461           wp_acc->addEgocentricWaypoint(0,0,VRmixin::pilot->curReq->searchRotationAngle,true,0.01f);
01462       }
01463     };
01464 
01465     virtual void setup() {
01466      startnode = new Search("startnode");
01467      addNode(startnode);
01468 
01469      Check *check1 = new Check("check1");
01470      addNode(check1);
01471 
01472      Rotate *rotate1 = new Rotate("rotate1");
01473      addNode(rotate1);
01474      rotate1->setMC(VRmixin::pilot->waypointwalk_id);
01475 
01476      startnode = startnode;
01477 
01478      startnode->addTransition(new EventTrans("eventtrans3",check1,EventBase::mapbuilderEGID,(size_t)startnode,EventBase::statusETID));
01479      check1->addTransition(new CompletionTrans("completiontrans27",rotate1));
01480      rotate1->addTransition(new CompletionTrans("completiontrans28",startnode));
01481     }
01482   };
01483 
01484 
01485 
01486   //================ Dispatch ================
01487   // All the Pilot's little state machines are children of the
01488   // Dispatch node, so when a call to Dispatch::finish() causes it to
01489   // complete and exit, everything gets shut down.
01490 
01491   class Dispatch : public StateNode {
01492    public:
01493     Dispatch(const std::string &nodename="Dispatch") : StateNode(nodename), localizeMachine_(NULL), walkMachine_(NULL), waypointWalkMachine_(NULL), setVelocityMachine_(NULL), goToShapeMachine_(NULL), pushObjectMachine_(NULL), visualSearchMachine_(NULL) {}
01494 
01495       StateNode *localizeMachine_, *walkMachine_, *waypointWalkMachine_, *setVelocityMachine_, 
01496   *goToShapeMachine_, *pushObjectMachine_, *visualSearchMachine_;
01497 
01498     void finish() {
01499       postStateCompletion();
01500     }
01501 
01502     virtual void doStart() {
01503       PilotTypes::RequestType_t reqType = VRmixin::pilot->curReq->getRequestType();
01504       switch ( reqType) {
01505       case localize:
01506         localizeMachine_->start();
01507         break;
01508       case walk:
01509         walkMachine_->start();
01510         break;
01511       case waypointWalk:
01512         waypointWalkMachine_->start();
01513         break;
01514       case setVelocity:
01515         setVelocityMachine_->start();
01516         break;
01517       case goToShape:
01518         goToShapeMachine_->start();
01519         break;
01520       case pushObject:
01521         pushObjectMachine_->start();
01522         break;
01523       case visualSearch:
01524         visualSearchMachine_->start();
01525         break;
01526       default:
01527         cout << "Illegal Pilot request type: " << reqType << endl;
01528         VRmixin::pilot->requestComplete(invalidRequest);
01529       }
01530     };
01531 
01532     virtual void setup(){
01533      StateNode *dispatchDummyStart = new StateNode("dispatchDummyStart");
01534      addNode(dispatchDummyStart);
01535 
01536      ReportCompletion *reportSuccess = new ReportCompletion("reportSuccess");
01537      addNode(reportSuccess);
01538 
01539      ReportCompletion *reportFailure = new ReportCompletion("reportFailure",someError);
01540      addNode(reportFailure);
01541 
01542      LocalizationMachine *localizemachine = new LocalizationMachine("localizemachine");
01543      addNode(localizemachine);
01544 
01545      ReportCompletion *reportcompletion19 = new ReportCompletion("reportcompletion19",cantLocalize);
01546      addNode(reportcompletion19);
01547 
01548      WalkMachine *walkmachine = new WalkMachine("walkmachine");
01549      addNode(walkmachine);
01550 
01551      WaypointWalkMachine *waypointwalkmachine = new WaypointWalkMachine("waypointwalkmachine");
01552      addNode(waypointwalkmachine);
01553 
01554      SetVelocityMachine *setvelocitymachine = new SetVelocityMachine("setvelocitymachine");
01555      addNode(setvelocitymachine);
01556 
01557      GoToShapeMachine *gotoshapemachine = new GoToShapeMachine("gotoshapemachine");
01558      addNode(gotoshapemachine);
01559 
01560      PushObjectMachine *pushobjectmachine = new PushObjectMachine("pushobjectmachine");
01561      addNode(pushobjectmachine);
01562 
01563      VisualSearchMachine *visualsearchmachine = new VisualSearchMachine("visualsearchmachine");
01564      addNode(visualsearchmachine);
01565 
01566      startnode = dispatchDummyStart;
01567 
01568      localizemachine->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans40",reportSuccess,StateNode::successSignal));
01569      localizemachine->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans41",reportcompletion19,StateNode::failureSignal));
01570      waypointwalkmachine->addTransition(new CompletionTrans("completiontrans29",reportSuccess));
01571      waypointwalkmachine->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans42",reportFailure,StateNode::failureSignal));
01572      gotoshapemachine->addTransition(new CompletionTrans("completiontrans30",reportSuccess));
01573      gotoshapemachine->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans43",reportFailure,StateNode::failureSignal));
01574      pushobjectmachine->addTransition(new CompletionTrans("completiontrans31",reportSuccess));
01575      pushobjectmachine->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans44",reportFailure,StateNode::failureSignal));
01576      visualsearchmachine->addTransition(new CompletionTrans("completiontrans32",reportSuccess));
01577      visualsearchmachine->addTransition(new SignalTrans<StateNode::SuccessOrFailure>("signaltrans45",reportFailure,StateNode::failureSignal));
01578 
01579       startnode = NULL; // keeps the dummy node out of the Event Logger trace
01580       // Save these statenode pointers for use by dispatch,
01581       localizeMachine_ = localizemachine;
01582       walkMachine_ = walkmachine;
01583       waypointWalkMachine_ = waypointwalkmachine;
01584       setVelocityMachine_ = setvelocitymachine;
01585       goToShapeMachine_ = gotoshapemachine;
01586       pushObjectMachine_ = pushobjectmachine;
01587       visualSearchMachine_ = visualsearchmachine;
01588     };
01589    private:  // dummy copy and assignment to suppress compiler warnings
01590     Dispatch(const Dispatch&);
01591     Dispatch& operator=(const Dispatch&);
01592   };
01593 
01594   virtual void setup() {   // Pilot's setup
01595     SharedObject<WaypointWalkMC> waypointwalk_mc;
01596     SharedObject<WalkMC> walk_mc;
01597 #ifdef PILOT_USES_SHARED_MOTION_COMMANDS
01598     walk_id = motman->addPersistentMotion(walk_mc, MotionManager::kIgnoredPriority);
01599     waypointwalk_id = motman->addPersistentMotion(waypointwalk_mc, MotionManager::kIgnoredPriority);
01600 #endif
01601    StateNode *pilotWaitForDispatch = new StateNode("pilotWaitForDispatch");
01602    addNode(pilotWaitForDispatch);
01603 
01604    Dispatch *dispatch = new Dispatch("dispatch");
01605    addNode(dispatch);
01606 
01607    startnode = pilotWaitForDispatch;
01608 
01609    CompletionTrans *pilot_dispatch = new CompletionTrans("pilot_dispatch",pilotWaitForDispatch);
01610    dispatch->addTransition(pilot_dispatch);
01611 
01612     VRmixin::pilot->dispatch_ = dispatch;
01613   }
01614 
01615 private:
01616   Pilot(const Pilot&); //!< copy constructor; do not call
01617   Pilot& operator=(const Pilot&); //!< assignment operator; do not call
01618 
01619   static PilotVerbosity_t verbosity;
01620 
01621   std::queue<PilotRequest*> requests;   //!< Queue of Pilot requests
01622   PilotRequest *curReq;
01623   unsigned int idCounter;   //!< Pilot request counter for assigning a unique id
01624   MotionManager::MC_ID walk_id;
01625   MotionManager::MC_ID waypointwalk_id;
01626   Dispatch *dispatch_;
01627 
01628   /*! @endcond */
01629 
01630   std::vector<ShapeRoot> defaultLandmarks;   // from $provide
01631   MapBuilderRequest* defaultLandmarkExtractor;   // from $provide
01632   Point initPos;   // from $provide
01633   AngTwoPi initHead;   // from $provide
01634   PilotRequest planReq;   // from $provide
01635   NavigationPlan plan;   // from $provide
01636   AngTwoPi maxTurn;   // from $provide
01637   bool pushingObj;   // from $provide
01638 };
01639 
01640 std::ostream& operator<<(std::ostream& os, const Pilot::NavigationStep &step);
01641 std::ostream& operator<<(std::ostream& os, const Pilot::NavigationPlan &plan);
01642 
01643 } // namespace
01644 
01645 #endif

DualCoding 5.1CVS
Generated Fri Mar 16 05:23:47 2012 by Doxygen 1.6.3