Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

DynamicMotionSequence.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_DynamicMotionSequence_h_
00003 #define INCLUDED_DynamicMotionSequence_h_
00004 
00005 #include "MotionSequenceEngine.h"
00006 #include "MotionCommand.h"
00007 #include "MotionManager.h"
00008 #include "Events/EventBase.h"
00009 #include <vector>
00010 
00011 //! Uses STL's vector for dynamic memory allocation - don't use this as a motion command, pointers in shared memory regions can be invalid in other processes
00012 /*! See MotionSequenceEngine for documentation on its members */
00013 class DynamicMotionSequence : public MotionCommand, public MotionSequenceEngine {
00014 public:
00015 
00016   //!constructor
00017   DynamicMotionSequence() : MotionCommand(), MotionSequenceEngine(), moves(), erased(), lastDirty(false) { clear(); }
00018 
00019   //!constructor, loads from a file and then resets the playtime to beginning and begins to play
00020   explicit DynamicMotionSequence(const char* filename) : MotionCommand(), MotionSequenceEngine(), moves(), erased(), lastDirty(false) {
00021     clear();
00022     loadFile(filename);
00023     setTime(1);
00024   }
00025 
00026   //!destructor
00027   virtual ~DynamicMotionSequence() {}
00028 
00029   // I put this here because i want direct access to moves so it'll be faster
00030 /*  void planJointCmds(unsigned int i, JointCmd frames[NumFrames]) {
00031     Move_idx_t prev=prevs[i],next=nexts[i];
00032     frames[0]=getJointCmd(i);
00033     for(unsigned int t=playtime+FrameTime,j=1;j<NumFrames;j++,t+=FrameTime) {
00034       setRange(t,prev,next);
00035       if(next!=invalid_move)
00036         calcJoint(frames[j],t,moves[prev],moves[next]);
00037       else
00038         frames[j]=unusedJoint;
00039     }
00040   }*/
00041   
00042 
00043   virtual int isDirty() { return isPlaying(); }
00044   virtual int isAlive() { return (playspeed>0) ? (playtime<=endtime) : (playtime>0); }
00045   
00046   virtual int updateOutputs() {
00047     MotionSequenceEngine::updateOutputs();
00048     if(!isPlaying()) {
00049       if(lastDirty)
00050         postEvent(EventBase(EventBase::motmanEGID,getID(),EventBase::statusETID));
00051       lastDirty=false;
00052       for(unsigned int i=0; i<NumOutputs; i++) //just copies getOutputCmd(i) across frames
00053         motman->setOutput(this,i,getOutputCmd(i));
00054     } else {
00055       lastDirty=true;
00056       for(unsigned int i=0; i<NumOutputs; i++) { //fill out the buffer of commands for smoother movement
00057         Move_idx_t prev=prevs[i],next=nexts[i];
00058         OutputCmd frames[NumFrames];
00059         frames[0]=getOutputCmd(i);
00060         for(unsigned int t=playtime+FrameTime,j=1;j<NumFrames;j++,t+=FrameTime) {
00061           setRange(t,prev,next);
00062           if(next!=invalid_move)
00063             calcOutput(frames[j],t,moves[prev],moves[next]);
00064           else
00065             frames[j].unset();
00066         }
00067         motman->setOutput(this,i,frames);
00068       }
00069     }
00070     return NumOutputs;
00071     //    if(i<NumLegJointss)
00072     //      log.push_back(logent(get_time(),playtime,i,frames));
00073   }
00074   
00075   virtual void clear() {
00076     moves.clear();
00077     erased.clear();
00078     for(unsigned int i=0; i<NumOutputs; i++) {
00079       moves.push_back(Move());
00080       moves.back().cmd.unset();
00081       moves.back().next=invalid_move;
00082       moves.back().prev=invalid_move;
00083       prevs[i]=starts[i]=moves.size()-1;
00084       nexts[i]=invalid_move;
00085     }
00086     setTime(1);
00087   }
00088   virtual unsigned int getMaxFrames() const { return -1U; }
00089   virtual unsigned int getUsedFrames() const { return moves.size()-erased.size(); }
00090 
00091 protected:
00092   // TYPES:
00093   typedef std::vector<Move> list_t; //!< shorthand for the ListMemBuf that stores all of the movement frames
00094 
00095   // MEMBERS:
00096   list_t moves;                     //!< stores all of the movement keyframes
00097   std::vector<Move_idx_t> erased;   //!< recycles erased keyframes, can't just shift elements in #moves, it would throw off index numbers in Move structures
00098   bool lastDirty; //!< true if last updateOutputs was dirty, so we know when to post status event
00099 
00100   virtual Move& getKeyFrame(Move_idx_t x) { return moves[x]; } //!< returns #moves[@a x]
00101   virtual const Move& getKeyFrame(Move_idx_t x) const { return moves[x]; } //!< returns #moves[@a x]
00102   virtual Move_idx_t newKeyFrame() {
00103     if(erased.empty()) {
00104       moves.push_back(Move());
00105       return moves.size()-1;
00106     } else { //recycle from used list
00107       Move_idx_t x=erased.back();
00108       erased.pop_back();
00109       return x;
00110     }
00111   }
00112   //! marks keyframe @a x unused
00113   virtual void eraseKeyFrame(Move_idx_t x) { erased.push_back(x); }
00114   //! advances (or rewinds) @a prev and @a next so that @a t falls between them
00115   bool setRange(unsigned int t,Move_idx_t& prev, Move_idx_t& next) const {
00116     bool moved=false;
00117     if(next!=invalid_move && moves[next].starttime<=t) {
00118       moved=true;
00119       do {
00120         prev=next;
00121         next=moves[prev].next;
00122       } while(next!=invalid_move && moves[next].starttime<=t);
00123     } else {
00124       while(moves[prev].prev!=invalid_move && t<moves[prev].starttime) {
00125         next=prev;
00126         prev=moves[next].prev;
00127         moved=true;
00128       }
00129     }
00130     return moved;
00131   }
00132 };
00133 
00134 /*! @file
00135  * @brief Uses STL's vector for dynamic memory allocation - don't use this as a motion command, pointers in shared memory regions can be invalid in other processes
00136  * @author ejt (Creator)
00137  */
00138 
00139 #endif

Tekkotsu v5.1CVS
Generated Fri Mar 16 05:26:36 2012 by Doxygen 1.6.3