se2ez
robot.h
Go to the documentation of this file.
1 /* Author: Zachary Kingston */
2 
3 #ifndef SE2EZ_CORE_ROBOT_
4 #define SE2EZ_CORE_ROBOT_
5 
6 #include <map>
7 #include <unordered_map>
8 #include <vector>
9 #include <functional>
10 
11 #include <kdl/tree.hpp>
12 #include <kdl/treejnttojacsolver.hpp>
13 
15 #include <se2ez/core/math.h>
16 
17 namespace se2ez
18 {
19  /** \cond IGNORE */
20  SE2EZ_CLASS_FORWARD(Frame)
21  SE2EZ_CLASS_FORWARD(State)
23  /** \endcond */
24 
25  /** \cond IGNORE */
26  SE2EZ_CLASS_FORWARD(Robot)
27  SE2EZ_CLASS_FORWARD(FrameMap)
28  /** \endcond */
29 
30  /** \class se2ez::RobotPtr
31  \brief A shared pointer wrapper for se2ez::Robot. */
32 
33  /** \class se2ez::RobotConstPtr
34  \brief A const shared pointer wrapper for se2ez::Robot. */
35 
36  /** \brief Map of frame name to a pair of that describes if the transform is "dirty" (needs updating)
37  * and its current transform.
38  */
39  class FrameMap
40  {
41  public:
43 
44  /** \brief A tuple that stores whether a transform is dirty (needs to be updated), the transform
45  * itself, and the transforms of the geometry associated with the frame.
46  */
47  struct Value
48  {
50 
51  bool dirty{true};
52  bool jc{false};
53  Eigen::Isometry2d pose{Eigen::Isometry2d::Identity()};
54  Eigen::MatrixXd jacobian;
56  };
57 
58  /** \name Constructors
59  \{ */
60 
61  /** \brief Constructor.
62  * \param[in] robot Robot that this is a frame map for.
63  */
64  FrameMap(const Robot &robot);
65 
66  /** \brief Constructor.
67  * \param[in] robot Robot that this is a frame map for.
68  */
69  FrameMap(const RobotPtr &robot);
70 
71  // non-copyable
72  FrameMap(const FrameMap &) = delete;
73  FrameMap(FrameMap &&) = delete;
74 
75  /** \} */
76 
77  /** \brief Dirties all frames within the frame map.
78  */
79  void dirty();
80 
81  /** \name Entry Manipulation
82  \{ */
83 
84  /** \brief Inserts all entries in this frame map into another frame map.
85  * \param[out] other Other frame map to insert entries into.
86  */
87  void insert(FrameMapPtr other);
88 
89  /** \brief Gets the entry in the frame map associated with \e frame_name. Creates the entry if one
90  * does not already exist.
91  * \param[in] frame_name Name of frame to get entry for.
92  * \return Entry associated with frame.
93  */
94  Value &getEntry(const std::string &frame_name);
95 
96  /** \brief Gets the entry in the frame map associated with \e frame_name. Throws error if it does
97  * not already exist.
98  * \param[in] frame_name Name of frame to get entry for.
99  * \return Entry associated with frame.
100  */
101  const Value &getEntryConst(const std::string &frame_name) const;
102 
103  /** \} */
104 
105  /** \brief Prints out all current frame pose information. Attaches "_[ x, y, t ]" to the
106  * Robot::printTree(), where '_' is 'C' for clean, 'D' for dirty, and 'X' for uninitialized.
107  * "[ x, y, t ]" is the transform of the frame.
108  * \param[in] robot Robot that this frame map is associated with.
109  * \return Printed tree with frame information.
110  */
111  std::string printFrames(const RobotPtr &robot) const;
112 
113  private:
114  tf::EigenHash<std::string, Value> frames; ///< Map of frame name to dirty / transform pairs.
115  };
116 
117  /** \brief A representation of a robot (in this case, a kinematic tree in the plane).
118  */
119  class Robot
120  {
121  public:
123 
124  /** \cond IGNORE */
126  /** \endcond */
127 
128  /** \class se2ez::Robot::FrameDataPtr
129  \brief A shared pointer wrapper for se2ez::Robot::FrameData. */
130 
131  /** \class se2ez::Robot::FrameDataConstPtr
132  \brief A const shared pointer wrapper for se2ez::Robot::FrameData. */
133 
134  /** \brief All associated data with a frame in a kinematic tree.
135  */
136  class FrameData
137  {
138  public:
140 
141  /** \name Constructors
142  \{ */
143 
144  /** \brief Constructor for the root element.
145  */
146  FrameData();
147 
148  /** \brief Constructor for any other frame of the tree.
149  * \param[in] frame Frame to create frame data for.
150  * \param[in] parent FrameData of parent.
151  */
152  FrameData(FramePtr frame, FrameDataPtr parent);
153 
154  // non-copyable
155  FrameData(const FrameData &) = delete;
156  FrameData(FrameData &&) = delete;
157 
158  /** \} */
159 
160  /** \name Configuration Management
161  \{ */
162 
163  /** \brief Returns a reference to the underlying subvector of the configuration associated with
164  * this frame.
165  * \param[in] data Configuration to extract component from.
166  * \return Reference to subvector within configuration associated with the frame's joint values.
167  */
168  Eigen::Ref<Eigen::VectorXd> getValues(Eigen::Ref<Eigen::VectorXd> data) const;
169 
170  /** \brief Returns a reference to the underlying subvector of the configuration associated with
171  * this frame.
172  * \param[in] data Configuration to extract component from.
173  * \return Reference to subvector within configuration associated with the frame's joint values.
174  */
175  const Eigen::Ref<const Eigen::VectorXd>
176  getValuesConst(const Eigen::Ref<const Eigen::VectorXd> &data) const;
177 
178  /** \} */
179 
180  bool root{false}; ///< Is this frame the root?
181  FramePtr frame{nullptr}; ///< Underlying frame.
182  std::vector<FrameDataPtr> children{}; ///< Children of this frame.
183  FrameDataPtr parent{nullptr}; ///< Parent of this frame.
184  unsigned int depth{0}; ///< Depth of frame in tree.
185 
186  unsigned int index{0}; ///< Index within tree's configuration for the frame's joint values.
187  unsigned int size{0}; ///< Number of joint values for this frame.
188 
189  bool movable{false}; ///< True if this frame has an actuated joint before it.
190  };
191 
192  /** \name Constructors
193  \{ */
194 
195  /** \brief Constructor. Nothing interesting right now.
196  */
197  Robot();
198 
199  // non-copyable
200  Robot(const Robot &) = delete;
201  Robot(Robot &&) = delete;
202 
203  /** \} */
204 
205  /** \name Frame / Kinematic Tree Management
206  \{ */
207 
208  /** \brief Attach a frame to the root of the kinematic tree. Will detach frame if attached
209  * elsewhere already. \param[in] frame Frame to attach.
210  */
211  void attachFrame(const FramePtr &frame);
212 
213  /** \brief Attach a frame to another frame in the kinematic tree. Will detach frame if attached
214  * elsewhere already.
215  * \param[in] frame Frame to attach.
216  * \param[in] parent Parent to attach frame to (must be in tree already).
217  */
218  void attachFrame(const FramePtr &frame, const FramePtr &parent);
219 
220  /** \brief Attach a frame to another frame in the kinematic tree. Will detach frame if attached
221  * elsewhere already.
222  * \param[in] frame Frame to attach.
223  * \param[in] parent_name Name of parent to attach frame to.
224  */
225  void attachFrame(const FramePtr &frame, const std::string &parent_name);
226 
227  /** \brief Detach a frame from a kinematic tree. If frame has children all children will be detached
228  * as well.
229  * \param[in] frame Frame to detach
230  */
231  void detachFrame(const FramePtr &frame);
232 
233  /** \brief Detach a frame from a kinematic tree. If frame has children all children will be detached
234  * as well.
235  * \param[in] frame_name Frame name to detach.
236  */
237  void detachFrame(const std::string &frame_name);
238 
239  /** \brief add a fixed Robot(frames with all joints fixed) on the current robot.
240  * The frame names are namespaced under the scene_name.
241  * \param[in] frobot Robot to add as a fixed scene.
242  * \param[in] state State of the attached Scene;
243  * \param[in] scene_name std::string name of the attached scene
244  */
245  void addFixedRobot(const RobotPtr &frobot, const StatePtr &state, const std::string &scene_name);
246 
247  /** \brief adds an active Robot with all its frames and corresponding joints.
248  * \param[in] arobot Robot to add as the active one.
249  */
250  void addActiveRobot(const RobotPtr &arobot);
251 
252  /** \brief Compiles the underlying kinematic tree representation after a call to attachFrame().
253  */
254  void compileTree();
255 
256  /** \brief Completely clears internal structures, a brand new robot!
257  */
258  void clear();
259 
260  /** \} */
261 
262  /** \name Pose / Configuration Management
263  \{ */
264 
265  /** \brief Compute the forward kinematics of the robot at a state \e q.
266  * \param[in] q Configuration of the robot.
267  * \param[out] frames Forward kinematics.
268  */
269  void fk(const Eigen::Ref<const Eigen::VectorXd> &q, FrameMapPtr frames) const;
270 
271  /** \brief Gets the pose of a frame \e frame_name at a configuration \e q. Also updates all dependent
272  * frames in \e frames.
273  * \param[in] frame_name Name of frame to get pose for.
274  * \param[in] q Configuration of robot to compute pose for.
275  * \param[in] frames Workspace for computing frames. Respects dirty frame information.
276  * \return Current pose of the frame.
277  */
278  const FrameMap::Value &getPose(const std::string &frame_name,
279  const Eigen::Ref<const Eigen::VectorXd> &q, FrameMapPtr frames) const;
280 
281  /** \brief Gets the jacobian for \e frame_name at configuration \e q.
282  * \param[in] frame_name Name of frame to get jacobian for.
283  * \param[in] q Configuration of robot to compute jacobian for.
284  * \param[in] frames Workspace for computing jacobian.
285  */
286  const FrameMap::Value &getJacobian(const std::string &frame_name,
287  const Eigen::Ref<const Eigen::VectorXd> &q,
288  FrameMapPtr frames) const;
289 
290  /** \brief Returns a reference to the underlying subvector of the configuration associated with a
291  * specific frame.
292  * \param[in] frame_name Name of frame to get component of configuration for.
293  * \param[in] q Configuration to extract component from.
294  * \return Reference to subvector within configuration associated with a frame's joint values.
295  */
296  Eigen::Ref<Eigen::VectorXd> getFrameValues(const std::string &frame_name,
297  Eigen::Ref<Eigen::VectorXd> q) const;
298 
299  /** \brief Returns a reference to the underlying subvector of the configuration associated with a
300  * specific frame.
301  * \param[in] frame_name Name of frame to get component of configuration for.
302  * \param[in] q Configuration to extract component from.
303  * \return Reference to subvector within configuration associated with a frame's joint values.
304  */
305  const Eigen::Ref<const Eigen::VectorXd>
306  getFrameValuesConst(const std::string &frame_name, const Eigen::Ref<const Eigen::VectorXd> &q) const;
307 
308  /** \brief Compute the distance between two states.
309  * \param[in] a One state.
310  * \param[in] b Other state.
311  * \param[in] weighted Weight distance by inverse of depth of frame in tree.
312  * \return The distance between a and b.
313  */
314  double distance(const StatePtr &a, const StatePtr &b, bool weighted = true) const;
315 
316  /** \brief Enforce joint limits on a robot and renormalize angles if necessary.
317  * \param[in, out] a State to enforce limits on.
318  */
319  void enforceLimits(StatePtr a) const;
320 
321  /** \brief Check if all configuration parameters are within limits.
322  * \param[in] a State to check.
323  * \return True if within limits, false otherwise.
324  */
325  bool inLimits(const StatePtr &a) const;
326 
327  /** \brief Interpolate between two states.
328  * \param[in] from State you are interpolating from.
329  * \param[in] to State you are interpolating to.
330  * \param[in] t Interpolation parameter in [0, 1]. 0 is \e from, 1 is \e to.
331  * \param[out] state Interpolated state.
332  */
333  void interpolate(const StatePtr &from, const StatePtr &to, double t, StatePtr state) const;
334 
335  /** \} */
336 
337  /** \name Getters and Setters
338  \{ */
339 
340  /** \brief Gets the number of controllable joints within the tree.
341  */
342  unsigned int getNumJoints() const;
343 
344  /** \brief Gets the names of end-effectors of the tree (leaf nodes).
345  * \return Vector of all end-effectors in the tree.
346  */
347  const std::vector<std::string> &getEEs() const;
348 
349  /** \brief Get a vector of all the frame names within this robot.
350  * \return A vector of all frame names.
351  */
352  const std::vector<std::string> &getFrameNames() const;
353 
354  /** \brief Get the frame with name \e name.
355  * \param[in] name Name of the frame to get.
356  * \return Frame information.
357  */
358  FramePtr getFrame(const std::string &name);
359 
360  /** \brief Get the parent of frame with name \e name. Throws Error if name is root.
361  * \param[in] name Name of the frame to get.
362  * \return Frame information.
363  */
364  FramePtr getFrameParent(const std::string &name);
365 
366  /** \brief Get the frame with name \e name.
367  * \param[in] name Name of the frame to get.
368  * \return Frame information.
369  */
370  const FramePtr &getFrameConst(const std::string &name) const;
371 
372  /** \brief Checks if a frame \e name is in the tree.
373  * \param[in] name Frame to check.
374  * \return True if frame is in tree, false otherwise.
375  */
376  bool inTree(const std::string &name) const;
377 
378  /** \brief Retrieves kinematic tree data associated with the frame \e frame_name.
379  * \param[in] frame_name Name of frame to get data for.
380  * \return The frame data of the frame.
381  * \throws Exception if frame does not exist.
382  */
383  const FrameDataPtr &getFrameDataConst(const std::string &frame_name) const;
384 
385  /** \brief Returns the signature of the robot
386  * \return the robot signature
387  */
388  const std::string &getSignature();
389 
390  /** \brief Sets a named state.
391  * \param[in] name Name of state to set.
392  * \param[in] state State to set named state to.
393  */
394  void setNamedState(const std::string &name, const StatePtr &state);
395 
396  /** \brief Sets a named state.
397  * \param[in] named Map of named states.
398  */
399  void setNamedStates(const std::map<std::string, StatePtr> &named);
400 
401  /** \brief Gets a named state.
402  * \param[in] name Name of state to get.
403  * \param[out] state State to fill with named state.
404  */
405  void getNamedState(const std::string &name, StatePtr state);
406 
407  /** \brief Gets the names of all named states.
408  * \return List of state names.
409  */
410  std::vector<std::string> getNamedStates() const;
411 
412  /** \brief Gets the names of all named states.
413  * \return map of state names.
414  */
415  const std::map<std::string, StatePtr> &getNamedStatesMap();
416 
417  /** \brief Gets the robot's default ACM.
418  * \return The robot's ACM.
419  */
420  ACMPtr getACM();
421 
422  /** \brief Sets the robot's default ACM.
423  * \param[in] acm The ACM to set.
424  */
425  void setACM(const ACMPtr &acm);
426 
427  /** \brief Get the upper limits of the joints for this robot.
428  * \return The upper limits of the robot.
429  */
430  const Eigen::VectorXd getUpperLimits() const;
431 
432  /** \brief Get the lower limits of the joints for this robot.
433  * \return The lower limits of the robot.
434  */
435  const Eigen::VectorXd getLowerLimits() const;
436 
437  /** \brief Returns a vector of booleans. If an entry is true, that index is a continuous joint.
438  * \return Continuity of joints.
439  */
440  const std::vector<bool> getContinuity() const;
441 
442  /** \brief Get the ordered list of active joints in this robot with their associated frame
443  * information. \return The ordered list of active joints.
444  */
445  const std::vector<std::pair<std::string, FrameDataPtr>> &getJoints() const;
446 
447  /** \brief Get the underlying KDL tree for this robot.
448  * \return The KDL tree.
449  */
450  const KDL::Tree &getTree() const;
451 
452  /** \} */
453 
454  /** \name Informative
455  \{ */
456 
457  /** \brief Function used by Robot::printTree() to print additional information about frames.
458  */
460 
461  /** \brief Returns a string that graphically shows the kinematic structure of the tree. For
462  * example: \verbatim
463  * \_ root (output of function goes here)
464  * \_ base
465  * \_ link_1
466  * \_ link_2
467  * |\_ link_3
468  * | \_ e2
469  * \_ e1
470  * \endverbatim
471  * \param[in] function A function to be called for each frame, with output attached at end of
472  * tree.
473  * \return A string that represents the tree.
474  */
475  std::string printTree(const PrintHelper &function = {}) const;
476 
477  /** \brief Returns a string of complete robot information for debugging purposes.
478  * \return A string of tree information.
479  */
480  std::string printDebug() const;
481 
482  /** \} */
483 
484  private:
485  /** \name Getters / Setters
486  \{ */
487 
488  /** \brief Retrieves kinematic tree data associated with the frame \e frame_name.
489  * \param[in] frame_name Name of frame to get data for.
490  * \return The frame data of the frame. Throws exception if frame does not exist.
491  */
492  FrameDataPtr getFrameData(const std::string &frame_name);
493 
494  /** \} */
495 
496  /** \name Frame / Kinematic Tree Management
497  \{ */
498 
499  /** \brief Removes \e child from the \e parent in the tree.
500  * \param[in] parent Parent to remove child from.
501  * \param[in] child Name of child to remove.
502  * \throws Exception if child is not a child of parent.
503  */
504  void removeChild(FrameDataPtr parent, const std::string &child);
505 
506  /** \brief Updates a frame's entry in the kinematic tree with a possibly new parent \e parent_name.
507  * \param[in] frame Frame to update (will also add frame if new).
508  * \param[in] parent_name Name of parent frame in kinematic tree.
509  */
510  void updateFrame(const FramePtr &frame, const std::string &parent_name);
511 
512  /** \brief Helper function to compileTree() that recursively build tree representation.
513  * \param[in] previous Previous frame in the kinematic tree.
514  * \param[in] data Frame to add to the tree.
515  * \param[in] movable Was there a movable joint before this frame?
516  */
517  void compileTreeRecursive(const std::string &previous, FrameDataPtr &data, bool movable = false);
518 
519  /** \brief Compute the transform for all non-movable frames.
520  */
521  void staticFK();
522 
523  /** \brief Creates a unique signature (based on active joints).
524  * \return the robot signature
525  */
526  void generateSignature();
527 
528  /** \} */
529 
530  /** \name Pose / Configuration Management
531  \{ */
532 
533  /** \brief Gets the pose of a frame \e data at a configuration \e q. Also updates all dependent
534  * frames in \e frames.
535  * \param[in] data Frame data to get pose for.
536  * \param[in] q Configuration of robot to compute pose for.
537  * \param[in] frames Workspace for computing frames. Respects dirty frame information.
538  * \return Current pose of the frame.
539  */
540  const FrameMap::Value &getPose(const FrameDataPtr &data, const Eigen::Ref<const Eigen::VectorXd> &q,
541  FrameMapPtr frames) const;
542 
543  /** \} */
544 
545  /** \name Informative
546  \{ */
547 
548  /** \brief Helper function to printTree() that recursively traverses the kinematic tree.
549  * \param[in] ss Stream to output data to.
550  * \param[in] frame Frame to output data about.
551  * \param[in] function User provided function to call for each frame.
552  * \param[in] prefix Prefix to attach to frame output.
553  */
554  void printTreeRecursive(std::stringstream &ss, const FrameDataPtr &frame, const PrintHelper &function,
555  const std::string &prefix = "") const;
556 
557  /** \} */
558 
559  std::map<std::string, FrameDataPtr> data_; ///< Kinematic tree data for all frames.
560  std::vector<std::string> ees_; ///< End-effectors (leaves) in the kinematic tree that are mobile.
561  std::vector<std::string> names_; ///< Names of the the kinematic tree frames (ordered).
562 
563  std::vector<std::pair<std::string, FrameDataPtr>> joints_; ///< Ordered vector of active joints.
564  Eigen::VectorXd upper_; ///< Upper limits of joints.
565  Eigen::VectorXd lower_; ///< Lower limits of joints.
566  unsigned int maxDepth_; ///< Maximum tree depth.
567 
568  KDL::Tree tree_; ///< Underlying tree representation.
569  std::shared_ptr<KDL::TreeJntToJacSolver> jac_{nullptr}; ///< Underlying tree representation.
570  bool tree_update_{true}; ///< Does the tree need recompiling?
571 
573  std::string signature_; ///< A string that represents the current kinematic chain
574 
575  ACMPtr acm_; ///< Default robot ACM.
576  FrameMapPtr static_{nullptr}; ///< Transforms for all non-movable links.
577  };
578 } // namespace se2ez
579 
580 #endif
Eigen::VectorXd upper_
Upper limits of joints.
Definition: robot.h:564
Eigen::MatrixXd jacobian
Definition: robot.h:54
A shared pointer wrapper for se2ez::State.
All associated data with a frame in a kinematic tree.
Definition: robot.h:136
tf::EigenHash< std::string, Value > frames
Map of frame name to dirty / transform pairs.
Definition: robot.h:114
A shared pointer wrapper for se2ez::Robot::FrameData.
unsigned int maxDepth_
Maximum tree depth.
Definition: robot.h:566
A shared pointer wrapper for se2ez::Frame.
Map of frame name to a pair of that describes if the transform is "dirty" (needs updating) and its cu...
Definition: robot.h:39
A representation of a robot (in this case, a kinematic tree in the plane).
Definition: robot.h:119
KDL::Tree tree_
Underlying tree representation.
Definition: robot.h:568
std::string signature_
A string that represents the current kinematic chain.
Definition: robot.h:573
#define SE2EZ_EIGEN_CLASS
Definition: class_forward.h:14
std::vector< std::string > ees_
End-effectors (leaves) in the kinematic tree that are mobile.
Definition: robot.h:560
A tuple that stores whether a transform is dirty (needs to be updated), the transform itself...
Definition: robot.h:47
std::map< std::string, StatePtr > named_
Named states.
Definition: robot.h:572
Eigen::VectorXd lower_
Lower limits of joints.
Definition: robot.h:565
A shared pointer wrapper for se2ez::ACM.
A shared pointer wrapper for se2ez::Robot.
std::vector< std::string > names_
Names of the the kinematic tree frames (ordered).
Definition: robot.h:561
Main namespace.
Definition: collision.h:11
ACMPtr acm_
Default robot ACM.
Definition: robot.h:575
std::map< std::string, FrameDataPtr > data_
Kinematic tree data for all frames.
Definition: robot.h:559
std::vector< std::pair< std::string, FrameDataPtr > > joints_
Ordered vector of active joints.
Definition: robot.h:563
#define SE2EZ_CLASS_FORWARD(C)
Definition: class_forward.h:9