Planning Around Objects

This tutorial will introduce you to inserting objects into the planning scene and planning around them.

Prerequisites

If you haven’t already done so, make sure you’ve completed the steps in Visualizing in RViz. This project assumes you are starting with the hello_moveit project, where the previous tutorial left off. If you just want to run the tutorial, you can follow the Docker Guide to start a container with the completed tutorial.

Steps

1 Add include for Planning Scene Interface

At the top of your source file, add this to the list of includes:

#include <moveit/planning_scene_interface/planning_scene_interface.h>

2 Change the Target Pose

First, update the target pose with the following change to make the robot plan to a different location:

// Set a target Pose with updated values !!!
auto const target_pose = [] {
  geometry_msgs::msg::Pose msg;
  msg.orientation.y = 0.8;
  msg.orientation.w = 0.6;
  msg.position.x = 0.1;
  msg.position.y = 0.4;
  msg.position.z = 0.4;
  return msg;
}();
move_group_interface.setPoseTarget(target_pose);

3 Create a Collision Object

In the next block of code, we create a collision object. The first thing to notice is that it is being placed in the coordinate frame of the robot. If we had a perception system that reported the location of obstacles in our scene, then this is the sort of message it would build. Because this is just an example, we are creating it manually. One thing to notice at the end of this block of code is that we set the operation on this message to ADD. This results in the object getting added to the collision scene. Place this code block between setting the target pose from the previous step and creating a plan.

// Create collision object for the robot to avoid
auto const collision_object = [frame_id =
                                 move_group_interface.getPlanningFrame()] {
  moveit_msgs::msg::CollisionObject collision_object;
  collision_object.header.frame_id = frame_id;
  collision_object.id = "box1";
  shape_msgs::msg::SolidPrimitive primitive;

  // Define the size of the box in meters
  primitive.type = primitive.BOX;
  primitive.dimensions.resize(3);
  primitive.dimensions[primitive.BOX_X] = 0.5;
  primitive.dimensions[primitive.BOX_Y] = 0.1;
  primitive.dimensions[primitive.BOX_Z] = 0.5;

  // Define the pose of the box (relative to the frame_id)
  geometry_msgs::msg::Pose box_pose;
  box_pose.orientation.w = 1.0;  // We can leave out the x, y, and z components of the quaternion since they are initialized to 0
  box_pose.position.x = 0.2;
  box_pose.position.y = 0.2;
  box_pose.position.z = 0.25;

  collision_object.primitives.push_back(primitive);
  collision_object.primitive_poses.push_back(box_pose);
  collision_object.operation = collision_object.ADD;

  return collision_object;
}();

4 Add the Object to the Planning Scene

Finally, we need to add this object to the collision scene. To do this, we use an object called the PlanningSceneInterface that uses ROS interfaces to communicate changes to the planning scene to MoveGroup. This code block should directly follow the code block that creates the collision object.

// Add the collision object to the scene
moveit::planning_interface::PlanningSceneInterface planning_scene_interface;
planning_scene_interface.applyCollisionObject(collision_object);

5 Run the Program and Observe the Change

Just as we did in the last tutorial, start RViz using the demo.launch.py script and run our program. If you’re using one of the Docker tutorial containers, you can specify a different RViz configuration that already has the RvizVisualToolsGui panel added using:

ros2 launch moveit2_tutorials demo.launch.py rviz_config:=kinova_hello_moveit.rviz
../../../_images/planning_around_object.png

Summary

Further Reading

Next Step

In the next tutorial Pick and Place with MoveIt Task Constructor, you will be introduced to a higher layer tool designed to solve harder motion plans. In this next tutorial, you will create a program to pick and place an object.