Homepage Demos Overview Downloads Tutorials 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 
00009 //! Instantiates MotionSequenceEngines - when you want to run a motion sequence, make one of these
00010 /*! Allows a compile-time variable amount of data storage through its template parameter.
00011  *  @see MotionSequenceEngine for the majority of the usage documentation
00012  *  @see TinyMotionSequenceMC, SmallMotionSequenceMC, MediumMotionSequenceMC, LargeMotionSequenceMC, XLargeMotionSequenceMC
00013  *  */
00014 template<unsigned int MAXMOVE>
00015 class MotionSequenceMC : public MotionCommand, public MotionSequenceEngine {
00016 public:
00017   static const unsigned int CAPACITY=MAXMOVE; //!< allows recovery of capacity in a general way (MAXMOVE may, and probably will, be obscured by a typedef)
00018 
00019   //!constructor
00020   MotionSequenceMC()
00021     : MotionCommand(), MotionSequenceEngine(), moves()
00022   {
00023     clear();
00024   }
00025   //!constructor, loads from a file and then resets the playtime to beginning and begins to play
00026   explicit MotionSequenceMC(const char* filename)
00027     : MotionSequenceEngine(), moves()
00028   {
00029     clear();
00030     LoadFile(filename);
00031     setTime(1);
00032   }
00033   //!destructor
00034   virtual ~MotionSequenceMC() {}
00035 
00036   virtual int isDirty() { return isPlaying(); }
00037   virtual int isAlive() { return (playspeed>0) ? (playtime<=endtime) : (playtime>0); }
00038   
00039   // I put this here because i want direct access to moves so it'll be faster
00040   virtual int updateOutputs() {
00041     MotionSequenceEngine::updateOutputs();
00042     if(!isPlaying()) {
00043       for(unsigned int i=0; i<NumOutputs; i++) //just copies getOutputCmd(i) across frames
00044         motman->setOutput(this,i,getOutputCmd(i));
00045     } else {
00046       for(unsigned int i=0; i<NumOutputs; i++) { //fill out the buffer of commands for smoother movement
00047         Move_idx_t prev=prevs[i],next=nexts[i];
00048         OutputCmd frames[NumFrames];
00049         frames[0]=getOutputCmd(i);
00050         for(unsigned int t=playtime+FrameTime,j=1;j<NumFrames;j++,t+=FrameTime) {
00051           setRange(t,prev,next);
00052           if(next!=invalid_move)
00053             calcOutput(frames[j],t,moves[prev],moves[next]);
00054           else
00055             frames[j].unset();
00056         }
00057         motman->setOutput(this,i,frames);
00058       }
00059     }
00060     return NumOutputs;
00061     //    if(i<NumLegJointss)
00062     //      log.push_back(logent(get_time(),playtime,i,frames));
00063   }
00064   
00065   virtual void clear() {
00066     moves.clear();
00067     for(unsigned int i=0; i<NumOutputs; i++) {
00068       prevs[i]=starts[i]=moves.new_back();
00069       moves.back().cmd.unset();
00070       moves.back().next=invalid_move;
00071       moves.back().prev=invalid_move;
00072       nexts[i]=invalid_move;
00073     }
00074     setTime(1);
00075   }
00076 
00077   virtual unsigned int getMaxFrames() const { return moves.getMaxCapacity(); }
00078   virtual unsigned int getUsedFrames() const { return moves.size(); }
00079 
00080 protected:
00081   // TYPES:
00082   typedef ListMemBuf<Move,MAXMOVE,Move_idx_t> list_t; //!< shorthand for the ListMemBuf that stores all of the movement frames
00083 
00084   // MEMBERS:
00085   list_t moves;                       //!< stores all of the movement keyframes
00086 
00087   virtual Move& getKeyFrame(Move_idx_t x) { return moves[x]; }
00088   virtual const Move& getKeyFrame(Move_idx_t x) const { return moves[x]; }
00089   virtual Move_idx_t newKeyFrame() {
00090     Move_idx_t i=moves.new_front();
00091     if(i==invalid_move)
00092       serr->printf("ERROR: MotionSequenceMC %d has run out of memory\n",getID());
00093     return i;
00094   }
00095   virtual void eraseKeyFrame(Move_idx_t x) { moves.erase(x); }
00096   void setRange(unsigned int t,Move_idx_t& prev, Move_idx_t& next) const {
00097     if(next!=invalid_move && moves[next].starttime<=t) {
00098       do {
00099         prev=next;
00100         next=moves[prev].next;
00101       } while(next!=invalid_move && moves[next].starttime<=t);
00102     } else {
00103       while(moves[prev].prev!=invalid_move && t<moves[prev].starttime) {
00104         next=prev;
00105         prev=moves[next].prev;
00106       } 
00107     }
00108   }
00109 };
00110 
00111 typedef MotionSequenceMC<NumOutputs*2> TinyMotionSequenceMC; //!< Tiny, but enough to handle a transition into a full-body pose
00112 typedef MotionSequenceMC<NumOutputs*3> SmallMotionSequenceMC;//!< Small, but still big enough to handle most of the included MS's (2 full-body frames ~ around 1KB)
00113 typedef MotionSequenceMC<NumOutputs*6> MediumMotionSequenceMC;//!< Medium (5 full body frames ~ est 4KB)
00114 typedef MotionSequenceMC<NumOutputs*11> LargeMotionSequenceMC;//!< Large (10 full body frames ~ est 8KB)
00115 typedef MotionSequenceMC<NumOutputs*26> XLargeMotionSequenceMC;//!< eXtra Large (25 full body frames ~ est 16KB)
00116 
00117 /*! @file
00118  * @brief Describes MotionSequenceEngine and defines MotionSequenceMC, handy little (or not so little) classes for switching between a sequence of postures
00119  * @author ejt (Creator)
00120  *
00121  * $Author: ejt $
00122  * $Name: tekkotsu-2_2_2 $
00123  * $Revision: 1.23 $
00124  * $State: Exp $
00125  * $Date: 2004/12/23 01:47:07 $
00126  */
00127 
00128 #endif

Tekkotsu v2.2.2
Generated Tue Jan 4 15:43:14 2005 by Doxygen 1.4.0