| Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
ArmMC.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_ArmMC_h 00003 #define INCLUDED_ArmMC_h 00004 00005 #include "MotionCommand.h" 00006 #include "OutputCmd.h" 00007 #include "PostureEngine.h" 00008 #include "PostureMC.h" 00009 #include "Shared/RobotInfo.h" 00010 #include "Shared/mathutils.h" 00011 00012 class ArmMC : public MotionCommand { 00013 public: 00014 //! Constructor, defaults to all joints to current value in ::state (i.e. calls takeSnapshot() automatically) 00015 ArmMC(); 00016 virtual ~ArmMC() {} 00017 00018 //! Constructor 00019 00020 //!Sets #hold - if this is set to false, it will allow a persistent motion to behave the same as a pruned motion, without being pruned 00021 virtual void setHold(bool h=true) { hold=h; } 00022 virtual bool getHold() { return hold; } //!< return #hold 00023 00024 virtual void setTolerance(float t) { tolerance=t; } //!< sets #tolerance 00025 virtual float getTolerance() { return tolerance; } //!< returns #tolerance 00026 virtual void setTimeout(unsigned int delay) { timeout=delay; } //!< sets #timeout 00027 virtual unsigned int getTimeout() { return timeout; } //!< returns #timeout 00028 00029 //! sets the target to last sent commands, and dirty to false; essentially freezes motion in place 00030 /*! This is very similar to takeSnapshot(), but will do the "right thing" (retain current position) when motion blending is involved. 00031 * A status event will be generated if/when the joints reach the currently commanded position. 00032 * Probably should use freezeMotion() if you want to stop a motion underway, but takeSnapshot() if you want to reset/intialize to the current joint positions. */ 00033 virtual void freezeMotion(); 00034 00035 //! sets the target joint positions to current sensor values 00036 /*! Similar to freezeMotion() when a motion is underway, but only if no other MotionCommands are using neck joints. 00037 * A status event will @e not be generated unless a motion was already underway. 00038 * Probably should use freezeMotion() if you want to stop a motion underway, but takeSnapshot() if you want to reset/intialize to the current joint positions. */ 00039 virtual void takeSnapshot(); 00040 00041 //!@name Speed Control 00042 00043 //! Sets #maxSpeed to 0 (no maximum) 00044 void noMaxSpeed() { for(unsigned int i=0; i<NumArmJoints; i++) maxSpeed[i]=0; } 00045 00046 //! Restores #maxSpeed to default settings from Config::Motion_Config 00047 /*! @param x ratio of the max speed to use; so 0.5 would limit motion to half the recommended upper limit */ 00048 void defaultMaxSpeed(float x=1); 00049 00050 //! Sets #maxSpeed for all joints in rad/sec 00051 void setMaxSpeed(float x) { for(unsigned int i=0; i<NumArmJoints; i++) setMaxSpeed(i,x); } 00052 00053 //! Sets #maxSpeed for join @a i in rad/sec 00054 /*! @param i joint offset relative to ArmOffset (i.e. one of TPROffset_t) 00055 * @param x maximum radians per second to move */ 00056 void setMaxSpeed(unsigned int i, float x) { maxSpeed[i]=x*FrameTime/1000; } 00057 00058 //! Returns #maxSpeed in rad/sec 00059 /*! @param i joint offset relative to ArmOffset (i.e. one of TPROffset_t) 00060 * @return the maximum speed of joint @a i in radians per second */ 00061 float getMaxSpeed(unsigned int i) { return maxSpeed[i]*1000/FrameTime; } 00062 00063 //@} 00064 00065 //!@name Joint Accessors 00066 00067 //! Sets the weight values for all the arm joints 00068 void setWeight(float w); 00069 void setWeight(int x, float w); 00070 float armJointValue(unsigned int i); 00071 00072 00073 void setJointValue(unsigned int i, float value) { 00074 #ifdef TGT_HAS_ARMS 00075 if(!ensureValidJoint(i)) return; 00076 setWeight(i, 1); 00077 armTargets[i]=clipAngularRange(ArmOffset+i,value); 00078 markDirty(); 00079 #endif 00080 } 00081 00082 //! Returns the target value of joint @a i. Use this if you want to know the current @b commanded joint value; To get the current joint @b position, look in WorldState::outputs 00083 /*! @param i joint offset relative to ArmOffset (i.e. one of TPROffset_t) */ 00084 float getJointValue(unsigned int i) const { 00085 if(ensureValidJoint(i)) 00086 return armTargets[i]; 00087 else 00088 return 0; 00089 } 00090 00091 void setJoints(float shoulder, float elbow, float wrist); //!< Set joint values for a three-link arm 00092 void setJoints(float shoulder, float elbow, float yaw, float pitch, float roll, float gripper); //!< Set joint values for a Chiara-style arm 00093 void setWrist(float pitch, float roll, float gripper); 00094 00095 //! Move arm to specified point in base frame coordinates; return false if unreachable 00096 bool moveToPoint(float x, float y, float z) { return moveOffsetToPoint(fmat::Column<3>(), fmat::pack(x,y,z)); } 00097 bool moveToPoint(const fmat::Column<3>& tgt) { return moveOffsetToPoint(fmat::Column<3>(), tgt); } 00098 bool moveOffsetToPoint(const fmat::Column<3>& offset, const fmat::Column<3>& tgt); 00099 bool moveOffsetToPointWithOrientation(const fmat::Column<3>& offset, const fmat::Column<3>& tgt, const fmat::Quaternion& ori); 00100 00101 void setOutputCmd(unsigned int i, const OutputCmd& c) { 00102 #ifdef TGT_HAS_ARMS 00103 dirty=true; 00104 completionReported=false; 00105 armTargets[i-ArmOffset]=c.value; 00106 if(armCmds[i-ArmOffset].weight==0) 00107 armCmds[i-ArmOffset].value = state->outputs[i]; 00108 armCmds[i-ArmOffset].weight = c.weight; 00109 #endif 00110 } 00111 00112 public: 00113 //!@name Inherited: 00114 virtual int updateOutputs(); //!< Updates where the arm is looking 00115 virtual int isDirty() { return (dirty || !completionReported)?3:0; } //!< true if a change has been made since the last updateJointCmds() and we're active 00116 virtual int isAlive(); //!< Alive while target is not reached 00117 virtual void doStart() { MotionCommand::doStart(); markDirty(); } //!< marks this as dirty each time it is added 00118 //@} 00119 00120 protected: 00121 /*//! checks if target point or direction is actually reachable 00122 bool isReachable(const NEWMAT::ColumnVector& Pobj) { 00123 NEWMAT::ColumnVector poE=armkin.convertLink(0,armkin.get_dof())*Pobj; 00124 const float theta = mathutils::rad2deg(acos(poE(3)/sqrt(poE(1)*poE(1)+poE(2)*poE(2)+poE(3)*poE(3)))); 00125 // cout << "theta: " << theta << " degrees\n"; 00126 return theta < 5.0; 00127 }*/ 00128 00129 //! puts x in the range (-pi,pi) 00130 static float normalizeAngle(float x) { return x - static_cast<float>( rint(x/(2*M_PI)) * (2*M_PI) ); } 00131 00132 //! if @a x is outside of the range of joint @a i, it is set to either the min or the max, whichever is closer 00133 static float clipAngularRange(unsigned int i, float x) { 00134 float min=outputRanges[i][MinRange]; 00135 float max=outputRanges[i][MaxRange]; 00136 if(x<min || x>max) { 00137 float mn_dist=std::abs(normalizeAngle(min-x)); 00138 float mx_dist=std::abs(normalizeAngle(max-x)); 00139 if(mn_dist<mx_dist) 00140 return min; 00141 else 00142 return max; 00143 } else 00144 return x; 00145 } 00146 00147 //! if completionReported, copies armCmds from MotionManager::getOutputCmd(), then sets dirty to true and completionReported to false 00148 /*! should be called each time a joint value gets modified in case 00149 * the arm isn't where it's supposed to be, it won't jerk around 00150 * 00151 * MotionManager::getOutputCmd() is called instead of 00152 * WorldState::outputs[] because if this is being called rapidly 00153 * (i.e. after every sensor reading) using the sensor values will 00154 * cause problems with very slow acceleration due to sensor lag 00155 * continually resetting the current position. Using the last 00156 * value sent by the MotionManager fixes this.*/ 00157 void markDirty(); 00158 00159 //! Makes sure @a i is in the range (0,NumArmJoints). If it is instead in the range (ArmOffset,ArmOffset+NumArmJoints), output a warning and reset @a i to the obviously intended value. 00160 /*! @param[in] i joint offset relative to either ArmOffset (i.e. one of TPROffset_t) or 0 00161 * @param[out] i joint offset relative to ArmOffset (i.e. one of TPROffset_t) 00162 * @return true if the intended joint could be ascertained, false otherwise */ 00163 static bool ensureValidJoint(unsigned int& i); 00164 00165 bool dirty; //!< true if a change has been made since last call to updateJointCmds() 00166 bool hold; //!< if set to true, the posture will be kept active; otherwise joints will be marked unused after each posture is achieved (as if the posture was pruned); set through setHold() 00167 float tolerance; //!< when autopruning, if the maxdiff() of this posture and the robot's current position is below this value, isAlive() will be false, defaults to 0.01 (5.7 degree error) 00168 bool completionReported; //!< true if the most recent movement request has completed 00169 unsigned int targetTimestamp; //!< time at which the completionReported flag was set 00170 unsigned int timeout; //!< number of milliseconds to wait before giving up on a target that should have already been reached, a value of -1U will try forever 00171 float armTargets[NumArmJoints]; //!< stores the target value of each joint 00172 OutputCmd armCmds[NumArmJoints]; //!< stores the last values we sent from updateOutputs 00173 float maxSpeed[NumArmJoints]; //!< initialized from Config::motion_config, but can be overridden by setMaxSpeed(); rad per frame 00174 }; 00175 00176 #endif |
|
Tekkotsu v5.1CVS |
Generated Tue Jan 31 04:31:47 2012 by Doxygen 1.6.3 |