Planning movement with constraints
Constraints in movement of the robot come from various sources. The movement of the robot can be constrained e.g. by their own geometry (self-collisions), by contraints set to the joints, by contraints from the surrounding physical space ...
In the first example it will be presented how collision object in the planning space are handled with MoveIt.
Avoiding collision with an object
Create a new file named avoid_collision.cpp
in the fanuc_manipulation
package.
Use the following code:
#include <moveit/move_group_interface/move_group_interface.h>
#include <moveit/planning_scene_interface/planning_scene_interface.h>
#include <moveit_visual_tools/moveit_visual_tools.h>
int main(int argc, char **argv)
{
ros::init(argc, argv, "move_group_interface_tutorial");
ros::NodeHandle node_handle;
ros::AsyncSpinner spinner(1);
spinner.start();
// Initialising and defining the planning group for move_base
static const std::string PLANNING_GROUP = "fanuc_arm";
moveit::planning_interface::MoveGroupInterface move_group(PLANNING_GROUP);
// Raw pointers are frequently used to refer to the planning group for improved performance.
const robot_state::JointModelGroup *joint_model_group =
move_group.getCurrentState()->getJointModelGroup(PLANNING_GROUP);
// Initialising the PlanninSceneInterface that enables taking
// collision objects into account during planning
moveit::planning_interface::PlanningSceneInterface planning_scene_interface;
// Initialisation of Rviz Visual Tools
moveit_visual_tools::MoveItVisualTools visual_tools("base_link");
// Clear existing markers
visual_tools.deleteAllMarkers();
// Pre-load remote control
visual_tools.loadRemoteControl();
Eigen::Isometry3d text_pose = Eigen::Isometry3d::Identity();
text_pose.translation().z() = 1;
visual_tools.publishText(text_pose, "Avoid Box Tutorial", rviz_visual_tools::YELLOW, rviz_visual_tools::XLARGE);
visual_tools.trigger();
// Define a collision object ROS message.
moveit_msgs::CollisionObject collision_object;
collision_object.header.frame_id = move_group.getPlanningFrame();
// The id of the object is used to identify it.
collision_object.id = "box1";
// Define a box to add to the world.
shape_msgs::SolidPrimitive primitive;
primitive.type = primitive.BOX;
primitive.dimensions.resize(3);
primitive.dimensions[0] = 0.2;
primitive.dimensions[1] = 0.1;
primitive.dimensions[2] = 0.3;
// Define a pose for the box (specified relative to frame_id)
geometry_msgs::Pose box_pose;
box_pose.orientation.w = 1.0;
box_pose.position.x = 0.25;
box_pose.position.y = -0.15;
box_pose.position.z = 0.3;
collision_object.primitives.push_back(primitive);
collision_object.primitive_poses.push_back(box_pose);
collision_object.operation = collision_object.ADD;
std::vector<moveit_msgs::CollisionObject> collision_objects;
collision_objects.push_back(collision_object);
// Now, let's add the collision object into the world
ROS_INFO_NAMED("tutorial", "Add an object into the world");
planning_scene_interface.addCollisionObjects(collision_objects);
// Show text in RViz of status
text_pose.translation().z() = 0.9;
visual_tools.publishText(text_pose, "Box added ...", rviz_visual_tools::CYAN, rviz_visual_tools::XLARGE);
visual_tools.trigger();
// Wait for MoveGroup to receive and process the collision object message
visual_tools.prompt("Press 'next' in the RvizVisualToolsGui window to once the collision object appears in RViz");
// Now when we plan a trajectory it will avoid the obstacle
move_group.setStartState(*move_group.getCurrentState());
geometry_msgs::Pose another_pose;
another_pose.orientation.y = sqrt(2) / 2;
another_pose.orientation.w = sqrt(2) / 2;
another_pose.position.x = 0.25;
another_pose.position.y = 0.0;
another_pose.position.z = 0.3;
move_group.setPoseTarget(another_pose);
moveit::planning_interface::MoveGroupInterface::Plan my_plan;
bool success = (move_group.plan(my_plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS);
ROS_INFO_NAMED("tutorial", "Visualizing plan %s", success ? "" : "FAILED");
visual_tools.prompt("Press 'next' in the RvizVisualToolsGui window to continue");
// Executing the movement
move_group.move();
move_group.setStartState(*move_group.getCurrentState());
another_pose.position.x = 0.0;
another_pose.position.y = -0.25;
move_group.setPoseTarget(another_pose);
success = (move_group.plan(my_plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS);
ROS_INFO_NAMED("tutorial", "Visualizing plan (pose goal move around cuboid) %s", success ? "" : "FAILED");
visual_tools.prompt("Press 'next' in the RvizVisualToolsGui window to continue");
// Executing the movement
move_group.move();
ros::shutdown();
return 0;
}
Task
Modify the above code in a new file avoid_two.cpp
accordingly:
- add another object (cuboid) to planning scene
- the dimensions of the new object are 1, 1, 0.01
- the position of the new object is 0, 0, 0.8
- send the robot again to the first pose