Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

MotionSequenceMC.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_MotionSequenceMC_h_
00003 #define INCLUDED_MotionSequenceMC_h_
00004 
00005 #include "MotionSequenceEngine.h"
00006 #include "MotionCommand.h"
00007 #include "MotionManager.h"
00008 #include "Events/EventBase.h"
00009 
00010 //! Instantiates MotionSequenceEngines - when you want to run a motion sequence, make one of these
00011 /*! Allows a compile-time variable amount of data storage through its template parameter.
00012  *  @see MotionSequenceEngine for the majority of the usage documentation
00013  *  @see TinyMotionSequenceMC, SmallMotionSequenceMC, MediumMotionSequenceMC, LargeMotionSequenceMC, XLargeMotionSequenceMC
00014  *  */
00015 template<unsigned int MAXMOVE>
00016 class MotionSequenceMC : public MotionCommand, public MotionSequenceEngine {
00017 public:
00018   static const unsigned int CAPACITY=MAXMOVE; //!< allows recovery of capacity in a general way (MAXMOVE may, and probably will, be obscured by a typedef)
00019 
00020   //!constructor
00021   MotionSequenceMC()
00022     : MotionCommand(), MotionSequenceEngine(), moves(), dirty(false)
00023   {
00024     clear();
00025   }
00026   //!constructor, loads from a file and then resets the playtime to beginning and begins to play
00027   explicit MotionSequenceMC(const std::string& filename)
00028     : MotionCommand(), MotionSequenceEngine(), moves(), dirty(false)
00029   {
00030     clear();
00031     loadFile(filename.c_str());
00032     setTime(1);
00033   }
00034   //!destructor
00035   virtual ~MotionSequenceMC() {}
00036 
00037   virtual int isDirty() { return isPlaying(); }
00038   virtual int isAlive() { return (playspeed>0) ? (playtime<=endtime) : (playtime>0); }
00039   
00040   virtual void setDirty() { dirty = true; }
00041 
00042   // I put this here because i want direct access to moves so it'll be faster
00043   virtual int updateOutputs() {
00044     MotionSequenceEngine::updateOutputs();
00045     if(!isPlaying()) {
00046       if(dirty)
00047         postEvent(EventBase(EventBase::motmanEGID,getID(),EventBase::statusETID));
00048       dirty=false;
00049       for(unsigned int i=0; i<NumOutputs; i++) //just copies getOutputCmd(i) across frames
00050         motman->setOutput(this,i,getOutputCmd(i));
00051     } else {
00052       dirty=true;
00053       //cout << getTime() << ": ";
00054       for(unsigned int i=0; i<NumOutputs; i++) { //fill out the buffer of commands for smoother movement
00055         Move_idx_t prev=prevs[i],next=nexts[i];
00056         OutputCmd frames[NumFrames];
00057         frames[0]=getOutputCmd(i);
00058         for(unsigned int t=playtime+FrameTime,j=1;j<NumFrames;j++,t+=FrameTime) {
00059           setRange(t,prev,next);
00060           if(next!=invalid_move)
00061             calcOutput(frames[j],t,moves[prev],moves[next]);
00062           else if(hold)
00063             frames[j]=moves[prev].cmd;
00064         }
00065         /*if(i==RFrLegOffset+RotatorOffset)
00066           for(unsigned int j=0; j<NumFrames; j++)
00067           cout << '(' << frames[j].value << ',' << frames[j].weight << ") "; */
00068         motman->setOutput(this,i,frames);
00069       }
00070       //cout <<'\n'<< flush;
00071     }
00072     return NumOutputs;
00073     //    if(i<NumLegJointss)
00074     //      log.push_back(logent(get_time(),playtime,i,frames));
00075   }
00076   
00077   virtual void clear() {
00078     moves.clear();
00079     for(unsigned int i=0; i<NumOutputs; i++) {
00080       prevs[i]=starts[i]=moves.new_back();
00081       moves.back().cmd.unset();
00082       moves.back().next=invalid_move;
00083       moves.back().prev=invalid_move;
00084       moves.back().starttime=0;
00085       nexts[i]=invalid_move;
00086     }
00087     endtime=0;
00088     setTime(1);
00089   }
00090 
00091   virtual unsigned int getMaxFrames() const { return moves.getMaxCapacity(); }
00092   virtual unsigned int getUsedFrames() const { return moves.size(); }
00093 
00094 protected:
00095   // TYPES:
00096   typedef ListMemBuf<Move,MAXMOVE,Move_idx_t> list_t; //!< shorthand for the ListMemBuf that stores all of the movement frames
00097 
00098   // MEMBERS:
00099   list_t moves; //!< stores all of the movement keyframes
00100   bool dirty; //!< true if last updateOutputs was dirty, so we know when to post status event
00101 
00102   virtual Move& getKeyFrame(Move_idx_t x) { return moves[x]; } //!< returns #moves[@a x]
00103   virtual const Move& getKeyFrame(Move_idx_t x) const { return moves[x]; } //!< returns #moves[@a x]
00104   virtual Move_idx_t newKeyFrame() {
00105     Move_idx_t i=moves.new_front();
00106     if(i==invalid_move)
00107       std::cerr << "ERROR: MotionSequenceMC " << getID() << " has run out of memory" << std::endl;
00108     return i;
00109   }
00110   //! marks keyframe @a x unused
00111   virtual void eraseKeyFrame(Move_idx_t x) { moves.erase(x); }
00112   //! advances (or rewinds) @a prev and @a next so that @a t falls between them
00113   bool setRange(unsigned int t,Move_idx_t& prev, Move_idx_t& next) const {
00114     bool moved=false;
00115     if(next!=invalid_move && moves[next].starttime<=t) {
00116       moved=true;
00117       do {
00118         prev=next;
00119         next=moves[prev].next;
00120       } while(next!=invalid_move && moves[next].starttime<=t);
00121     } else {
00122       while(moves[prev].prev!=invalid_move && t<moves[prev].starttime) {
00123         next=prev;
00124         prev=moves[next].prev;
00125         moved=true;
00126       } 
00127     }
00128     return moved;
00129   }
00130 };
00131 
00132 typedef MotionSequenceMC<NumOutputs*2> TinyMotionSequenceMC; //!< Tiny, but enough to handle a transition into a full-body pose
00133 typedef MotionSequenceMC<NumOutputs*3> SmallMotionSequenceMC;//!< Small, but still big enough to handle most of the included MS's (2 full-body frames ~ around 1KB)
00134 typedef MotionSequenceMC<NumOutputs*6> MediumMotionSequenceMC;//!< Medium (5 full body frames ~ est 4KB)
00135 typedef MotionSequenceMC<NumOutputs*11> LargeMotionSequenceMC;//!< Large (10 full body frames ~ est 8KB)
00136 typedef MotionSequenceMC<NumOutputs*26> XLargeMotionSequenceMC;//!< eXtra Large (25 full body frames ~ est 16KB)
00137 
00138 /*! @file
00139  * @brief Describes MotionSequenceEngine and defines MotionSequenceMC, handy little (or not so little) classes for switching between a sequence of postures
00140  * @author ejt (Creator)
00141  */
00142 
00143 #endif

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