| Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
HeadPointerMC.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_HeadPointerMC_h 00003 #define INCLUDED_HeadPointerMC_h 00004 #include "MotionCommand.h" 00005 #include "OutputCmd.h" 00006 #include "Shared/RobotInfo.h" 00007 #include "Shared/mathutils.h" 00008 #include "roboop/robot.h" 00009 00010 //! This class gives some quick and easy functions to point the head at things 00011 class HeadPointerMC : public MotionCommand { 00012 public: 00013 //! Constructor, defaults to all joints to current value in ::state (i.e. calls takeSnapshot() automatically) 00014 HeadPointerMC(); 00015 00016 //! Destructor 00017 virtual ~HeadPointerMC() {} 00018 00019 //!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 00020 virtual void setHold(bool h=true) { hold=h; } 00021 virtual bool getHold() { return hold; } //!< return #hold 00022 00023 virtual void setTolerance(float t) { tolerance=t; } //!< sets #tolerance 00024 virtual float getTolerance() { return tolerance; } //!< returns #tolerance 00025 virtual void setTimeout(unsigned int delay) { timeout=delay; } //!< sets #timeout 00026 virtual unsigned int getTimeout() { return timeout; } //!< returns #timeout 00027 00028 //! sets the target to last sent commands, and dirty to false; essentially freezes motion in place 00029 /*! This is very similar to takeSnapshot(), but will do the "right thing" (retain current position) when motion blending is involved. 00030 * A status event will be generated if/when the joints reach the currently commanded position. 00031 * 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. */ 00032 virtual void freezeMotion(); 00033 //! sets the target joint positions to current sensor values 00034 /*! Similar to freezeMotion() when a motion is underway, but only if no other MotionCommands are using neck joints. 00035 * A status event will @e not be generated unless a motion was already underway. 00036 * 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. */ 00037 virtual void takeSnapshot(); 00038 00039 //!@name Speed Control 00040 00041 //! Sets #maxSpeed to 0 (no maximum) 00042 void noMaxSpeed() { for(unsigned int i=0; i<NumHeadJoints; i++) maxSpeed[i]=0; } 00043 00044 //! Restores #maxSpeed to default settings from Config::Motion_Config 00045 /*! @param x ratio of the max speed to use; so 0.5 would limit motion to half the recommended upper limit */ 00046 void defaultMaxSpeed(float x=1); 00047 00048 //! Sets #maxSpeed in rad/sec 00049 /*! @param i joint offset relative to HeadOffset (i.e. one of TPROffset_t) 00050 * @param x maximum radians per second to move */ 00051 void setMaxSpeed(unsigned int i, float x) { maxSpeed[i]=x*FrameTime/1000; } 00052 00053 //! Returns #maxSpeed in rad/sec 00054 /*! @param i joint offset relative to HeadOffset (i.e. one of TPROffset_t) 00055 * @return the maximum speed of joint @a i in radians per second */ 00056 float getMaxSpeed(unsigned int i) { return maxSpeed[i]*1000/FrameTime; } 00057 00058 //@} 00059 00060 //!@name Joint Accessors 00061 00062 //! Sets the weight values for all the neck joints 00063 void setWeight(float w); 00064 00065 //! Directly sets the neck values (all values in radians) 00066 /*! @param j1 value for first neck joint (tilt on all ERS models) 00067 * @param j2 value for second neck joint (pan on all ERS models) 00068 * @param j3 value for third neck joint (nod on ERS-7, roll on ERS-2xx) */ 00069 void setJoints(float j1, float j2, float j3); 00070 00071 //! Directly set a single neck joint value 00072 /*! @param i joint offset relative to HeadOffset (i.e. one of TPROffset_t) 00073 * @param value the value to be assigned to join @a i, in radians */ 00074 void setJointValue(unsigned int i, float value) { 00075 if(!ensureValidJoint(i)) 00076 return; 00077 headTargets[i]=clipAngularRange(HeadOffset+i,value); 00078 markDirty(); 00079 } 00080 00081 //! 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 00082 /*! @param i joint offset relative to HeadOffset (i.e. one of TPROffset_t) */ 00083 float getJointValue(unsigned int i) const { 00084 if(ensureValidJoint(i)) 00085 return headTargets[i]; 00086 else 00087 return 0; 00088 } 00089 00090 //! Centers the camera on a point in space, attempting to keep the camera as far away from the point as possible 00091 /*! Point should be relative to the body reference frame (see ::BaseFrameOffset). Returns true if the target is reachable. 00092 * @param x location in millimeters 00093 * @param y location in millimeters 00094 * @param z location in millimeters 00095 * 00096 * @todo this method is an approximation, could be more precise, and perhaps faster, although this is pretty good. */ 00097 bool lookAtPoint(float x, float y, float z); 00098 00099 //! Centers the camera on a point in space, attempting to move the camera @a d millimeters away from the point 00100 /*! Point should be relative to the body reference frame (see ::BaseFrameOffset). Returns true if the target is reachable. 00101 * @param x location in millimeters 00102 * @param y location in millimeters 00103 * @param z location in millimeters 00104 * @param d target distance from point in millimeters */ 00105 bool lookAtPoint(float x, float y, float z, float d); 00106 00107 //! Points the camera in a given direction 00108 /*! Vector should be relative to the body reference frame (see ::BaseFrameOffset). Returns true if the target is reachable. 00109 * @param x component of the direction vector 00110 * @param y component of the direction vector 00111 * @param z component of the direction vector */ 00112 bool lookInDirection(float x, float y, float z); 00113 00114 00115 00116 //@} 00117 00118 public: 00119 //!@name Inherited: 00120 virtual int updateOutputs(); //!< Updates where the head is looking 00121 virtual int isDirty() { return (dirty || !targetReached)?3:0; } //!< true if a change has been made since the last updateJointCmds() and we're active 00122 virtual int isAlive(); //!< Alive while target is not reached 00123 virtual void DoStart() { MotionCommand::DoStart(); markDirty(); } //!< marks this as dirty each time it is added 00124 //@} 00125 00126 protected: 00127 //! checks if target point or direction is actually reachable 00128 bool isReachable(const NEWMAT::ColumnVector& Pobj) { 00129 NEWMAT::ColumnVector poE=headkin.convertLink(0,headkin.get_dof())*Pobj; 00130 const float theta = mathutils::rad2deg(acos(poE(3)/sqrt(poE(1)*poE(1)+poE(2)*poE(2)+poE(3)*poE(3)))); 00131 // cout << "theta: " << theta << " degrees\n"; 00132 return theta < 5.0; 00133 } 00134 00135 //! puts x in the range (-pi,pi) 00136 static float normalizeAngle(float x) { return x-rint(x/(2*M_PI))*(2*M_PI); } 00137 00138 //! 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 00139 static float clipAngularRange(unsigned int i, float x) { 00140 float min=outputRanges[i][MinRange]; 00141 float max=outputRanges[i][MaxRange]; 00142 if(x<min || x>max) { 00143 float mn_dist=fabs(normalizeAngle(min-x)); 00144 float mx_dist=fabs(normalizeAngle(max-x)); 00145 if(mn_dist<mx_dist) 00146 return min; 00147 else 00148 return max; 00149 } else 00150 return x; 00151 } 00152 //! if targetReached, reassigns headCmds from MotionManager::getOutputCmd(), then sets dirty to true and targetReached to false 00153 /*! should be called each time a joint value gets modified in case 00154 * the head isn't where it's supposed to be, it won't jerk around 00155 * 00156 * MotionManager::getOutputCmd() is called instead of 00157 * WorldState::outputs[] because if this is being called rapidly 00158 * (i.e. after every sensor reading) using the sensor values will 00159 * cause problems with very slow acceleration due to sensor lag 00160 * continually resetting the current position. Using the last 00161 * value sent by the MotionManager fixes this.*/ 00162 void markDirty(); 00163 00164 //! Makes sure @a i is in the range (0,NumHeadJoints). If it is instead in the range (HeadOffset,HeadOffset+NumHeadJoints), output a warning and reset @a i to the obviously intended value. 00165 /*! @param[in] i joint offset relative to either HeadOffset (i.e. one of TPROffset_t) or 0 00166 * @param[out] i joint offset relative to HeadOffset (i.e. one of TPROffset_t) 00167 * @return true if the intended joint could be ascertained, false otherwise */ 00168 static bool ensureValidJoint(unsigned int& i); 00169 00170 bool dirty; //!< true if a change has been made since last call to updateJointCmds() 00171 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() 00172 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) 00173 bool targetReached; //!< false if the head is still moving towards its target 00174 unsigned int targetTimestamp; //!< time at which the targetReached flag was set 00175 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 00176 float headTargets[NumHeadJoints]; //!< stores the target value of each joint 00177 OutputCmd headCmds[NumHeadJoints]; //!< stores the last values we sent from updateOutputs 00178 float maxSpeed[NumHeadJoints]; //!< initialized from Config::motion_config, but can be overridden by setMaxSpeed(); rad per frame 00179 ROBOOP::Robot headkin; //!< provides kinematics computations, there's a small leak and safety issue here because ROBOOP::Robot contains pointers, and those pointers typically aren't freed because MotionCommand destructor isn't called when detaching shared region 00180 }; 00181 00182 /*! @file 00183 * @brief Describes HeadPointerMC, a class for various ways to control where the head is looking 00184 * @author ejt (Creator) 00185 * 00186 * $Author: ejt $ 00187 * $Name: tekkotsu-3_0 $ 00188 * $Revision: 1.25 $ 00189 * $State: Exp $ 00190 * $Date: 2006/09/26 19:29:40 $ 00191 */ 00192 00193 #endif 00194 |
|
Tekkotsu v3.0 |
Generated Wed Oct 4 00:03:43 2006 by Doxygen 1.4.7 |