Skip to content

Commit 7c4886c

Browse files
MarqRazzmergify[bot]
authored andcommitted
Fix seg fault with attached objects during motion execution (#3466)
(cherry picked from commit c81ac91) # Conflicts: # moveit_core/robot_state/src/robot_state.cpp # moveit_ros/planning/plan_execution/src/plan_execution.cpp
1 parent a60ed9f commit 7c4886c

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

moveit_core/robot_state/src/robot_state.cpp

+21-1
Original file line numberDiff line numberDiff line change
@@ -1033,9 +1033,29 @@ void RobotState::getAttachedBodies(std::vector<const AttachedBody*>& attached_bo
10331033
attached_bodies.clear();
10341034
attached_bodies.reserve(attached_body_map_.size());
10351035
for (const auto& it : attached_body_map_)
1036-
attached_bodies.push_back(it.second.get());
1036+
{
1037+
if (it.second)
1038+
{
1039+
attached_bodies.push_back(it.second.get());
1040+
}
1041+
}
1042+
}
1043+
1044+
<<<<<<< HEAD
1045+
=======
1046+
void RobotState::getAttachedBodies(std::map<std::string, const AttachedBody*>& attached_bodies) const
1047+
{
1048+
attached_bodies.clear();
1049+
for (const auto& it : attached_body_map_)
1050+
{
1051+
if (it.second && !it.first.empty())
1052+
{
1053+
attached_bodies[it.first] = it.second.get();
1054+
}
1055+
}
10371056
}
10381057

1058+
>>>>>>> c81ac917e (Fix seg fault with attached objects during motion execution (#3466))
10391059
void RobotState::getAttachedBodies(std::vector<const AttachedBody*>& attached_bodies, const JointModelGroup* group) const
10401060
{
10411061
attached_bodies.clear();

moveit_ros/planning/plan_execution/src/plan_execution.cpp

+94
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ bool plan_execution::PlanExecution::isRemainingPathValid(const ExecutableMotionP
297297
std::size_t wpc = t.getWayPointCount();
298298
collision_detection::CollisionRequest req;
299299
req.group_name = t.getGroupName();
300+
<<<<<<< HEAD
300301
for (std::size_t i = std::max(path_segment.second - 1, 0); i < wpc; ++i)
301302
{
302303
collision_detection::CollisionResult res;
@@ -306,18 +307,81 @@ bool plan_execution::PlanExecution::isRemainingPathValid(const ExecutableMotionP
306307
plan.planning_scene_->checkCollisionUnpadded(req, res, t.getWayPoint(i));
307308

308309
if (res.collision || !plan.planning_scene_->isStateFeasible(t.getWayPoint(i), false))
310+
=======
311+
req.pad_environment_collisions = false;
312+
moveit::core::RobotState start_state = plan.planning_scene->getCurrentState();
313+
std::map<std::string, const moveit::core::AttachedBody*> current_attached_objects, waypoint_attached_objects;
314+
start_state.getAttachedBodies(current_attached_objects);
315+
if (plan_components_attached_objects_.size() > static_cast<size_t>(path_segment.first))
316+
waypoint_attached_objects = plan_components_attached_objects_[path_segment.first];
317+
moveit::core::RobotState waypoint_state(start_state);
318+
for (std::size_t i = std::max(path_segment.second - 1, 0); i < wpc; ++i)
319+
{
320+
collision_detection::CollisionResult res;
321+
waypoint_attached_objects.clear(); // clear out the last waypoints attached objects
322+
waypoint_state = t.getWayPoint(i);
323+
if (plan_components_attached_objects_[path_segment.first].empty())
324+
{
325+
waypoint_state.getAttachedBodies(waypoint_attached_objects);
326+
}
327+
328+
// If sample state has attached objects that are not in the current state, remove them from the sample state
329+
for (const auto& [name, object] : waypoint_attached_objects)
330+
{
331+
if (current_attached_objects.find(name) == current_attached_objects.end())
332+
{
333+
RCLCPP_DEBUG(logger_, "Attached object '%s' is not in the current scene. Removing it.", name.c_str());
334+
waypoint_state.clearAttachedBody(name);
335+
}
336+
}
337+
338+
// If current state has attached objects that are not in the sample state, add them to the sample state
339+
for (const auto& [name, object] : current_attached_objects)
340+
{
341+
if (waypoint_attached_objects.find(name) == waypoint_attached_objects.end())
342+
{
343+
RCLCPP_DEBUG(logger_, "Attached object '%s' is not in the robot state. Adding it.", name.c_str());
344+
waypoint_state.attachBody(std::make_unique<moveit::core::AttachedBody>(*object));
345+
}
346+
}
347+
348+
if (acm)
349+
{
350+
plan.planning_scene->checkCollision(req, res, waypoint_state, *acm);
351+
}
352+
else
353+
{
354+
plan.planning_scene->checkCollision(req, res, waypoint_state);
355+
}
356+
357+
if (res.collision || !plan.planning_scene->isStateFeasible(waypoint_state, false))
358+
>>>>>>> c81ac917e (Fix seg fault with attached objects during motion execution (#3466))
309359
{
310360
RCLCPP_INFO(LOGGER, "Trajectory component '%s' is invalid for waypoint %ld out of %ld",
311361
plan.plan_components_[path_segment.first].description_.c_str(), i, wpc);
312362

313363
// call the same functions again, in verbose mode, to show what issues have been detected
364+
<<<<<<< HEAD
314365
plan.planning_scene_->isStateFeasible(t.getWayPoint(i), true);
315366
req.verbose = true;
316367
res.clear();
317368
if (acm)
318369
plan.planning_scene_->checkCollisionUnpadded(req, res, t.getWayPoint(i), *acm);
319370
else
320371
plan.planning_scene_->checkCollisionUnpadded(req, res, t.getWayPoint(i));
372+
=======
373+
plan.planning_scene->isStateFeasible(waypoint_state, true);
374+
req.verbose = true;
375+
res.clear();
376+
if (acm)
377+
{
378+
plan.planning_scene->checkCollision(req, res, waypoint_state, *acm);
379+
}
380+
else
381+
{
382+
plan.planning_scene->checkCollision(req, res, waypoint_state);
383+
}
384+
>>>>>>> c81ac917e (Fix seg fault with attached objects during motion execution (#3466))
321385
return false;
322386
}
323387
}
@@ -426,6 +490,36 @@ moveit_msgs::msg::MoveItErrorCodes plan_execution::PlanExecution::executeAndMoni
426490
path_became_invalid_ = false;
427491
bool preempt_requested = false;
428492

493+
<<<<<<< HEAD
494+
=======
495+
// Check that attached objects remain consistent throughout the trajectory and store them.
496+
// This avoids querying the scene for attached objects at each waypoint whenever possible.
497+
// If a change in attached objects is detected, they will be queried at each waypoint.
498+
plan_components_attached_objects_.clear();
499+
plan_components_attached_objects_.reserve(plan.plan_components.size());
500+
for (const auto& component : plan.plan_components)
501+
{
502+
const auto& trajectory = component.trajectory;
503+
std::map<std::string, const moveit::core::AttachedBody*> trajectory_attached_objects;
504+
if (trajectory && trajectory->getWayPointCount() > 0)
505+
{
506+
std::map<std::string, const moveit::core::AttachedBody*> attached_objects;
507+
trajectory->getWayPoint(0).getAttachedBodies(trajectory_attached_objects);
508+
for (std::size_t i = 1; i < trajectory->getWayPointCount(); ++i)
509+
{
510+
trajectory->getWayPoint(i).getAttachedBodies(attached_objects);
511+
if (attached_objects != trajectory_attached_objects)
512+
{
513+
trajectory_attached_objects.clear();
514+
break;
515+
}
516+
}
517+
}
518+
if (!trajectory_attached_objects.empty())
519+
plan_components_attached_objects_.push_back(trajectory_attached_objects);
520+
}
521+
522+
>>>>>>> c81ac917e (Fix seg fault with attached objects during motion execution (#3466))
429523
while (rclcpp::ok() && !execution_complete_ && !path_became_invalid_)
430524
{
431525
r.sleep();

0 commit comments

Comments
 (0)