Homepage Demos Overview Downloads Tutorials Reference
Credits

PostureMC.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_PostureMC_h
00003 #define INCLUDED_PostureMC_h
00004 
00005 #include "MotionCommand.h"
00006 #include "PostureEngine.h"
00007 #include "MotionManager.h"
00008 
00009 //! a MotionCommand shell for PostureEngine
00010 /*! Will autoprune by default once it reaches the target pose.
00011  * 
00012  *  If you want to keep it alive so your behavior can use the posture
00013  *  to move around, either call setAutoPrune(@c false), or pass
00014  *  @c false to the MotionManager::addMotion() function.
00015  */
00016 class PostureMC : public MotionCommand, public PostureEngine {
00017 public:
00018   //!constructor
00019   PostureMC() : MotionCommand(),PostureEngine(),dirty(true),tolerance(.01) { }
00020   //!constructor, loads from @a filename
00021   PostureMC(const char* filename) : MotionCommand(),PostureEngine(filename),dirty(true),tolerance(.01) { }
00022   //!destructor
00023   virtual ~PostureMC() {}
00024   
00025   //!@name New Stuff
00026   /*!@brief call this if you call PostureEngine::setOutputCmd(), that doesn't know about dirty flags */
00027   /* This is the downside of making setOutputCmd() not virtual - if you pass this around as just a
00028    * PostureEngine, calls made to that won't be able to update the dirty flag automatically.  However,
00029    * if the object is typed as a PostureMC at the time the call is made, then you don't have to worry.\n
00030    * These are also not virtual - otherwise you'd have to still check the motion out and it would make
00031    * this all pointless! @return @c *this */
00032   PostureMC& setDirty(bool d=true) { dirty=d; return *this; } 
00033   bool isDirty() const {return dirty;} //!< if you want to check the dirty flag
00034   virtual PostureMC& setTolerance(float t) { tolerance=t; return *this; } //!< sets #tolerance, returns @c *this
00035   virtual float getTolerance() { return tolerance; } //!< returns #tolerance
00036   //@}
00037 
00038 
00039   //!@name MotionCommand Stuff
00040   virtual int updateOutputs() {
00041     for(unsigned int i=0; i<NumOutputs; i++)
00042       if(cmds[i].weight>0)
00043         motman->setOutput(this,i,cmds[i]);
00044     bool r=dirty; dirty=false; return r;
00045   }
00046   virtual int isDirty() { return dirty; }
00047 
00048   //! returns non-zero (true) if PostureEngine::maxdiff() between this and the current position is over #tolerance
00049   /*! This is handy so you can set to have the robot go to a position and then automatically remove
00050    *  the MotionCommand when it gets there - but beware fighting Postures which average out and neither
00051    *  succeeds */
00052   virtual int isAlive() {
00053     if(dirty || getAutoPrune()==false) //doesn't bother computing if we're staying alive anyway
00054       return true;
00055     PostureEngine tmp; 
00056     tmp.takeSnapshot(); 
00057     return (maxdiff(tmp)>tolerance);
00058   }
00059   //@}
00060 
00061   //!Had to override stuff to manage a dirty flag
00062   //!@name PostureEngine Stuff
00063   inline virtual void takeSnapshot() { dirty=true; PostureEngine::takeSnapshot(); }
00064   inline virtual void clear() { dirty=true; PostureEngine::clear(); }
00065   inline virtual PostureEngine& setOverlay(const PostureEngine& pe) { dirty=true; PostureEngine::setOverlay(pe); return *this; }
00066   inline virtual PostureEngine& setUnderlay(const PostureEngine& pe) { dirty=true; PostureEngine::setUnderlay(pe); return *this; }
00067   inline virtual PostureEngine& setAverage(const PostureEngine& pe,float w=0.5) { dirty=true; PostureEngine::setAverage(pe,w); return *this; }
00068   inline virtual PostureEngine& setCombine(const PostureEngine& pe) { dirty=true; PostureEngine::setCombine(pe); return *this; }
00069   inline PostureEngine& setOutputCmd(unsigned int i, const OutputCmd& c) { dirty=true; PostureEngine::setOutputCmd(i,c); return *this; }
00070   inline virtual unsigned int LoadBuffer(const char buf[], unsigned int len) { dirty=true; return PostureEngine::LoadBuffer(buf,len); }
00071   //@}
00072 
00073 protected:
00074   bool dirty; //!< true if changes have been made since last updateOutputs()
00075   float tolerance; //!< when autopruning, if the maxdiff() of this posture and the robot's current position is below this value, isAlive() will be false, defaults to 0.01 (5.7 degree error)
00076 
00077   //!defines Registerable stuff
00078   /*  REGDEFCUSTOMMEM(PostureMC) {
00079     MotionCommand::registerDataRegions(regions);
00080     registerRegion(regions,&cmds,&cmds,sizeof(cmds));//for PostureEngine, LoadSave doesn't have any (nonstatic) members
00081     registerRegion(regions,&dirty,&tolerance,sizeof(tolerance));
00082     }*/
00083 };
00084 
00085 /*! @file
00086  * @brief Defines PostureMC, a MotionCommand shell for PostureEngine
00087  * @author ejt (Creator)
00088  *
00089  * $Author: ejt $
00090  * $Name: tekkotsu-2_1 $
00091  * $Revision: 1.7 $
00092  * $State: Exp $
00093  * $Date: 2004/03/03 03:37:13 $
00094  */
00095 
00096 #endif

Tekkotsu v2.1
Generated Tue Mar 16 23:19:15 2004 by Doxygen 1.3.5