rop_inv_kin.cpp
Go to the documentation of this file.
1 
32 
33 namespace tesseract_kinematics
34 {
35 using Eigen::MatrixXd;
36 using Eigen::VectorXd;
37 
39  const tesseract_scene_graph::SceneState& scene_state,
40  InverseKinematics::UPtr manipulator,
41  double manipulator_reach,
42  std::unique_ptr<ForwardKinematics> positioner,
43  const Eigen::VectorXd& positioner_sample_resolution,
44  std::string solver_name)
45 {
46  if (positioner == nullptr)
47  throw std::runtime_error("Provided positioner is a nullptr");
48 
49  if (!scene_graph.getLink(scene_graph.getRoot()))
50  throw std::runtime_error("The scene graph has an invalid root.");
51 
52  std::vector<std::string> joint_names = positioner->getJointNames();
53  auto s = static_cast<Eigen::Index>(joint_names.size());
54  Eigen::MatrixX2d positioner_limits;
55  positioner_limits.resize(s, 2);
56  for (Eigen::Index i = 0; i < s; ++i)
57  {
58  auto joint = scene_graph.getJoint(joint_names[static_cast<std::size_t>(i)]);
59  positioner_limits(i, 0) = joint->limits->lower;
60  positioner_limits(i, 1) = joint->limits->upper;
61  }
62 
63  init(scene_graph,
64  scene_state,
65  std::move(manipulator),
66  manipulator_reach,
67  std::move(positioner),
68  positioner_limits,
69  positioner_sample_resolution,
70  std::move(solver_name));
71 }
72 
74  const tesseract_scene_graph::SceneState& scene_state,
75  InverseKinematics::UPtr manipulator,
76  double manipulator_reach,
77  std::unique_ptr<ForwardKinematics> positioner,
78  const Eigen::MatrixX2d& positioner_sample_range,
79  const Eigen::VectorXd& positioner_sample_resolution,
80  std::string solver_name)
81 {
82  init(scene_graph,
83  scene_state,
84  std::move(manipulator),
85  manipulator_reach,
86  std::move(positioner),
87  positioner_sample_range,
88  positioner_sample_resolution,
89  std::move(solver_name));
90 }
91 
93  const tesseract_scene_graph::SceneState& scene_state,
94  InverseKinematics::UPtr manipulator,
95  double manipulator_reach,
96  std::unique_ptr<ForwardKinematics> positioner,
97  const Eigen::MatrixX2d& poitioner_sample_range,
98  const Eigen::VectorXd& positioner_sample_resolution,
99  std::string solver_name)
100 {
101  if (solver_name.empty())
102  throw std::runtime_error("Solver name must not be empty.");
103 
104  if (!scene_graph.getLink(scene_graph.getRoot()))
105  throw std::runtime_error("The scene graph has an invalid root.");
106 
107  if (manipulator == nullptr)
108  throw std::runtime_error("Provided manipulator is a nullptr");
109 
110  if (!(manipulator_reach > 0))
111  throw std::runtime_error("Manipulator reach is not greater than zero");
112 
113  if (positioner == nullptr)
114  throw std::runtime_error("Provided positioner is a nullptr");
115 
116  if (positioner_sample_resolution.size() != positioner->numJoints())
117  throw std::runtime_error("Positioner sample resolution must be same size as positioner number of joints");
118 
119  for (long i = 0; i < positioner_sample_resolution.size(); ++i)
120  {
121  if (!(positioner_sample_resolution(i) > 0))
122  throw std::runtime_error("Positioner sample resolution is not greater than zero");
123  }
124 
125  // Check if the manipulator base link is the child of the positioner tip link.
126  if (positioner->getTipLinkNames()[0] != manipulator->getBaseLinkName())
127  {
128  positioner_to_robot_ = scene_state.link_transforms.at(positioner->getTipLinkNames()[0]).inverse() *
129  scene_state.link_transforms.at(manipulator->getBaseLinkName());
130  }
131 
132  solver_name_ = std::move(solver_name);
133  manip_inv_kin_ = std::move(manipulator);
134  positioner_fwd_kin_ = std::move(positioner);
135  manip_tip_link_ = manip_inv_kin_->getTipLinkNames()[0];
136  positioner_tip_link_ = positioner_fwd_kin_->getTipLinkNames()[0];
137  manip_reach_ = manipulator_reach;
138  dof_ = positioner_fwd_kin_->numJoints() + manip_inv_kin_->numJoints();
139 
140  joint_names_ = positioner_fwd_kin_->getJointNames();
141  const auto& manip_joints = manip_inv_kin_->getJointNames();
142  joint_names_.insert(joint_names_.end(), manip_joints.begin(), manip_joints.end());
143 
144  // For the kinematics object to be sampled we need to create the joint values at the sampling resolution
145  // The sampled joints results are stored in dof_range[joint index] to be used by the nested_ik function
146  auto positioner_num_joints = static_cast<int>(positioner_fwd_kin_->numJoints());
147  dof_range_.reserve(static_cast<std::size_t>(positioner_num_joints));
148  for (int d = 0; d < positioner_num_joints; ++d)
149  {
150  // given the sampling resolution for the joint calculate the number of samples such that the resolution is not
151  // exceeded.
152  int cnt = static_cast<int>(std::ceil(std::abs(poitioner_sample_range(d, 1) - poitioner_sample_range(d, 0)) /
153  positioner_sample_resolution(d))) +
154  1;
155  dof_range_.emplace_back(
156  Eigen::VectorXd::LinSpaced(cnt, poitioner_sample_range(d, 0), poitioner_sample_range(d, 1)));
157  }
158 }
159 
160 InverseKinematics::UPtr ROPInvKin::clone() const { return std::make_unique<ROPInvKin>(*this); }
161 
162 ROPInvKin::ROPInvKin(const ROPInvKin& other) { *this = other; }
163 
165 {
166  manip_inv_kin_ = other.manip_inv_kin_->clone();
167  positioner_fwd_kin_ = other.positioner_fwd_kin_->clone();
170  manip_reach_ = other.manip_reach_;
171  joint_names_ = other.joint_names_;
172  dof_ = other.dof_;
173  dof_range_ = other.dof_range_;
174 
175  return *this;
176 }
177 
179  const Eigen::Ref<const Eigen::VectorXd>& seed) const
180 {
181  Eigen::VectorXd positioner_pose(positioner_fwd_kin_->numJoints());
182  IKSolutions solutions;
183  nested_ik(solutions, 0, dof_range_, tip_link_poses, positioner_pose, seed);
184  return solutions;
185 }
186 
188  int loop_level,
189  const std::vector<Eigen::VectorXd>& dof_range,
190  const tesseract_common::TransformMap& tip_link_poses,
191  Eigen::VectorXd& positioner_pose,
192  const Eigen::Ref<const Eigen::VectorXd>& seed) const
193 {
194  if (loop_level >= positioner_fwd_kin_->numJoints())
195  {
196  ikAt(solutions, tip_link_poses, positioner_pose, seed);
197  return;
198  }
199 
200  for (long i = 0; i < static_cast<long>(dof_range[static_cast<std::size_t>(loop_level)].size()); ++i)
201  {
202  positioner_pose(loop_level) = dof_range[static_cast<std::size_t>(loop_level)][i];
203  nested_ik(solutions, loop_level + 1, dof_range, tip_link_poses, positioner_pose, seed);
204  }
205 }
206 
207 void ROPInvKin::ikAt(IKSolutions& solutions,
208  const tesseract_common::TransformMap& tip_link_poses,
209  Eigen::VectorXd& positioner_pose,
210  const Eigen::Ref<const Eigen::VectorXd>& seed) const
211 {
212  tesseract_common::TransformMap positioner_poses = positioner_fwd_kin_->calcFwdKin(positioner_pose);
213  Eigen::Isometry3d positioner_tf = positioner_poses[positioner_tip_link_] * positioner_to_robot_;
214  Eigen::Isometry3d robot_target_pose = positioner_tf.inverse() * tip_link_poses.at(manip_tip_link_);
215  if (robot_target_pose.translation().norm() > manip_reach_)
216  return;
217 
218  tesseract_common::TransformMap robot_target_poses{ std::make_pair(manip_tip_link_, robot_target_pose) };
219  auto robot_dof = static_cast<Eigen::Index>(manip_inv_kin_->numJoints());
220  auto positioner_dof = static_cast<Eigen::Index>(positioner_pose.size());
221 
222  IKSolutions robot_solution_set = manip_inv_kin_->calcInvKin(robot_target_poses, seed.tail(robot_dof));
223  if (robot_solution_set.empty())
224  return;
225 
226  for (const auto& robot_solution : robot_solution_set)
227  {
228  Eigen::VectorXd full_sol;
229  full_sol.resize(positioner_dof + robot_dof);
230  full_sol.head(positioner_dof) = positioner_pose;
231  full_sol.tail(robot_dof) = robot_solution;
232 
233  solutions.push_back(full_sol);
234  }
235 }
236 
238  const Eigen::Ref<const Eigen::VectorXd>& seed) const
239 {
240  assert(tip_link_poses.find(manip_tip_link_) != tip_link_poses.end()); // NOLINT
241  assert(std::abs(1.0 - tip_link_poses.at(manip_tip_link_).matrix().determinant()) < 1e-6); // NOLINT
242 
243  return calcInvKinHelper(tip_link_poses, seed); // NOLINT
244 }
245 
246 std::vector<std::string> ROPInvKin::getJointNames() const { return joint_names_; }
247 
248 Eigen::Index ROPInvKin::numJoints() const { return dof_; }
249 
250 std::string ROPInvKin::getBaseLinkName() const { return positioner_fwd_kin_->getBaseLinkName(); }
251 
252 std::string ROPInvKin::getWorkingFrame() const { return positioner_fwd_kin_->getBaseLinkName(); }
253 
254 std::vector<std::string> ROPInvKin::getTipLinkNames() const { return manip_inv_kin_->getTipLinkNames(); }
255 
256 std::string ROPInvKin::getSolverName() const { return solver_name_; }
257 
258 } // namespace tesseract_kinematics
tesseract_kinematics::ROPInvKin::manip_inv_kin_
InverseKinematics::UPtr manip_inv_kin_
Definition: rop_inv_kin.h:119
graph.h
tesseract_kinematics::ROPInvKin::manip_tip_link_
std::string manip_tip_link_
Definition: rop_inv_kin.h:121
tesseract_kinematics::ROPInvKin::positioner_tip_link_
std::string positioner_tip_link_
Definition: rop_inv_kin.h:122
tesseract_kinematics::ROPInvKin::dof_range_
std::vector< Eigen::VectorXd > dof_range_
Definition: rop_inv_kin.h:126
tesseract_kinematics::ROPInvKin::getSolverName
std::string getSolverName() const override final
Get the name of the solver. Recommend using the name of the class.
Definition: rop_inv_kin.cpp:256
tesseract_kinematics::ROPInvKin::calcInvKinHelper
IKSolutions calcInvKinHelper(const tesseract_common::TransformMap &tip_link_poses, const Eigen::Ref< const Eigen::VectorXd > &seed) const
calcFwdKin helper function
Definition: rop_inv_kin.cpp:178
tesseract_kinematics::ROPInvKin::getBaseLinkName
std::string getBaseLinkName() const override final
Get the robot base link name.
Definition: rop_inv_kin.cpp:250
tesseract_kinematics::ROPInvKin::manip_reach_
double manip_reach_
Definition: rop_inv_kin.h:123
tesseract_common::TransformMap
AlignedMap< std::string, Eigen::Isometry3d > TransformMap
joint.h
tesseract_kinematics::ROPInvKin::positioner_to_robot_
Eigen::Isometry3d positioner_to_robot_
Definition: rop_inv_kin.h:125
tesseract_scene_graph::SceneGraph
tesseract_kinematics::InverseKinematics::UPtr
std::unique_ptr< InverseKinematics > UPtr
Definition: inverse_kinematics.h:52
tesseract_scene_graph::SceneState
tesseract_kinematics::ROPInvKin::joint_names_
std::vector< std::string > joint_names_
Definition: rop_inv_kin.h:118
tesseract_kinematics::ROPInvKin::ikAt
void ikAt(IKSolutions &solutions, const tesseract_common::TransformMap &tip_link_poses, Eigen::VectorXd &positioner_pose, const Eigen::Ref< const Eigen::VectorXd > &seed) const
Definition: rop_inv_kin.cpp:207
tesseract_kinematics::ROPInvKin::clone
InverseKinematics::UPtr clone() const override final
Clone the forward kinematics object.
Definition: rop_inv_kin.cpp:160
tesseract_kinematics::ROPInvKin::numJoints
Eigen::Index numJoints() const override final
Number of joints in robot.
Definition: rop_inv_kin.cpp:248
tesseract_kinematics::ROPInvKin::dof_
Eigen::Index dof_
Definition: rop_inv_kin.h:124
tesseract_kinematics::ROPInvKin::getWorkingFrame
std::string getWorkingFrame() const override final
Get the inverse kinematics working frame.
Definition: rop_inv_kin.cpp:252
tesseract_kinematics::ROPInvKin::getTipLinkNames
std::vector< std::string > getTipLinkNames() const override final
Get the names of the tip links of the kinematics group.
Definition: rop_inv_kin.cpp:254
tesseract_kinematics::ROPInvKin::ROPInvKin
ROPInvKin(const ROPInvKin &other)
Definition: rop_inv_kin.cpp:162
tesseract_kinematics::ROPInvKin::solver_name_
std::string solver_name_
Name of this solver.
Definition: rop_inv_kin.h:127
tesseract_kinematics::ROPInvKin::nested_ik
void nested_ik(IKSolutions &solutions, int loop_level, const std::vector< Eigen::VectorXd > &dof_range, const tesseract_common::TransformMap &tip_link_poses, Eigen::VectorXd &positioner_pose, const Eigen::Ref< const Eigen::VectorXd > &seed) const
Definition: rop_inv_kin.cpp:187
forward_kinematics.h
Forward kinematics functions.
tesseract_kinematics::ROPInvKin::positioner_fwd_kin_
std::unique_ptr< ForwardKinematics > positioner_fwd_kin_
Definition: rop_inv_kin.h:120
scene_state.h
tesseract_scene_graph::SceneGraph::getRoot
const std::string & getRoot() const
tesseract_scene_graph::SceneGraph::getJoint
std::shared_ptr< const Joint > getJoint(const std::string &name) const
tesseract_kinematics
Definition: forward_kinematics.h:40
tesseract_kinematics::ROPInvKin::getJointNames
std::vector< std::string > getJointNames() const override final
Get list of joint names for kinematic object.
Definition: rop_inv_kin.cpp:246
tesseract_scene_graph::SceneGraph::getLink
std::shared_ptr< const Link > getLink(const std::string &name) const
tesseract_kinematics::ROPInvKin::init
void init(const tesseract_scene_graph::SceneGraph &scene_graph, const tesseract_scene_graph::SceneState &scene_state, InverseKinematics::UPtr manipulator, double manipulator_reach, std::unique_ptr< ForwardKinematics > positioner, const Eigen::MatrixX2d &poitioner_sample_range, const Eigen::VectorXd &positioner_sample_resolution, std::string solver_name=DEFAULT_ROP_INV_KIN_SOLVER_NAME)
Definition: rop_inv_kin.cpp:92
tesseract_kinematics::ROPInvKin::calcInvKin
IKSolutions calcInvKin(const tesseract_common::TransformMap &tip_link_poses, const Eigen::Ref< const Eigen::VectorXd > &seed) const override final
Calculates joint solutions given a pose for each tip link.
Definition: rop_inv_kin.cpp:237
tesseract_scene_graph::SceneState::link_transforms
tesseract_common::TransformMap link_transforms
tesseract_kinematics::IKSolutions
std::vector< Eigen::VectorXd > IKSolutions
The inverse kinematics solutions container.
Definition: types.h:38
rop_inv_kin.h
tesseract_kinematics::ROPInvKin
Robot on Positioner Inverse kinematic implementation.
Definition: rop_inv_kin.h:46
tesseract_kinematics::ROPInvKin::operator=
ROPInvKin & operator=(const ROPInvKin &other)
Definition: rop_inv_kin.cpp:164


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