joint_group.cpp
Go to the documentation of this file.
1 
28 #include <console_bridge/console.h>
30 
32 #include <tesseract_common/utils.h>
33 
38 
40 
41 namespace tesseract_kinematics
42 {
43 JointGroup::JointGroup(std::string name,
44  std::vector<std::string> joint_names,
45  const tesseract_scene_graph::SceneGraph& scene_graph,
46  const tesseract_scene_graph::SceneState& scene_state)
47  : name_(std::move(name)), state_(scene_state), joint_names_(std::move(joint_names))
48 {
49  for (const auto& joint_name : joint_names_)
50  {
51  if (scene_graph.getJoint(joint_name) == nullptr)
52  throw std::runtime_error("Joint name '" + joint_name + "' does not exist in the provided scene graph!");
53  }
54 
56  scene_graph, joint_names_, scene_state.joints, scene_state.floating_joints);
57  state_solver_ = std::make_unique<tesseract_scene_graph::KDLStateSolver>(scene_graph, data);
58  jacobian_map_.reserve(joint_names_.size());
59  std::vector<std::string> solver_jn = state_solver_->getActiveJointNames();
60  for (const auto& joint_name : joint_names_)
61  jacobian_map_.push_back(
62  std::distance(solver_jn.begin(), std::find(solver_jn.begin(), solver_jn.end(), joint_name)));
63 
64  std::vector<std::string> active_link_names = state_solver_->getActiveLinkNames();
65  for (const auto& link : scene_graph.getLinks())
66  {
67  link_names_.push_back(link->getName());
68  auto it = std::find(active_link_names.begin(), active_link_names.end(), link->getName());
69  if (it == active_link_names.end())
70  {
71  static_link_names_.push_back(link->getName());
72  static_link_transforms_[link->getName()] = scene_state.link_transforms.at(link->getName());
73  }
74  }
75 
76  limits_.resize(static_cast<Eigen::Index>(joint_names_.size()));
77  for (Eigen::Index i = 0; i < static_cast<Eigen::Index>(joint_names_.size()); ++i)
78  {
79  auto joint = scene_graph.getJoint(joint_names_[static_cast<std::size_t>(i)]);
80 
81  // Set limits
82  limits_.joint_limits(i, 0) = joint->limits->lower;
83  limits_.joint_limits(i, 1) = joint->limits->upper;
84  limits_.velocity_limits(i, 0) = -joint->limits->velocity;
85  limits_.velocity_limits(i, 1) = joint->limits->velocity;
86  limits_.acceleration_limits(i, 0) = -joint->limits->acceleration;
87  limits_.acceleration_limits(i, 1) = joint->limits->acceleration;
88  limits_.jerk_limits(i, 0) = -joint->limits->jerk;
89  limits_.jerk_limits(i, 1) = joint->limits->jerk;
90 
91  // Set redundancy indices
92  switch (joint->type)
93  {
96  redundancy_indices_.push_back(static_cast<Eigen::Index>(i));
97  break;
98  default:
99  break;
100  }
101  }
102 
103  if (static_link_names_.size() + active_link_names.size() != scene_graph.getLinks().size())
104  throw std::runtime_error("JointGroup: Static link names are not correct!");
105 }
106 
107 JointGroup::~JointGroup() = default;
108 
109 JointGroup::JointGroup(const JointGroup& other) { *this = other; }
110 
112 {
113  name_ = other.name_;
114  state_ = other.state_;
115  state_solver_ = other.state_solver_->clone();
116  joint_names_ = other.joint_names_;
117  link_names_ = other.link_names_;
120  limits_ = other.limits_;
123  return *this;
124 }
125 
126 tesseract_common::TransformMap JointGroup::calcFwdKin(const Eigen::Ref<const Eigen::VectorXd>& joint_angles) const
127 {
128  tesseract_common::TransformMap state = state_solver_->getState(joint_names_, joint_angles).link_transforms;
129  state.insert(static_link_transforms_.begin(), static_link_transforms_.end());
130  return state;
131 }
132 
133 Eigen::MatrixXd JointGroup::calcJacobian(const Eigen::Ref<const Eigen::VectorXd>& joint_angles,
134  const std::string& link_name) const
135 {
136  Eigen::MatrixXd solver_jac = state_solver_->getJacobian(joint_names_, joint_angles, link_name);
137 
138  Eigen::MatrixXd kin_jac(6, numJoints());
139  for (Eigen::Index i = 0; i < numJoints(); ++i)
140  kin_jac.col(i) = solver_jac.col(jacobian_map_[static_cast<std::size_t>(i)]);
141 
142  return kin_jac;
143 }
144 
145 Eigen::MatrixXd JointGroup::calcJacobian(const Eigen::Ref<const Eigen::VectorXd>& joint_angles,
146  const std::string& link_name,
147  const Eigen::Vector3d& link_point) const
148 {
149  Eigen::MatrixXd kin_jac = calcJacobian(joint_angles, link_name);
150 
151  tesseract_scene_graph::SceneState state = state_solver_->getState(joint_names_, joint_angles);
152  assert(state.link_transforms.find(link_name) != state.link_transforms.end());
153 
154  const Eigen::Isometry3d& link_tf = state.link_transforms[link_name];
155 
156  tesseract_common::jacobianChangeRefPoint(kin_jac, link_tf.linear() * link_point);
157  return kin_jac;
158 }
159 
160 Eigen::MatrixXd JointGroup::calcJacobian(const Eigen::Ref<const Eigen::VectorXd>& joint_angles,
161  const std::string& base_link_name,
162  const std::string& link_name) const
163 {
164  if (base_link_name == getBaseLinkName())
165  return calcJacobian(joint_angles, link_name);
166 
167  Eigen::MatrixXd solver_jac = state_solver_->getJacobian(joint_names_, joint_angles, link_name);
168 
169  Eigen::MatrixXd kin_jac(6, numJoints());
170  for (Eigen::Index i = 0; i < numJoints(); ++i)
171  kin_jac.col(i) = solver_jac.col(jacobian_map_[static_cast<std::size_t>(i)]);
172 
173  std::vector<std::string> active_links = getActiveLinkNames();
174  if (std::find(active_links.begin(), active_links.end(), base_link_name) != active_links.end())
175  {
176  tesseract_scene_graph::SceneState state = state_solver_->getState(joint_names_, joint_angles);
177  assert(state.link_transforms.find(base_link_name) != state.link_transforms.end());
178  const Eigen::Isometry3d& base_link_tf = state.link_transforms[base_link_name];
179 
180  Eigen::MatrixXd base_link_jac = state_solver_->getJacobian(joint_names_, joint_angles, base_link_name);
181  Eigen::MatrixXd base_kin_jac(6, numJoints());
182  for (Eigen::Index i = 0; i < numJoints(); ++i)
183  base_kin_jac.col(i) = base_link_jac.col(jacobian_map_[static_cast<std::size_t>(i)]);
184 
185  tesseract_common::jacobianChangeBase(kin_jac, base_link_tf.inverse());
186  tesseract_common::jacobianChangeBase(base_kin_jac, base_link_tf.inverse());
187 
188  kin_jac = kin_jac + base_kin_jac;
189  }
190  else
191  {
192  tesseract_common::jacobianChangeBase(kin_jac, state_.link_transforms.at(base_link_name).inverse());
193  }
194 
195  return kin_jac;
196 }
197 
198 Eigen::MatrixXd JointGroup::calcJacobian(const Eigen::Ref<const Eigen::VectorXd>& joint_angles,
199  const std::string& base_link_name,
200  const std::string& link_name,
201  const Eigen::Vector3d& link_point) const
202 {
203  if (base_link_name == getBaseLinkName())
204  return calcJacobian(joint_angles, link_name, link_point);
205 
206  Eigen::MatrixXd solver_jac = state_solver_->getJacobian(joint_names_, joint_angles, link_name);
207 
208  Eigen::MatrixXd kin_jac(6, numJoints());
209  for (Eigen::Index i = 0; i < numJoints(); ++i)
210  kin_jac.col(i) = solver_jac.col(jacobian_map_[static_cast<std::size_t>(i)]);
211 
212  tesseract_scene_graph::SceneState state = state_solver_->getState(joint_names_, joint_angles);
213  assert(state.link_transforms.find(link_name) != state.link_transforms.end());
214  assert(state.link_transforms.find(base_link_name) != state.link_transforms.end());
215  const Eigen::Isometry3d& link_tf = state.link_transforms[link_name];
216  const Eigen::Isometry3d& base_link_tf = state.link_transforms[base_link_name];
217 
218  std::vector<std::string> active_links = getActiveLinkNames();
219  if (std::find(active_links.begin(), active_links.end(), base_link_name) != active_links.end())
220  {
221  Eigen::MatrixXd base_link_jac = state_solver_->getJacobian(joint_names_, joint_angles, base_link_name);
222  Eigen::MatrixXd base_kin_jac(6, numJoints());
223  for (Eigen::Index i = 0; i < numJoints(); ++i)
224  base_kin_jac.col(i) = base_link_jac.col(jacobian_map_[static_cast<std::size_t>(i)]);
225 
226  tesseract_common::jacobianChangeBase(kin_jac, base_link_tf.inverse());
227  tesseract_common::jacobianChangeRefPoint(kin_jac, (base_link_tf.inverse() * link_tf).linear() * link_point);
228 
229  tesseract_common::jacobianChangeBase(base_kin_jac, base_link_tf.inverse());
230 
231  kin_jac = kin_jac + base_kin_jac;
232  }
233  else
234  {
235  tesseract_common::jacobianChangeBase(kin_jac, base_link_tf.inverse());
236  tesseract_common::jacobianChangeRefPoint(kin_jac, (base_link_tf.inverse() * link_tf).linear() * link_point);
237  }
238 
239  return kin_jac;
240 }
241 
242 bool JointGroup::checkJoints(const Eigen::Ref<const Eigen::VectorXd>& vec) const
243 {
244  if (vec.size() != static_cast<Eigen::Index>(joint_names_.size()))
245  {
246  CONSOLE_BRIDGE_logError(
247  "Number of joint angles (%d) don't match robot_model (%d)", static_cast<int>(vec.size()), numJoints());
248  return false;
249  }
250 
251  for (int i = 0; i < vec.size(); ++i)
252  {
253  if ((vec[i] < limits_.joint_limits(i, 0)) || (vec(i) > limits_.joint_limits(i, 1)))
254  {
255  CONSOLE_BRIDGE_logDebug("Joint %s is out-of-range (%g < %g < %g)",
256  joint_names_[static_cast<size_t>(i)].c_str(),
257  limits_.joint_limits(i, 0),
258  vec(i),
259  limits_.joint_limits(i, 1));
260  return false;
261  }
262  }
263 
264  return true;
265 }
266 
267 std::vector<std::string> JointGroup::getJointNames() const { return joint_names_; }
268 
269 std::vector<std::string> JointGroup::getLinkNames() const { return link_names_; }
270 
271 std::vector<std::string> JointGroup::getActiveLinkNames() const { return state_solver_->getActiveLinkNames(); }
272 
273 std::vector<std::string> JointGroup::getStaticLinkNames() const { return static_link_names_; }
274 
275 bool JointGroup::isActiveLinkName(const std::string& link_name) const
276 {
277  return state_solver_->isActiveLinkName(link_name);
278 }
279 
280 bool JointGroup::hasLinkName(const std::string& link_name) const
281 {
282  return (std::find(link_names_.begin(), link_names_.end(), link_name) != link_names_.end());
283 }
284 
286 
288 {
289  Eigen::Index nj = numJoints();
290  if (limits.joint_limits.rows() != nj || limits.velocity_limits.rows() != nj ||
291  limits.acceleration_limits.rows() != nj || limits.jerk_limits.rows() != nj)
292  throw std::runtime_error("Kinematics Group limits assigned are invalid!");
293 
294  limits_ = limits;
295 }
296 
297 std::vector<Eigen::Index> JointGroup::getRedundancyCapableJointIndices() const { return redundancy_indices_; }
298 
299 Eigen::Index JointGroup::numJoints() const { return static_cast<Eigen::Index>(joint_names_.size()); }
300 
301 std::string JointGroup::getBaseLinkName() const { return state_solver_->getBaseLinkName(); }
302 
303 std::string JointGroup::getName() const { return name_; }
304 
305 } // namespace tesseract_kinematics
tesseract_scene_graph::JointType::REVOLUTE
@ REVOLUTE
graph.h
tesseract_scene_graph::SceneState::floating_joints
tesseract_common::TransformMap floating_joints
tesseract_kinematics::JointGroup::calcJacobian
Eigen::MatrixXd calcJacobian(const Eigen::Ref< const Eigen::VectorXd > &joint_angles, const std::string &link_name) const
Calculated jacobian of robot given joint angles.
Definition: joint_group.cpp:133
tesseract_kinematics::JointGroup::isActiveLinkName
bool isActiveLinkName(const std::string &link_name) const
Check if link is an active link.
Definition: joint_group.cpp:275
tesseract_kinematics::JointGroup::numJoints
Eigen::Index numJoints() const
Number of joints in robot.
Definition: joint_group.cpp:299
tesseract_common::KinematicLimits::resize
void resize(Eigen::Index size)
kdl_state_solver.h
tesseract_scene_graph::SceneGraph::getLinks
std::vector< std::shared_ptr< const Link > > getLinks() const
utils.h
tesseract_kinematics::JointGroup::getStaticLinkNames
std::vector< std::string > getStaticLinkNames() const
Get list of static link names (with and without geometry) for kinematic object.
Definition: joint_group.cpp:273
tesseract_common::KinematicLimits
tesseract_kinematics::JointGroup::hasLinkName
bool hasLinkName(const std::string &link_name) const
Check if link name exists.
Definition: joint_group.cpp:280
tesseract_common::TransformMap
AlignedMap< std::string, Eigen::Isometry3d > TransformMap
tesseract_common::jacobianChangeRefPoint
void jacobianChangeRefPoint(Eigen::Ref< Eigen::MatrixXd > jacobian, const Eigen::Ref< const Eigen::Vector3d > &ref_point)
tesseract_kinematics::JointGroup
A Joint Group is defined by a list of joint_names.
Definition: joint_group.h:44
joint.h
tesseract_kinematics::JointGroup::getBaseLinkName
std::string getBaseLinkName() const
Get the robot base link name.
Definition: joint_group.cpp:301
tesseract_kinematics::JointGroup::jacobian_map_
std::vector< Eigen::Index > jacobian_map_
Definition: joint_group.h:214
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
joint_group.h
A joint group with forward kinematics, Jacobian, limits methods.
tesseract_kinematics::JointGroup::state_
tesseract_scene_graph::SceneState state_
Definition: joint_group.h:206
tesseract_scene_graph::SceneGraph
tesseract_kinematics::JointGroup::static_link_names_
std::vector< std::string > static_link_names_
Definition: joint_group.h:210
tesseract_common::KinematicLimits::jerk_limits
Eigen::MatrixX2d jerk_limits
tesseract_kinematics::JointGroup::limits_
tesseract_common::KinematicLimits limits_
Definition: joint_group.h:212
tesseract_scene_graph::parseSceneGraph
KDLTreeData parseSceneGraph(const SceneGraph &scene_graph)
tesseract_kinematics::JointGroup::name_
std::string name_
Definition: joint_group.h:205
tesseract_scene_graph::SceneState
tesseract_kinematics::JointGroup::getName
std::string getName() const
Name of the manipulator.
Definition: joint_group.cpp:303
kdl_parser.h
tesseract_kinematics::JointGroup::operator=
JointGroup & operator=(const JointGroup &other)
Definition: joint_group.cpp:111
tesseract_kinematics::JointGroup::getLinkNames
std::vector< std::string > getLinkNames() const
Get list of all link names (with and without geometry) for kinematic object.
Definition: joint_group.cpp:269
tesseract_kinematics::JointGroup::static_link_transforms_
tesseract_common::TransformMap static_link_transforms_
Definition: joint_group.h:211
tesseract_kinematics::JointGroup::getJointNames
std::vector< std::string > getJointNames() const
Get list of joint names for kinematic object.
Definition: joint_group.cpp:267
tesseract_kinematics::JointGroup::state_solver_
std::unique_ptr< tesseract_scene_graph::StateSolver > state_solver_
Definition: joint_group.h:207
tesseract_kinematics::JointGroup::link_names_
std::vector< std::string > link_names_
Definition: joint_group.h:209
tesseract_scene_graph::SceneState::joints
std::unordered_map< std::string, double > joints
tesseract_kinematics::JointGroup::getActiveLinkNames
std::vector< std::string > getActiveLinkNames() const
Get list of active link names (with and without geometry) for kinematic object.
Definition: joint_group.cpp:271
tesseract_kinematics::JointGroup::JointGroup
JointGroup(const JointGroup &other)
Definition: joint_group.cpp:109
tesseract_kinematics::JointGroup::getRedundancyCapableJointIndices
std::vector< Eigen::Index > getRedundancyCapableJointIndices() const
Get vector indicating which joints are capable of producing redundant solutions.
Definition: joint_group.cpp:297
tesseract_scene_graph::KDLTreeData
tesseract_scene_graph::JointType::CONTINUOUS
@ CONTINUOUS
TESSERACT_COMMON_IGNORE_WARNINGS_POP
#define TESSERACT_COMMON_IGNORE_WARNINGS_POP
tesseract_scene_graph::SceneGraph::getJoint
std::shared_ptr< const Joint > getJoint(const std::string &name) const
tesseract_common::jacobianChangeBase
void jacobianChangeBase(Eigen::Ref< Eigen::MatrixXd > jacobian, const Eigen::Isometry3d &change_base)
tesseract_kinematics::JointGroup::checkJoints
bool checkJoints(const Eigen::Ref< const Eigen::VectorXd > &vec) const
Check for consistency in # and limits of joints.
Definition: joint_group.cpp:242
tesseract_kinematics::JointGroup::getLimits
tesseract_common::KinematicLimits getLimits() const
Get the kinematic limits (joint, velocity, acceleration, etc.)
Definition: joint_group.cpp:285
tesseract_common::KinematicLimits::acceleration_limits
Eigen::MatrixX2d acceleration_limits
tesseract_common::KinematicLimits::velocity_limits
Eigen::MatrixX2d velocity_limits
tesseract_kinematics
Definition: forward_kinematics.h:40
tesseract_kinematics::JointGroup::calcFwdKin
tesseract_common::TransformMap calcFwdKin(const Eigen::Ref< const Eigen::VectorXd > &joint_angles) const
Calculates tool pose of robot chain.
Definition: joint_group.cpp:126
tesseract_kinematics::JointGroup::joint_names_
std::vector< std::string > joint_names_
Definition: joint_group.h:208
tesseract_scene_graph::SceneState::link_transforms
tesseract_common::TransformMap link_transforms
macros.h
tesseract_common::KinematicLimits::joint_limits
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::MatrixX2d joint_limits
tesseract_kinematics::JointGroup::~JointGroup
virtual ~JointGroup()
tesseract_kinematics::JointGroup::redundancy_indices_
std::vector< Eigen::Index > redundancy_indices_
Definition: joint_group.h:213
tesseract_kinematics::JointGroup::setLimits
void setLimits(const tesseract_common::KinematicLimits &limits)
Setter for kinematic limits (joint, velocity, acceleration, etc.)
Definition: joint_group.cpp:287


tesseract_kinematics
Author(s): Levi Armstrong
autogenerated on Sun May 18 2025 03:02:14