moveit2
The MoveIt Motion Planning Framework for ROS 2.
utils.cpp
Go to the documentation of this file.
1 // Copyright 2024 Intrinsic Innovation LLC.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
20 #include <sstream>
21 #include <string>
22 #include <vector>
23 
26 #include <moveit_msgs/msg/robot_state.hpp>
27 #include <moveit_msgs/msg/robot_trajectory.hpp>
28 #include <moveit_msgs/msg/constraints.hpp>
29 #include <moveit_msgs/srv/get_cartesian_path.hpp>
30 
31 #include <tf2_ros/buffer.h>
32 
33 #include <warehouse_ros/message_collection.h>
34 
36 
37 namespace
38 {
39 
40 rclcpp::Logger getLogger()
41 {
42  return moveit::getLogger("moveit.ros.trajectory_cache.features");
43 }
44 
45 } // namespace
46 
47 // Frames. =========================================================================================
48 
49 namespace moveit_ros
50 {
51 namespace trajectory_cache
52 {
53 
54 using ::warehouse_ros::Metadata;
55 using ::warehouse_ros::Query;
56 
57 using ::moveit::core::MoveItErrorCode;
58 using ::moveit::planning_interface::MoveGroupInterface;
59 
60 using ::moveit_msgs::srv::GetCartesianPath;
61 
62 std::string getWorkspaceFrameId(const MoveGroupInterface& move_group,
63  const moveit_msgs::msg::WorkspaceParameters& workspace_parameters)
64 {
65  if (workspace_parameters.header.frame_id.empty())
66  {
67  return move_group.getRobotModel()->getModelFrame();
68  }
69  else
70  {
71  return workspace_parameters.header.frame_id;
72  }
73 }
74 
75 std::string getCartesianPathRequestFrameId(const MoveGroupInterface& move_group,
76  const GetCartesianPath::Request& path_request)
77 {
78  if (path_request.header.frame_id.empty())
79  {
80  return move_group.getPoseReferenceFrame();
81  }
82  else
83  {
84  return path_request.header.frame_id;
85  }
86 }
87 
88 MoveItErrorCode restateInNewFrame(const std::shared_ptr<tf2_ros::Buffer>& tf, const std::string& target_frame,
89  const std::string& source_frame, geometry_msgs::msg::Point* translation,
90  geometry_msgs::msg::Quaternion* rotation, const tf2::TimePoint& lookup_time)
91 {
92  if (target_frame == source_frame)
93  {
94  return MoveItErrorCode::SUCCESS;
95  }
96  if (translation == nullptr && rotation == nullptr)
97  {
98  return MoveItErrorCode::SUCCESS;
99  }
100 
101  // Fetch transforms.
102  geometry_msgs::msg::TransformStamped transform;
103  try
104  {
105  transform = tf->lookupTransform(target_frame, source_frame, lookup_time);
106  }
107  catch (tf2::TransformException& ex)
108  {
109  std::stringstream ss;
110  ss << "Could not get transform for " << source_frame << " to " << target_frame << ": " << ex.what();
111  return moveit::core::MoveItErrorCode(moveit_msgs::msg::MoveItErrorCodes::FRAME_TRANSFORM_FAILURE, ss.str());
112  }
113 
114  // Translation.
115  if (translation != nullptr)
116  {
117  translation->x += transform.transform.translation.x;
118  translation->y += transform.transform.translation.y;
119  translation->z += transform.transform.translation.z;
120  }
121 
122  // Rotation.
123  if (rotation != nullptr)
124  {
125  tf2::Quaternion input_quat(rotation->x, rotation->y, rotation->z, rotation->w);
126  tf2::Quaternion transform_quat(transform.transform.rotation.x, transform.transform.rotation.y,
127  transform.transform.rotation.z, transform.transform.rotation.w);
128 
129  input_quat.normalize();
130  transform_quat.normalize();
131 
132  auto final_quat = input_quat * transform_quat;
133  final_quat.normalize();
134 
135  rotation->x = final_quat.getX();
136  rotation->y = final_quat.getY();
137  rotation->z = final_quat.getZ();
138  rotation->w = final_quat.getW();
139  }
140 
141  return moveit::core::MoveItErrorCode::SUCCESS;
142 }
143 
144 // Execution Time. =================================================================================
145 
146 double getExecutionTime(const moveit_msgs::msg::RobotTrajectory& trajectory)
147 {
148  return rclcpp::Duration(trajectory.joint_trajectory.points.back().time_from_start).seconds();
149 }
150 
151 // Request Construction. ===========================================================================
152 
153 GetCartesianPath::Request constructGetCartesianPathRequest(MoveGroupInterface& move_group,
154  const std::vector<geometry_msgs::msg::Pose>& waypoints,
155  double max_step, double jump_threshold,
156  bool avoid_collisions)
157 {
158  GetCartesianPath::Request out;
159 
160  move_group.constructRobotState(out.start_state);
161 
162  out.group_name = move_group.getName();
163  out.max_velocity_scaling_factor = move_group.getMaxVelocityScalingFactor();
164  out.max_acceleration_scaling_factor = move_group.getMaxVelocityScalingFactor();
165 
166  out.header.frame_id = move_group.getPoseReferenceFrame();
167  out.waypoints = waypoints;
168  out.max_step = max_step;
169  out.jump_threshold = jump_threshold;
170  out.path_constraints = moveit_msgs::msg::Constraints();
171  out.avoid_collisions = avoid_collisions;
172  out.link_name = move_group.getEndEffectorLink();
173  out.header.stamp = move_group.getNode()->now();
174 
175  return out;
176 }
177 
178 // Queries. ========================================================================================
179 
180 void queryAppendCenterWithTolerance(Query& query, const std::string& name, double center, double tolerance)
181 {
182  query.appendRangeInclusive(name, center - tolerance / 2, center + tolerance / 2);
183 }
184 
185 // Constraints. ====================================================================================
186 
187 void sortJointConstraints(std::vector<moveit_msgs::msg::JointConstraint>& joint_constraints)
188 {
189  std::sort(joint_constraints.begin(), joint_constraints.end(),
190  [](const moveit_msgs::msg::JointConstraint& l, const moveit_msgs::msg::JointConstraint& r) {
191  return l.joint_name < r.joint_name;
192  });
193 }
194 
195 void sortPositionConstraints(std::vector<moveit_msgs::msg::PositionConstraint>& position_constraints)
196 {
197  std::sort(position_constraints.begin(), position_constraints.end(),
198  [](const moveit_msgs::msg::PositionConstraint& l, const moveit_msgs::msg::PositionConstraint& r) {
199  return l.link_name < r.link_name;
200  });
201 }
202 
203 void sortOrientationConstraints(std::vector<moveit_msgs::msg::OrientationConstraint>& orientation_constraints)
204 {
205  std::sort(orientation_constraints.begin(), orientation_constraints.end(),
206  [](const moveit_msgs::msg::OrientationConstraint& l, const moveit_msgs::msg::OrientationConstraint& r) {
207  return l.link_name < r.link_name;
208  });
209 }
210 
212 appendConstraintsAsFetchQueryWithTolerance(Query& query, std::vector<moveit_msgs::msg::Constraints> constraints,
213  const MoveGroupInterface& move_group, double match_tolerance,
214  const std::string& reference_frame_id, const std::string& prefix)
215 {
216  const std::shared_ptr<tf2_ros::Buffer> tf_buffer = move_group.getTF(); // NOLINT: Deliberate lifetime extension.
217 
218  // Make ignored members explicit.
219 
220  bool emit_position_constraint_warning = false;
221  for (const auto& constraint : constraints)
222  {
223  for (const auto& position_constraint : constraint.position_constraints)
224  {
225  if (!position_constraint.constraint_region.primitives.empty())
226  {
227  emit_position_constraint_warning = true;
228  break;
229  }
230  }
231  if (emit_position_constraint_warning)
232  {
233  break;
234  }
235  }
236  if (emit_position_constraint_warning)
237  {
238  RCLCPP_WARN_STREAM(getLogger(), "Ignoring " << prefix << ".position_constraints.constraint_region: Not supported.");
239  }
240 
241  bool emit_visibility_constraint_warning = false;
242  for (const auto& constraint : constraints)
243  {
244  if (!constraint.visibility_constraints.empty())
245  {
246  emit_visibility_constraint_warning = true;
247  break;
248  }
249  }
250  if (emit_visibility_constraint_warning)
251  {
252  RCLCPP_WARN_STREAM(getLogger(), "Ignoring " << prefix << ".visibility_constraints: Not supported.");
253  }
254 
255  // Begin extraction.
256 
257  size_t constraint_idx = 0;
258  for (auto& constraint : constraints) // Non-const as constraints are sorted in-place.
259  {
260  // We sort to avoid cardinality.
261  sortJointConstraints(constraint.joint_constraints);
262  sortPositionConstraints(constraint.position_constraints);
263  sortOrientationConstraints(constraint.orientation_constraints);
264 
265  std::string constraint_prefix = prefix + "_" + std::to_string(constraint_idx++);
266 
267  // Joint constraints
268  size_t joint_idx = 0;
269  for (const auto& joint_constraint : constraint.joint_constraints)
270  {
271  std::string query_name = constraint_prefix + ".joint_constraints_" + std::to_string(joint_idx++);
272  query.append(query_name + ".joint_name", joint_constraint.joint_name);
273  queryAppendCenterWithTolerance(query, query_name + ".position", joint_constraint.position, match_tolerance);
274  query.appendGTE(query_name + ".tolerance_above", joint_constraint.tolerance_above);
275  query.appendLTE(query_name + ".tolerance_below", joint_constraint.tolerance_below);
276  }
277 
278  // Position constraints
279  if (!constraint.position_constraints.empty())
280  {
281  // All offsets will be "frozen" and computed wrt. the workspace frame instead.
282  query.append(constraint_prefix + ".position_constraints.header.frame_id", reference_frame_id);
283 
284  size_t position_idx = 0;
285  for (const auto& position_constraint : constraint.position_constraints)
286  {
287  std::string query_name = constraint_prefix + ".position_constraints_" + std::to_string(position_idx++);
288 
289  geometry_msgs::msg::Point canonical_position;
290  canonical_position.x = position_constraint.target_point_offset.x;
291  canonical_position.y = position_constraint.target_point_offset.y;
292  canonical_position.z = position_constraint.target_point_offset.z;
293 
294  // Canonicalize to robot base frame if necessary.
295  if (position_constraint.header.frame_id != reference_frame_id)
296  {
297  if (MoveItErrorCode status =
298  restateInNewFrame(move_group.getTF(), position_constraint.header.frame_id, reference_frame_id,
299  &canonical_position, /*rotation=*/nullptr, tf2::TimePointZero);
300  status != MoveItErrorCode::SUCCESS)
301  {
302  // NOTE: methyldragon -
303  // Ideally we would restore the original state here and undo our changes, however copy of the query is not
304  // supported.
305  std::stringstream ss;
306  ss << "Skipping " << prefix << ":" << query_name << " query append: " << status.message;
307  return MoveItErrorCode(status.val, status.message);
308  }
309  }
310 
311  query.append(query_name + ".link_name", position_constraint.link_name);
312  queryAppendCenterWithTolerance(query, query_name + ".target_point_offset.x", canonical_position.x,
313  match_tolerance);
314  queryAppendCenterWithTolerance(query, query_name + ".target_point_offset.y", canonical_position.y,
315  match_tolerance);
316  queryAppendCenterWithTolerance(query, query_name + ".target_point_offset.z", canonical_position.z,
317  match_tolerance);
318  }
319  }
320 
321  // Orientation constraints
322  if (!constraint.orientation_constraints.empty())
323  {
324  // All offsets will be "frozen" and computed wrt. the workspace frame instead.
325  query.append(constraint_prefix + ".orientation_constraints.header.frame_id", reference_frame_id);
326 
327  size_t ori_idx = 0;
328  for (const auto& orientation_constraint : constraint.orientation_constraints)
329  {
330  std::string query_name = constraint_prefix + ".orientation_constraints_" + std::to_string(ori_idx++);
331  geometry_msgs::msg::Quaternion canonical_orientation = orientation_constraint.orientation;
332 
333  // Canonicalize to robot base frame if necessary.
334  if (orientation_constraint.header.frame_id != reference_frame_id)
335  {
336  if (MoveItErrorCode status =
337  restateInNewFrame(move_group.getTF(), orientation_constraint.header.frame_id, reference_frame_id,
338  /*translation=*/nullptr, &canonical_orientation, tf2::TimePointZero);
339  status != MoveItErrorCode::SUCCESS)
340  {
341  // NOTE: methyldragon -
342  // Ideally we would restore the original state here and undo our changes, however copy of the query is not
343  // supported.
344  std::stringstream ss;
345  ss << "Skipping " << prefix << ":" << query_name << " query append: " << status.message;
346  return MoveItErrorCode(status.val, status.message);
347  }
348  }
349 
350  query.append(query_name + ".link_name", orientation_constraint.link_name);
351  queryAppendCenterWithTolerance(query, query_name + ".orientation.x", canonical_orientation.x, match_tolerance);
352  queryAppendCenterWithTolerance(query, query_name + ".orientation.y", canonical_orientation.y, match_tolerance);
353  queryAppendCenterWithTolerance(query, query_name + ".orientation.z", canonical_orientation.z, match_tolerance);
354  queryAppendCenterWithTolerance(query, query_name + ".orientation.w", canonical_orientation.w, match_tolerance);
355  }
356  }
357  }
358 
359  return moveit::core::MoveItErrorCode::SUCCESS;
360 }
361 
363  std::vector<moveit_msgs::msg::Constraints> constraints,
364  const MoveGroupInterface& move_group,
365  const std::string& workspace_frame_id,
366  const std::string& prefix)
367 {
368  const std::shared_ptr<tf2_ros::Buffer> tf_buffer = move_group.getTF(); // NOLINT: Deliberate lifetime extension.
369 
370  // Make ignored members explicit
371 
372  bool emit_position_constraint_warning = false;
373  for (const auto& constraint : constraints)
374  {
375  for (const auto& position_constraint : constraint.position_constraints)
376  {
377  if (!position_constraint.constraint_region.primitives.empty())
378  {
379  emit_position_constraint_warning = true;
380  break;
381  }
382  }
383  if (emit_position_constraint_warning)
384  {
385  break;
386  }
387  }
388  if (emit_position_constraint_warning)
389  {
390  RCLCPP_WARN_STREAM(getLogger(), "Ignoring " << prefix << ".position_constraints.constraint_region: Not supported.");
391  }
392 
393  bool emit_visibility_constraint_warning = false;
394  for (const auto& constraint : constraints)
395  {
396  if (!constraint.visibility_constraints.empty())
397  {
398  emit_visibility_constraint_warning = true;
399  break;
400  }
401  }
402  if (emit_visibility_constraint_warning)
403  {
404  RCLCPP_WARN_STREAM(getLogger(), "Ignoring " << prefix << ".visibility_constraints: Not supported.");
405  }
406 
407  // Begin extraction.
408 
409  size_t constraint_idx = 0;
410  for (auto& constraint : constraints) // Non-const as constraints are sorted in-place.
411  {
412  // We sort to avoid cardinality.
413  sortJointConstraints(constraint.joint_constraints);
414  sortPositionConstraints(constraint.position_constraints);
415  sortOrientationConstraints(constraint.orientation_constraints);
416 
417  std::string constraint_prefix = prefix + "_" + std::to_string(constraint_idx++);
418 
419  // Joint constraints
420  size_t joint_idx = 0;
421  for (const auto& joint_constraint : constraint.joint_constraints)
422  {
423  std::string meta_name = constraint_prefix + ".joint_constraints_" + std::to_string(joint_idx++);
424  metadata.append(meta_name + ".joint_name", joint_constraint.joint_name);
425  metadata.append(meta_name + ".position", joint_constraint.position);
426  metadata.append(meta_name + ".tolerance_above", joint_constraint.tolerance_above);
427  metadata.append(meta_name + ".tolerance_below", joint_constraint.tolerance_below);
428  }
429 
430  // Position constraints
431  if (!constraint.position_constraints.empty())
432  {
433  // All offsets will be "frozen" and computed wrt. the workspace frame instead.
434  metadata.append(constraint_prefix + ".position_constraints.header.frame_id", workspace_frame_id);
435 
436  size_t position_idx = 0;
437  for (const auto& position_constraint : constraint.position_constraints)
438  {
439  std::string meta_name = constraint_prefix + ".position_constraints_" + std::to_string(position_idx++);
440 
441  geometry_msgs::msg::Point canonical_position;
442  canonical_position.x = position_constraint.target_point_offset.x;
443  canonical_position.y = position_constraint.target_point_offset.y;
444  canonical_position.z = position_constraint.target_point_offset.z;
445 
446  // Canonicalize to robot base frame if necessary.
447  if (position_constraint.header.frame_id != workspace_frame_id)
448  {
449  if (MoveItErrorCode status =
450  restateInNewFrame(move_group.getTF(), position_constraint.header.frame_id, workspace_frame_id,
451  &canonical_position, /*rotation=*/nullptr, tf2::TimePointZero);
452  status != MoveItErrorCode::SUCCESS)
453  {
454  // NOTE: methyldragon -
455  // Ideally we would restore the original state here and undo our changes, however copy of the query is not
456  // supported.
457  std::stringstream ss;
458  ss << "Skipping " << prefix << ":" << meta_name << " metadata append: " << status.message;
459  return MoveItErrorCode(status.val, status.message);
460  }
461  }
462 
463  metadata.append(meta_name + ".link_name", position_constraint.link_name);
464  metadata.append(meta_name + ".target_point_offset.x", canonical_position.x);
465  metadata.append(meta_name + ".target_point_offset.y", canonical_position.y);
466  metadata.append(meta_name + ".target_point_offset.z", canonical_position.z);
467  }
468  }
469 
470  // Orientation constraints
471  if (!constraint.orientation_constraints.empty())
472  {
473  // All offsets will be "frozen" and computed wrt. the workspace frame instead.
474  metadata.append(constraint_prefix + ".orientation_constraints.header.frame_id", workspace_frame_id);
475 
476  size_t ori_idx = 0;
477  for (const auto& orientation_constraint : constraint.orientation_constraints)
478  {
479  std::string meta_name = constraint_prefix + ".orientation_constraints_" + std::to_string(ori_idx++);
480  geometry_msgs::msg::Quaternion canonical_orientation = orientation_constraint.orientation;
481 
482  // Canonicalize to robot base frame if necessary.
483  if (orientation_constraint.header.frame_id != workspace_frame_id)
484  {
485  if (MoveItErrorCode status =
486  restateInNewFrame(move_group.getTF(), orientation_constraint.header.frame_id, workspace_frame_id,
487  /*translation=*/nullptr, &canonical_orientation, tf2::TimePointZero);
488  status != MoveItErrorCode::SUCCESS)
489  {
490  // NOTE: methyldragon -
491  // Ideally we would restore the original state here and undo our changes, however copy of the query is not
492  // supported.
493  std::stringstream ss;
494  ss << "Skipping " << prefix << ":" << meta_name << " metadata append: " << status.message;
495  return MoveItErrorCode(status.val, status.message);
496  }
497  }
498 
499  metadata.append(meta_name + ".link_name", orientation_constraint.link_name);
500  metadata.append(meta_name + ".orientation.x", canonical_orientation.x);
501  metadata.append(meta_name + ".orientation.y", canonical_orientation.y);
502  metadata.append(meta_name + ".orientation.z", canonical_orientation.z);
503  metadata.append(meta_name + ".orientation.w", canonical_orientation.w);
504  }
505  }
506  }
507 
508  return moveit::core::MoveItErrorCode::SUCCESS;
509 }
510 
511 // RobotState. =====================================================================================
512 
514 appendRobotStateJointStateAsFetchQueryWithTolerance(Query& query, const moveit_msgs::msg::RobotState& robot_state,
515  const MoveGroupInterface& move_group, double match_tolerance,
516  const std::string& prefix)
517 {
518  // Make ignored members explicit
519 
520  if (!robot_state.multi_dof_joint_state.joint_names.empty())
521  {
522  RCLCPP_WARN_STREAM(getLogger(), "Ignoring " << prefix << ".multi_dof_joint_states: Not supported.");
523  }
524  if (!robot_state.attached_collision_objects.empty())
525  {
526  RCLCPP_WARN_STREAM(getLogger(), "Ignoring " << prefix << ".attached_collision_objects: Not supported.");
527  }
528 
529  // Begin extraction.
530 
531  if (robot_state.is_diff)
532  {
533  // If plan request states that the start_state is_diff, then we need to get
534  // the current state from the move_group.
535 
536  // NOTE: methyldragon -
537  // I think if is_diff is on, the joint states will not be populated in all
538  // of the motion plan requests? If this isn't the case we might need to
539  // apply the joint states as offsets as well.
540  //
541  // TODO: Since MoveIt also potentially does another getCurrentState() call
542  // when planning, there is a chance that the current state in the cache
543  // differs from the state used in MoveIt's plan.
544  //
545  // This issue should go away once the class is used within the move group's
546  // Plan call.
547  moveit::core::RobotStatePtr current_state = move_group.getCurrentState();
548  if (!current_state)
549  {
550  // NOTE: methyldragon -
551  // Ideally we would restore the original state here and undo our changes, however copy of the metadata is not
552  // supported.
553  std::stringstream ss;
554  ss << "Skipping " << prefix << " query append: "
555  << "Could not get robot state.";
556  return MoveItErrorCode(MoveItErrorCode::UNABLE_TO_AQUIRE_SENSOR_DATA, ss.str());
557  }
558 
559  moveit_msgs::msg::RobotState current_state_msg;
560  robotStateToRobotStateMsg(*current_state, current_state_msg);
561 
562  for (size_t i = 0; i < current_state_msg.joint_state.name.size(); ++i)
563  {
564  query.append(prefix + ".joint_state.name_" + std::to_string(i), current_state_msg.joint_state.name.at(i));
565  queryAppendCenterWithTolerance(query, prefix + ".joint_state.position_" + std::to_string(i),
566  current_state_msg.joint_state.position.at(i), match_tolerance);
567  }
568  }
569  else
570  {
571  for (size_t i = 0; i < robot_state.joint_state.name.size(); ++i)
572  {
573  query.append(prefix + ".joint_state.name_" + std::to_string(i), robot_state.joint_state.name.at(i));
574  queryAppendCenterWithTolerance(query, prefix + ".joint_state.position_" + std::to_string(i),
575  robot_state.joint_state.position.at(i), match_tolerance);
576  }
577  }
578 
579  return moveit::core::MoveItErrorCode::SUCCESS;
580 }
581 
583 appendRobotStateJointStateAsInsertMetadata(Metadata& metadata, const moveit_msgs::msg::RobotState& robot_state,
584  const MoveGroupInterface& move_group, const std::string& prefix)
585 {
586  // Make ignored members explicit
587 
588  if (!robot_state.multi_dof_joint_state.joint_names.empty())
589  {
590  RCLCPP_WARN_STREAM(getLogger(), "Ignoring " << prefix << ".multi_dof_joint_states: Not supported.");
591  }
592  if (!robot_state.attached_collision_objects.empty())
593  {
594  RCLCPP_WARN_STREAM(getLogger(), "Ignoring " << prefix << ".attached_collision_objects: Not supported.");
595  }
596 
597  // Begin extraction.
598 
599  if (robot_state.is_diff)
600  {
601  // If plan request states that the start_state is_diff, then we need to get
602  // the current state from the move_group.
603 
604  // NOTE: methyldragon -
605  // I think if is_diff is on, the joint states will not be populated in all
606  // of the motion plan requests? If this isn't the case we might need to
607  // apply the joint states as offsets as well.
608  //
609  // TODO: Since MoveIt also potentially does another getCurrentState() call
610  // when planning, there is a chance that the current state in the cache
611  // differs from the state used in MoveIt's plan.
612  //
613  // This issue should go away once the class is used within the move group's
614  // Plan call.
615  moveit::core::RobotStatePtr current_state = move_group.getCurrentState();
616  if (!current_state)
617  {
618  // NOTE: methyldragon -
619  // Ideally we would restore the original state here and undo our changes, however copy of the metadata is not
620  // supported.
621  std::stringstream ss;
622  ss << "Skipping " << prefix << " metadata append: "
623  << "Could not get robot state.";
624  return MoveItErrorCode(MoveItErrorCode::UNABLE_TO_AQUIRE_SENSOR_DATA, ss.str());
625  }
626 
627  moveit_msgs::msg::RobotState current_state_msg;
628  robotStateToRobotStateMsg(*current_state, current_state_msg);
629 
630  for (size_t i = 0; i < current_state_msg.joint_state.name.size(); ++i)
631  {
632  metadata.append(prefix + ".joint_state.name_" + std::to_string(i), current_state_msg.joint_state.name.at(i));
633  metadata.append(prefix + ".joint_state.position_" + std::to_string(i),
634  current_state_msg.joint_state.position.at(i));
635  }
636  }
637  else
638  {
639  for (size_t i = 0; i < robot_state.joint_state.name.size(); ++i)
640  {
641  metadata.append(prefix + ".joint_state.name_" + std::to_string(i), robot_state.joint_state.name.at(i));
642  metadata.append(prefix + ".joint_state.position_" + std::to_string(i), robot_state.joint_state.position.at(i));
643  }
644  }
645 
646  return moveit::core::MoveItErrorCode::SUCCESS;
647 }
648 
649 } // namespace trajectory_cache
650 } // namespace moveit_ros
a wrapper around moveit_msgs::MoveItErrorCodes to make it easier to return an error code message from...
Utilities used by the trajectory_cache package.
void robotStateToRobotStateMsg(const RobotState &state, moveit_msgs::msg::RobotState &robot_state, bool copy_attached_bodies=true)
Convert a MoveIt robot state to a robot state message.
void sortJointConstraints(std::vector< moveit_msgs::msg::JointConstraint > &joint_constraints)
Sorts a vector of joint constraints in-place by joint name.
Definition: utils.cpp:187
moveit::core::MoveItErrorCode appendConstraintsAsFetchQueryWithTolerance(warehouse_ros::Query &query, std::vector< moveit_msgs::msg::Constraints > constraints, const moveit::planning_interface::MoveGroupInterface &move_group, double match_tolerance, const std::string &reference_frame_id, const std::string &prefix)
Extracts relevant features from a vector of moveit_msgs::msg::Constraints messages to a fetch query,...
std::string getWorkspaceFrameId(const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::msg::WorkspaceParameters &workspace_parameters)
Gets workspace frame ID. If workspace_parameters has no frame ID, fetch it from move_group.
double getExecutionTime(const moveit_msgs::msg::RobotTrajectory &trajectory)
Returns the execution time of the trajectory in double seconds.
Definition: utils.cpp:146
moveit::core::MoveItErrorCode restateInNewFrame(const std::shared_ptr< tf2_ros::Buffer > &tf, const std::string &target_frame, const std::string &source_frame, geometry_msgs::msg::Point *translation, geometry_msgs::msg::Quaternion *rotation, const tf2::TimePoint &lookup_time=tf2::TimePointZero)
Restates a translation and rotation in a new frame.
Definition: utils.cpp:88
std::string getCartesianPathRequestFrameId(const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::srv::GetCartesianPath::Request &path_request)
Gets cartesian path request frame ID. If path_request has no frame ID, fetch it from move_group.
moveit_msgs::srv::GetCartesianPath::Request constructGetCartesianPathRequest(moveit::planning_interface::MoveGroupInterface &move_group, const std::vector< geometry_msgs::msg::Pose > &waypoints, double max_step, double jump_threshold, bool avoid_collisions=true)
Constructs a GetCartesianPath request.
moveit::core::MoveItErrorCode appendConstraintsAsInsertMetadata(warehouse_ros::Metadata &metadata, std::vector< moveit_msgs::msg::Constraints > constraints, const moveit::planning_interface::MoveGroupInterface &move_group, const std::string &reference_frame_id, const std::string &prefix)
Extracts relevant features from a vector of moveit_msgs::msg::Constraints messages to a cache entry's...
void sortOrientationConstraints(std::vector< moveit_msgs::msg::OrientationConstraint > &orientation_constraints)
Sorts a vector of orientation constraints in-place by link name.
Definition: utils.cpp:203
void sortPositionConstraints(std::vector< moveit_msgs::msg::PositionConstraint > &position_constraints)
Sorts a vector of position constraints in-place by link name.
Definition: utils.cpp:195
moveit::core::MoveItErrorCode appendRobotStateJointStateAsInsertMetadata(warehouse_ros::Metadata &metadata, const moveit_msgs::msg::RobotState &robot_state, const moveit::planning_interface::MoveGroupInterface &move_group, const std::string &prefix)
Extracts relevant features from a vector of moveit_msgs::msg::Constraints messages to a cache entry's...
moveit::core::MoveItErrorCode appendRobotStateJointStateAsFetchQueryWithTolerance(warehouse_ros::Query &query, const moveit_msgs::msg::RobotState &robot_state, const moveit::planning_interface::MoveGroupInterface &move_group, double match_tolerance, const std::string &prefix)
Extracts relevant features from a vector of moveit_msgs::msg::Constraints messages to a fetch query,...
void queryAppendCenterWithTolerance(warehouse_ros::Query &query, const std::string &name, double center, double tolerance)
Appends a range inclusive query with some tolerance about some center value.
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition: logger.cpp:79
name
Definition: setup.py:7