| 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 00005 #include "Shared/RobotInfo.h" 00006 #include "MotionCommand.h" 00007 #include "OutputCmd.h" 00008 #include "Shared/mathutils.h" 00009 00010 namespace DualCoding { 00011 class Point; 00012 } 00013 00014 //! This class gives some quick and easy functions to point the head at things 00015 class HeadPointerMC : public MotionCommand { 00016 public: 00017 //! Constructor, defaults to all joints to current value in ::state (i.e. calls takeSnapshot() automatically) 00018 HeadPointerMC(); 00019 00020 //! Destructor 00021 virtual ~HeadPointerMC() {} 00022 00023 //!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 00024 virtual void setHold(bool h=true) { hold=h; } 00025 virtual bool getHold() { return hold; } //!< return #hold 00026 00027 virtual void setTolerance(float t) { tolerance=t; } //!< sets #tolerance 00028 virtual float getTolerance() { return tolerance; } //!< returns #tolerance 00029 virtual void setTimeout(unsigned int delay) { timeout=delay; } //!< sets #timeout 00030 virtual unsigned int getTimeout() { return timeout; } //!< returns #timeout 00031 00032 //! sets the target to last sent commands, and dirty to false; essentially freezes motion in place 00033 /*! This is very similar to takeSnapshot(), but will do the "right thing" (retain current position) when motion blending is involved. 00034 * A status event will be generated if/when the joints reach the currently commanded position. 00035 * 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. */ 00036 virtual void freezeMotion(); 00037 //! sets the target joint positions to current sensor values 00038 /*! Similar to freezeMotion() when a motion is underway, but only if no other MotionCommands are using neck joints. 00039 * A status event will @e not be generated unless a motion was already underway. 00040 * 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. */ 00041 virtual void takeSnapshot(); 00042 00043 //!@name Speed Control 00044 00045 //! Sets #maxSpeed to 0 (no maximum) 00046 void noMaxSpeed() { for(unsigned int i=0; i<NumHeadJoints; i++) maxSpeed[i]=0; } 00047 00048 //! Restores #maxSpeed to default settings from Config::Motion_Config 00049 /*! @param x ratio of the max speed to use; so 0.5 would limit motion to half the recommended upper limit */ 00050 void defaultMaxSpeed(float x=1); 00051 00052 //! Sets #maxSpeed in rad/sec 00053 /*! @param i joint offset relative to HeadOffset (i.e. one of TPROffset_t) 00054 * @param x maximum radians per second to move */ 00055 void setMaxSpeed(unsigned int i, float x) { maxSpeed[i]=x*FrameTime/1000; } 00056 00057 //! Returns #maxSpeed in rad/sec 00058 /*! @param i joint offset relative to HeadOffset (i.e. one of TPROffset_t) 00059 * @return the maximum speed of joint @a i in radians per second */ 00060 float getMaxSpeed(unsigned int i) { return maxSpeed[i]*1000/FrameTime; } 00061 00062 //@} 00063 00064 //!@name Joint Accessors 00065 00066 //! Sets the weight values for all the neck joints 00067 void setWeight(float w); 00068 00069 //! Request a set of neck joint values 00070 /*! Originally this corresponded directly to the neck joints of the aibo, however 00071 * on other platforms it will use capabilties mapping to try to set correspnding joints if available. 00072 * (we're not doing kinematics here, trying to set joint values directly. If your 00073 * want a more generic/abstract interface, use lookAtPoint()/lookInDirection(). 00074 * 00075 * Note that for a "pan-tilt" camera, you actually want to set the @em last two parameters, 00076 * @em not the first two! 00077 * 00078 * @param tilt value - this is an initial rotation about the camera x axis 00079 * @param pan value - this is a rotation about the camera y axis 00080 * @param tilt2 value - a second rotation about the camera x axis ("nod") 00081 * 00082 * On ERS-210 and 220, the tilt2 is actually a roll about camera z (ugly, but no one's using those anymore, so moot issue) */ 00083 void setJoints(float tilt, float pan, float tilt2); 00084 void setJoints(float pan, float shoulder, float elbow, float pitch); 00085 00086 //! Directly set a single neck joint value 00087 /*! @param i joint offset relative to HeadOffset (i.e. one of TPROffset_t) 00088 * @param value the value to be assigned to join @a i, in radians */ 00089 void setJointValue(unsigned int i, float value) { 00090 #ifdef TGT_HAS_HEAD 00091 if(!ensureValidJoint(i)) 00092 return; 00093 headTargets[i]=clipAngularRange(HeadOffset+i,value); 00094 markDirty(); 00095 #endif 00096 } 00097 00098 //! 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 00099 /*! @param i joint offset relative to HeadOffset (i.e. one of TPROffset_t) */ 00100 float getJointValue(unsigned int i) const { 00101 if(ensureValidJoint(i)) 00102 return headTargets[i]; 00103 else 00104 return 0; 00105 } 00106 00107 //! Centers the camera on a point in space, attempting to keep the camera as far away from the point as possible 00108 /*! Point should be relative to the body reference frame (see ::BaseFrameOffset). Returns true if the target is reachable. 00109 * @param x location in millimeters 00110 * @param y location in millimeters 00111 * @param z location in millimeters 00112 * 00113 * @todo this method is an approximation, could be more precise, and perhaps faster, although this is pretty good. */ 00114 bool lookAtPoint(float x, float y, float z); 00115 00116 //! Centers the camera on a point in space, attempting to keep the camera as far away from the point as possible 00117 /*! Point should be relative to the body reference frame (see ::BaseFrameOffset). Returns true if the target is reachable. 00118 * @param p point to look at */ 00119 bool lookAtPoint(const DualCoding::Point &p); 00120 00121 //! Centers the camera on a point in space, attempting to move the camera @a d millimeters away from the point 00122 /*! Point should be relative to the body reference frame (see ::BaseFrameOffset). Returns true if the target is reachable. 00123 * @param x location in millimeters 00124 * @param y location in millimeters 00125 * @param z location in millimeters 00126 * @param d target distance from point in millimeters */ 00127 bool lookAtPoint(float x, float y, float z, float d); 00128 00129 //! Points the camera in a given direction 00130 /*! Vector should be relative to the body reference frame (see ::BaseFrameOffset). Returns true if the target is reachable. 00131 * @param x component of the direction vector 00132 * @param y component of the direction vector 00133 * @param z component of the direction vector */ 00134 bool lookInDirection(float x, float y, float z); 00135 00136 00137 00138 //@} 00139 00140 public: 00141 //!@name Inherited: 00142 virtual int updateOutputs(); //!< Updates where the head is looking 00143 virtual int isDirty() { return (dirty || !targetReached)?3:0; } //!< true if a change has been made since the last updateJointCmds() and we're active 00144 virtual int isAlive(); //!< Alive while target is not reached 00145 virtual void doStart() { MotionCommand::doStart(); markDirty(); } //!< marks this as dirty each time it is added 00146 //@} 00147 00148 protected: 00149 //! puts x in the range (-pi,pi) 00150 static float normalizeAngle(float x) { return x - static_cast<float>( rint(x/(2*M_PI)) * (2*M_PI) ); } 00151 00152 //! 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 00153 static float clipAngularRange(unsigned int i, float x) { 00154 float min=outputRanges[i][MinRange]; 00155 float max=outputRanges[i][MaxRange]; 00156 if(x<min || x>max) { 00157 float mn_dist=std::abs(normalizeAngle(min-x)); 00158 float mx_dist=std::abs(normalizeAngle(max-x)); 00159 if(mn_dist<mx_dist) 00160 return min; 00161 else 00162 return max; 00163 } else 00164 return x; 00165 } 00166 //! if targetReached, reassigns headCmds from MotionManager::getOutputCmd(), then sets dirty to true and targetReached to false 00167 /*! should be called each time a joint value gets modified in case 00168 * the head isn't where it's supposed to be, it won't jerk around 00169 * 00170 * MotionManager::getOutputCmd() is called instead of 00171 * WorldState::outputs[] because if this is being called rapidly 00172 * (i.e. after every sensor reading) using the sensor values will 00173 * cause problems with very slow acceleration due to sensor lag 00174 * continually resetting the current position. Using the last 00175 * value sent by the MotionManager fixes this.*/ 00176 void markDirty(); 00177 00178 //! 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. 00179 /*! @param[in] i joint offset relative to either HeadOffset (i.e. one of TPROffset_t) or 0 00180 * @param[out] i joint offset relative to HeadOffset (i.e. one of TPROffset_t) 00181 * @return true if the intended joint could be ascertained, false otherwise */ 00182 static bool ensureValidJoint(unsigned int& i); 00183 00184 bool dirty; //!< true if a change has been made since last call to updateJointCmds() 00185 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() 00186 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.05 radian (2.86 degree error) 00187 bool targetReached; //!< false if the head is still moving towards its target 00188 unsigned int targetTimestamp; //!< time at which the targetReached flag was set 00189 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 00190 float headTargets[NumHeadJoints]; //!< stores the target value of each joint 00191 OutputCmd headCmds[NumHeadJoints]; //!< stores the last values we sent from updateOutputs 00192 float maxSpeed[NumHeadJoints]; //!< initialized from Config::motion_config, but can be overridden by setMaxSpeed(); rad per frame 00193 }; 00194 00195 /*! @file 00196 * @brief Describes HeadPointerMC, a class for various ways to control where the head is looking 00197 * @author ejt (Creator) 00198 */ 00199 00200 #endif |
|
Tekkotsu v5.1CVS |
Generated Fri Mar 16 05:26:41 2012 by Doxygen 1.6.3 |