Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

DynamicMotionSequence.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_DynamicMotionSequenceMC_h_
00003 #define INCLUDED_DynamicMotionSequenceMC_h_
00004 
00005 #include "MotionSequenceEngine.h"
00006 #include "MotionCommand.h"
00007 #include "MotionManager.h"
00008 #include <vector>
00009 #include "MotionManager.h"
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   //!constructor
00016   DynamicMotionSequence() : MotionCommand(), MotionSequenceEngine(), moves(), erased() {clear();}
00017   //!constructor, loads from a file and then resets the playtime to beginning and begins to play
00018   explicit DynamicMotionSequence(const char* filename) : MotionCommand(), MotionSequenceEngine(), moves(), erased() {clear();LoadFile(filename);setTime(1);}
00019   //!destructor
00020   virtual ~DynamicMotionSequence() {}
00021 
00022   // I put this here because i want direct access to moves so it'll be faster
00023 /*  void planJointCmds(unsigned int i, JointCmd frames[NumFrames]) {
00024     Move_idx_t prev=prevs[i],next=nexts[i];
00025     frames[0]=getJointCmd(i);
00026     for(unsigned int t=playtime+FrameTime,j=1;j<NumFrames;j++,t+=FrameTime) {
00027       setRange(t,prev,next);
00028       if(next!=invalid_move)
00029         calcJoint(frames[j],t,moves[prev],moves[next]);
00030       else
00031         frames[j]=unusedJoint;
00032     }
00033   }*/
00034   
00035 
00036   virtual int isDirty() { return isPlaying(); }
00037   virtual int isAlive() { return (playspeed>0) ? (playtime<=endtime) : (playtime>0); }
00038   
00039   virtual int updateOutputs() {
00040     MotionSequenceEngine::updateOutputs();
00041     if(!isPlaying()) {
00042       for(unsigned int i=0; i<NumOutputs; i++) //just copies getOutputCmd(i) across frames
00043         motman->setOutput(this,i,getOutputCmd(i));
00044     } else {
00045       for(unsigned int i=0; i<NumOutputs; i++) { //fill out the buffer of commands for smoother movement
00046         Move_idx_t prev=prevs[i],next=nexts[i];
00047         OutputCmd frames[NumFrames];
00048         frames[0]=getOutputCmd(i);
00049         for(unsigned int t=playtime+FrameTime,j=1;j<NumFrames;j++,t+=FrameTime) {
00050           setRange(t,prev,next);
00051           if(next!=invalid_move)
00052             calcOutput(frames[j],t,moves[prev],moves[next]);
00053           else
00054             frames[j].unset();
00055         }
00056         motman->setOutput(this,i,frames);
00057       }
00058     }
00059     return NumOutputs;
00060     //    if(i<NumLegJointss)
00061     //      log.push_back(logent(get_time(),playtime,i,frames));
00062   }
00063   
00064   virtual void clear() {
00065     moves.clear();
00066     erased.clear();
00067     for(unsigned int i=0; i<NumOutputs; i++) {
00068       moves.push_back(Move());
00069       moves.back().cmd.unset();
00070       moves.back().next=invalid_move;
00071       moves.back().prev=invalid_move;
00072       prevs[i]=starts[i]=moves.size()-1;
00073       nexts[i]=invalid_move;
00074     }
00075     setTime(1);
00076   }
00077   virtual unsigned int getMaxFrames() const { return -1U; }
00078   virtual unsigned int getUsedFrames() const { return moves.size()-erased.size(); }
00079 
00080 protected:
00081   // TYPES:
00082   typedef std::vector<Move> 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   std::vector<Move_idx_t> erased;   //!< recycles erased keyframes, can't just shift elements in #moves, it would throw of index numbers in Move structures
00087 
00088   virtual Move& getKeyFrame(Move_idx_t x) { return moves[x]; } //!< returns #moves[@a x]
00089   virtual const Move& getKeyFrame(Move_idx_t x) const { return moves[x]; } //!< returns #moves[@a x]
00090   virtual Move_idx_t newKeyFrame() {
00091     if(erased.empty()) {
00092       moves.push_back(Move());
00093       return moves.size()-1;
00094     } else { //recycle from used list
00095       Move_idx_t x=erased.back();
00096       erased.pop_back();
00097       return x;
00098     }
00099   }
00100   //! marks keyframe @a x unused
00101   virtual void eraseKeyFrame(Move_idx_t x) { erased.push_back(x); }
00102   //! advances (or rewinds) @a prev and @a next so that @a t falls between them
00103   void setRange(unsigned int t,Move_idx_t& prev, Move_idx_t& next) const {
00104     if(next!=invalid_move && moves[next].starttime<=t) {
00105       do {
00106         prev=next;
00107         next=moves[prev].next;
00108       } while(next!=invalid_move && moves[next].starttime<=t);
00109     } else if(t<moves[prev].starttime) {
00110       do {
00111         next=prev;
00112         prev=moves[next].prev;
00113       } while(t<moves[prev].starttime);
00114     }
00115   }
00116 };
00117 
00118 /*! @file
00119  * @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
00120  * @author ejt (Creator)
00121  *
00122  * $Author: ejt $
00123  * $Name: tekkotsu-2_4_1 $
00124  * $Revision: 1.8 $
00125  * $State: Exp $
00126  * $Date: 2005/08/07 04:11:03 $
00127  */
00128 
00129 #endif

Tekkotsu v2.4.1
Generated Tue Aug 16 16:32:46 2005 by Doxygen 1.4.4