Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tutorials:intermediate:collisions_and_constraints [2015/06/05 07:52] – Added basic structure and some content for collision checking. mpomarlan | tutorials:intermediate:collisions_and_constraints [2015/06/18 06:25] (current) – [Allowed Collision Matrix] mpomarlan | ||
---|---|---|---|
Line 63: | Line 63: | ||
Let's try to check the other state: | Let's try to check the other state: | ||
+ | |||
+ | <code lisp> | ||
+ | (check-state-validity rs-cube " | ||
+ | </ | ||
+ | |||
+ | You should see as a response something like: | ||
<code lisp> | <code lisp> | ||
Line 97: | Line 103: | ||
(Author' | (Author' | ||
+ | |||
+ | Collision and constraint checking are considered by MoveIt! while doing motion generation as well. For example, let's try this now: | ||
+ | |||
+ | <code lisp> | ||
+ | (compute-cartesian-path "/ | ||
+ | rs-mid | ||
+ | " | ||
+ | " | ||
+ | (list tuti: | ||
+ | 0.1 | ||
+ | 1.5 | ||
+ | t | ||
+ | (roslisp: | ||
+ | </ | ||
+ | |||
+ | We ask MoveIt! to create a simple, linear path for the right wrist roll link that will take it from one side of the cube to the other. But that means the motion must pass through the cube, so obviously it will fail; you can see in the RViz window that MoveIt created an incomplete path that stops just before hitting the cube, and you can see in the return values in the REPL window that the completion fraction is below 1. | ||
+ | |||
+ | Sometimes however collisions between the robot and objects in the environment are ok, and even desired. To handle such cases, we will look at the Allowed Collision Matrix next. | ||
==== Allowed Collision Matrix ==== | ==== Allowed Collision Matrix ==== | ||
+ | |||
+ | MoveIt!' | ||
+ | |||
+ | The acm is useful when you want a more fine-tuned collision checking behavior. Perhaps your robot should touch certain objects (this is a certain requirement for manipulation, | ||
+ | |||
+ | Let's remember first how we can retrieve the acm from the planning scene. In the REPL, run the following: | ||
+ | |||
+ | <code lisp> | ||
+ | (defvar ps-acm nil) | ||
+ | (setf ps-acm (second (first (get-planning-scene-info : | ||
+ | </ | ||
+ | |||
+ | Let's query the matrix first. Try: | ||
+ | |||
+ | <code lisp> | ||
+ | (get-collision-matrix-entry ps-acm " | ||
+ | </ | ||
+ | |||
+ | (Note: cram-moveit stores objects with names in all-caps, and those are the names it sends to MoveIt! when adding/ | ||
+ | |||
+ | The response you should get is nil, because this entry wasn't defined yet. Since we'll want to allow some links of the robot to pass through the cube, we'll need to define that entry (and a few others) so we run: | ||
+ | |||
+ | <code lisp> | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | </ | ||
+ | |||
+ | (Note that set-collision-matrix-entry returns a modified acm, but does not change the original acm however.) | ||
+ | |||
+ | You can try get-collision-matrix-entry on one of those pairs to verify that its value is now T. | ||
+ | |||
+ | The above calls only affected cram-moveit variables, so we now need to make the MoveIt! planning scene aware of the changes. Run the following in the REPL: | ||
+ | |||
+ | <code lisp> | ||
+ | (set-planning-scene-collision-matrix ps-acm) | ||
+ | </ | ||
+ | |||
+ | and lets try the cartesian path request again: | ||
+ | |||
+ | <code lisp> | ||
+ | (compute-cartesian-path "/ | ||
+ | rs-mid | ||
+ | " | ||
+ | " | ||
+ | (list tuti: | ||
+ | 0.1 | ||
+ | 1.5 | ||
+ | t | ||
+ | (roslisp: | ||
+ | </ | ||
+ | |||
+ | As you can see, the robot arm now passes through the cube with no protest. | ||
+ | |||
+ | Before we proceed, let's remove the new entries from the collision matrix because we will want the cube to function as an obstacle again. | ||
+ | |||
+ | <code lisp> | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (setf ps-acm (set-collision-matrix-entry ps-acm " | ||
+ | (set-planning-scene-collision-matrix ps-acm) | ||
+ | </ | ||
+ | |||
+ | NOTE: MoveIt! will NOT remove entries in the allowed collision matrix when an object is removed from the planning scene. For clean removal, you should remember to do this yourself. | ||
===== Constraint checking ===== | ===== Constraint checking ===== | ||
+ | |||
+ | Sometimes motion must satisfy more requirements than just getting from A to B without bumping into anything. Suppose, for example, that the robot is carrying a glass full of water, in which case it shouldn' | ||
==== Primer to MoveIt! kinematic constraints ==== | ==== Primer to MoveIt! kinematic constraints ==== | ||
Line 155: | Line 253: | ||
If the target radius is on the order of machine epsilon or smaller, the constraint is considered perfectly satisfied. | If the target radius is on the order of machine epsilon or smaller, the constraint is considered perfectly satisfied. | ||
+ | |||
+ | ==== Using kinematic constraints during planning ==== | ||
+ | |||
+ | From the previous part of the tutorial, we should have a running REPL with the cram moveit tutorial loaded and initialized, | ||
+ | |||
+ | cram-moveit also allows you to define path constraints for **compute-cartesian-path**, | ||
+ | |||
+ | Let's first try a simple motion plan request, in which we ask the robot to move from one pose around the cube to another: | ||
+ | |||
+ | <code lisp> | ||
+ | (plan-link-movement " | ||
+ | </ | ||
+ | |||
+ | (Note the use of the &key parameter start-robot-state to plan a motion from a state that might not be the robot' | ||
+ | |||
+ | Run that plan request a few times and watch the path taken by the end effector in RViz. You'll notice that the planner has no objection to rotating the gripper in various ways; it hasn't been told not to do it. | ||
+ | |||
+ | So let's do just that: | ||
+ | |||
+ | <code lisp> | ||
+ | (defvar or-con nil) | ||
+ | (setf or-con | ||
+ | (roslisp: | ||
+ | : | ||
+ | | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | :x 0.0 | ||
+ | :y 0.0 | ||
+ | :z 0.0 | ||
+ | :w 1.0) | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | : | ||
+ | (plan-link-movement " | ||
+ | : | ||
+ | </ | ||
+ | |||
+ | (We leave some tolerance in the axis to help the sampler; a too strict constraint may be impossible to satisfy anyway.) | ||
+ | |||
+ | Unfortunately, | ||
+ | |||
+ | There is a solution however-- look below. | ||
+ | |||
+ | ==== A note about MoveIt!' | ||
+ | |||
+ | MoveIt! does not do continuous collision checking, which means, instead, that it chooses some points along a robot trajectory segment and does collision checking on them. Usually this won't affect you, unless you work with very narrow objects and/or constraints. | ||
+ | |||
+ | Narrow objects are a problem because the poses MoveIt! chooses to check along a trajectory segment may just miss the object, even if, in fact, the trajectory passes through the object. Kinematic constraints seem to be a problem for a more complicated reason: there tends to be more space, and longer segments, between samples produced by constrained samplers. | ||
+ | |||
+ | There is a tradeoff between increasing the resolution of the collision checks along a trajectory segment and planning time. Sadly, MoveIt! doesn' | ||
+ | |||
+ | For the example above to work, you will have to close move_group, go to pr2_moveit_config/ | ||
+ | |||
+ | From the REPL, rerun the lisp code we tried above, for sending a constrained plan request. This time you should receive a multi-value consisting of a robot state and a robot trajectory as answer-- and the trajectory is a valid solution. You can also observe it in RViz (remember to enable Loop Animation from the Planned Path submenu on the left): notice how the planned path keeps the end effector in the same orientation while it moves around the cube. | ||
+ | |||
+ | == Next == | ||
+ | |||
+ | Coming soon! | ||
+ |