-
Notifications
You must be signed in to change notification settings - Fork 727
Description
Description
Hello everyone,
Firstly, thanks for this great project. I want to inform you about some bad practices in move_group_interface . There occur some functionality problem in
the part of plan method of MoveGroupInterface
moveit2/moveit_ros/planning_interface/move_group_interface/src/move_group_interface.cpp
Lines 691 to 710 in 672e0ec
| auto goal_handle_future = move_action_client_->async_send_goal(goal, send_goal_opts); | |
| // wait until send_goal_opts.result_callback is called | |
| while (!done) | |
| { | |
| std::this_thread::sleep_for(std::chrono::milliseconds(1)); | |
| } | |
| if (code != rclcpp_action::ResultCode::SUCCEEDED) | |
| { | |
| RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::plan() failed or timeout reached"); | |
| return res->error_code; | |
| } | |
| plan.trajectory = res->planned_trajectory; | |
| plan.start_state = res->trajectory_start; | |
| plan.planning_time = res->planning_time; | |
| RCLCPP_INFO(logger_, "time taken to generate plan: %g seconds", plan.planning_time); | |
| return res->error_code; |
the part of move method of MoveGroupInterface
moveit2/moveit_ros/planning_interface/move_group_interface/src/move_group_interface.cpp
Lines 767 to 782 in 672e0ec
| auto goal_handle_future = move_action_client_->async_send_goal(goal, send_goal_opts); | |
| if (!wait) | |
| return moveit::core::MoveItErrorCode::SUCCESS; | |
| // wait until send_goal_opts.result_callback is called | |
| while (!done) | |
| { | |
| std::this_thread::sleep_for(std::chrono::milliseconds(1)); | |
| } | |
| if (code != rclcpp_action::ResultCode::SUCCEEDED) | |
| { | |
| RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::move() failed or timeout reached"); | |
| } | |
| return res->error_code; | |
| } |
and maybe this part of execute method of MoveGroupInterface
moveit2/moveit_ros/planning_interface/move_group_interface/src/move_group_interface.cpp
Lines 831 to 850 in 672e0ec
| moveit_msgs::action::ExecuteTrajectory::Goal goal; | |
| goal.trajectory = trajectory; | |
| goal.controller_names = controllers; | |
| auto goal_handle_future = execute_action_client_->async_send_goal(goal, send_goal_opts); | |
| if (!wait) | |
| return moveit::core::MoveItErrorCode::SUCCESS; | |
| // wait until send_goal_opts.result_callback is called | |
| while (!done) | |
| { | |
| std::this_thread::sleep_for(std::chrono::milliseconds(1)); | |
| } | |
| if (code != rclcpp_action::ResultCode::SUCCEEDED) | |
| { | |
| RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::execute() failed or timeout reached"); | |
| } | |
| return res->error_code; | |
| } |
I also want to make a critic about node spinning inside separate thread in move_group_interface. For users who don't know node starts to spin in separate thread when move group interface is created, this logic maybe can be problem. I think we need better implementation for this part as well.
moveit2/moveit_ros/planning_interface/move_group_interface/src/move_group_interface.cpp
Lines 117 to 120 in 672e0ec
| callback_group_ = node_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive, | |
| false /* don't spin with node executor */); | |
| callback_executor_.add_callback_group(callback_group_, node->get_node_base_interface()); | |
| callback_thread_ = std::thread([this]() { callback_executor_.spin(); }); |
Problem is that there is a possibility that request is sent by client but is not received forever by server, especially move_group_server. This can bring about move_group_interface to get stuck inside while loop and plan method not to finish its own job.
In addition, these implementations normally work for rmw_fastrtps and rmw_cyclonedds, but get stuck with rmw_zenoh.
If you want, i can deal with it and can try to come up with better implementation.
Your environment
- ROS Distro: Rolling
- OS Version: Ubuntu 22.04
- Source Build
- Branch : main
- RMW : rmw_zenoh
Steps to reproduce
Firstly, run zenoh router (be sure that rmw_zenoh_cpp is built at your workspace)
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 run rmw_zenoh_cpp rmw_zenohdSecondly, Follow the MoveIt tutorials(but use this tutorial repository i forked) and run demo launch of MoveIt2 using following command.
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 run moveit2_tutorials perception_pipeline_demo.launch.pyRun this benchmark code from this repository using below command
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 run moveit_middleware_benchmark test_scenario_perception_pipelineExpected behaviour
plan method of MoveGroupInterface should not get stuck. If planning has timeout due to the fact that server doesn't receive request even though sending request from move_group_interface client is successfull, it is returned timeout error by plan method of move_group_interface.
Actual behaviour
plan method gets stuck inside while loop.
Backtrace or Console output
I have no console output and backtrace logs at the moment.