task_sequence_processor.cpp
Go to the documentation of this file.
1 //
2 // Created by yijiangh on 6/25/17.
3 //
7 
9 
12 
15 
16 #include <ros/ros.h>
17 #include <ros/console.h>
18 #include <boost/filesystem.hpp>
19 
20 namespace
21 {
22 Eigen::Vector3d transformPoint(const Eigen::Vector3d &pt, const double &scale, const Eigen::Vector3d &ref_transf)
23 {
24  return (pt * scale + ref_transf);
25 }
26 
27 void scalePoseMsg(const double& scale, geometry_msgs::Pose& p)
28 {
29  p.position.x *= scale;
30  p.position.y *= scale;
31  p.position.z *= scale;
32 }
33 
34 void scalePoseFramefabMsg(const double& scale, choreo_msgs::Grasp& g)
35 {
36  scalePoseMsg(scale, g.pick_grasp_pose);
37  scalePoseMsg(scale, g.pick_grasp_approach_pose);
38  scalePoseMsg(scale, g.pick_grasp_retreat_pose);
39 
40  scalePoseMsg(scale, g.place_grasp_pose);
41  scalePoseMsg(scale, g.place_grasp_approach_pose);
42  scalePoseMsg(scale, g.place_grasp_retreat_pose);
43 }
44 }
45 
47 {
48  unit_scale_ = 1;
49  ref_pt_ = Eigen::Vector3d(0, 0, 0);
50  transf_vec_ = Eigen::Vector3d(0, 0, 0);
51  verbose_ = false;
52 }
53 
55  choreo_msgs::ModelInputParameters model_params,
56  choreo_msgs::TaskSequenceInputParameters task_sequence_params,
57  std::string world_frame)
58 {
59  model_input_params_ = model_params;
60  path_input_params_ = task_sequence_params;
61  world_frame_ = world_frame;
62 
63  // set unit scale
64  switch (model_input_params_.unit_type)
65  {
66  case choreo_msgs::ModelInputParameters::MILLIMETER:
67  {
68  unit_scale_ = 0.001;
69  break;
70  }
71  case choreo_msgs::ModelInputParameters::CENTIMETER:
72  {
73  unit_scale_ = 0.01;
74  break;
75  }
76  case choreo_msgs::ModelInputParameters::INCH:
77  {
78  unit_scale_ = 0.0254;
79  break;
80  }
81  case choreo_msgs::ModelInputParameters::FOOT:
82  {
83  unit_scale_ = 0.3048;
84  break;
85  }
86  default:
87  {
88  ROS_ERROR("Unrecognized Unit type in Model Input Parameters!");
89  }
90  }
91 
92  if(verbose_)
93  {
94  ROS_INFO_STREAM("unit type config succeeded! - unit_scale: " << unit_scale_);
95  }
96 
97  // element diameter and shrink length (scaled)
99  shrink_length_ = model_params.shrink_length * unit_scale_;
100 
101  // set ref point
102  ref_pt_ = Eigen::Vector3d(model_input_params_.ref_pt_x, model_input_params_.ref_pt_y, model_input_params_.ref_pt_z);
103 }
104 
106  const choreo_msgs::ModelInputParameters& model_params,
107  const choreo_msgs::TaskSequenceInputParameters& task_sequence_params,
108  const std::string& world_frame,
109  choreo_msgs::AssemblySequencePickNPlace& as_pnp)
110 {
111  this->setParams(model_params, task_sequence_params, world_frame);
112 
113  using namespace rapidjson;
114  using namespace choreo_geometry_conversion_helpers;
115 
116  // https://stackoverflow.com/questions/8520560/get-a-file-name-from-a-path
117  const std::string json_whole_path = task_sequence_params.file_path;
118  boost::filesystem::path boost_json_path(json_whole_path);
119 
120  FILE* fp = fopen(json_whole_path.c_str(), "r");
121 
122  assert(fp);
123 
124  char readBuffer[65536];
125  FileReadStream is(fp, readBuffer, sizeof(readBuffer));
126 
127  Document document;
128 
129  if(document.ParseStream(is).HasParseError())
130  {
131  ROS_ERROR_STREAM("TaskSequenceProcessor has ERROR parsing the input json file!");
132  return false;
133  }
134 
135  fclose(fp);
136 
137  assert(document.HasMember("assembly_type"));
138  std::string at = document["assembly_type"].GetString();
139 
140  // wire in assembly type
141  as_pnp.assembly_type = at;
142 
143  assert(document.HasMember("element_number"));
144  int e_num = document["element_number"].GetInt();
145 
146  // wire in element number
147  as_pnp.element_number = e_num;
148 
149  assert(document.HasMember("pick_base_center_point"));
150  assert(document.HasMember("place_base_center_point"));
151  const Value& pick_bcp = document["pick_base_center_point"];
152  const Value& place_bcp = document["place_base_center_point"];
153  Eigen::Vector3d pick_base_center_pt(pick_bcp["X"].GetDouble(), pick_bcp["Y"].GetDouble(), pick_bcp["Z"].GetDouble());
154  pick_base_center_pt *= unit_scale_;
155  Eigen::Vector3d place_base_center_pt(place_bcp["X"].GetDouble(), place_bcp["Y"].GetDouble(), place_bcp["Z"].GetDouble());
156  place_base_center_pt *= unit_scale_;
157 
158  // wire in base center point msg TODO: this should be a frame!!
159  tf::pointEigenToMsg(pick_base_center_pt, as_pnp.pick_base_center_point);
160  tf::pointEigenToMsg(place_base_center_pt, as_pnp.place_base_center_point);
161 
162  // wire in file path
163  as_pnp.file_path = boost_json_path.parent_path().string() + boost::filesystem::path::preferred_separator;
164 
165  // wire in support surfaces file name
166  assert(document.HasMember("pick_support_surface_file_names"));
167  assert(document["pick_support_surface_file_names"].IsArray());
168  as_pnp.pick_support_surface_file_names.clear();
169  for(int i=0; i<document["pick_support_surface_file_names"].Size();i++)
170  {
171  as_pnp.pick_support_surface_file_names.push_back(document["pick_support_surface_file_names"][i].GetString());
172  }
173 
174  assert(document.HasMember("place_support_surface_file_names"));
175  assert(document["place_support_surface_file_names"].IsArray());
176  as_pnp.place_support_surface_file_names.clear();
177  for(int i=0; i<document["place_support_surface_file_names"].Size();i++)
178  {
179  as_pnp.place_support_surface_file_names.push_back(document["place_support_surface_file_names"][i].GetString());
180  }
181 
182  if(0 == document["place_support_surface_file_names"].Size()
183  || 0 == document["pick_support_surface_file_names"].Size())
184  {
185  ROS_WARN_STREAM("task sequence processing: no pick and place support surfaces are found!");
186  }
187 
188  assert(document.HasMember("sequenced_elements"));
189  const Value& se_array = document["sequenced_elements"];
190  assert(se_array.Size() > 0);
191 
192  as_pnp.sequenced_elements.clear();
193 
194  for (SizeType i = 0; i < se_array.Size(); i++)
195  {
196  choreo_msgs::SequencedElement se_msg;
197 
198  const Value& se = se_array[i];
199 
200  assert(se.HasMember("order_id"));
201  se_msg.order_id = se["order_id"].GetInt();
202 
203  // https://www.boost.org/doc/libs/1_61_0/libs/filesystem/doc/reference.html
204  // last character includes separator
205  se_msg.file_path = boost_json_path.parent_path().string() + boost::filesystem::path::preferred_separator;
206 
207  assert(se.HasMember("pick_element_geometry_file_name"));
208  se_msg.pick_element_geometry_file_name = se["pick_element_geometry_file_name"].GetString();
209  // check file existence
210  assert(boost::filesystem::exists(se_msg.file_path + se_msg.pick_element_geometry_file_name));
211 
212  assert(se.HasMember("place_element_geometry_file_name"));
213  se_msg.place_element_geometry_file_name = se["place_element_geometry_file_name"].GetString();
214  assert(boost::filesystem::exists(se_msg.file_path + se_msg.place_element_geometry_file_name));
215 
216  if(se.HasMember("pick_support_surface_file_names"))
217  {
218  const Value& pick_surf_names = se["pick_support_surface_file_names"];
219  assert(pick_surf_names.IsArray());
220  se_msg.pick_support_surface_file_names.clear();
221 
222  for (SizeType j=0; j<pick_surf_names.Size(); j++)
223  {
224  assert(pick_surf_names[j].IsString());
225  assert(boost::filesystem::exists(se_msg.file_path + std::string(pick_surf_names[j].GetString())));
226  se_msg.pick_support_surface_file_names.push_back(std::string(pick_surf_names[j].GetString()));
227  }
228  }
229 
230  if(se.HasMember("place_support_surface_file_names"))
231  {
232  const Value &place_surf_names = se["place_support_surface_file_names"];
233  assert(place_surf_names.IsArray());
234  se_msg.place_support_surface_file_names.clear();
235 
236  for (SizeType j=0; j<place_surf_names.Size(); j++)
237  {
238  assert(place_surf_names[j].IsString());
239  assert(boost::filesystem::exists(se_msg.file_path + std::string(place_surf_names[j].GetString())));
240  se_msg.place_support_surface_file_names.push_back(std::string(place_surf_names[j].GetString()));
241  }
242  }
243 
244  if(se.HasMember("pick_contact_ngh_ids"))
245  {
246  const Value &pick_ngh_ids = se["pick_contact_ngh_ids"];
247  assert(pick_ngh_ids.IsArray());
248  se_msg.pick_contact_ngh_ids.clear();
249 
250  for (SizeType j=0; j<pick_ngh_ids.Size(); j++)
251  {
252  assert(pick_ngh_ids[j].IsInt());
253  se_msg.pick_contact_ngh_ids.push_back(pick_ngh_ids[j].GetInt());
254  }
255  }
256 
257  if(se.HasMember("place_contact_ngh_ids"))
258  {
259  const Value &place_ngh_ids = se["place_contact_ngh_ids"];
260  assert(place_ngh_ids.IsArray());
261  se_msg.place_contact_ngh_ids.clear();
262 
263  for (SizeType j=0; j<place_ngh_ids.Size(); j++)
264  {
265  assert(place_ngh_ids[j].IsInt());
266  se_msg.place_contact_ngh_ids.push_back(place_ngh_ids[j].GetInt());
267  }
268  }
269 
270  // data must include at least one grasp
271  assert(se.HasMember("grasps"));
272  assert(se["grasps"].IsArray() && se["grasps"].Size() > 0);
273 
274  se_msg.grasps.clear();
275 
276  for(SizeType j=0; j<se["grasps"].Size(); j++)
277  {
278  choreo_msgs::Grasp g_msg;
279 
280  jsonToGraspFrameFabMsg(se["grasps"][j], g_msg);
281  scalePoseFramefabMsg(unit_scale_, g_msg);
282 
283  se_msg.grasps.push_back(g_msg);
284  }
285 
286  as_pnp.sequenced_elements.push_back(se_msg);
287  }
288 
289 // ROS_INFO_STREAM(as_pnp);
290 
291  ROS_INFO_STREAM("[task sequence processor] assembly sequence [PICKNPLCAE] json parsing succeeded.");
292  return true;
293 }
294 
296 {
297  using namespace rapidjson;
298 
299  /* --- 1. Parse the input JSON file into a document --- */
300  std::string fpath = path_input_params_.file_path;
301 
302  FILE* fp = fopen(fpath.c_str(), "r");
303 
304  if(NULL == fp)
305  {
306  ROS_WARN_STREAM("[ts processor] seq result json file not found.");
307  return false;
308  }
309 
310  char readBuffer[65536];
311  FileReadStream is(fp, readBuffer, sizeof(readBuffer));
312 
313  Document document;
314 
315  if(document.ParseStream(is).HasParseError())
316  {
317  ROS_ERROR_STREAM("TaskSequenceProcessor has ERROR parsing the input json file!");
318  return false;
319  }
320 
321  fclose(fp);
322 
323  assert(document.HasMember("element_number"));
324  int m = document["element_number"].GetInt();
325 
326  assert(document.HasMember("base_center_pt"));
327  const Value& bcp = document["base_center_pt"];
328  Eigen::Vector3d base_center_pt(bcp[0].GetDouble(), bcp[1].GetDouble(), bcp[2].GetDouble());
329 
330  if(verbose_)
331  {
332  ROS_INFO_STREAM("model element member: " << m);
333  ROS_INFO_STREAM("base_center_pt: \n" << base_center_pt);
334  }
335 
336  setTransfVec(ref_pt_, base_center_pt, unit_scale_);
337 
338  assert(document.HasMember("sequenced_elements"));
339  const Value& process_path_array = document["sequenced_elements"];
340  assert(process_path_array.IsArray());
341 
342  path_array_.clear();
343 
344  for (SizeType i = 0; i < process_path_array.Size(); i++)
345  {
346  const Value& element_path = process_path_array[i];
347 
348  assert(element_path.HasMember("start_pt"));
349  Eigen::Vector3d st_pt(element_path["start_pt"][0].GetDouble(),
350  element_path["start_pt"][1].GetDouble(),
351  element_path["start_pt"][2].GetDouble());
352 
353  assert(element_path.HasMember("end_pt"));
354  Eigen::Vector3d end_pt(element_path["end_pt"][0].GetDouble(),
355  element_path["end_pt"][1].GetDouble(),
356  element_path["end_pt"][2].GetDouble());
357 
358  assert(element_path.HasMember("type"));
359  std::string type_str = element_path["type"].GetString();
360 
361  assert(element_path.HasMember("wireframe_id"));
362  int wireframe_id = element_path["wireframe_id"].GetInt();
363 
364  if(verbose_)
365  {
366  ROS_INFO_STREAM("element-" << i);
367  ROS_INFO_STREAM("start_pt:\n" << st_pt);
368  ROS_INFO_STREAM("end_pt:\n" << end_pt);
369  ROS_INFO_STREAM("element type - " << type_str);
370  }
371 
372  // fetch the feasible orients
373  std::vector<Eigen::Vector3d> feasible_orients;
374 
375  assert(element_path.HasMember("feasible_orientation"));
376  const Value& f_orients = element_path["feasible_orientation"];
377  assert(f_orients.IsArray());
378 
379  for(SizeType j = 0; j < f_orients.Size(); j++)
380  {
381  Eigen::Vector3d f_vec(f_orients[j][0].GetDouble(),
382  f_orients[j][1].GetDouble(),
383  f_orients[j][2].GetDouble());
384  feasible_orients.push_back(f_vec);
385 
386  if (verbose_)
387  {
388  ROS_INFO_STREAM("feasible orient[" << j << "] =\n" << f_vec);
389  }
390  }
391 
392  // create UnitProcess & Add UnitProcess into ProcessPath
393  path_array_.push_back(createScaledUnitProcess(i, wireframe_id, st_pt, end_pt, feasible_orients,
394  type_str, element_diameter_, shrink_length_));
395  }
396 
397  ROS_INFO_STREAM("[task sequence processor] task sequence json [spatial extrusion] parsing succeeded.");
398  return true;
399 }
400 
402 {
403  // for now, only a simple flat box, representing the build plate, is added.
404  // TODO: might need to use load mesh approach for user-customized scene collision setup
405  // https://github.com/JeroenDM/descartes_tutorials/blob/indigo-devel/tutorial_utilities/src/collision_object_utils.cpp
406 
407  moveit_msgs::CollisionObject collision_env_obj;
408  std::string env_obj_id = "env_obj_table";
409 
410  // table box's dimension
411  double dx = 1;
412  double dy = 1;
413  double dz = 0.03;
414 
415  // pose
416  Eigen::Affine3d rtn = Eigen::Translation3d(ref_pt_[0] * unit_scale_,
417  ref_pt_[1] * unit_scale_,
418  ref_pt_[2] * unit_scale_ - dz/2)
419  * Eigen::AngleAxisd(0, Eigen::Vector3d::UnitX())
420  * Eigen::AngleAxisd(0, Eigen::Vector3d::UnitY())
421  * Eigen::AngleAxisd(0, Eigen::Vector3d::UnitZ());
422  geometry_msgs::Pose pose;
423  tf::poseEigenToMsg(rtn, pose);
424 
425  collision_env_obj.id = env_obj_id;
426  collision_env_obj.header.frame_id = world_frame_;
427  collision_env_obj.operation = moveit_msgs::CollisionObject::ADD;
428 
429  shape_msgs::SolidPrimitive env_obj_solid;
430  env_obj_solid.type = shape_msgs::SolidPrimitive::BOX;
431  env_obj_solid.dimensions.resize(3);
432  env_obj_solid.dimensions[0] = dx;
433  env_obj_solid.dimensions[1] = dy;
434  env_obj_solid.dimensions[2] = dz;
435  collision_env_obj.primitives.push_back(env_obj_solid);
436  collision_env_obj.primitive_poses.push_back(pose);
437 
438  env_collision_objs_.push_back(collision_env_obj);
439  return true;
440 }
441 
444  int index, int wireframe_id,
445  Eigen::Vector3d st_pt, Eigen::Vector3d end_pt,
446  std::vector<Eigen::Vector3d> feasible_orients,
447  std::string type_str,
448  double element_diameter,
449  double shrink_length)
450 {
452  index, wireframe_id,
453  transformPoint(st_pt, unit_scale_, transf_vec_),
454  transformPoint(end_pt, unit_scale_, transf_vec_),
455  feasible_orients, type_str, element_diameter, shrink_length, world_frame_);
456 
457  return upp;
458 }
void setParams(choreo_msgs::ModelInputParameters model_params, choreo_msgs::TaskSequenceInputParameters task_sequence_params, std::string world_frame)
std::vector< choreo_task_sequence_processing_utils::UnitProcess > path_array_
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
void setTransfVec(const Eigen::Vector3d &ref_pt, const Eigen::Vector3d &base_center_pt, const double &scale)
void jsonToGraspFrameFabMsg(const rapidjson::Value &json, choreo_msgs::Grasp &g)
bool parseAssemblySequencePickNPlace(const choreo_msgs::ModelInputParameters &model_params, const choreo_msgs::TaskSequenceInputParameters &task_sequence_params, const std::string &world_frame_, choreo_msgs::AssemblySequencePickNPlace &as_pnp)
choreo_task_sequence_processing_utils::UnitProcess createScaledUnitProcess(int index, int wireframe_id, Eigen::Vector3d st_pt, Eigen::Vector3d end_pt, std::vector< Eigen::Vector3d > feasible_orients, std::string type_str, double element_diameter, double shrink_length)
#define ROS_WARN_STREAM(args)
choreo_msgs::TaskSequenceInputParameters path_input_params_
void pointEigenToMsg(const Eigen::Vector3d &e, geometry_msgs::Point &m)
#define ROS_INFO_STREAM(args)
#define ROS_ERROR_STREAM(args)
#define ROS_ERROR(...)
bool HasParseError() const
std::vector< moveit_msgs::CollisionObject > env_collision_objs_
GenericDocument & ParseStream(InputStream &is)


choreo_task_sequence_processor
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:29