Hello,
I would be delighted if someone can explain very clearly.
I have recently started working on a robot that has a Jaco Arm. (MetraLab Scitos G5).
I am using the ASUS xtion pro for the obstacle avoidance. Once this is done, I am able to view the Octree in the monitored_planning_scene topic (using rviz).
1. I also found that I could specify collision objects using the PlanningSceneInterface Class. What is the difference between the two approaches?
2. Also, what is the exact approach to using a PlanningSceneMonitor. In the planning scene tutorial, it is mentioned that the PlanninSceneMonitor is the elegant way to manage a Planning Scene. But, is there a tutorial for the PlanningSceneMonitor?
3. I saw that the PlanningSceneMonitor has a protected function called "excludeWorldObjectFromOctree()" .
Sometimes when I try to grasp an object (using xtion for obstacle avoidance), the plan fails since there is a potential collision between the fingers of the JACO arm and the object that I intend to pickup. I thought I could add it as a World object using the Planning Scene Interface (this I am able to do) and then use the "excludeWorldObjectFromOctree()" method to exclude the object from being considered for collision checking. Is there a more straight forward way of excluding a world object from collision checking?
4. I have somewhat understood how you could modify the AllowedCollisionMatrix. But then, how do I ensure that this ACM is updated to the current Planning Scene? I expect that there is a method in PlanningSceneInterface like "updateAllowedCollisionMatrix()" ? Am I guessing right? or is there a serious error in my understanding?
Please clarify!
Thank you so much!
Chittaranjan S Srinivas
Orebro University
Hi! I have a similar need, and following your comments I created the following code: I created a collision object in the same space that an object on the table. and I want to add it to the allowed collision matrix. I am able to get the collision matrix, update it, and publish it (in 2 different ways) but nothing happens. If I try to touch the objects a collision with the collision object is found.I guess my problem comes from the point that ' rosrun info /planning_scene ' returns nothing, RViz does not publish on it. I also realize that the MoveIt's RViz plug-in is properly receiving information from the move_group node. Is this right? If I select in the MoveIt's RViz plug-in /move_group/monitor_planning_scene and I execute some (e.g. random) movement with the robot I will see it in RViz. But If I select the topic /planning_scene nothing changes on RViz. Which is the main difference about these 2 topics?
{
object.header = handle_pose.header;
object.id = "transport_box";
shape_msgs::SolidPrimitive primitive;
primitive.type = primitive.BOX;
primitive.dimensions.resize(3);
primitive.dimensions[0] = box_height_*2.0;
primitive.dimensions[1] = box_width_;
primitive.dimensions[2] = box_length_;
object.primitives.push_back(primitive);
object.primitive_poses.push_back(handle_pose.pose);
object.operation = attached_object.object.ADD;
moveit_msgs::PlanningScene planning_scene_add;
planning_scene_add.world.collision_objects.push_back(object);
planning_scene_add.is_diff = true;
planning_scene_diff_publisher_.publish(planning_scene_add);
moveit_msgs::GetPlanningScene srv;
srv.request.components.components = moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_NAMES;
//wait until box is published (I don't think that this is really needed)
bool object_in_world = false;
while(!object_in_world)
{
ROS_ERROR("waiting for box to appear");
if (client_get_scene_.call(srv))
{
for (int i = 0; i < (int)srv.response.scene.world.collision_objects.size(); ++i)
{
if (srv.response.scene.world.collision_objects[i].id == "transport_box")
object_in_world = true;
}
}
}
moveit_msgs::PlanningScene currentScene;
moveit_msgs::PlanningScene newSceneDiff;
moveit_msgs::GetPlanningScene scene_srv;
scene_srv.request.components.components = scene_srv.request.components.ALLOWED_COLLISION_MATRIX;
if(!client_get_scene_.call(scene_srv))
{
ROS_WARN("Failed to call service /get_planning_scene");
}
else
{
ROS_INFO_STREAM("Initial scene!");
currentScene = scene_srv.response.scene;
moveit_msgs::AllowedCollisionMatrix currentACM = currentScene.allowed_collision_matrix;
ROS_ERROR_STREAM("size of acm_entry_names before " << currentACM.entry_names.size());
ROS_ERROR_STREAM("size of acm_entry_values before " << currentACM.entry_values.size());
ROS_ERROR_STREAM("size of acm_entry_values[0].entries before " << currentACM.entry_values[0].enabled.size());
currentACM.entry_names.push_back("transport_box");
moveit_msgs::AllowedCollisionEntry entry;
entry.enabled.resize(currentACM.entry_names.size());
for(int i = 0; i < entry.enabled.size(); i++)
entry.enabled[i] = true;
//add new row to allowed collsion matrix
currentACM.entry_values.push_back(entry);
for(int i = 0; i < currentACM.entry_values.size(); i++)
{
//extend the last column of the matrix
currentACM.entry_values[i].enabled.push_back(true);
}
newSceneDiff.is_diff = true;
newSceneDiff.allowed_collision_matrix = currentACM;
planning_scene_diff_publisher_.publish(newSceneDiff);
}
if(!client_get_scene_.call(scene_srv))
{
ROS_WARN("Failed to call service /get_planning_scene");
}
else
{
ROS_INFO_STREAM("Modified scene!");
currentScene = scene_srv.response.scene;
moveit_msgs::AllowedCollisionMatrix currentACM = currentScene.allowed_collision_matrix;
ROS_ERROR_STREAM("size of acm_entry_names after " << currentACM.entry_names.size());
ROS_ERROR_STREAM("size of acm_entry_values after " << currentACM.entry_values.size());
ROS_ERROR_STREAM("size of acm_entry_values[0].entries after " << currentACM.entry_values[0].enabled.size());
}
}
Best regards,
Julia