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
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
37namespace
38{
39
40rclcpp::Logger getLogger()
41{
42 return moveit::getLogger("moveit.ros.trajectory_cache.features");
43}
44
45} // namespace
46
47// Frames. =========================================================================================
48
49namespace moveit_ros
50{
51namespace trajectory_cache
52{
53
54using ::warehouse_ros::Metadata;
55using ::warehouse_ros::Query;
56
57using ::moveit::core::MoveItErrorCode;
58using ::moveit::planning_interface::MoveGroupInterface;
59
60using ::moveit_msgs::srv::GetCartesianPath;
61
62std::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
75std::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
88MoveItErrorCode 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
146double 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
153GetCartesianPath::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
180void 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
187void 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
195void 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
203void 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
212appendConstraintsAsFetchQueryWithTolerance(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
514appendRobotStateJointStateAsFetchQueryWithTolerance(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
583appendRobotStateJointStateAsInsertMetadata(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 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