kinematic_tree.h
Go to the documentation of this file.
1 //
2 // Copyright (c) 2018, University of Edinburgh
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without specific
15 // prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
28 //
29 
30 #ifndef EXOTICA_CORE_KINEMATIC_TREE_H_
31 #define EXOTICA_CORE_KINEMATIC_TREE_H_
32 
33 #include <map>
34 #include <random>
35 #include <string>
36 #include <vector>
37 
39 #include <tf/transform_datatypes.h>
40 #include <visualization_msgs/MarkerArray.h>
41 #include <Eigen/Eigen>
42 #include <kdl/jacobian.hpp>
43 #include <kdl/tree.hpp>
44 
46 
47 namespace exotica
48 {
50 {
51  FIXED = 0,
52  FLOATING = 10,
53  PLANAR = 20
54 };
55 
57 {
58  KIN_FK = 0,
59  KIN_J = 2,
61  KIN_H = 8
62 };
63 
65 {
68 };
69 
70 constexpr double inf = std::numeric_limits<double>::infinity();
71 constexpr double pi = M_PI;
72 
74 {
75  return static_cast<KinematicRequestFlags>(static_cast<int>(a) | static_cast<int>(b));
76 }
77 
79 {
80  return static_cast<KinematicRequestFlags>(static_cast<int>(a) & static_cast<int>(b));
81 }
82 
84 {
86  KinematicFrameRequest(std::string _frame_A_link_name, KDL::Frame _frame_A_offset = KDL::Frame(), std::string _frame_B_link_name = "", KDL::Frame _frame_B_offset = KDL::Frame());
87  std::string frame_A_link_name;
89  std::string frame_B_link_name;
91 };
92 
94 {
97  std::vector<KinematicFrameRequest> frames; // The segments to which the end-effectors are attached
98 };
99 
101 {
102  std::weak_ptr<KinematicElement> frame_A;
104  std::weak_ptr<KinematicElement> frame_B;
109 };
110 
114 {
116  KinematicResponse(KinematicRequestFlags _flags, int _size, int _N = 0);
118  std::vector<KinematicFrame> frame;
119  Eigen::VectorXd x;
124 };
125 
128 {
129 public:
131  KinematicSolution(int start, int length);
132  void Create(std::shared_ptr<KinematicResponse> solution);
133  int start = -1;
134  int length = -1;
135  Eigen::Map<Eigen::VectorXd> X{nullptr, 0};
136  Eigen::Map<ArrayFrame> Phi{nullptr, 0};
137  Eigen::Map<ArrayTwist> Phi_dot{nullptr, 0};
138  Eigen::Map<ArrayJacobian> jacobian{nullptr, 0};
139  Eigen::Map<ArrayHessian> hessian{nullptr, 0};
140 };
141 
142 class KinematicTree : public Uncopyable
143 {
144 public:
145  void Instantiate(const std::string& joint_group, robot_model::RobotModelPtr model, const std::string& name);
146  const std::string& GetRootFrameName() const;
147  const std::string& GetRootJointName() const;
148  robot_model::RobotModelPtr GetRobotModel() const;
149  BaseType GetModelBaseType() const;
150  BaseType GetControlledBaseType() const;
151  std::shared_ptr<KinematicResponse> RequestFrames(const KinematicsRequest& request);
152  void Update(Eigen::VectorXdRefConst x);
153  void ResetJointLimits();
154  const Eigen::MatrixXd& GetJointLimits() const { return joint_limits_; }
155  void SetJointLimitsLower(Eigen::VectorXdRefConst lower_in);
156  void SetJointLimitsUpper(Eigen::VectorXdRefConst upper_in);
157  void SetJointVelocityLimits(Eigen::VectorXdRefConst velocity_in);
158  void SetJointAccelerationLimits(Eigen::VectorXdRefConst acceleration_in);
159  void SetFloatingBaseLimitsPosXYZEulerZYX(const std::vector<double>& lower, const std::vector<double>& upper);
160  void SetFloatingBaseLimitsPosXYZEulerZYX(const std::vector<double>& lower, const std::vector<double>& upper, const std::vector<double>& velocity, const std::vector<double>& acceleration);
161  void SetPlanarBaseLimitsPosXYEulerZ(const std::vector<double>& lower, const std::vector<double>& upper);
162  void SetPlanarBaseLimitsPosXYEulerZ(const std::vector<double>& lower, const std::vector<double>& upper, const std::vector<double>& velocity, const std::vector<double>& acceleration);
163  std::map<std::string, std::vector<double>> GetUsedJointLimits() const;
164  const bool& HasAccelerationLimits() const { return has_acceleration_limit_; }
165  const Eigen::VectorXd& GetAccelerationLimits() const { return acceleration_limits_; }
166  const Eigen::VectorXd& GetVelocityLimits() const { return velocity_limits_; }
167  int GetNumControlledJoints() const;
168  int GetNumModelJoints() const;
169  void PublishFrames(const std::string& tf_prefix = "exotica");
170 
171  const std::vector<std::string>& GetControlledJointNames() const
172  {
173  return controlled_joints_names_;
174  }
175 
176  const std::vector<std::string>& GetControlledLinkNames() const
177  {
178  return controlled_link_names_;
179  }
180 
181  const std::vector<std::string>& GetModelJointNames() const
182  {
183  return model_joints_names_;
184  }
185 
186  const std::vector<std::string>& GetModelLinkNames() const
187  {
188  return model_link_names_;
189  }
190 
191  bool HasModelLink(const std::string& link) const;
192 
193  Eigen::VectorXd GetControlledLinkMass() const;
194 
195  KDL::Frame FK(KinematicFrame& frame) const;
196  KDL::Frame FK(std::shared_ptr<KinematicElement> element_A, const KDL::Frame& offset_a, std::shared_ptr<KinematicElement> element_B, const KDL::Frame& offset_b) const;
197  KDL::Frame FK(const std::string& element_A, const KDL::Frame& offset_a, const std::string& element_B, const KDL::Frame& offset_b) const;
198  Eigen::MatrixXd Jacobian(std::shared_ptr<KinematicElement> element_A, const KDL::Frame& offset_a, std::shared_ptr<KinematicElement> element_B, const KDL::Frame& offset_b) const;
199  Eigen::MatrixXd Jacobian(const std::string& element_A, const KDL::Frame& offset_a, const std::string& element_B, const KDL::Frame& offset_b) const;
200  exotica::Hessian Hessian(std::shared_ptr<KinematicElement> element_A, const KDL::Frame& offset_a, std::shared_ptr<KinematicElement> element_B, const KDL::Frame& offset_b) const;
201  exotica::Hessian Hessian(const std::string& element_A, const KDL::Frame& offset_a, const std::string& element_B, const KDL::Frame& offset_b) const;
202 
203  void ResetModel();
204  std::shared_ptr<KinematicElement> AddElement(const std::string& name, const Eigen::Isometry3d& transform, const std::string& parent = "", shapes::ShapeConstPtr shape = shapes::ShapeConstPtr(nullptr), const KDL::RigidBodyInertia& inertia = KDL::RigidBodyInertia::Zero(), const Eigen::Vector4d& color = Eigen::Vector4d(0.5, 0.5, 0.5, 1.0), const std::vector<VisualElement>& visual = {}, bool is_controlled = false);
205  std::shared_ptr<KinematicElement> AddEnvironmentElement(const std::string& name, const Eigen::Isometry3d& transform, const std::string& parent = "", shapes::ShapeConstPtr shape = shapes::ShapeConstPtr(nullptr), const KDL::RigidBodyInertia& inertia = KDL::RigidBodyInertia::Zero(), const Eigen::Vector4d& color = Eigen::Vector4d(0.5, 0.5, 0.5, 1.0), const std::vector<VisualElement>& visual = {}, bool is_controlled = false);
206  std::shared_ptr<KinematicElement> AddElement(const std::string& name, const Eigen::Isometry3d& transform, const std::string& parent, const std::string& shape_resource_path, Eigen::Vector3d scale = Eigen::Vector3d::Ones(), const KDL::RigidBodyInertia& inertia = KDL::RigidBodyInertia::Zero(), const Eigen::Vector4d& color = Eigen::Vector4d(0.5, 0.5, 0.5, 1.0), const std::vector<VisualElement>& visual = {}, bool is_controlled = false);
207  void UpdateModel();
208  void ChangeParent(const std::string& name, const std::string& parent, const KDL::Frame& pose, bool relative);
209  int IsControlled(std::shared_ptr<KinematicElement> joint);
210  int IsControlledLink(const std::string& link_name);
211 
212  Eigen::VectorXd GetModelState() const;
213  std::map<std::string, double> GetModelStateMap() const;
214 
219  std::vector<std::string> GetKinematicChain(const std::string& begin, const std::string& end) const;
220 
225  std::vector<std::string> GetKinematicChainLinks(const std::string& begin, const std::string& end) const;
226 
227  void SetModelState(Eigen::VectorXdRefConst x);
228  void SetModelState(const std::map<std::string, double>& x);
229  Eigen::VectorXd GetControlledState() const;
230 
231  const std::vector<std::weak_ptr<KinematicElement>>& GetTree() const { return tree_; }
232  const std::vector<std::shared_ptr<KinematicElement>>& GetModelTree() const { return model_tree_; }
233  const std::map<std::string, std::weak_ptr<KinematicElement>>& GetTreeMap() const { return tree_map_; }
234  const std::map<std::string, std::weak_ptr<KinematicElement>>& GetCollisionTreeMap() const { return collision_tree_map_; }
235  bool DoesLinkWithNameExist(std::string name) const;
236  std::shared_ptr<KinematicElement> FindKinematicElementByName(const std::string& frame_name);
237 
238  const std::vector<std::weak_ptr<KinematicElement>>& GetControlledJoints() const { return controlled_joints_; }
239  const std::map<std::string, std::weak_ptr<KinematicElement>>& GetControlledJointsMap() const { return controlled_joints_map_; }
240  const std::map<std::string, std::weak_ptr<KinematicElement>>& GetModelJointsMap() const { return model_joints_map_; }
241  std::map<std::string, shapes::ShapeType> GetCollisionObjectTypes() const;
242 
245  void SetSeed(const uint_fast32_t seed) { generator_.seed(seed); }
247  Eigen::VectorXd GetRandomControlledState();
248 
249  void SetKinematicResponse(std::shared_ptr<KinematicResponse> response_in) { solution_ = response_in; }
250  std::shared_ptr<KinematicResponse> GetKinematicResponse() { return solution_; }
251  bool debug = false;
252 
253 private:
254  void BuildTree(const KDL::Tree& RobotKinematics);
255  void AddElementFromSegmentMapIterator(KDL::SegmentMap::const_iterator segment, std::shared_ptr<KinematicElement> parent);
256  void UpdateTree();
257  void UpdateFK();
258  void UpdateJ();
259  void ComputeJ(KinematicFrame& frame, KDL::Jacobian& jacobian) const;
260  void UpdateH();
261  void ComputeH(KinematicFrame& frame, const KDL::Jacobian& jacobian, exotica::Hessian& hessian) const;
262 
263  // Joint limits
264  // TODO: Add effort limits
265  Eigen::MatrixXd joint_limits_;
266  Eigen::VectorXd velocity_limits_;
267  Eigen::VectorXd acceleration_limits_;
268  bool has_acceleration_limit_ = false;
269  void UpdateJointLimits();
270 
271  // Random state generation
272  std::random_device rd_;
273  std::mt19937 generator_;
274  std::vector<std::uniform_real_distribution<double>> random_state_distributions_;
275 
277  BaseType controlled_base_type_ = BaseType::FIXED;
280  int state_size_ = -1;
281  Eigen::VectorXd tree_state_;
282  robot_model::RobotModelPtr model_;
283  std::string root_joint_name_ = "";
284  std::vector<std::weak_ptr<KinematicElement>> tree_;
285  std::vector<std::shared_ptr<KinematicElement>> model_tree_;
286  std::vector<std::shared_ptr<KinematicElement>> environment_tree_;
287  std::map<std::string, std::weak_ptr<KinematicElement>> tree_map_;
288  std::map<std::string, std::weak_ptr<KinematicElement>> collision_tree_map_;
289  std::shared_ptr<KinematicElement> root_;
290  std::vector<std::weak_ptr<KinematicElement>> controlled_joints_;
291  std::map<std::string, std::weak_ptr<KinematicElement>> controlled_joints_map_;
292  std::map<std::string, std::weak_ptr<KinematicElement>> model_joints_map_;
293  std::vector<std::string> model_joints_names_;
294  std::vector<std::string> controlled_joints_names_;
295  std::vector<std::string> model_link_names_;
296  std::vector<std::string> controlled_link_names_;
297  std::shared_ptr<KinematicResponse> solution_ = std::make_shared<KinematicResponse>();
299 
300  std::vector<tf::StampedTransform> debug_tree_;
301  std::vector<tf::StampedTransform> debug_frames_;
305  visualization_msgs::MarkerArray marker_array_msg_;
306  std::string name_;
307 };
308 } // namespace exotica
309 
310 #endif // EXOTICA_CORE_KINEMATIC_TREE_H_
visualization_msgs::MarkerArray marker_array_msg_
const Eigen::VectorXd & GetAccelerationLimits() const
const std::vector< std::weak_ptr< KinematicElement > > & GetControlledJoints() const
std::vector< std::shared_ptr< KinematicElement > > environment_tree_
Eigen::Array< KDL::Twist, Eigen::Dynamic, 1 > ArrayTwist
Definition: conversions.h:152
std::vector< KinematicFrameRequest > frames
robot_model::RobotModelPtr model_
std::map< std::string, std::weak_ptr< KinematicElement > > tree_map_
const std::vector< std::string > & GetControlledLinkNames() const
std::weak_ptr< KinematicElement > frame_B
std::map< std::string, std::weak_ptr< KinematicElement > > collision_tree_map_
const Eigen::MatrixXd & GetJointLimits() const
std::vector< std::string > controlled_joints_names_
const std::map< std::string, std::weak_ptr< KinematicElement > > & GetControlledJointsMap() const
std::vector< std::string > model_joints_names_
std::vector< std::shared_ptr< KinematicElement > > model_tree_
ros::Publisher octomap_pub_
#define M_PI
const std::map< std::string, std::weak_ptr< KinematicElement > > & GetModelJointsMap() const
KinematicRequestFlags
void SetSeed(const uint_fast32_t seed)
SetSeed sets the seed of the random generator for deterministic joint state sampling.
std::vector< std::uniform_real_distribution< double > > random_state_distributions_
const std::vector< std::string > & GetModelLinkNames() const
std::weak_ptr< KinematicElement > frame_A
const bool & HasAccelerationLimits() const
std::map< std::string, std::weak_ptr< KinematicElement > > controlled_joints_map_
void SetKinematicResponse(std::shared_ptr< KinematicResponse > response_in)
const std::vector< std::weak_ptr< KinematicElement > > & GetTree() const
const std::map< std::string, std::weak_ptr< KinematicElement > > & GetTreeMap() const
const Eigen::VectorXd & GetVelocityLimits() const
KinematicRequestFlags flags_
constexpr double inf
std::shared_ptr< KinematicElement > root_
std::map< std::string, std::weak_ptr< KinematicElement > > model_joints_map_
Eigen::Array< Eigen::MatrixXd, Eigen::Dynamic, 1 > Hessian
Definition: conversions.h:154
constexpr double pi
The KinematicSolution is created from - and maps into - a KinematicResponse.
const std::map< std::string, std::weak_ptr< KinematicElement > > & GetCollisionTreeMap() const
const std::vector< std::string > & GetModelJointNames() const
Eigen::MatrixXd joint_limits_
Eigen::Array< Eigen::Array< Eigen::MatrixXd, Eigen::Dynamic, 1 >, Eigen::Dynamic, 1 > ArrayHessian
Definition: conversions.h:155
const std::vector< std::shared_ptr< KinematicElement > > & GetModelTree() const
Eigen::VectorXd acceleration_limits_
std::vector< std::weak_ptr< KinematicElement > > controlled_joints_
std::shared_ptr< KinematicResponse > GetKinematicResponse()
static RigidBodyInertia Zero()
std::random_device rd_
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
Convenience wrapper for storing references to sub-matrices/vectors.
Definition: conversions.h:52
std::vector< std::string > controlled_link_names_
const std::vector< std::string > & GetControlledJointNames() const
Eigen::Array< KDL::Jacobian, Eigen::Dynamic, 1 > ArrayJacobian
Definition: conversions.h:153
std::vector< KinematicFrame > frame
Eigen::VectorXd velocity_limits_
KinematicRequestFlags operator&(KinematicRequestFlags a, KinematicRequestFlags b)
KinematicRequestFlags operator|(KinematicRequestFlags a, KinematicRequestFlags b)
Eigen::VectorXd tree_state_
The KinematicResponse is the container to keep kinematic update data. The corresponding KinematicSolu...
int num_joints_
Number of joints of the model (including floating/planar base, passive joints, and uncontrolled joint...
std::vector< std::weak_ptr< KinematicElement > > tree_
double x
ros::Publisher shapes_pub_
Eigen::Array< KDL::Frame, Eigen::Dynamic, 1 > ArrayFrame
Definition: conversions.h:151
std::vector< tf::StampedTransform > debug_frames_
std::vector< tf::StampedTransform > debug_tree_
int num_controlled_joints_
Number of controlled joints in the joint group.
std::vector< std::string > model_link_names_
std::shared_ptr< const Shape > ShapeConstPtr


exotica_core
Author(s): Yiming Yang, Michael Camilleri
autogenerated on Sat Apr 10 2021 02:34:49