00001 #include <moveit_object_handling/GraspedObjectHandler.h>
00002 #include <moveit_msgs/CollisionObject.h>
00003 #include <moveit_msgs/GetPlanningScene.h>
00004 #include <convenience_ros_functions/ROSFunctions.h>
00005
00006 using moveit_object_handling::GraspedObjectHandler;
00007 using moveit_object_handling::GraspedObjectHandlerMoveIt;
00008
00009 GraspedObjectHandlerMoveIt::GraspedObjectHandlerMoveIt(
00010 ros::NodeHandle& n, const std::vector<std::string>& _gripperLinkNames,
00011 const std::string& get_planning_scene_service,
00012 const std::string& set_planning_scene_topic):
00013 node(n),
00014 gripperLinkNames(_gripperLinkNames)
00015 {
00016
00017
00018
00019 convenience_ros_functions::ROSFunctions::initSingleton();
00020 subscribeAndAdvertise(get_planning_scene_service, set_planning_scene_topic);
00021 }
00022
00023 bool GraspedObjectHandlerMoveIt::attachObjectToRobot(const std::string& object_name, const std::string& attach_link_name) {
00024
00025 if (!attachObjectToRobot(object_name, attach_link_name, gripperLinkNames)) {
00026 ROS_ERROR("Could not attach object to robot");
00027 return false;
00028 }
00029
00030 ROS_INFO_STREAM("Have attached object "<<object_name<<" to "<<attach_link_name);
00031 return true;
00032 }
00033
00034 bool GraspedObjectHandlerMoveIt::detachObjectFromRobot(const std::string& object_name)
00035 {
00036
00037 if (moveit_planning_scene_publisher.getNumSubscribers() < 1)
00038 {
00039 ROS_WARN("detachObjectToRobot: No node subscribed to planning scene publisher.");
00040 return false;
00041 }
00042
00043 moveit_msgs::GetPlanningScene srv;
00044 srv.request.components.components = moveit_msgs::PlanningSceneComponents::ROBOT_STATE_ATTACHED_OBJECTS;
00045
00046
00047
00048 if (!moveit_planning_scene_client.call(srv))
00049 {
00050 ROS_ERROR("Can't obtain planning scene");
00051 return false;
00052 }
00053
00054 moveit_msgs::PlanningScene planning_scene;
00055 planning_scene.is_diff = true;
00056
00057 ROS_INFO("Now detaching object '%s' from robot", object_name.c_str());
00058
00059 moveit_msgs::AttachedCollisionObject attObj;
00060 if (!hasObject(object_name, srv.response.scene.robot_state.attached_collision_objects, attObj))
00061 {
00062 ROS_WARN("GraspedObjectHandlerMoveIt: Object %s was not attached to robot, but it was tried to detach it.", object_name.c_str());
00063 return true;
00064 }
00065
00066
00067 attObj.object.operation = attObj.object.REMOVE;
00068 planning_scene.robot_state.attached_collision_objects.push_back(attObj);
00069 planning_scene.robot_state.is_diff = true;
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 moveit_planning_scene_publisher.publish(planning_scene);
00086
00087
00088 return true;
00089 }
00090
00091
00092 bool GraspedObjectHandlerMoveIt::attachObjectToRobot(const std::string& name,
00093 const std::string& link_name, const std::vector<std::string>& allowedTouchLinks)
00094 {
00095
00096 ROS_INFO("GraspedObjectHandlerMoveIt: Attaching %s to %s", name.c_str(), link_name.c_str());
00097
00098 if (moveit_planning_scene_publisher.getNumSubscribers() < 1)
00099 {
00100 ROS_ERROR("GraspedObjectHandlerMoveIt: attachObjectToRobot: No node subscribed to planning scene publisher.");
00101 return false;
00102 }
00103
00104 moveit_msgs::GetPlanningScene srv;
00105 srv.request.components.components = moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_NAMES |
00106 moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY;
00107
00108
00109
00110 if (!moveit_planning_scene_client.call(srv))
00111 {
00112 ROS_ERROR("GraspedObjectHandlerMoveIt: Can't obtain planning scene in order to attach object.");
00113 return false;
00114 }
00115
00116 moveit_msgs::PlanningScene planning_scene;
00117 planning_scene.is_diff = true;
00118
00119
00120
00121 moveit_msgs::CollisionObject collObj;
00122 if (!hasObject(name, srv.response.scene.world.collision_objects, collObj))
00123 {
00124 ROS_ERROR("GraspedObjectHandlerMoveIt: Object %s was not in the scene, but it was tried to attach it to robot.", name.c_str());
00125 return false;
00126 }
00127 else
00128 {
00129
00130 collObj.operation = collObj.REMOVE;
00131 planning_scene.world.collision_objects.push_back(collObj);
00132 }
00133
00134
00135 if (!transformCollisionObject(link_name, collObj))
00136 {
00137 ROS_ERROR("GraspedObjectHandlerMoveIt: Could not transform object to link frame");
00138 return false;
00139 }
00140
00141 moveit_msgs::AttachedCollisionObject attached_object;
00142 attached_object.object = collObj;
00143 attached_object.object.header.frame_id = link_name;
00144 attached_object.link_name = link_name;
00145 attached_object.touch_links = allowedTouchLinks;
00146
00147 attached_object.object.operation = attached_object.object.ADD;
00148 planning_scene.robot_state.attached_collision_objects.push_back(attached_object);
00149 planning_scene.robot_state.is_diff = true;
00150
00151 moveit_planning_scene_publisher.publish(planning_scene);
00152
00153
00154
00155 while (true)
00156 {
00157 srv.request.components.components = moveit_msgs::PlanningSceneComponents::ROBOT_STATE_ATTACHED_OBJECTS;
00158
00159
00160
00161 if (!moveit_planning_scene_client.call(srv))
00162 {
00163 ROS_ERROR("GraspedObjectHandlerMoveIt: Can't obtain planning scene");
00164 return false;
00165 }
00166
00167
00168 moveit_msgs::AttachedCollisionObject o;
00169 if (hasObject(name, srv.response.scene.robot_state.attached_collision_objects, o))
00170 {
00171 ROS_INFO("GraspedObjectHandlerMoveIt: Scene is updated with attached object.");
00172 break;
00173 }
00174 ROS_INFO("GraspedObjectHandlerMoveIt: Waiting for scene update to attach object...");
00175 ros::Duration(0.5).sleep();
00176 }
00177
00178
00179
00180 return true;
00181 }
00182
00183
00184
00185
00186 bool GraspedObjectHandlerMoveIt::hasObject(const std::string& name, const std::vector<moveit_msgs::AttachedCollisionObject>& objs, moveit_msgs::AttachedCollisionObject& o)
00187 {
00188 for (int i = 0; i < objs.size(); ++i)
00189 {
00190 if (objs[i].object.id == name)
00191 {
00192 o = objs[i];
00193 return true;
00194 }
00195 }
00196 return false;
00197 }
00198
00199
00200 bool GraspedObjectHandlerMoveIt::hasObject(const std::string& name, const std::vector<moveit_msgs::CollisionObject>& objs, moveit_msgs::CollisionObject& o)
00201 {
00202 for (int i = 0; i < objs.size(); ++i)
00203 {
00204 if (objs[i].id == name)
00205 {
00206 o = objs[i];
00207 return true;
00208 }
00209 }
00210 return false;
00211 }
00212
00213
00214 bool GraspedObjectHandlerMoveIt::removeObject(const std::string& name, std::vector<moveit_msgs::CollisionObject>& objs)
00215 {
00216 for (int i = 0; i < objs.size(); ++i)
00217 {
00218 if (objs[i].id == name)
00219 {
00220 objs.erase(objs.begin() + i);
00221 return true;
00222 }
00223 }
00224 return false;
00225 }
00226
00227
00228 bool GraspedObjectHandlerMoveIt::removeObject(const std::string& name, std::vector<moveit_msgs::AttachedCollisionObject>& objs)
00229 {
00230 for (int i = 0; i < objs.size(); ++i)
00231 {
00232 if (objs[i].object.id == name)
00233 {
00234 objs.erase(objs.begin() + i);
00235 return true;
00236 }
00237 }
00238 return false;
00239 }
00240
00241
00242 void GraspedObjectHandlerMoveIt::subscribeAndAdvertise(const std::string& get_planning_scene_service,
00243 const std::string& set_planning_scene_topic)
00244 {
00245 moveit_planning_scene_client = node.serviceClient<moveit_msgs::GetPlanningScene>(get_planning_scene_service);
00246 moveit_planning_scene_publisher = node.advertise<moveit_msgs::PlanningScene>(set_planning_scene_topic, 1);
00247 }
00248
00249 void GraspedObjectHandlerMoveIt::waitForSubscribers()
00250 {
00251 while (moveit_planning_scene_publisher.getNumSubscribers() == 0)
00252 {
00253 ROS_INFO_STREAM("GraspedObjectHandler: waiting for subscribers to "
00254 << moveit_planning_scene_publisher.getTopic() << "...");
00255 ros::Duration(0.5).sleep();
00256 }
00257 }
00258
00259 bool GraspedObjectHandlerMoveIt::transformPose(const geometry_msgs::Pose& pose,
00260 const std::string& from_frame, const std::string& to_frame, geometry_msgs::Pose& p)
00261 {
00262 if (to_frame.empty() || from_frame.empty())
00263 {
00264 ROS_ERROR("GraspObjectHandler::transformPose(): Both frames must be set.");
00265 return false;
00266 }
00267
00268 if (from_frame == to_frame)
00269 {
00270 p = pose;
00271 return true;
00272 }
00273
00274 geometry_msgs::PoseStamped newPose, resultPose;
00275 newPose.pose = pose;
00276 newPose.header.frame_id = from_frame;
00277 newPose.header.stamp = ros::Time(0);
00278 if (convenience_ros_functions::ROSFunctions::Singleton()->transformPose(newPose, to_frame, resultPose, 1) != 0)
00279 {
00280 ROS_ERROR("ObjectInfoManager: Transform into frame %s failed. Ignoring transform.", to_frame.c_str());
00281 return false;
00282 }
00283 p = resultPose.pose;
00284 return true;
00285 }
00286
00290 bool GraspedObjectHandlerMoveIt::transformCollisionObject(const std::string& to_frame,
00291 moveit_msgs::CollisionObject& collision_object)
00292 {
00293
00294 for (int i = 0; i < collision_object.primitive_poses.size(); ++i)
00295 {
00296 geometry_msgs::Pose& p = collision_object.primitive_poses[i];
00297 if (!transformPose(p, collision_object.header.frame_id, to_frame, p))
00298 {
00299 ROS_ERROR("GraspObjectHandler: Could not transform object to link frame %s", to_frame.c_str());
00300 return false;
00301 }
00302 if (i < collision_object.mesh_poses.size())
00303 {
00304 p = collision_object.mesh_poses[i];
00305 collision_object.mesh_poses[i] = p;
00306 if (!transformPose(p, collision_object.header.frame_id, to_frame, p))
00307 {
00308 ROS_ERROR("GraspObjectHandler: Could not transform object mesh to link frame %s", to_frame.c_str());
00309 return false;
00310 }
00311 }
00312 if (i < collision_object.plane_poses.size())
00313 {
00314 p = collision_object.plane_poses[i];
00315 collision_object.plane_poses[i] = p;
00316 if (!transformPose(p, collision_object.header.frame_id, to_frame, p))
00317 {
00318 ROS_ERROR("GraspObjectHandler: Could not transform object plane to link frame %s", to_frame.c_str());
00319 return false;
00320 }
00321 }
00322 }
00323 collision_object.header.frame_id = to_frame;
00324 collision_object.header.stamp = ros::Time::now();
00325 return true;
00326 }