trajectory_info.cpp
Go to the documentation of this file.
1 #include <mutex>
2 
4 #include <ram_msgs/AdditiveManufacturingTrajectory.h>
5 #include <ram_msgs/AdditiveManufacturingTrajectoryInfo.h>
6 #include <ram_utils/GetLayerSize.h>
7 #include <ram_utils/GetNumberOfLayersLevels.h>
8 #include <ram_utils/GetTrajectoryInfos.h>
9 #include <ram_utils/GetTrajectorySize.h>
10 #include <ros/ros.h>
11 
12 std::mutex trajectory_mutex;
13 ram_msgs::AdditiveManufacturingTrajectory layers;
15 std::mutex traj_info_mutex;
16 ram_msgs::AdditiveManufacturingTrajectoryInfo traj_info;
17 
18 void trajReceived(const ram_msgs::AdditiveManufacturingTrajectory::Ptr& msg)
19 {
20  std::lock_guard<std::mutex> lock_1(trajectory_mutex);
21  std::lock_guard<std::mutex> lock_2(traj_info_mutex);
22 
23  layers = *msg;
24 
25  traj_info.file = msg->file;
26  traj_info.generation_info = msg->generation_info;
27  traj_info.generated = msg->generated;
28  traj_info.modified = msg->modified;
29  traj_info.similar_layers = msg->similar_layers;
30  traj_info.number_of_poses = msg->poses.size();
31 
32  traj_info.number_of_layers_levels = 0;
33  traj_info.number_of_layers_indices = 0;
34  traj_info.trajectory_length = 0;
35  traj_info.execution_time = 0;
36  traj_info.wire_length = 0;
37  if (msg->poses.empty())
38  {
39  pub_traj_info.publish(traj_info);
40  return;
41  }
42 
43  traj_info.number_of_layers_levels = msg->poses.back().layer_level + 1;
44  traj_info.number_of_layers_indices = msg->poses.back().layer_index + 1;
45 
46  unsigned polygon_count(0);
47  for (auto pose : msg->poses)
48  {
49  if (pose.polygon_start == true)
50  ++polygon_count;
51  }
52  traj_info.number_of_polygons = polygon_count;
53 
54  Eigen::Vector3d last_position(msg->poses.front().pose.position.x,
55  msg->poses.front().pose.position.y,
56  msg->poses.front().pose.position.z);
57  double last_speed(msg->poses.front().params.speed);
58  double last_feed_rate(msg->poses.front().params.feed_rate);
59  for (auto pose : msg->poses)
60  {
61  // Compute Euclidian distance
62  Eigen::Vector3d position(pose.pose.position.x, pose.pose.position.y, pose.pose.position.z);
63  Eigen::Vector3d difference(position - last_position);
64  traj_info.trajectory_length += difference.norm(); // Result is in meters
65 
66  // Compute time to go from pose A to pose B - we assume a mean speed
67  double speed(pose.params.speed);
68  // Divide speed at pose by 2 if approach type is 'FINE': this is arbitrary to simulate
69  // the fact that the robot will stop and then continue going
70  if (pose.params.approach_type == 0)
71  speed /= 2.0;
72 
73  const double mean_speed((last_speed + speed) / 2.0);
74  const double segment_time(difference.norm() / mean_speed);
75  traj_info.execution_time += segment_time; // Result is in seconds
76 
77  // Warning: This code is specific to the "feed_rate" unit!
78  // Institut Maupertuis: Wire deposition is in meters/second
79  double mean_feed_rate((last_feed_rate + pose.params.feed_rate) / 2.0);
80  traj_info.wire_length += segment_time * mean_feed_rate;
81 
82  last_position = position;
83  last_speed = speed;
84  }
85 
86  pub_traj_info.publish(traj_info);
87 }
88 
89 bool getTrajectorySizeCallback(ram_utils::GetTrajectorySize::Request &,
90  ram_utils::GetTrajectorySize::Response &res)
91 {
92  std::lock_guard<std::mutex> lock(trajectory_mutex);
93  res.trajectory_size = layers.poses.size();
94  return true;
95 }
96 
97 bool getNumberOfLayersLevelsCallback(ram_utils::GetNumberOfLayersLevels::Request &,
98  ram_utils::GetNumberOfLayersLevels::Response &res)
99 {
100  std::lock_guard<std::mutex> lock(trajectory_mutex);
101 
102  if (layers.poses.empty())
103  return false;
104 
105  // Even if a layer has been completely removed, the layer count will NOT change
106  unsigned max_layer_level = 0;
107  for (auto pose : layers.poses)
108  {
109  if (max_layer_level < pose.layer_level)
110  max_layer_level = pose.layer_level;
111  }
112 
113  res.number_of_layers = max_layer_level + 1; // The level of the first layer is zero
114  return true;
115 }
116 
117 bool getLayerSizeCallback(ram_utils::GetLayerSize::Request &req,
118  ram_utils::GetLayerSize::Response &res)
119 {
120  std::lock_guard<std::mutex> lock(trajectory_mutex);
121 
122  // Empty trajectory
123  if (layers.poses.empty())
124  return false;
125 
126  if (req.layer_level > layers.poses.back().layer_level)
127  return false;
128 
129  unsigned pose_count = 0;
130  for (auto &pose : layers.poses)
131  if (pose.layer_level == req.layer_level)
132  ++pose_count;
133 
134  res.layer_size = pose_count;
135 
136  return true;
137 }
138 
139 bool getTrajectoryInfosCallback(ram_utils::GetTrajectoryInfos::Request &,
140  ram_utils::GetTrajectoryInfos::Response &res)
141 {
142  std::lock_guard<std::mutex> lock(traj_info_mutex);
143  res.informations = traj_info;
144  return true;
145 }
146 
147 int main(int argc,
148  char** argv)
149 {
150  ros::init(argc, argv, "ram_utils_trajectory_info");
152 
154  spinner.start();
155 
156  // Subscribe to trajectory topic
157  ros::Subscriber traj = nh.subscribe("ram/trajectory", 10, trajReceived);
158 
159  // Publish trajectory info
160  pub_traj_info = nh.advertise<ram_msgs::AdditiveManufacturingTrajectoryInfo>("ram/information/trajectory", 1, true);
161 
162  ros::ServiceServer service_1 = nh.advertiseService("ram/information/get_trajectory_size", getTrajectorySizeCallback);
163  ros::ServiceServer service_2 = nh.advertiseService("ram/information/get_number_of_layers_levels",
165  ros::ServiceServer service_3 = nh.advertiseService("ram/information/get_layer_size", getLayerSizeCallback);
166  ros::ServiceServer service_4 = nh.advertiseService("ram/information/get_trajectory_infos", getTrajectoryInfosCallback);
167 
169  spinner.stop();
170  return 0;
171 }
int main(int argc, char **argv)
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::unique_ptr< ros::NodeHandle > nh
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool getNumberOfLayersLevelsCallback(ram_utils::GetNumberOfLayersLevels::Request &, ram_utils::GetNumberOfLayersLevels::Response &res)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void spinner()
ram_msgs::AdditiveManufacturingTrajectory layers
std::mutex traj_info_mutex
bool getLayerSizeCallback(ram_utils::GetLayerSize::Request &req, ram_utils::GetLayerSize::Response &res)
bool getTrajectorySizeCallback(ram_utils::GetTrajectorySize::Request &, ram_utils::GetTrajectorySize::Response &res)
bool getTrajectoryInfosCallback(ram_utils::GetTrajectoryInfos::Request &, ram_utils::GetTrajectoryInfos::Response &res)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ram_msgs::AdditiveManufacturingTrajectoryInfo traj_info
ros::Publisher pub_traj_info
void trajReceived(const ram_msgs::AdditiveManufacturingTrajectory::Ptr &msg)
std::mutex trajectory_mutex
ROSCPP_DECL void waitForShutdown()


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