node.cpp
Go to the documentation of this file.
1 #include <memory>
2 #include <numeric>
3 #include <ros/ros.h>
4 #include <std_msgs/Float32.h>
5 #include <std_msgs/Float64.h>
6 #include <std_msgs/Int16.h>
7 #include <std_msgs/Int32.h>
8 #include <std_msgs/Int64.h>
9 #include <std_msgs/Int8.h>
10 #include <std_msgs/UInt16.h>
11 #include <std_msgs/UInt32.h>
12 #include <std_msgs/UInt64.h>
13 #include <std_msgs/UInt8.h>
14 
15 std::unique_ptr<ros::NodeHandle> nh;
16 std::unique_ptr<ros::Publisher> pub;
17 
19 std::vector<std::pair<ros::Time, int64_t>> time_values_i;
20 std::vector<std::pair<ros::Time, uint64_t>> time_values_u;
21 std::vector<std::pair<ros::Time, double>> time_values_d;
22 
23 template <class T, class U>
24 void callbackI(const T &msg)
25 {
26  const ros::Time now(ros::Time::now());
27  // Add new value
28  time_values_d.emplace_back(now, msg->data);
29 
30  // Remove values that are too old
31  for (auto it(time_values_d.begin()); it != time_values_d.end();)
32  {
33  ros::Duration delta(now - it->first);
34  if (delta > window_length)
35  time_values_d.erase(it);
36  else
37  break;
38  }
39 
40  // Compute and publish mean
41  long long int sum(0);
42  for (auto tv : time_values_d)
43  sum += tv.second;
44  U mean;
45  mean.data = sum / time_values_d.size();
46  pub->publish(mean);
47 }
48 
49 void callbackInt8(const std_msgs::Int8ConstPtr &msg)
50 {
51  callbackI<std_msgs::Int8ConstPtr, std_msgs::Int8>(msg);
52 }
53 
54 void callbackInt16(const std_msgs::Int16ConstPtr &msg)
55 {
56  callbackI<std_msgs::Int16ConstPtr, std_msgs::Int16>(msg);
57 }
58 
59 void callbackInt32(const std_msgs::Int32ConstPtr &msg)
60 {
61  callbackI<std_msgs::Int32ConstPtr, std_msgs::Int32>(msg);
62 }
63 
64 void callbackInt64(const std_msgs::Int64ConstPtr &msg)
65 {
66  callbackI<std_msgs::Int64ConstPtr, std_msgs::Int64>(msg);
67 }
68 
69 template <class T, class U>
70 void callbackU(const T &msg)
71 {
72  const ros::Time now(ros::Time::now());
73  // Add new value
74  time_values_d.emplace_back(now, msg->data);
75 
76  // Remove values that are too old
77  for (auto it(time_values_d.begin()); it != time_values_d.end();)
78  {
79  ros::Duration delta(now - it->first);
80  if (delta > window_length)
81  time_values_d.erase(it);
82  else
83  break;
84  }
85 
86  // Compute and publish mean
87  long long unsigned sum(0);
88  for (auto tv : time_values_d)
89  sum += tv.second;
90  U mean;
91  mean.data = sum / time_values_d.size();
92  pub->publish(mean);
93 }
94 
95 void callbackUInt8(const std_msgs::UInt8ConstPtr &msg)
96 {
97  callbackU<std_msgs::UInt8ConstPtr, std_msgs::UInt8>(msg);
98 }
99 
100 void callbackUInt16(const std_msgs::UInt16ConstPtr &msg)
101 {
102  callbackU<std_msgs::UInt16ConstPtr, std_msgs::UInt16>(msg);
103 }
104 
105 void callbackUInt32(const std_msgs::UInt32ConstPtr &msg)
106 {
107  callbackU<std_msgs::UInt32ConstPtr, std_msgs::UInt32>(msg);
108 }
109 
110 void callbackUInt64(const std_msgs::UInt64ConstPtr &msg)
111 {
112  callbackU<std_msgs::UInt64ConstPtr, std_msgs::UInt64>(msg);
113 }
114 
115 template <class T, class U>
116 void callbackD(const T &msg)
117 {
118  const ros::Time now(ros::Time::now());
119 
120  // Add new value
121  if (!std::isnan(msg->data))
122  time_values_d.emplace_back(now, msg->data);
123 
124  // Remove values that are too old
125  for (auto it(time_values_d.begin()); it != time_values_d.end();)
126  {
127  ros::Duration delta(now - it->first);
128  if (delta > window_length)
129  time_values_d.erase(it);
130  else
131  break;
132  }
133 
134  // Compute and publish mean
135  long double sum(0);
136  for (auto tv : time_values_d)
137  sum += tv.second;
138  U mean;
139  mean.data = sum / time_values_d.size();
140  pub->publish(mean);
141 }
142 
143 void callbackFloat32(const std_msgs::Float32ConstPtr &msg)
144 {
145  callbackD<std_msgs::Float32ConstPtr, std_msgs::Float32>(msg);
146 }
147 
148 void callbackFloat64(const std_msgs::Float64ConstPtr &msg)
149 {
150  callbackD<std_msgs::Float64ConstPtr, std_msgs::Float64>(msg);
151 }
152 
153 int main(int argc,
154  char *argv[])
155 {
156  // FIXME Check if overflow happened and warn user
157 
158  ros::init(argc, argv, "republish");
159  nh = std::make_unique<ros::NodeHandle>("~");
160 
161  std::string in_topic, out_topic;
162  nh->getParam("in_topic", in_topic);
163  nh->getParam("out_topic", out_topic);
164 
165  {
166  double window_length_tmp(2);
167  nh->getParam("window_length", window_length_tmp);
168  window_length.sec = (int) window_length_tmp;
169  window_length.nsec = (window_length_tmp - (int) window_length_tmp) * 1e9;
170  }
171 
172  ROS_DEBUG_STREAM("Subscriber topic = " << in_topic);
173  ROS_DEBUG_STREAM("Publisher topic = " << out_topic);
174  ROS_DEBUG_STREAM("Window length = " << window_length.toSec() << " seconds");
175 
176  if (in_topic.empty())
177  {
178  ROS_ERROR_STREAM("in_topic must be specified");
179  return 1;
180  }
181 
182  if (out_topic.empty())
183  {
184  ROS_ERROR_STREAM("out_topic must be specified");
185  return 1;
186  }
187 
188  std::string topic_type;
189  while (1)
190  {
192  if (!ros::master::getTopics(topics))
193  {
194  ROS_ERROR_STREAM("Error getting topics: Could not retrieve the topics names");
195  return 1;
196  }
197 
198  ros::master::V_TopicInfo::iterator topic =
199  std::find_if(topics.begin(), topics.end(), [=](const ros::master::TopicInfo &ti)
200  {
201  return ti.name == in_topic;
202  });
203 
204  if (topic != topics.end())
205  {
206  topic_type = topic->datatype;
207  ROS_DEBUG_STREAM("Topic " << in_topic << " " << "type is " << topic_type);
208  break;
209  }
210 
211  ROS_WARN_STREAM_THROTTLE(2, "Waiting for topic " << in_topic << " to be available");
212  ros::Duration(0.1).sleep();
213 
214  if (!nh->ok())
215  return 0;
216  }
217 
218  ros::Subscriber sub;
219  if (topic_type == "std_msgs/Float32")
220  {
221  sub = nh->subscribe(in_topic, 5, &callbackFloat32);
222  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::Float32>(out_topic, 5));
223  }
224  else if (topic_type == "std_msgs/Float64")
225  {
226  sub = nh->subscribe(in_topic, 5, &callbackFloat64);
227  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::Float64>(out_topic, 5));
228  }
229  else if (topic_type == "std_msgs/Int8")
230  {
231  sub = nh->subscribe(in_topic, 5, &callbackInt8);
232  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::Int8>(out_topic, 5));
233  }
234  else if (topic_type == "std_msgs/Int16")
235  {
236  sub = nh->subscribe(in_topic, 5, &callbackInt16);
237  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::Int16>(out_topic, 5));
238  }
239  else if (topic_type == "std_msgs/Int32")
240  {
241  sub = nh->subscribe(in_topic, 5, &callbackInt32);
242  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::Int32>(out_topic, 5));
243  }
244  else if (topic_type == "std_msgs/Int64")
245  {
246  sub = nh->subscribe(in_topic, 5, &callbackInt64);
247  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::Int64>(out_topic, 5));
248  }
249  else if (topic_type == "std_msgs/UInt8")
250  {
251  sub = nh->subscribe(in_topic, 5, &callbackUInt8);
252  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::UInt8>(out_topic, 5));
253  }
254  else if (topic_type == "std_msgs/UInt16")
255  {
256  sub = nh->subscribe(in_topic, 5, &callbackUInt16);
257  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::UInt16>(out_topic, 5));
258  }
259  else if (topic_type == "std_msgs/UInt32")
260  {
261  sub = nh->subscribe(in_topic, 5, &callbackUInt32);
262  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::UInt32>(out_topic, 5));
263  }
264  else if (topic_type == "std_msgs/UInt64")
265  {
266  sub = nh->subscribe(in_topic, 5, &callbackUInt64);
267  pub = std::make_unique<ros::Publisher>(nh->advertise<std_msgs::UInt64>(out_topic, 5));
268  }
269  else
270  {
271  ROS_ERROR_STREAM("Topic type " << topic_type << " is not supported");
272  return 1;
273  }
274 
275  ros::AsyncSpinner spinner(1);
276  spinner.start();
278  return 0;
279 }
ros::Duration window_length
Definition: node.cpp:18
#define ROS_WARN_STREAM_THROTTLE(period, args)
int main(int argc, char *argv[])
Definition: node.cpp:153
void callbackI(const T &msg)
Definition: node.cpp:24
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ROSCPP_DECL bool getTopics(V_TopicInfo &topics)
void callbackUInt8(const std_msgs::UInt8ConstPtr &msg)
Definition: node.cpp:95
std::vector< TopicInfo > V_TopicInfo
void callbackU(const T &msg)
Definition: node.cpp:70
void callbackUInt16(const std_msgs::UInt16ConstPtr &msg)
Definition: node.cpp:100
std::vector< std::pair< ros::Time, uint64_t > > time_values_u
Definition: node.cpp:20
void callbackInt8(const std_msgs::Int8ConstPtr &msg)
Definition: node.cpp:49
void callbackInt32(const std_msgs::Int32ConstPtr &msg)
Definition: node.cpp:59
void callbackUInt64(const std_msgs::UInt64ConstPtr &msg)
Definition: node.cpp:110
std::vector< std::pair< ros::Time, int64_t > > time_values_i
Definition: node.cpp:19
std::vector< std::pair< ros::Time, double > > time_values_d
Definition: node.cpp:21
void callbackUInt32(const std_msgs::UInt32ConstPtr &msg)
Definition: node.cpp:105
#define ROS_DEBUG_STREAM(args)
std::unique_ptr< ros::NodeHandle > nh
Definition: node.cpp:15
void callbackFloat32(const std_msgs::Float32ConstPtr &msg)
Definition: node.cpp:143
static Time now()
bool sleep() const
#define ROS_ERROR_STREAM(args)
void callbackInt16(const std_msgs::Int16ConstPtr &msg)
Definition: node.cpp:54
std::unique_ptr< ros::Publisher > pub
Definition: node.cpp:16
void callbackFloat64(const std_msgs::Float64ConstPtr &msg)
Definition: node.cpp:148
void callbackD(const T &msg)
Definition: node.cpp:116
ROSCPP_DECL void waitForShutdown()
void callbackInt64(const std_msgs::Int64ConstPtr &msg)
Definition: node.cpp:64


moving_average
Author(s): Victor Lamoine - Institut Maupertuis
autogenerated on Mon Feb 28 2022 22:50:22