| Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
PostureEngine.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_PostureEngine_h 00003 #define INCLUDED_PostureEngine_h 00004 00005 #include "Motion/OutputCmd.h" 00006 #include "Motion/Kinematics.h" 00007 #include "Shared/RobotInfo.h" 00008 #include "Shared/LoadSave.h" 00009 00010 class WorldState; 00011 00012 //! A class for storing a set of positions and weights for all the outputs 00013 /*! Handy for any class which wants to deal with setting joints and postures without writing a custom class 00014 * @see PostureMC 00015 * @see <a href="http://www.cs.cmu.edu/~tekkotsu/Kinematics.html">Tekkotsu's Kinematics page</a> 00016 * @see <a href="http://www.cs.cmu.edu/~dst/Tekkotsu/Tutorial/postures.shtml">David Touretzky's "Postures and Motion Sequences" Chapter</a> 00017 * @see <a href="http://www.cs.cmu.edu/~dst/Tekkotsu/Tutorial/forwardkin.shtml">David Touretzky's "Forward Kinematics" Chapter</a> 00018 * @see <a href="http://www.cs.cmu.edu/afs/cs/academic/class/15494-s06/www/lectures/postures.pdf">CMU's Cognitive Robotics posture slides</a> 00019 * @see <a href="http://www.cs.cmu.edu/afs/cs/academic/class/15494-s06/www/lectures/kinematics.pdf">CMU's Cognitive Robotics kinematics slides</a> 00020 */ 00021 class PostureEngine : public LoadSave, public Kinematics { 00022 public: 00023 00024 //!@name Constructors 00025 00026 //!constructor 00027 PostureEngine() : LoadSave(), Kinematics(*kine), saveFormatCondensed(false), loadSaveSensors(NULL) {} 00028 //!constructor, loads a position from a file 00029 /*! @todo might want to make a library stored in memory of common positions so they don't have to be loaded repeatedly from memstick */ 00030 PostureEngine(const std::string& filename) : LoadSave(), Kinematics(*kine), saveFormatCondensed(false), loadSaveSensors(NULL) { loadFile(filename.c_str()); } 00031 //!constructor, initializes joint positions to the current state of the outputs as defined by @a state 00032 PostureEngine(const WorldState* st) : LoadSave(), Kinematics(*kine), saveFormatCondensed(false), loadSaveSensors(NULL) { if(st!=NULL) takeSnapshot(*st); } 00033 00034 //! copy constructor 00035 PostureEngine(const PostureEngine& pe) 00036 : LoadSave(pe), Kinematics(pe), saveFormatCondensed(pe.saveFormatCondensed), loadSaveSensors(pe.loadSaveSensors) 00037 { 00038 for(unsigned int i=0; i<NumOutputs; i++) 00039 cmds[i]=pe.cmds[i]; 00040 } 00041 00042 //! assignment operator 00043 PostureEngine& operator=(const PostureEngine& pe) { 00044 LoadSave::operator=(pe); 00045 Kinematics::operator=(pe); 00046 saveFormatCondensed=pe.saveFormatCondensed; 00047 loadSaveSensors=pe.loadSaveSensors; 00048 for(unsigned int i=0; i<NumOutputs; i++) 00049 cmds[i]=pe.cmds[i]; 00050 return *this; 00051 } 00052 00053 //! destructor 00054 virtual ~PostureEngine(); 00055 //@} 00056 00057 00058 00059 //! You should be able to call the non-virtual functions without checking out, just a MotionManager::peekMotion(). Theoretically. 00060 //!@name Output Value Access/Control 00061 virtual void takeSnapshot(); //!< sets the values of #cmds to the current state of the outputs (doesn't change the weights) 00062 virtual void takeSnapshot(const WorldState& st); //!< sets the values of #cmds to the current state of the outputs as defined by @a state (doesn't change the weights) 00063 virtual void setWeights(float w) { setWeights(w,0,NumOutputs); } //!< set the weights of all #cmds 00064 virtual void setWeights(float w, unsigned int lowjoint, unsigned int highjoint); //!< the the weights of a range of #cmds 00065 virtual void clear(); //!< sets all joints to unused 00066 inline PostureEngine& setOutputCmd(unsigned int i, const OutputCmd& c) { cmds[i]=c; return *this; } //!<sets output @a i to OutputCmd @a c, returns @c *this so you can chain them; also remember that OutputCmd support implicit conversion from floats (so you can just pass a float) 00067 inline OutputCmd& operator()(unsigned int i) { return cmds[i]; } //!< returns output @a i, returns a reference so you can also set through an assignment to this call, e.g. pose(MouthOffset)=.1; (remember that OutputCmd support implicit conversion from floats) 00068 inline const OutputCmd& operator()(unsigned int i) const { return cmds[i]; } //!< returns output @a i 00069 inline OutputCmd& getOutputCmd(unsigned int i) { return cmds[i]; } //!< returns output @a i, returns a reference so you can also set through an assignment 00070 inline const OutputCmd& getOutputCmd(unsigned int i) const { return cmds[i]; } //!< returns output @a i 00071 //@} 00072 00073 00074 00075 //!Uses LoadSave interface so you can load/save to files, uses a human-readable storage format 00076 //!@name LoadSave 00077 virtual void setSaveFormat(bool condensed, WorldState* ws); //!< sets #saveFormatCondensed and #loadSaveSensors (pass ::state for @a ws if you want to use current sensor values) 00078 virtual void setLoadedSensors(WorldState* ws) { loadSaveSensors=ws; } //!< if @a ws is non-NULL, any sensor values in loaded postures will be stored there (otherwise they are ignored) 00079 virtual WorldState* getLoadedSensors() const { return loadSaveSensors; } //!< returns value previously stored by setLoadSensors() 00080 virtual unsigned int getBinSize() const; 00081 virtual unsigned int loadBuffer(const char buf[], unsigned int len); 00082 virtual unsigned int saveBuffer(char buf[], unsigned int len) const; 00083 virtual unsigned int loadFile(const char filename[]); 00084 virtual unsigned int saveFile(const char filename[]) const; 00085 //@} 00086 00087 00088 00089 //!@name Kinematics 00090 00091 //! Performs inverse kinematics to solve for positioning @a Peff on link @a j as close as possible to @a Ptgt (base coordinates in homogenous form); if solution found, stores result in this posture and returns true 00092 /*! @param Ptgt the target point, in base coordinates 00093 * @param link the output offset of the joint to move 00094 * @param Peff the point (relative to @a link) which you desire to have moved to @a Ptgt (it's the desired "effector") 00095 * 00096 * The difference between solveLinkPosition() and solveLinkVector() is typically small, 00097 * but critical when you're trying to look at something -- the solution obtained by 00098 * simplying trying to solve for the position may not align the vector with the target -- 00099 * solveLinkVector() tries to ensure the vector is aligned with the target, even if that 00100 * isn't the closest solution position-wise. 00101 */ 00102 virtual bool solveLinkPosition(const NEWMAT::ColumnVector& Ptgt, unsigned int link, const NEWMAT::ColumnVector& Peff); 00103 00104 //! Performs inverse kinematics to solve for positioning Peff on link @a j as close as possible to @a Ptgt (base coordinates); if solution found, stores result in this posture and returns true 00105 /*! @param Ptgt_x the target x position (relative to base frame) 00106 * @param Ptgt_y the target y position (relative to base frame) 00107 * @param Ptgt_z the target z position (relative to base frame) 00108 * @param link the output offset of the joint to move 00109 * @param Peff_x the x position (relative to @a link) which you desire to have moved to @a Ptgt (it's the desired "effector") 00110 * @param Peff_y the y position (relative to @a link) which you desire to have moved to @a Ptgt (it's the desired "effector") 00111 * @param Peff_z the z position (relative to @a link) which you desire to have moved to @a Ptgt (it's the desired "effector") 00112 * 00113 * The difference between solveLinkPosition() and solveLinkVector() is typically small, 00114 * but critical when you're trying to look at something -- the solution obtained by 00115 * simplying trying to solve for the position may not align the vector with the target -- 00116 * solveLinkVector() tries to ensure the vector is aligned with the target, even if that 00117 * isn't the closest solution position-wise. 00118 */ 00119 virtual bool solveLinkPosition(float Ptgt_x, float Ptgt_y, float Ptgt_z, unsigned int link, float Peff_x, float Peff_y, float Peff_z) 00120 { return solveLinkPosition(pack(Ptgt_x,Ptgt_y,Ptgt_z),link,pack(Peff_x,Peff_y,Peff_z)); } 00121 00122 //! Performs inverse kinematics to solve for aligning the vector through Peff on link @a j and the link's origin to point at @a Ptgt (base coordinates in homogenous form); if solution found, stores result in this posture and returns true 00123 /*! @param Ptgt the target point, in base coordinates 00124 * @param link the output offset of the joint to move 00125 * @param Peff the point (relative to @a link) which you desire to have moved to @a Ptgt (it's the desired "effector") 00126 * 00127 * The difference between solveLinkPosition() and solveLinkVector() is typically small, 00128 * but critical when you're trying to look at something -- the solution obtained by 00129 * simplying trying to solve for the position may not align the vector with the target -- 00130 * solveLinkVector() tries to ensure the vector is aligned with the target, even if that 00131 * isn't the closest solution position-wise. 00132 */ 00133 virtual bool solveLinkVector(const NEWMAT::ColumnVector& Ptgt, unsigned int link, const NEWMAT::ColumnVector& Peff); 00134 00135 //! Performs inverse kinematics to solve for aligning the vector through Peff on link @a j and the link's origin to point at @a Ptgt (base coordinates); if solution found, stores result in this posture and returns true 00136 /*! @param Ptgt_x the target x position (relative to base frame) 00137 * @param Ptgt_y the target y position (relative to base frame) 00138 * @param Ptgt_z the target z position (relative to base frame) 00139 * @param link the output offset of the joint to move 00140 * @param Peff_x the x position (relative to @a link) which you desire to have moved to @a Ptgt (it's the desired "effector") 00141 * @param Peff_y the y position (relative to @a link) which you desire to have moved to @a Ptgt (it's the desired "effector") 00142 * @param Peff_z the z position (relative to @a link) which you desire to have moved to @a Ptgt (it's the desired "effector") 00143 * 00144 * @todo this method is an approximation, could be more precise, and perhaps faster, although this is pretty good. 00145 * 00146 * The difference between solveLinkPosition() and solveLinkVector() is typically small, 00147 * but critical when you're trying to look at something -- the solution obtained by 00148 * simplying trying to solve for the position may not align the vector with the target -- 00149 * solveLinkVector() tries to ensure the vector is aligned with the target, even if that 00150 * isn't the closest solution position-wise. 00151 */ 00152 virtual bool solveLinkVector(float Ptgt_x, float Ptgt_y, float Ptgt_z, unsigned int link, float Peff_x, float Peff_y, float Peff_z) 00153 { return solveLinkVector(pack(Ptgt_x,Ptgt_y,Ptgt_z),link,pack(Peff_x,Peff_y,Peff_z)); } 00154 00155 //@} 00156 00157 00158 00159 //!@name Combining Postures 00160 00161 //! sets joints of this to all joints of @a pe which are not equal to unused (layers @a pe over this) stores into this 00162 virtual PostureEngine& setOverlay(const PostureEngine& pe); 00163 //! sets joints of this to all joints of @a pe which are not equal to unused (layers @a pe over this) returns new PostureEngine 00164 virtual PostureEngine createOverlay(const PostureEngine& pe) const; 00165 00166 //! sets joints of this which are equal to unused to @a pe, (layers this over @a pe) stores into this 00167 virtual PostureEngine& setUnderlay(const PostureEngine& pe); 00168 //! sets joints of this which are equal to unused to @a pe, (layers this over @a pe) returns new PostureEngine 00169 virtual PostureEngine createUnderlay(const PostureEngine& pe) const; 00170 00171 //! computes a weighted average of this vs. @a pe, @a w being the weight towards @a pe (so @a w==1 just copies @a pe) 00172 virtual PostureEngine& setAverage(const PostureEngine& pe,float w=0.5); 00173 //! computes a weighted average of this vs. @a pe, @a w being the weight towards @a pe (so @a w==1 just copies @a pe) 00174 virtual PostureEngine createAverage(const PostureEngine& pe,float w=0.5) const; 00175 00176 //! computes a weighted average of this vs. @a pe, using the weight values of the joints, storing the total weight in the result's weight value 00177 virtual PostureEngine& setCombine(const PostureEngine& pe); 00178 //! computes a weighted average of this vs. @a pe, using the weight values of the joints, storing the total weight in the result's weight value 00179 virtual PostureEngine createCombine(const PostureEngine& pe) const; 00180 00181 //! returns the sum squared error between this and pe's output values, but only between outputs which are both not unused 00182 /*! @todo create a version which does weighted summing? This treats weights as all or nothing */ 00183 virtual float diff(const PostureEngine& pe) const; 00184 00185 //! returns the average sum squared error between this and pe's output values for outputs which are both not unused 00186 /*! @todo create a version which does weighted summing? This treats weights as all or nothing */ 00187 virtual float avgdiff(const PostureEngine& pe) const; 00188 00189 //! returns the max error between this and pe's output values for outputs which are both not unused 00190 /*! @todo create a version which does weighted summing? This treats weights as all or nothing */ 00191 virtual float maxdiff(const PostureEngine& pe) const; 00192 00193 //@} 00194 00195 protected: 00196 //all updates come from this posture engine's own state, not WorldState 00197 virtual void update(unsigned int c, unsigned int l); 00198 00199 //!the table of outputs' values and weights, can be accessed through setOutputCmd() and getOutputCmd() 00200 OutputCmd cmds[NumOutputs]; 00201 00202 bool saveFormatCondensed; //!< requests a condensed file format, smaller but less readable 00203 WorldState* loadSaveSensors; //!< If non-null, saves will include sensor readings from here, and loads will store any read sensors into here 00204 }; 00205 00206 /*! @file 00207 * @brief Describes PostureEngine, a base class for managing the values and weights of all the outputs 00208 * @author ejt (Creator) 00209 * 00210 * $Author: ejt $ 00211 * $Name: tekkotsu-3_0 $ 00212 * $Revision: 1.23 $ 00213 * $State: Exp $ 00214 * $Date: 2006/10/04 02:57:12 $ 00215 */ 00216 00217 #endif |
|
Tekkotsu v3.0 |
Generated Wed Oct 4 00:03:45 2006 by Doxygen 1.4.7 |