Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

TailWagMC.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_TailWagMC_h
00003 #define INCLUDED_TailWagMC_h
00004 
00005 #include "Motion/MotionCommand.h"
00006 #include "Motion/MotionManager.h"
00007 #include "Shared/get_time.h"
00008 #include "Shared/ERS7Info.h"
00009 #include "Shared/ERS210Info.h"
00010 #include "Shared/WorldState.h"
00011 #include <cmath>
00012 
00013 //! A simple motion command for wagging the tail - you can specify period, magnitude, and tilt
00014 class TailWagMC : public MotionCommand {
00015 public:
00016 
00017   //!constructor
00018   TailWagMC() :
00019     MotionCommand(), period(500), magnitude(22*(float)M_PI/180), 
00020     offset(0), active(true), last_pan(0), last_sign(0), tilt() { }
00021 
00022   //!constructor
00023   TailWagMC(unsigned int cyc_period, float cyc_magnitude) :
00024     MotionCommand(), period(cyc_period), magnitude(cyc_magnitude), 
00025     offset(0), active(true), last_pan(0), last_sign(0), tilt() { }
00026 
00027   //!destructor
00028   virtual ~TailWagMC() {}
00029 
00030   virtual int updateOutputs() {
00031     if(!active)
00032       return 0;
00033 
00034     // only ERS-210 and ERS-7 have moveable tails
00035     unsigned int tail_pan_offset=-1U, tail_tilt_offset=-1U;
00036     if(RobotName == ERS210Info::TargetName) {
00037       // might be in 2xx compatability mode, use dynamic lookup
00038       unsigned tail = capabilities.getOutputOffset(ERS210Info::outputNames[ERS210Info::TailOffset]);
00039       tail_pan_offset = tail+PanOffset;
00040       tail_tilt_offset = tail+TiltOffset;
00041     }
00042     else if(RobotName == ERS7Info::TargetName) {
00043       // no compatability mode, just use direct symbol:
00044       tail_pan_offset = ERS7Info::TailOffset+PanOffset;
00045       tail_tilt_offset = ERS7Info::TailOffset+TiltOffset;
00046     } else {
00047       // unknown model, see if we have a tail named after the ERS-210 tail:
00048       tail_pan_offset = capabilities.getOutputOffset(ERS210Info::outputNames[ERS210Info::TailOffset+PanOffset]);
00049       if(tail_pan_offset!=-1U) {
00050         // try the tilt too...
00051         tail_tilt_offset = capabilities.getOutputOffset(ERS210Info::outputNames[ERS210Info::TailOffset+TiltOffset]);
00052       } else {
00053         // maybe just named "tail"?
00054         tail_pan_offset = capabilities.getOutputOffset("Tail");
00055       }
00056     }
00057     if(tail_pan_offset==-1U)
00058       return 0;
00059 
00060     for(unsigned int i=0; i<NumFrames; i++) {
00061       float new_pan = std::sin((2*(float)M_PI*(get_time()+offset+i*FrameTime))/period)*magnitude; //bug fix thanks L.A.Olsson AT herts ac uk
00062       pans[i].set(new_pan);
00063       if ( (new_pan-last_pan >= 0 && last_sign == -1) ||
00064            (new_pan-last_pan < 0 && last_sign == +1) )
00065         postEvent(EventBase(EventBase::motmanEGID,getID(),EventBase::statusETID));
00066       last_sign = new_pan-last_pan >= 0 ? 1 : -1;
00067       last_pan = new_pan;
00068     }
00069     motman->setOutput(this,tail_pan_offset,pans);
00070     if(tail_tilt_offset!=-1U)
00071       motman->setOutput(this,tail_tilt_offset,tilt);
00072     return tilt.weight>0?2:1;
00073   }
00074 
00075   virtual int isDirty() { return active; }
00076   virtual void setDirty() { active=true; }
00077 
00078   virtual int isAlive() { return true; }
00079 
00080   //! sets the period of time between swings, in milliseconds
00081   /*! a bit complicated in order to avoid jerking around when the period changes */
00082   void setPeriod(unsigned int p) {
00083     float prevPos=((get_time()+offset)%period)/(float)period;
00084     period=p;
00085     float curPos=(get_time()%period)/(float)period;
00086     offset=static_cast<unsigned int>((prevPos-curPos)*period);
00087   } 
00088   unsigned int getPeriod() const { return period; } //!< gets the period of time between swings, in milliseconds
00089   void setMagnitude(float mag) { magnitude=mag; } //!< sets the magnitude of swings, in radians
00090   double getMagnitude() const { return magnitude; } //!< gets the magnitude of swings, in radians
00091   void setTilt(float r) { tilt.set(r,1); }  //!< sets the tilt of the tail while wagging, in radians
00092   void unsetTilt() { tilt.unset(); } //!< makes the tilt control unspecified, will let something else control tilt
00093   double getTilt() const { return tilt.value; }  //!< gets the tilt of the tail while wagging, in radians
00094         double getPan() const { return last_pan; } //!< returns the most recent pan value of the tail while wagging, in radians
00095 
00096   bool getActive() { return active; } //!< returns true if this is currently trying to wag the tail
00097 
00098   //! turns the tail wagger on or off
00099   void setActive(bool a) {
00100     if ( active != a )
00101       last_sign = 0;
00102     active=a;
00103   }
00104   
00105 protected:
00106   unsigned int period; //!< period of time between swings, in milliseconds
00107   float magnitude; //!< magnitude of swings, in radians
00108   unsigned int offset; //!< offset in the period, only used if period is changed to avoid twitching
00109   bool active; //!< true if this is currently trying to wag the tail
00110   float last_pan; //!< last tail position
00111   int last_sign; //!< sign of tail movement direction
00112   OutputCmd tilt; //!< holds current setting for the tilt joint
00113   OutputCmd pans[NumFrames]; //!< holds commands for planning ahead the wagging
00114 };
00115 
00116 /*! @file
00117  * @brief Defines TailWagMC, which will wag the tail on a ERS-210 robot.
00118  * @author ejt (Creator)
00119  */
00120 
00121 #endif
00122 

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