Skip to content
This repository has been archived by the owner on Nov 13, 2017. It is now read-only.

Stop execution on motion planning rviz plugin #709

Closed
wants to merge 3 commits into from

Conversation

wkentaro
Copy link
Contributor

@wkentaro wkentaro commented Jul 10, 2016

moveit_motion_planning_rviz_plugin_stop_button

@davetcoleman
Copy link
Member

Sounds cool - can you provide a screenshot of the GUI change?

@wkentaro
Copy link
Contributor Author

I added a GIF.

@@ -129,15 +135,31 @@ void MotionPlanningFrame::computePlanButtonClicked()
void MotionPlanningFrame::computeExecuteButtonClicked()
{
if (move_group_ && current_plan_)
move_group_->execute(*current_plan_);
ui_->stop_button->setEnabled(true);
move_group_->asyncExecute(*current_plan_);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need brackets around these two lines

@wkentaro
Copy link
Contributor Author

Oops, I sent the wip code. Fixed.

@davetcoleman
Copy link
Member

+1, looks great!

}

void MotionPlanningFrame::computePlanAndExecuteButtonClicked()
{
if (!move_group_)
return;
configureForPlanning();
move_group_->move();
ui_->stop_button->setEnabled(true);
move_group_->asyncMove();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing from synchronous to asynchronous command here, immediately (re)enables the "plan+execute" button.
This changes behaviour. Before, the button was enabled only when move() finished.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe reenabling the button after the execution is necessary?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The button should be only re-enabled after execution. Because you switch to asynchronous execution now, the button gets re-enabled immediately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@rhaschke
Copy link
Contributor

Nice feature. Have a look at the inline comments.

@rhaschke
Copy link
Contributor

Hm. While your recent code will fix the enabling of the stop button, I think the code is rather complicated.
Why do you need to use asynchronous execution at all? The execute() and move() calls were already executed within a separate thread of rviz. Hence, there is no problem to synchronously wait for their end.
Did you tried that?

@wkentaro
Copy link
Contributor Author

Did you tried that?

Yeah, I have tried move() calls and tried to pushing the stop button, but the joint trajectory action could not be canceled.

@@ -129,15 +137,28 @@ void MotionPlanningFrame::computePlanButtonClicked()
void MotionPlanningFrame::computeExecuteButtonClicked()
{
if (move_group_ && current_plan_)
move_group_->execute(*current_plan_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replacing move_group_->execute() with move_group_->asyncMove() is not possible, because behaviour is changed: While the former executes a previously planned, manually validated trajectory, the latter will actually plan a new trajectory and directly execute it - with no chance for inspection/validation.

I cannot accept this PR in this form.

Looking deeper into the reasons, I found the following: There are essentially to methods to plan/execute:

  • move_group::plan() and move_group::move() are calls to an action, that can be interrupted. The flag plan_only allows to switch off/on execution.
  • However, move_group::execute() is a call to a service (MoveGroupExecuteService), which cannot be interrupted.

In order to allow stopping of a trajectory, the service should be turned into an action as well. As far as I can see, that changed could be hidden transparently behind the existing MoveGroupInterface. However, I'm not sure, whether some (3rd-party) code is directly calling the service. Within the MoveIt code base, I couldn't find any other usage.

@davetcoleman Do you think, this change is reasonable?

Alternatively, we do not allow to stop an executed-only trajectory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to allow stopping of a trajectory, the service should be turned into an action as well.

Precisely speaking, for stopping of a trajectory, the service call with wait_for_execution:=false and stop() method call is enough. The reason I needed to change the execute() method to move() is to get the trajectory execution server status to handle GUI button status correctly in 5503fa9.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replacing move_group_->execute() with move_group_->asyncMove() is not possible, because behaviour is changed: While the former executes a previously planned, manually validated trajectory, the latter will actually plan a new trajectory and directly execute it - with no chance for inspection/validation.

I see.

the service should be turned into an action as well.

I agree with the change.

Copy link
Contributor

@rhaschke rhaschke Jul 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Precisely speaking, for stopping of a trajectory, the service call
with |wait_for_execution:=false| and |stop()| method call is enough.
The reason I needed to change the |execute()| method to |move()| is to
get the trajectory execution server status to handle GUI button status
correctly in 5503fa9
The service call doesn't have a stop() method, does it? I guess you are
intermixing with the move action?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wkentaro: Could you propose a PR (w.r.t. #713) for turning the execute service into an action?
Dave agreed on that approach, but I don't have time for it right now.
I think, having that done too, we can merge this branch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The service call doesn't have a stop() method, does it? I guess you are
intermixing with the move action?

I don't use stop() method of the move action, but use stop() method in move_group with trajectory_event_manager.
https://github.com/ros-planning/moveit_ros/blob/kinetic-devel/planning_interface/move_group_interface/src/move_group.cpp#L763
https://github.com/ros-planning/moveit_ros/blob/kinetic-devel/planning_interface/move_group_interface/src/move_group.cpp#L130

I think the execution can be interrupted if wait_for_execution=false for execution service, with stop() calling in move_group.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. That looks promising. Could you prepare a PR for this?

Copy link
Contributor Author

@wkentaro wkentaro Jul 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. That looks promising. Could you prepare a PR for this?

This PR without last commit is that approach. The trajectory execution with execute_button on rviz plugin was able to be interrupted with asyncExecute() and move_group_->stop().
However, it is unable to get the status of execution of service call, so I could not handle the GUI button status, enable/disable, correctly.
That's why I needed to change the asyncExecute() to asyncMove() in the last commit, in order to handle the enable/disable status of GUI precisely.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wkentaro Doesn't work like you described. Of course, using asynchronous execution (wait_for_execution=false) will allow the stop call to get through and stop motion.
However, asynchronous execution through a service doesn't allow to get feedback when execution finished. We need to turn the service into an action.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. You're right. I meant it does not work.

@rhaschke
Copy link
Contributor

If you agree, please close this PR in favor of #713.

@rhaschke
Copy link
Contributor

Closed in favor of #713.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants