| Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
XWalkMC.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_XWalkMC_h_ 00003 #define INCLUDED_XWalkMC_h_ 00004 00005 #include "Motion/XWalkParameters.h" 00006 #include "Motion/MotionCommand.h" 00007 #include "Motion/MotionManager.h" 00008 #include "Motion/KinematicJoint.h" 00009 #include "Motion/IKSolver.h" 00010 #include "Shared/fmatSpatial.h" 00011 #include "Shared/Config.h" 00012 #include "Shared/get_time.h" 00013 #include "IPC/DriverMessaging.h" 00014 #include <set> 00015 00016 //! Extreme walk engine handles legged locomotion on hexapods and beyond 00017 class XWalkMC : public MotionCommand, public XWalkParameters { 00018 public: 00019 //! constructor 00020 XWalkMC() : MotionCommand(), XWalkParameters(), targetVel(), targetAngVel(0), targetDisp(), targetAngDisp(0), velocityMode(true), 00021 displacementTime(0), plantingLegs(false), initialPlacement(true), p(), transitions(), active(), startTime(get_time()), 00022 period(0), globPhase(0), rotationCenter(), contactMsg() { 00023 if(kine==NULL) { 00024 kine = new KinematicJoint; 00025 kine->loadFile(::config->makePath(config->motion.kinematics).c_str()); 00026 kine->buildChildMap(childMap,0,NumReferenceFrames); 00027 } 00028 loadFile(::config->motion.makePath("xwalk.plist").c_str()); 00029 p.loadFile(::config->motion.makePath("xwalk.plist").c_str()); 00030 spiderSettings(*this,p); 00031 if(kine!=NULL && kine->getBranches().size()>0) 00032 updateNeutralPos((unsigned int)startTime); 00033 setTargetVelocity(targetVel[0],targetVel[1],targetAngVel); 00034 } 00035 00036 //! Returns the current x and y velocities in mm/sec 00037 const fmat::Column<2>& getTargetVelocity() const { return targetVel; }; 00038 00039 //! Returns the current angular velocity in radians/sec 00040 float getTargetAngVelocity() const { return targetAngVel; } 00041 00042 //! Specify the desired body velocity in x and y (millimeters per second) and angular velocity (radians per second) 00043 virtual void getTargetVelocity(float &xvel, float &yvel, float &avel) { 00044 xvel = targetVel[0]; 00045 yvel = targetVel[1]; 00046 avel = targetAngVel; 00047 } 00048 00049 //! Specify the desired body velocity in x and y (millimeters per second) and angular velocity (radians per second); does not stop automatically 00050 virtual void setTargetVelocity(float xvel, float yvel, float avel); 00051 00052 //! Specify the desired body velocity in x and y (millimeters per second) and angular velocity (radians per second), and amount of time (seconds) before stopping 00053 virtual void setTargetVelocity(float xvel, float yvel, float avel, float time); 00054 00055 //! Specify the desired body displacement in x and y (millimeters) and angle (radians), optionally specify time (seconds) 00056 /*! Corresponding velocity will be limited to max velocity, so setting time=0 implies max speed */ 00057 virtual void setTargetDisplacement(float xdisp, float ydisp, float adisp, float time=0); 00058 00059 virtual int updateOutputs(); 00060 00061 virtual int isDirty() { 00062 for(unsigned int i=0; i<NumLegs; ++i) 00063 if(legStates[i].support<1) 00064 return true; 00065 return (targetVel.norm()>=EPSILON || std::abs(targetAngVel)>=EPSILON || active.size()>0); 00066 } 00067 00068 virtual int isAlive() { return true; } 00069 00070 virtual void start(); 00071 00072 virtual void stop(); 00073 00074 //! Posts a LocomotionEvent and sets velocities to zero. Also forces an output frame setting wheel velocities to zero; needed because if we remove a motion command there may be nothing left to zero the velocities. 00075 virtual void zeroVelocities(); 00076 00077 00078 #if 0 00079 //! Adjusts body height to lock knees and minimize joint torque to hold position, doesn't move feet 00080 /*! Implies a call to setTargetVelocity(0,0,0); later calls to set a non-zero velocity will cancel the leg lock. */ 00081 void lockLegsInPlace(); 00082 #endif 00083 00084 protected: 00085 //! recomputes each leg's LegState::neutralPos based on current values in #p 00086 void updateNeutralPos(unsigned int curTime); 00087 // updates period based on stride length parameter, returns true if no significant motion is currently requested 00088 bool resetPeriod(float time, float speed); 00089 //! recomputes LegState::downPos and LegState::liftPos based on specified state variables, such that the direction of stride rotates about the current position 00090 void resetLegState(unsigned int leg, float phase, const fmat::Column<3>& curPos, bool inAir, float speed); 00091 00092 void updateOutputsInitial(unsigned int curTime, const fmat::Column<3>& ground, const fmat::Column<3>& gravity, IKSolver::Point tgts[]); 00093 void updateOutputsWalking(float dt, const fmat::Column<3>& ground, const fmat::Column<3>& gravity, float speed, IKSolver::Point tgts[]); 00094 void sendLoadPredictions(IKSolver::Point tgts[]); 00095 00096 //! updates #globPhase based on specified stride time (relative to #startTime) 00097 void computePhase(float time); 00098 //! computes current leg state based on #globPhase 00099 void computeLegPhase(unsigned int leg, bool& inAir, float& phase); 00100 //! computes the leg position (in xy plane only) based on leg state 00101 void computeCurrentPosition(unsigned int leg, bool inAir, float speed, float phase, fmat::Column<3>& tgt); 00102 //! computes body position based on settings in #p, which should then be added to leg positions before projecting onto ground plane 00103 void computeCurrentBodyOffset(float* legPhases, float speed, float& offx, float& offy, float& offa); 00104 //! solves inverse kinematics and send affected output values to motion manager 00105 void solveIK(unsigned int leg, const IKSolver::Point& tgt); 00106 00107 // Given the mass, its position x and y, and a list of contact points, stores results into @a pressures 00108 /*! @param mass being supported in kilograms 00109 * @param massx center of mass along x axis, in millimeters 00110 * @param massy center of mass along y axis, in millimeters 00111 * @param contacts position of each support contact, in millimeters 00112 * @param[out] pressures will be resized and overwritten with pressure at each corresponding point in @a contacts, in newtons 00113 * 00114 * Note the z position is irrelevant, all points should be projected to the same plane, normal to gravity vector.<br> 00115 * Thanks Jacqueline K. Libby for helping figure out the free-body diagram/computation upon which this function is based. */ 00116 void computePressure(float mass, float massx, float massy, const std::vector<fmat::Column<2> >& contacts, std::vector<float>& pressures); 00117 00118 //! recursively processes contents of @a src, creating a ParameterTransition for each entry to smoothly update corresponding entries in @a dst 00119 void spiderSettings(plist::DictionaryBase& src, plist::DictionaryBase& dst); 00120 //! recursively processes contents of @a src, creating a ParameterTransition for each entry to smoothly update corresponding entries in @a dst 00121 void spiderSettings(plist::ArrayBase& src, plist::ArrayBase& dst); 00122 00123 //! 00124 class ParameterTransition : plist::PrimitiveListener { 00125 public: 00126 //! constructor, specify source to be monitored, destination to be kept in sync, a collection to be updated when transitions are in progress, and desired duration of transitions 00127 ParameterTransition(const plist::PrimitiveBase& srcVal, plist::PrimitiveBase& dstVal, std::set<ParameterTransition*>& activeTrans, unsigned int dur) : src(srcVal), dst(dstVal), active(activeTrans), curd(0), cura(0), 00128 startTime(), duration(dur), lastUpdate(), decelerate(false) 00129 { 00130 dst=src; 00131 src.addPrimitiveListener(this); 00132 } 00133 //! destructor 00134 ~ParameterTransition() { src.removePrimitiveListener(this); } 00135 virtual void plistValueChanged(const plist::PrimitiveBase& /*pl*/); 00136 bool update(unsigned int curTime); 00137 00138 const plist::PrimitiveBase& src; //!< the parameter which is being monitored for changes (a member of the superclass of XWalkMC) 00139 plist::PrimitiveBase& dst; //!< the parameter which is updated with smoothly transitioning values based on #src 00140 std::set<ParameterTransition*>& active; //!< collection which ParameterTransition will insert itself when src has been changed and transition is in progress 00141 float curd; //!< current velocity of parameter (d for derivative) 00142 float cura; //!< current acceleration of parameter 00143 unsigned int startTime; //!< time at which src was changed 00144 unsigned int duration; //!< how much time to use in transitioning (#cura is then based on difference between #src and #dst, and this) 00145 unsigned int lastUpdate; //!< time of last call to update() or reset() 00146 bool decelerate; //!< set to true if in the deceleration phase of transitioning 00147 }; 00148 00149 00150 fmat::Column<2> targetVel; //!< the requested xy velocity of the body (ignoring parameterized body motion, like sway or surge), millimeters per second 00151 float targetAngVel; //!< the requested angular velocity of the body, radians per second 00152 fmat::Column<2> targetDisp; //!< the requesed xy displacement of the body, in millimeters 00153 float targetAngDisp; //!< the requested angular displacement of the body in radians 00154 bool velocityMode; //!< True if we just want to maintain a velocity; false if we're trying to achieve a displacement 00155 unsigned int displacementTime; //!< time in msecs since setTargetDisplacement called 00156 bool plantingLegs; //!< True if we've finished a displacement and are waiting for all legs to come to ground before posting a status event 00157 bool initialPlacement; //!< set to true when legs are in an unknown configuration (e.g. following start()) 00158 XWalkParameters p; //!< current parameter values, subject to smoothed transition from those as members of the superclass (see ParameterTransition) 00159 std::set<ParameterTransition*> transitions; //!< full collection of parameter listeners 00160 std::set<ParameterTransition*> active; //!< collection of those listeners which are actively transitioning their corresponding parameters in #p 00161 float startTime; //!< must be float (not unsigned int) because value can go negative: phase offset of "walk time" from system get_time() (milliseconds) 00162 float period; //!< the time between leg lifts (milliseconds), calculated value to yield target speed (#targetVel) 00163 float globPhase; //!< the current phase within the walk, in turn controls phase of individual legs via updateLegPhase() 00164 fmat::Column<2> rotationCenter; //!< if the target angular velocity (#targetAngVel) is producing a reasonable curvature vs. targetVel, this is the point about which the body is arcing 00165 DriverMessaging::FixedPoints contactMsg; //!< list of current contact points, for better Mirage simulation 00166 00167 //! contains cached information about each leg's stride 00168 struct LegState { 00169 //! constructor 00170 LegState() : inAir(false), onGround(false), initialHeight(), support(1), reorder(-1U), neutralPos(), liftPos(), downPos() {} 00171 00172 //! True if the leg is currently in the return flight phase, false if its xy motion is linked to the ground. 00173 /*! Note that if this is false, the leg may be in the process of raising or lowering to the ground, but not actually providing support */ 00174 bool inAir; 00175 //! True if the leg is currently providing support on the ground, false if in the air (including raise or lower) 00176 bool onGround; 00177 float initialHeight; //!< during initial placement, stores the height of the leg when start() was called 00178 float support; //!< at the beginning and end of support phase, leg is lifted... this indicates how much lift has occurred/remains (range 0: in air, to 1: on ground) 00179 unsigned int reorder; //!< if a valid leg index (i.e. not -1U), indicates the index of the leg from which the phase offset parameter (XWalkParameters::LegParameters::flightPhase) should be used 00180 fmat::Column<2> neutralPos; //!< indicates the mid-stride foot position 00181 fmat::Column<2> liftPos; //!< indicates the position the leg was lifted from during flight, or the last target point during support 00182 fmat::Column<2> downPos; //!< indicates the position the leg will be placed following flight, or would have been placed to maintain continuity if target velocities change (see resetLegState()) 00183 }; 00184 LegState legStates[NumLegs]; //!< storage of cached stride information for each leg 00185 00186 static KinematicJoint* kine; 00187 static KinematicJoint* childMap[NumReferenceFrames]; 00188 }; 00189 00190 /*! @file 00191 * @brief Defines XWalkMC, which DESCRIPTION 00192 * @author Ethan Tira-Thompson (ejt) (Creator) 00193 */ 00194 00195 #endif |
|
Tekkotsu v5.1CVS |
Generated Fri Mar 16 05:26:55 2012 by Doxygen 1.6.3 |