Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible bug in ModifyPlanningScene #349

Open
JafarAbdi opened this issue Mar 31, 2022 · 10 comments
Open

Possible bug in ModifyPlanningScene #349

JafarAbdi opened this issue Mar 31, 2022 · 10 comments

Comments

@JafarAbdi
Copy link
Member

JafarAbdi commented Mar 31, 2022

I'm not sure if this's a bug in ModifyPlanningScene or a misuse from my side, so I have the following task

CurrentState
Connect                  
MoveRelative           ------------------------------------
ModifyPlanningScene                                       | 
GeneratePose(monitor CurrentState)                        |   Collision Enabled Between EE and Octomap
ModifyPlanningScene                                       |
...                    ------------------------------------
ModifyPlanningScene (Forbid collision)

The reason why I have two ModifyPlanningScene between GeneratePose is that I need the collision to be disabled for the MoveRelative (maybe could be replaced with #253)

This's isn't working because in modify_planning_scene.cpp#L90-L92 we revert the user choice in the backward case so allowing collision become forbid collision, is this a bug or intended behavior?

If ModifyPlanningScene is only meant to be used as forward should it inherit from PropagatingForward?

@JafarAbdi JafarAbdi reopened this Mar 31, 2022
@rhaschke
Copy link
Contributor

long story short: yes, if a ModifyPlanningScene stage is applied in backwards fashion, its actions are actually reversed as well.
This was to make the linear sequence look correct when read from the top, i.e. going from Connect to MoveRelative to GeneratePose.
This is interesting for serial containers that can apply their stages in forward and reverse order. For example, I have a Grasp and an UnGrasp container, applying essentially the same series of stages, simply in reverse order.

@AndyZe
Copy link
Member

AndyZe commented Mar 31, 2022

I think I might be facing the same issue on a different project. We would like the suction cups to be able to touch the object during a MoveRelative but not before the MoveRelative.

@v4hn
Copy link
Contributor

v4hn commented Mar 31, 2022

maybe could be replaced with #253

That is an interesting idea, though not as straight-forward as you might expect. The modifying wrapper was mostly meant to modify solutions of children stages, not the stages passed to them. And if I understood you correctly that's what you would want here to adapt the ACM.

As Robert explained the ModifyPlanningScene container is meant to be defined in temporal order, not causal.
That has some problems in itself, but I don't think the one you describe actually exists? Can't you just invert the logic there?

The main issue I am aware of is that you cannot specify "delete" operations and reverse them unless you would also provide the whole object that is deleted in this step. You can work around it with a custom stage, but it might make sense to address this in an API in the ModifyPlanningScene class.

@AndyZe
Copy link
Member

AndyZe commented Mar 31, 2022

Can't you just invert the logic there?

You mean we should set allowCollisions() to false to allow the collision? Wow, that would be nonintuitive. I'll try it.

@v4hn
Copy link
Contributor

v4hn commented Mar 31, 2022

You mean we should set allowCollisions() to false to allow the collision? Wow, that would be unintuitive. I'll try it.

I'm not sure why you think this behavior is unintuitive. I think it's one of the few sane parts of the pipeline. :-)
The correct phrasing is "set allowCollisions() to false to have the collisions enabled before the stage and disabled after the stage.
The generated solution is always interpreted start to end and so are the defined stages when you read through the task.
So if you see a Stage with allowCollisions(false), you know that when you get there during execution of a solution the collisions will be forbidden before executing the next subsolutions.

In theory the logical flow you are focused on here could be seen as an implementation detail that is rather independent of the task specification.
But the monitoring structure and backward planning make it efficient/possible for the modular framework to solve the tasks.

@schornakj
Copy link

schornakj commented Apr 2, 2022

@rhaschke @v4hn I'll post here since I'm working on the same code as @JafarAbdi. As he said, we're working on a task where the robot needs to be able to partly intersect with the planning scene's collision octomap during the final part of a grasp motion, but needs to avoid collision with the octomap during other motions.

In more detail, our task looks like this:

CurrentState
Connect (freespace motion to pre-approach pose -- we want to avoid colliding with <octomap> here)
SerialContainer
  ModifyPlanningScene (allow collisions between <octomap> and the gripper links)
  MoveRelative (do a linear approach move towards the object to grasp)
  ModifyPlanningScene (forbid collisions between <octomap> and the gripper links)
  ComputeIK (we call setIgnoreCollisions(true) for this stage)
    GeneratePose (uses a pose passed in from outside the context of the task, and is set to monitor the first CurrentState stage)
  ModifyPlanningScene (allow collisions between <octomap> and the gripper links)
  MoveTo (move the gripper planning group to be closed)
  MoveRelative (lift the gripper along the world Z+ axis and, hopefully, the object too)
  MoveRelative (reverse the initial linear approach move)
  ModifyPlanningScene (forbid collisions between <octomap> and the gripper links)

There are a few things I wanted to ask about:

  • While this task does find a trajectory that intersects the octomap during the final part of the grasp while avoiding it during the initial freespace motion, when we go to execute the motion the MoveIt Trajectory Execution Manager halts the motion before the approach move is performed because it detects that we're about to go into collision with the octomap. Shouldn't the planning scene diffs associated with each subtrajectory make this set of collisions permissible by modifying the planning scene's Allowed Collision Matrix before the motion is executed?
  • It seems like we needed to add more ModifyPlanningScene stages than expected to produce the right behavior. In particular the ones right before and after the ComputeIK stage seem like they should not be necessary, since the one at the beginning of the SerialContainer should allow these collisions for the subsequent stages. Am I misunderstanding the propagation of the result of these stages throughout the task?
  • What is the right way to generate a pose that is in collision with some planning scene object? I think the reason why we need to use setIgnoreCollisions(true) is that the state of the scene produce by the CurrentState stage which is monitored by the GeneratePose stage has an ACM that forbids collision between the octomap and the gripper links. Is there a way to modify the monitored stage to allow certain collisions before using it to generate poses?

@v4hn
Copy link
Contributor

v4hn commented Apr 2, 2022 via email

@AndyZe
Copy link
Member

AndyZe commented Apr 7, 2022

Just wondering, have you considered inverting the logic internally so the user doesn't need to? It would be pretty nice if allowCollisions(true) always meant the same thing

@schornakj
Copy link

@v4hn Thank you for writing up that explanation. @JafarAbdi and I are going to implement the update to planning scene diff propagation you mentioned.

@v4hn
Copy link
Contributor

v4hn commented Oct 11, 2022 via email

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

No branches or pull requests

5 participants