entry_exit_strategies.cpp
Go to the documentation of this file.
1 #include <mutex>
2 #include <math.h>
3 
5 #include <ram_msgs/AdditiveManufacturingTrajectory.h>
6 #include <ros/ros.h>
7 
8 #include <ram_utils/AddEntryExitStrategies.h>
9 #include <ram_utils/EntryExitParameters.h>
10 
11 #include <unique_id/unique_id.h>
12 
13 ram_utils::EntryExitParameters entry_params;
14 ram_utils::EntryExitParameters exit_params;
15 
16 std::mutex params_mutex;
17 
18 bool entryParametersCallback(ram_utils::EntryExitParameters::Request &req,
19  ram_utils::EntryExitParameters::Response &)
20 {
21  std::lock_guard<std::mutex> lock(params_mutex);
22 
23  entry_params.request.angle = req.angle;
24  entry_params.request.distance = req.distance;
25  entry_params.request.number_of_poses = req.number_of_poses;
26  return true;
27 }
28 
29 bool exitParametersCallback(ram_utils::EntryExitParameters::Request &req,
30  ram_utils::EntryExitParameters::Response &)
31 {
32  std::lock_guard<std::mutex> lock(params_mutex);
33 
34  exit_params.request.angle = req.angle;
35  exit_params.request.distance = req.distance;
36  exit_params.request.number_of_poses = req.number_of_poses;
37  return true;
38 }
39 
40 bool entryStrategy(unsigned ref_pose_id,
41  std::vector<ram_msgs::AdditiveManufacturingPose> req_poses,
42  std::vector<ram_msgs::AdditiveManufacturingPose>&res_poses)
43 {
44  Eigen::Vector3d ref_vector(Eigen::Vector3d::Identity());
45 
46  if (req_poses.size() != 1)
47  {
48  ref_vector.x() = req_poses[ref_pose_id].pose.position.x - req_poses[ref_pose_id + 1].pose.position.x;
49  ref_vector.y() = req_poses[ref_pose_id].pose.position.y - req_poses[ref_pose_id + 1].pose.position.y;
50  ref_vector.z() = req_poses[ref_pose_id].pose.position.z - req_poses[ref_pose_id + 1].pose.position.z;
51  }
52 
53  double rho;
54  double phi;
55  double theta;
56 
57  ram_msgs::AdditiveManufacturingPose pose(req_poses[ref_pose_id]);
58  pose.params.laser_power = 0;
59  pose.params.feed_rate = 0;
60  pose.entry_pose = true;
61  pose.polygon_start = false;
62  pose.polygon_end = false;
63 
64  phi = atan2(ref_vector.y(), ref_vector.x());
65  theta = M_PI / 2 - entry_params.request.angle;
66 
67  for (unsigned j(entry_params.request.number_of_poses); j > 0; --j)
68  {
69  rho = entry_params.request.distance * j / entry_params.request.number_of_poses;
70 
71  ram_msgs::AdditiveManufacturingPose pose_tmp(pose);
72  //Spherical to Cartesian coordinates
73  pose_tmp.pose.position.x += rho * sin(theta) * cos(phi);
74  pose_tmp.pose.position.y += rho * sin(theta) * sin(phi);
75  pose_tmp.pose.position.z += rho * cos(theta);
76 
77  pose_tmp.unique_id = unique_id::toMsg(unique_id::fromRandom());
78  res_poses.push_back(pose_tmp);
79  }
80  return true;
81 }
82 
83 bool exitStrategy(unsigned ref_pose_id,
84  std::vector<ram_msgs::AdditiveManufacturingPose> req_poses,
85  std::vector<ram_msgs::AdditiveManufacturingPose>&res_poses)
86 {
87  Eigen::Vector3d ref_vector(Eigen::Vector3d::Identity());
88 
89  // Make sure it is not the only pose
90  // Make sure it is not the first pose
91  if (req_poses.size() != 1 && ref_pose_id != 0)
92  {
93  ref_vector.x() = req_poses[ref_pose_id].pose.position.x - req_poses[ref_pose_id - 1].pose.position.x;
94  ref_vector.y() = req_poses[ref_pose_id].pose.position.y - req_poses[ref_pose_id - 1].pose.position.y;
95  ref_vector.z() = req_poses[ref_pose_id].pose.position.z - req_poses[ref_pose_id - 1].pose.position.z;
96  }
97  double rho;
98  double phi;
99  double theta;
100 
101  ram_msgs::AdditiveManufacturingPose pose(req_poses[ref_pose_id]);
102  pose.params.laser_power = 0;
103  pose.params.feed_rate = 0;
104  pose.exit_pose = true;
105  pose.polygon_start = false;
106  pose.polygon_end = false;
107 
108  phi = atan2(ref_vector.y(), ref_vector.x());
109  theta = M_PI / 2 - exit_params.request.angle;
110 
111  for (unsigned j(1); j <= exit_params.request.number_of_poses; ++j)
112  {
113  rho = exit_params.request.distance * j / exit_params.request.number_of_poses;
114 
115  ram_msgs::AdditiveManufacturingPose pose_tmp(pose);
116  //Spherical to Cartesian coordinates
117  pose_tmp.pose.position.x += rho * sin(theta) * cos(phi);
118  pose_tmp.pose.position.y += rho * sin(theta) * sin(phi);
119  pose_tmp.pose.position.z += rho * cos(theta);
120 
121  pose_tmp.unique_id = unique_id::toMsg(unique_id::fromRandom());
122  res_poses.push_back(pose_tmp);
123  }
124  return true;
125 }
126 
127 int poseInPolygon(std::vector<ram_msgs::AdditiveManufacturingPose> poses,
128  unsigned pose_id)
129 {
130  int pose_in_polygon = 0;
131  for (unsigned i(0); i < poses.size(); ++i)
132  {
133  if (i == pose_id)
134  return pose_in_polygon;
135 
136  if (poses[i].polygon_start && poses[i].polygon_end)
137  continue;
138 
139  if (poses[i].polygon_start)
140  pose_in_polygon++;
141  if (poses[i].polygon_end)
142  pose_in_polygon--;
143  }
144  return -1;
145 }
146 
147 bool addEntryExitStrategiesCallback(ram_utils::AddEntryExitStrategies::Request &req,
148  ram_utils::AddEntryExitStrategies::Response &res)
149 {
150  std::lock_guard<std::mutex> lock(params_mutex);
151 
152  for (unsigned i(0); i < req.poses.size(); ++i)
153  {
154  bool limit_between_polygons = false;
155  bool add_entry_strategy = false;
156  bool add_exit_strategy = false;
157 
158  // * Special case. limit between to polygons
159  if (req.poses[i].polygon_start && req.poses[i].polygon_end)
160  {
161  int pose_in_polygon = poseInPolygon(req.poses, i);
162  if (pose_in_polygon < 0 || pose_in_polygon > 1)
163  return false;
164  if (pose_in_polygon == 1) // limit between to polygons .there should be no strategies
165  {
166  limit_between_polygons = true;
167 
168  if (i != 0 && req.poses[i - 1].entry_pose == true)
169  return false;
170  if (i != (req.poses.size() - 1) && req.poses[i + 1].exit_pose == true)
171  return false;
172  //
173  }
174  }
175 
176  // find polygon_start
177  if (req.poses[i].polygon_start)
178  {
179  // Add Entry Strategy
180  if (i == 0) //First Element
181  add_entry_strategy = true;
182  if (i != 0 && req.poses[i - 1].entry_pose == false)
183  add_entry_strategy = true;
184  }
185 
186  // find polygon_end
187  if (req.poses[i].polygon_end)
188  {
189  // Add Exit Pose
190  if (i == (req.poses.size() - 1)) //Last Element
191  add_exit_strategy = true;
192  if (i != (req.poses.size() - 1) && req.poses[i + 1].exit_pose == false)
193  add_exit_strategy = true;
194  }
195 
196  // ADD STRATEGIES
197  if (limit_between_polygons)
198  {
199  res.poses.push_back(req.poses[i]);
200  res.poses.back().polygon_start = false;
201 
202  exitStrategy(i, req.poses, res.poses);
203  add_exit_strategy = false;
204 
205  entryStrategy(i, req.poses, res.poses);
206  add_entry_strategy = false;
207 
208  res.poses.push_back(req.poses[i]);
209  res.poses.back().polygon_end = false;
210  res.poses.back().unique_id = unique_id::toMsg(unique_id::fromRandom());
211  }
212  else
213  {
214  if (add_entry_strategy)
215  {
216  entryStrategy(i, req.poses, res.poses);
217  add_entry_strategy = false;
218  }
219 
220  res.poses.push_back(req.poses[i]);
221 
222  if (add_exit_strategy)
223  {
224  exitStrategy(i, req.poses, res.poses);
225  add_exit_strategy = false;
226  }
227 
228  }
229  }
230 
231  return true;
232 }
233 
234 int main(int argc,
235  char** argv)
236 {
237  ros::init(argc, argv, "entry_exit_strategies");
239 
240  entry_params.request.angle = M_PI / 4; // 45 degrees (phi in spherical coordinates)
241  entry_params.request.distance = 0.05; // 5 cm
242  entry_params.request.number_of_poses = 1;
243 
244  exit_params.request.angle = M_PI / 4; // 45 degrees (phi in spherical coordinates)
245  exit_params.request.distance = 0.05; // 5 cm
246  exit_params.request.number_of_poses = 1;
247 
248  ros::ServiceServer service_1 = nh.advertiseService("ram/information/add_entry_exit_strategies",
250 
251  ros::ServiceServer service_2 = nh.advertiseService("ram/information/entry_parameters", entryParametersCallback);
252  ros::ServiceServer service_3 = nh.advertiseService("ram/information/exit_parameters", exitParametersCallback);
253 
255  spinner.start();
257  return 0;
258 }
static boost::uuids::uuid fromRandom(void)
std::unique_ptr< ros::NodeHandle > nh
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
ram_utils::EntryExitParameters exit_params
void spinner()
bool addEntryExitStrategiesCallback(ram_utils::AddEntryExitStrategies::Request &req, ram_utils::AddEntryExitStrategies::Response &res)
bool entryStrategy(unsigned ref_pose_id, std::vector< ram_msgs::AdditiveManufacturingPose > req_poses, std::vector< ram_msgs::AdditiveManufacturingPose > &res_poses)
int poseInPolygon(std::vector< ram_msgs::AdditiveManufacturingPose > poses, unsigned pose_id)
int main(int argc, char **argv)
bool exitParametersCallback(ram_utils::EntryExitParameters::Request &req, ram_utils::EntryExitParameters::Response &)
bool entryParametersCallback(ram_utils::EntryExitParameters::Request &req, ram_utils::EntryExitParameters::Response &)
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
static uuid_msgs::UniqueID toMsg(boost::uuids::uuid const &uu)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
std::mutex params_mutex
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
bool exitStrategy(unsigned ref_pose_id, std::vector< ram_msgs::AdditiveManufacturingPose > req_poses, std::vector< ram_msgs::AdditiveManufacturingPose > &res_poses)
ROSCPP_DECL void waitForShutdown()
ram_utils::EntryExitParameters entry_params


ram_utils
Author(s): Victor Lamoine - Institut Maupertuis
autogenerated on Mon Jun 10 2019 14:49:54