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