Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

MCNode.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_MCNode_h_
00003 #define INCLUDED_MCNode_h_
00004 
00005 #include "Behaviors/StateNode.h"
00006 #include "Motion/MotionManager.h"
00007 #include "Motion/MMAccessor.h"
00008 #include "IPC/SharedObject.h"
00009 
00010 //! Common parent class for all the templated MCNode, which is what you want to instantiate.
00011 class MCNodeBase : public StateNode {
00012 public:
00013   static const char defName[]; //!< the default name for MCNodes -- can be overridden via MCNode's template arguments
00014   static const char defDesc[]; //!< the default description for MCNodes -- can be overridden via MCNode's template arguments
00015 
00016   //! destructor, free #mc
00017   virtual ~MCNodeBase() { delete mc; mc=NULL; }
00018   
00019   //! Removes the motion command from the motion manager if it was our own creation
00020   virtual void stop();  
00021   
00022   //! Assumes the event is a completion event from the motion, throws a corresponding state node completion event
00023   virtual void doEvent();
00024   
00025   //! Allows you to assign a previously created motion, which might be shared among several MCNodes
00026   /*! If this node already has an #mc, then it will be freed, removing from MotionManager if necessary */
00027   virtual void setMC(MotionManager::MC_ID mcid);
00028   
00029   //! reveal the MC_ID; if the motion isn't currently active, returns MotionManager::invalid_MC_ID
00030   virtual MotionManager::MC_ID getMC_ID() { return mc_id; }
00031   
00032   //! Return the priority assigned to this node's motion command
00033   virtual float getPriority() const { return priority; }
00034 
00035   //! Set the priority that will be used when adding this motion command; if the command is already active, change its priority in the MotionManager
00036   virtual void setPriority(const float p);
00037 
00038   //! Post a failure event and abort the motion command
00039   /*! This is useful if the user calls some IK method that determines
00040     that the target is unreachable, and an approximate solution isn't
00041     acceptable.
00042    */
00043   virtual void motionFails();
00044 
00045   static std::string getClassDescription() { return defName; }
00046   virtual std::string getDescription() const { return getClassDescription(); }
00047   
00048 protected:
00049   //! constructor for subclasses
00050   MCNodeBase(bool expectCompletion)
00051     : StateNode(), mc(NULL), mc_id(MotionManager::invalid_MC_ID), 
00052       priority(MotionManager::kStdPriority), mcCompletes(expectCompletion)
00053   {}
00054 
00055   //! constructor for subclasses which provide instance name
00056   MCNodeBase(const std::string &node_name, bool expectCompletion=true)
00057     : StateNode(node_name), mc(NULL), mc_id(MotionManager::invalid_MC_ID), 
00058       priority(MotionManager::kStdPriority), mcCompletes(expectCompletion)
00059   {}
00060   
00061   //! returns reference to #mc or a new SharedObject<T> if #mc is currently NULL (so it will always return a valid value)
00062   /*! if a particular motion command needs some initial setup besides the default constructor,
00063    *  overriding this function is a good opportunity to do so */
00064   virtual SharedObjectBase& getPrivateMC()=0;
00065 
00066   //! returns true if the motion command being used was created internally via getPrivateMC()
00067   virtual bool hasPrivateMC() { return mc!=NULL; }
00068 
00069   SharedObjectBase* mc;    //!< MotionCommand used by this node (may be NULL if sharing the MC with other nodes)
00070   MotionManager::MC_ID mc_id;  //!< id number for the MotionCommand
00071   float priority; //!< Priority to use when adding this motion commmand to the MotionManager
00072   bool mcCompletes; //!< if true, will post a completion when the underlying MotionCommand posts a status
00073 
00074 private:
00075   MCNodeBase(const MCNodeBase&); //!< don't call (copy constructor)
00076   MCNodeBase& operator=(const MCNodeBase&); //!< don't call (assignment operator)
00077 };
00078 
00079 //! A generic wrapper for any MotionCommand.  Note that some functions are provided by the MCNodeBase common base class, namely MCNodeBase::setMC() and MCNodeBase::getMC_ID()
00080 template<class T, const char* mcName=MCNodeBase::defName, const char* mcDesc=MCNodeBase::defDesc, bool completes=true>
00081 class MCNode : public MCNodeBase {
00082 public:
00083   //! default constructor
00084   MCNode()
00085     : MCNodeBase(completes)
00086   {}
00087   
00088   //! constructor, take an instance name
00089   explicit MCNode(const std::string& nm)
00090     : MCNodeBase(nm,completes)
00091   {}
00092   
00093   //! constructor, take an instance name
00094   explicit MCNode(const char* nm)
00095     : MCNodeBase(nm,completes)
00096   {}
00097   
00098   //! destructor
00099   virtual ~MCNode() {}
00100   
00101   //! reveal the MotionCommand through an MMAccessor
00102   /*! This is a no-op if the motion command hasn't been added to motion manager yet, and enforces mutual exclusion if it has */
00103   virtual MMAccessor<T> getMC();
00104 
00105   //! Adds the motion command to the motion manager, but stops it from running until the user has a chance to program it
00106   virtual void preStart();
00107 
00108   //! Adds a listener and then starts the motion command
00109   virtual void postStart();
00110 
00111   static std::string getClassDescription() { return mcDesc; }
00112   virtual std::string getDescription() const { return getClassDescription(); }
00113 
00114 protected:
00115   explicit MCNode(bool subCompletes) : MCNodeBase(subCompletes) {}
00116   
00117   //! constructor, take an instance name
00118   MCNode(const std::string& nm, bool subCompletes) : MCNodeBase(nm,subCompletes) {}
00119   
00120   virtual SharedObject<T>& getPrivateMC();
00121 };
00122 
00123 
00124 // ****************************
00125 // ******* IMPLEMENTATION *******
00126 // ****************************
00127 
00128 template<class T, const char* mcName, const char* mcDesc, bool completes>
00129 MMAccessor<T> MCNode<T,mcName,mcDesc,completes>::getMC() {
00130   if(mc_id==MotionManager::invalid_MC_ID) {
00131     // motion hasn't been added to motion manager yet; don't try to check it out
00132     return MMAccessor<T>(*getPrivateMC(),false);
00133   } else {
00134     // motion has been added to motion manager, check it out
00135     return MMAccessor<T>(mc_id);
00136   }
00137 }
00138 
00139 template<class T, const char* mcName, const char* mcDesc, bool completes>
00140 SharedObject<T>& MCNode<T,mcName,mcDesc,completes>::getPrivateMC() {
00141   if(mc==NULL)
00142     mc=new SharedObject<T>;
00143   return dynamic_cast<SharedObject<T>&>(*mc);
00144 }
00145 
00146 template<class T, const char* mcName, const char* mcDesc, bool completes>
00147 void MCNode<T,mcName,mcDesc,completes>::preStart() {
00148     StateNode::preStart();
00149     getMC()->stop();  // prevent generation of premature completion events
00150 }
00151 
00152 template<class T, const char* mcName, const char* mcDesc, bool completes>
00153 void MCNode<T,mcName,mcDesc,completes>::postStart() {
00154     StateNode::postStart();
00155     if(mc_id==MotionManager::invalid_MC_ID)
00156       mc_id = motman->addPersistentMotion(getPrivateMC(),priority);
00157     else {
00158       getMC()->start();
00159       motman->setPriority(mc_id,priority);
00160     }
00161     erouter->addListener(this,EventBase::motmanEGID,mc_id,EventBase::statusETID);
00162     getMC()->setDirty();  // in case addPersistentMotion caused an immediate completion that we missed
00163 }
00164 
00165 /*! @file
00166  * @brief Defines MCNode, which provides generic wrapper for any MotionCommand
00167  * @author Ethan Tira-Thompson (ejt) (Creator)
00168  */
00169 
00170 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:44 2016 by Doxygen 1.6.3