choreo_output_processor.cpp
Go to the documentation of this file.
1 //
2 // Created by yijiangh on 9/10/17.
3 //
4 
5 #include <ros/ros.h>
6 #include <ros/console.h>
7 
9 
13 
14 //msg
15 #include <trajectory_msgs/JointTrajectoryPoint.h>
16 
19 
20 namespace
21 {
22 std::string translateProcessType(const int& process_type_id)
23 {
24  // ref choreo_msgs/SubProcess.msg process_type table
25  switch(process_type_id)
26  {
27  case 0:
28  {
29  return std::string("Process");
30  }
31  case 1:
32  {
33  return std::string("Retraction");
34  }
35  case 2:
36  {
37  return std::string("Transition");
38  }
39  default:
40  {
41  ROS_WARN("[output processor] Unknown process_type. Save default 'None' type.");
42  return std::string("Unknown");
43  }
44  }
45 }
46 
47 std::string translateMainDataType(const int& main_data_type_id)
48 {
49  // ref choreo_msgs/SubProcess.msg main_data_type_type table
50  switch(main_data_type_id)
51  {
52  case -1:
53  {
54  return std::string("Joint");
55  }
56  case -2:
57  {
58  return std::string("Cartesian");
59  }
60  default:
61  {
62  ROS_ERROR("[output processor] Unknown process_type. Save default 'Joint' type.");
63  return std::string("Joint");
64  }
65  }
66 }
67 
68 std::string translateElementProcessType(const int& element_process_type_id)
69 {
70  // ref choreo_msgs/SubProcess.msg element_process_type table
71  switch(element_process_type_id)
72  {
73  case 3:
74  {
75  return std::string("Support");
76  }
77  case 4:
78  {
79  return std::string("Create");
80  }
81  case 5:
82  {
83  return std::string("Connect");
84  }
85  case 6:
86  {
87  return std::string("None");
88  }
89  case 7:
90  {
91  return std::string("Approach");
92  }
93  case 8:
94  {
95  return std::string("Depart");
96  }
97  default:
98  {
99 // ROS_WARN("[output processor] Unknown element_process_type. Save default 'None' type");
100  return std::string("None");
101  }
102  }
103 }
104 
105 std::string translateAxisName(const int& axis_id)
106 {
107  switch (axis_id)
108  {
109  case 0:
110  {
111  return std::string("x");
112  }
113  case 1:
114  {
115  return std::string("y");
116  }
117  case 2:
118  {
119  return std::string("z");
120  }
121  }
122 }
123 }// name space util
124 
125 
126 bool choreo_output_processor::OutputProcessor::outputJson(std::vector<choreo_msgs::UnitProcessPlan>& plans)
127 {
128  using namespace rapidjson;
129 
130  // document is the root of a json message
131  rapidjson::Document document;
132 
133  // define the document as an object rather than an array
134  document.SetObject();
135 
136  // must pass an allocator when the object may need to allocate memory
137  rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
138 
139  document.AddMember("process_num", plans.size(), allocator);
140 // document.AddMember("support_num", support_, allocator);
141 
142  Value process_plans_container(rapidjson::kArrayType);
143 
144  for(const auto& unit_process_plan : plans)
145  {
146  rapidjson::Value unit_process_plan_container(rapidjson::kArrayType);
147 
148  for (const auto &sub_process : unit_process_plan.sub_process_array)
149  {
150  rapidjson::Value sub_process_object_container(rapidjson::kObjectType);
151 
152  // parent_unit_process_plan_id
153  sub_process_object_container.AddMember("parent_unit_process_plan_id", sub_process.unit_process_id, allocator);
154 
155  // subprocess_id
156  sub_process_object_container.AddMember("sub_process_id", sub_process.sub_process_id, allocator);
157 
158  // process_type
159  sub_process_object_container.AddMember("process_type",
160  Value().SetString(translateProcessType(sub_process.process_type).c_str(), allocator),
161  allocator);
162 
163  // element_process_type
164  sub_process_object_container.AddMember("element_process_type",
165  Value().SetString(translateElementProcessType(sub_process.element_process_type).c_str(), allocator),
166  allocator);
167 
168  // main_data_type
169  sub_process_object_container.AddMember("main_data_type",
170  Value().SetString(translateMainDataType(sub_process.main_data_type).c_str(), allocator),
171  allocator);
172 
173  // TODO comment msg
174 
175  // joint_array
176  rapidjson::Value joint_array_container(rapidjson::kArrayType);
177 
178  for(const auto& joint_pt : sub_process.joint_array.points)
179  {
180  rapidjson::Value joint_pt_container(rapidjson::kArrayType);
181 
182  // add robot joint values
183  for (const auto& joint_value : joint_pt.positions)
184  {
185  joint_pt_container.PushBack(Value().SetDouble(joint_value), allocator);
186  }
187 
188  joint_array_container.PushBack(joint_pt_container, allocator);
189  }
190 
191  sub_process_object_container.AddMember("joint_array", joint_array_container, allocator);
192 
193  // TCP_pose_array
194  rapidjson::Value TCP_pose_array_container(rapidjson::kArrayType);
195 
196  for(const auto& TCP_pose_pt : sub_process.TCP_pose_array)
197  {
198  // add robot joint values
199  rapidjson::Value TCP_pose_pt_container(rapidjson::kObjectType);
200 
201  // from geometry pose to affine3d matrix
202  Eigen::Affine3d m;
203  tf::poseMsgToEigen(TCP_pose_pt, m);
204  Eigen::Matrix3d orientation = m.matrix().block<3,3>(0,0);
205  Eigen::Vector3d position = m.matrix().col(3).head<3>();
206 
207  // add axes
208  for(int i=0; i < 3; i++)
209  {
210  rapidjson::Value axis_vector3d_container(rapidjson::kArrayType);
211  // x, y, z axis
212  for (int j = 0; j < 3; j++)
213  {
214  // coordinates for axis
215  axis_vector3d_container.PushBack(Value().SetDouble(orientation.col(i)[j]), allocator);
216  }
217 
218  std::string axis_name = "axis_" + translateAxisName(i);
219  TCP_pose_pt_container.AddMember(Value().SetString(axis_name.c_str(), allocator), axis_vector3d_container, allocator);
220  }
221 
222  // add origin position
223  rapidjson::Value TCP_origin_container(rapidjson::kArrayType);
224  for (int j = 0; j < 3; j++)
225  {
226  TCP_origin_container.PushBack(Value().SetDouble(position[j]), allocator);
227  }
228  TCP_pose_pt_container.AddMember("origin", TCP_origin_container, allocator);
229 
230  // add TCP pose into TCP_array
231  TCP_pose_array_container.PushBack(TCP_pose_pt_container, allocator);
232  }
233 
234  sub_process_object_container.AddMember("TCP_pose_array", TCP_pose_array_container, allocator);
235 
236  // end sub process adding
237  unit_process_plan_container.PushBack(sub_process_object_container, allocator);
238  } // end subprocess
239 
240  process_plans_container.PushBack(unit_process_plan_container, allocator);
241  }
242 
243  document.AddMember("process_plans", process_plans_container, allocator);
244 
245  // output files to path
246  FILE *js_file = fopen(this->save_file_path_.c_str(), "w+");
247  if(NULL == js_file)
248  {
249  ROS_ERROR("[output_processor]: invalid output file path!!!");
250  }
251 
252  char writeBuffer[65536];
253  FileWriteStream os(js_file, writeBuffer, sizeof(writeBuffer));
254 
255  PrettyWriter<FileWriteStream> p_writer(os);
256  document.Accept(p_writer);
257 
258  std::fclose(js_file);
259  ROS_INFO("[output_processor] json output file saved successfully!");
260 
261  return true;
262 }
void poseMsgToEigen(const geometry_msgs::Pose &m, Eigen::Affine3d &e)
#define ROS_WARN(...)
#define ROS_INFO(...)
bool outputJson(std::vector< choreo_msgs::UnitProcessPlan > &plans)
#define ROS_ERROR(...)


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