construct_planning_scene.cpp
Go to the documentation of this file.
1 //
2 // Created by yijiangh on 4/9/18.
3 //
4 
6 
8 
10 
11 #include <shape_msgs/Mesh.h>
12 
13 #include <moveit_msgs/PlanningSceneComponents.h>
14 #include <moveit_msgs/ApplyPlanningScene.h>
15 #include <moveit_msgs/GetPlanningScene.h>
16 
17 #include <moveit_msgs/AttachedCollisionObject.h>
18 
19 #include <geometry_msgs/Point.h>
20 
21 const static std::string PICKNPLACE_EEF_NAME = "mit_arch_suction_gripper";
22 
23 const static std::string GET_PLANNING_SCENE_SERVICE = "get_planning_scene";
24 
25 // TODO: replace this hardcoded scale vector with parm input!!
26 const static Eigen::Vector3d MESH_SCALE_VECTOR = Eigen::Vector3d(0.001, 0.001, 0.001);
27 
28 namespace {
29 
30 void setEmptyPoseMsg(geometry_msgs::Pose& pose)
31 {
32  pose.position.x = 0.0;
33  pose.position.y = 0.0;
34  pose.position.z = 0.0;
35  pose.orientation.w= 0.0;
36  pose.orientation.x= 0.0;
37  pose.orientation.y= 0.0;
38  pose.orientation.z= 0.0;
39 }
40 
41 geometry_msgs::Point reversePointMsg(const geometry_msgs::Point& p)
42 {
43  geometry_msgs::Point rp;
44  rp.x = - p.x;
45  rp.y = - p.y;
46  rp.z = - p.z;
47  return rp;
48 }
49 
50 }
52 {
53 
54 void constructPlanningScene(const planning_scene::PlanningScenePtr base_scene,
55  const std::vector <moveit_msgs::CollisionObject> &add_cos,
56  const std::vector <moveit_msgs::CollisionObject> &remove_cos,
57  const std::vector <moveit_msgs::AttachedCollisionObject> &attach_objs,
58  const std::vector <moveit_msgs::AttachedCollisionObject> &detach_objs,
59  planning_scene::PlanningScenePtr s)
60 {
61  s = base_scene->diff();
62 
63  for(auto add_co : add_cos)
64  {
65  add_co.operation = moveit_msgs::CollisionObject::ADD;
66  assert(s->processCollisionObjectMsg(add_co));
67  }
68 
69  for(auto remove_co : remove_cos)
70  {
71  remove_co.operation = moveit_msgs::CollisionObject::REMOVE;
72  assert(s->processCollisionObjectMsg(remove_co));
73  }
74 
75  for(auto ato : attach_objs)
76  {
77  ato.object.operation = moveit_msgs::CollisionObject::ADD;
78  assert(s->processAttachedCollisionObjectMsg(ato));
79  }
80 
81  for(auto rto : detach_objs)
82  {
83  rto.object.operation = moveit_msgs::CollisionObject::REMOVE;
84  assert(s->processAttachedCollisionObjectMsg(rto));
85  }
86 }
87 
88 planning_scene::PlanningScenePtr constructPlanningScene(const planning_scene::PlanningScenePtr base_scene,
89  const std::vector <moveit_msgs::CollisionObject> &add_cos,
90  const std::vector <moveit_msgs::CollisionObject> &remove_cos,
91  const std::vector <moveit_msgs::AttachedCollisionObject> &attach_objs,
92  const std::vector <moveit_msgs::AttachedCollisionObject> &detach_objs)
93 {
94  planning_scene::PlanningScenePtr scene = base_scene->diff();
95  constructPlanningScene(base_scene, add_cos, remove_cos, attach_objs, detach_objs, scene);
96  return scene;
97 }
98 
99 void constructPlanningScenes(moveit::core::RobotModelConstPtr moveit_model,
100  const std::string& world_frame,
101  const choreo_msgs::AssemblySequencePickNPlace& as_pnp,
102  std::vector<std::vector<planning_scene::PlanningScenePtr>>& planning_scenes_transition,
103  std::vector<std::vector<planning_scene::PlanningScenePtr>>& planning_scenes_subprocess)
104 {
105  using namespace choreo_geometry_conversion_helpers;
106 
107  const auto build_scenes_start = ros::Time::now();
108 
109  // parse all the collision objects, they are naturally named after id number
110  std::vector <moveit_msgs::CollisionObject> pick_cos;
111  std::vector <moveit_msgs::CollisionObject> place_cos;
112 
113  std::map <std::string, moveit_msgs::CollisionObject> pick_support_surfaces;
114  std::map <std::string, moveit_msgs::CollisionObject> place_support_surfaces;
115 
116  int overall_process_num = as_pnp.sequenced_elements.size();
117  planning_scenes_transition.resize(overall_process_num);
118  planning_scenes_subprocess.resize(overall_process_num);
119 
120  // TODO: replace this hard-coded eef name!!
121  // TODO: not sure if this is the right ik link
122  const robot_model::JointModelGroup *eef = moveit_model->getEndEffector(PICKNPLACE_EEF_NAME);
123  assert(eef);
124  const std::string &ik_link = eef->getEndEffectorParentGroup().second;
125 
126 // ROS_INFO_STREAM("ik link: " << ik_link);
127 
128  // use empty pose for all objs, as the positions are built in the mesh itself (using global base frame)
129  geometry_msgs::Pose empty_pose;
130  setEmptyPoseMsg(empty_pose);
131 
132  // TODO: maybe should use file name explicitly here, to be safer
133  for(const std::string &pn : as_pnp.pick_support_surface_file_names)
134  {
135  pick_support_surfaces[pn] = savedSTLToCollisionObjectMsg(
136  as_pnp.file_path + pn,
138  world_frame,
139  empty_pose);
140  }
141 
142  for(const std::string &pn : as_pnp.place_support_surface_file_names)
143  {
144  place_support_surfaces[pn] = savedSTLToCollisionObjectMsg(
145  as_pnp.file_path + pn,
147  world_frame,
148  empty_pose);
149  }
150 
151  for(const auto &se : as_pnp.sequenced_elements)
152  {
153  // construct pick element collision mesh
154  pick_cos.push_back(
156  se.file_path + se.pick_element_geometry_file_name,
158  world_frame,
159  empty_pose));
160 
161  place_cos.push_back(
163  se.file_path + se.place_element_geometry_file_name,
165  world_frame,
166  empty_pose));
167 
168  assert(se.order_id == pick_cos.size() - 1 && se.order_id == place_cos.size() - 1);
169  }
170 
171  assert(pick_cos.size() == as_pnp.sequenced_elements.size());
172  assert(place_cos.size() == as_pnp.sequenced_elements.size());
173 
174  // construct planning scene
175 
176  // get current planning scene as base scene
177  ros::NodeHandle nh;
178  auto planning_scene_client = nh.serviceClient<moveit_msgs::GetPlanningScene>(GET_PLANNING_SCENE_SERVICE);
179 
180  if (!planning_scene_client.waitForExistence())
181  {
182  ROS_ERROR_STREAM("[Process Planning] cannot connect with get planning scene server...");
183  }
184 
185  moveit_msgs::GetPlanningScene srv;
186  srv.request.components.components =
187  moveit_msgs::PlanningSceneComponents::ROBOT_STATE
188  | moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY;
189 
190  if (!planning_scene_client.call(srv))
191  {
192  ROS_ERROR_STREAM("[Process Planning] Failed to fetch planning scene srv!");
193  }
194 
195  planning_scene::PlanningScenePtr root_scene(new planning_scene::PlanningScene(moveit_model));
196  root_scene->getCurrentStateNonConst().setToDefaultValues();
197  root_scene->getCurrentStateNonConst().update();
198  root_scene->setPlanningSceneDiffMsg(srv.response.scene);
199 
200  // TODO: if a material feeder (repetitive picking) is used
201  // TODO: this part needs to be changed as these blocks will collide
202  // add all pick elements to the init pick scene
203  for(int i = 0; i < as_pnp.sequenced_elements.size(); i++)
204  {
205  pick_cos[i].operation = pick_cos[i].ADD;
206  assert(root_scene->processCollisionObjectMsg(pick_cos[i]));
207  }
208 
209  moveit_msgs::AttachedCollisionObject last_attached_co;
210 
211  for(int i=0; i < as_pnp.sequenced_elements.size(); i++)
212  {
213  const auto& se = as_pnp.sequenced_elements[i];
214  assert(i == se.order_id);
215 
216  // transition 2 pick
217  planning_scene::PlanningScenePtr last_place_scene = 0==i ? root_scene : planning_scenes_subprocess[i-1].back();
218 
219  auto tr2pick_scene = last_place_scene->diff();
220 
221  // add last place element
222  if(i > 0)
223  {
224 // // remove attach last element to end effector
225 // assert(last_attached_co.object.meshes.size() > 0 || last_attached_co.object.primitives.size() > 0);
226 // last_attached_co.object.operation = last_attached_co.object.REMOVE;
227 // assert(tr2pick_scene->processAttachedCollisionObjectMsg(last_attached_co));
228 
229  place_cos[i-1].operation = place_cos[i-1].ADD;
230  assert(tr2pick_scene->processCollisionObjectMsg(place_cos[i-1]));
231  }
232 
233  planning_scenes_transition[i].push_back(tr2pick_scene);
234 
235 // ROS_INFO_STREAM("#" << i << ": tr 2 pick");
236 
237  // pick: approach - pick - depart
238  auto pick_scene = tr2pick_scene->diff();
239 
240  // remove pick element
241  pick_cos[i].operation = pick_cos[i].REMOVE;
242  assert(pick_scene->processCollisionObjectMsg(pick_cos[i]));
243 
244  // TODO: maybe try only use attached one here?
245  // attach pick element to ee
246  // TODO: needs to apply a "reverse" linear transformation using the grasp pose
247 // last_attached_co.object = pick_cos[i];
248 // assert(last_attached_co.object.mesh_poses.size() > 0);
249 // assert(se.grasps.size() > 0);
250 // last_attached_co.object.header.frame_id = ik_link;
251 // last_attached_co.object.mesh_poses[0].position = reversePointMsg(se.grasps[0].pick_grasp_pose.position);
252 //
253 // last_attached_co.link_name = ik_link;
254 // last_attached_co.object.operation = last_attached_co.object.ADD;
255 // assert(pick_scene->processAttachedCollisionObjectMsg(last_attached_co));
256 
257  // approach and depart
258  planning_scenes_subprocess[i].push_back(pick_scene);
259 
260  planning_scenes_transition[i].push_back(pick_scene);
261 
262  planning_scenes_subprocess[i].push_back(pick_scene);
263 
264 // ROS_INFO_STREAM("#" << i << ": pick");
265 
266  // transition 2 place
267  auto tr2place_scene = pick_scene->diff();
268 
269 // TODO: maybe try only use attached one here? WIP
270 // attach pick element to ee
271 // TODO: needs to apply a "reverse" linear transformation using the grasp pose
272 // last_attached_co.object = pick_cos[i];
273 // assert(last_attached_co.object.mesh_poses.size() > 0);
274 // assert(se.grasps.size() > 0);
275 // last_attached_co.object.header.frame_id = ik_link;
276 //
277 // Eigen::Affine3d pick_pose, obj_pose_in_gripper = Eigen::Affine3d::Identity();
278 // tf::poseMsgToEigen(se.grasps[0].pick_grasp_pose, pick_pose);
279 //
280 // obj_pose_in_gripper.linear() = pick_pose.linear();
281 // obj_pose_in_gripper.translation() = - obj_pose_in_gripper.linear();
282 //
283 // tf::poseEigenToMsg(obj_pose_in_gripper, last_attached_co.object.mesh_poses[0]);
284 
285 // last_attached_co.object.mesh_poses[0].position = reversePointMsg(se.grasps[0].pick_grasp_pose.position);
286 
287 // last_attached_co.link_name = ik_link;
288 // last_attached_co.object.operation = last_attached_co.object.ADD;
289 // assert(tr2place_scene->processAttachedCollisionObjectMsg(last_attached_co));
290 
291  planning_scenes_transition[i].push_back(tr2place_scene);
292 
293 // ROS_INFO_STREAM("#" << i << ": tr 2 place");
294 
295  // place: approach - place (drop) - depart
296  auto place_scene = tr2place_scene->diff();
297 
298  // remove pick attached element
299  last_attached_co.object.operation = last_attached_co.object.REMOVE;
300  assert(place_scene->processAttachedCollisionObjectMsg(last_attached_co));
301  // cancel this "auto-release" from removing an attached obj
302  assert(place_scene->processCollisionObjectMsg(last_attached_co.object));
303 
304 // // TODO: needs to apply a "reverse" linear transformation using the grasp pose
305 // last_attached_co.object = place_cos[i];
306 // assert(last_attached_co.object.mesh_poses.size() > 0);
307 // assert(se.grasps.size() > 0);
308 // last_attached_co.object.header.frame_id = ik_link;
309 // last_attached_co.object.mesh_poses[0].position = reversePointMsg(se.grasps[0].place_grasp_pose.position);
310 
311 // last_attached_co.link_name = ik_link;
312 // last_attached_co.object.operation = last_attached_co.object.ADD;
313 // assert(place_scene->processAttachedCollisionObjectMsg(last_attached_co));
314 
315  planning_scenes_subprocess[i].push_back(place_scene);
316 
317  planning_scenes_transition[i].push_back(place_scene);
318 
319  planning_scenes_subprocess[i].push_back(place_scene);
320 
321 // ROS_INFO_STREAM("#" << i << ": place");
322 
323  // TODO: are we ignoring element on hold with its neighbor in the picking or placing process?
324  // Allowed Collision Object
325 // collision_detection::AllowedCollisionMatrix
326 // pick_acm, place_acm = root_scene->getAllowedCollisionMatrixNonConst();
327 //
328 // // during picking, end effector is allowed to touch the pick block
329 // // pick block is allowed to touch neighboring blocks and support surface
330 // pick_acm.setEntry(ik_link, se.pick_element_geometry_file_name, true);
331 //
332 // for(const auto& id : se.pick_contact_ngh_ids)
333 // {
334 // pick_acm.setEntry(se.pick_element_geometry_file_name, pick_cos[id].id, true);
335 // }
336 //
337 // for(const auto& id : se.pick_support_surface_file_names)
338 // {
339 // pick_acm.setEntry(se.pick_element_geometry_file_name, pick_support_surfaces[id].id, true);
340 // }
341 //
342 // pick_acms.push_back(pick_acm);
343 //
344 // // during placing, end effector is allowed to touch the place block
345 // // place block is allowed to touch neighboring blocks and support surface
346 // place_acm.setEntry(ik_link, se.place_element_geometry_file_name, true);
347 //
348 // for(const auto& id : se.place_contact_ngh_ids)
349 // {
350 // place_acm.setEntry(se.place_element_geometry_file_name, place_cos[id].id, true);
351 // }
352 //
353 // for(const auto& id : se.place_support_surface_file_names)
354 // {
355 // place_acm.setEntry(se.place_element_geometry_file_name, place_support_surfaces[id].id, true);
356 // }
357 //
358 // place_acms.push_back(place_acm);
359  }
360 
361  const auto build_scenes_end = ros::Time::now();
363  "[Process Planning] constructing planning scenes took " << (build_scenes_end - build_scenes_start).toSec()
364  << " seconds.");
365 }
366 
367 void constructPlanningScenes(moveit::core::RobotModelConstPtr moveit_model,
368  const std::vector <choreo_msgs::WireFrameCollisionObject> &wf_collision_objs,
369  std::vector <planning_scene::PlanningScenePtr> &planning_scenes_shrinked_approach,
370  std::vector <planning_scene::PlanningScenePtr> &planning_scenes_shrinked_depart,
371  std::vector <planning_scene::PlanningScenePtr> &planning_scenes_full)
372 {
373  const auto build_scenes_start = ros::Time::now();
374 
375  planning_scenes_shrinked_approach.reserve(wf_collision_objs.size());
376  planning_scenes_shrinked_depart.reserve(wf_collision_objs.size());
377  planning_scenes_full.reserve(wf_collision_objs.size());
378 
379  ros::NodeHandle nh;
380  auto planning_scene_client = nh.serviceClient<moveit_msgs::GetPlanningScene>(GET_PLANNING_SCENE_SERVICE);
381 
382  if (!planning_scene_client.waitForExistence())
383  {
384  ROS_ERROR_STREAM("[Process Planning] cannot connect with get planning scene server...");
385  }
386 
387  moveit_msgs::GetPlanningScene srv;
388  srv.request.components.components =
389  moveit_msgs::PlanningSceneComponents::ROBOT_STATE
390  | moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY;
391 
392  if (!planning_scene_client.call(srv))
393  {
394  ROS_ERROR_STREAM("[Process Planning] Failed to fetch planning scene srv!");
395  }
396 
397  planning_scene::PlanningScenePtr root_scene(new planning_scene::PlanningScene(moveit_model));
398  root_scene->getCurrentStateNonConst().setToDefaultValues();
399  root_scene->getCurrentStateNonConst().update();
400  root_scene->setPlanningSceneDiffMsg(srv.response.scene);
401 
402  // start with no element constructed in the scene
403  planning_scenes_shrinked_approach.push_back(root_scene);
404  planning_scenes_shrinked_depart.push_back(root_scene);
405  planning_scenes_full.push_back(root_scene);
406 
407  for (std::size_t i = 1; i < wf_collision_objs.size(); ++i) // We use all but the last collision object
408  {
409  auto last_scene_shrinked = planning_scenes_shrinked_approach.back();
410  auto child_shrinked = last_scene_shrinked->diff();
411 
412  auto c_list = wf_collision_objs[i].recovered_last_neighbor_objs;
413  c_list.push_back(wf_collision_objs[i].last_full_obj);
414 
415  const auto &shrinked_neighbor_objs = wf_collision_objs[i].shrinked_neighbor_objs;
416  c_list.insert(c_list.begin(), shrinked_neighbor_objs.begin(), shrinked_neighbor_objs.end());
417 
418  for (const auto &c_obj : c_list)
419  {
420  if (!child_shrinked->processCollisionObjectMsg(c_obj))
421  {
422  ROS_WARN("[Process Planning] Failed to process shrinked collision object");
423  }
424  }
425 
426  auto child_shrinked_depart = child_shrinked->diff();
427  if (!child_shrinked_depart->processCollisionObjectMsg(wf_collision_objs[i].both_side_shrinked_obj))
428  {
429  ROS_WARN("[Process Planning] Failed to process shrinked collision object");
430  }
431 
432  // push in partial_collision_geometry_planning_scene
433  planning_scenes_shrinked_approach.push_back(child_shrinked);
434  planning_scenes_shrinked_depart.push_back(child_shrinked_depart);
435 
436  // get diff as child
437  // restore changed element back to full geometry
438  // push in full_collision_geometry_planning_scene
439  auto last_scene_full = planning_scenes_full.back();
440  auto child_full = last_scene_full->diff();
441 
442  // TODO: temp fix
443  auto inflated_full_obj = wf_collision_objs[i - 1].full_obj;
444 // inflated_full_obj.primitives[0].dimensions[1] += 0.0;
445 
446  if (!child_full->processCollisionObjectMsg(inflated_full_obj))
447  {
448  ROS_WARN("[Process Planning] Failed to process full collision object");
449  }
450 
451  // push in full_scene[i]
452  planning_scenes_full.push_back(child_full);
453  }
454 
455  const auto build_scenes_end = ros::Time::now();
457  "[Process Planning] constructing planning scenes took " << (build_scenes_end - build_scenes_start).toSec()
458  << " seconds.");
459 }
460 
461 }
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
#define ROS_WARN(...)
void constructPlanningScenes(moveit::core::RobotModelConstPtr moveit_model, const std::string &world_frame, const choreo_msgs::AssemblySequencePickNPlace &as_pnp, std::vector< std::vector< planning_scene::PlanningScenePtr >> &planning_scenes_transition, std::vector< std::vector< planning_scene::PlanningScenePtr >> &planning_scenes_subprocess)
void savedSTLToCollisionObjectMsg(const std::string &file_path, const Eigen::Vector3d &scale_vector, const std::string &frame_id, const geometry_msgs::Pose &p, moveit_msgs::CollisionObject &co, int object_operation=moveit_msgs::CollisionObject::ADD)
static const std::string PICKNPLACE_EEF_NAME
#define ROS_INFO_STREAM(args)
void constructPlanningScene(const planning_scene::PlanningScenePtr base_scene, const std::vector< moveit_msgs::CollisionObject > &add_cos, const std::vector< moveit_msgs::CollisionObject > &remove_cos, const std::vector< moveit_msgs::AttachedCollisionObject > &attach_objs, const std::vector< moveit_msgs::AttachedCollisionObject > &detach_objs, planning_scene::PlanningScenePtr s)
static Time now()
#define ROS_ERROR_STREAM(args)
static const std::string GET_PLANNING_SCENE_SERVICE
static const Eigen::Vector3d MESH_SCALE_VECTOR


choreo_process_planning
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:02