Skip to content

Commit 7a58501

Browse files
committed
lots of diagnostics
1 parent 539a659 commit 7a58501

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

ur_robot_driver/src/ros/hardware_interface_node.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#include <ros/ros.h>
2828
#include <controller_manager/controller_manager.h>
2929

30+
#include <diagnostic_msgs/DiagnosticArray.h>
31+
#include <diagnostic_msgs/DiagnosticStatus.h>
32+
#include <diagnostic_msgs/KeyValue.h>
33+
3034
#include <csignal>
3135
#include <ur_robot_driver/ros/hardware_interface.h>
3236

@@ -53,6 +57,8 @@ int main(int argc, char** argv)
5357
ros::NodeHandle nh;
5458
ros::NodeHandle nh_priv("~");
5559

60+
ros::Publisher diagnostic_pub = nh.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1);
61+
5662
// register signal SIGINT and signal handler
5763
signal(SIGINT, signalHandler);
5864

@@ -129,21 +135,161 @@ int main(int argc, char** argv)
129135

130136
double expected_cycle_time = 1.0 / (static_cast<double>(g_hw_interface->getControlFrequency()));
131137

138+
ros::Duration min_period = ros::Duration(0);
139+
ros::Duration max_period = ros::Duration(0);
140+
ros::Duration period_totals = ros::Duration(0);
141+
142+
std::chrono::duration<double> min_read = std::chrono::duration<double>::zero();
143+
std::chrono::duration<double> max_read = std::chrono::duration<double>::zero();
144+
std::chrono::duration<double> read_totals = std::chrono::duration<double>::zero();
145+
std::chrono::duration<double> min_cm_update = std::chrono::duration<double>::zero();
146+
std::chrono::duration<double> max_cm_update = std::chrono::duration<double>::zero();
147+
std::chrono::duration<double> cm_update_totals = std::chrono::duration<double>::zero();
148+
std::chrono::duration<double> min_write = std::chrono::duration<double>::zero();
149+
std::chrono::duration<double> max_write = std::chrono::duration<double>::zero();
150+
std::chrono::duration<double> write_totals = std::chrono::duration<double>::zero();
151+
long debug_loops = 0;
152+
153+
// Debug timing printout every 5 seconds
154+
const std::chrono::seconds debug_timing_period{5};
155+
std::chrono::steady_clock::time_point debug_timing_start = std::chrono::steady_clock::now();
156+
132157
// Run as fast as possible
133158
while (ros::ok())
134159
{
135160
// Receive current state from robot
161+
const std::chrono::steady_clock::time_point read_start = std::chrono::steady_clock::now();
136162
g_hw_interface->read(timestamp, period);
163+
const std::chrono::duration<double> read_elapsed = std::chrono::steady_clock::now() - read_start;
164+
if (min_read == std::chrono::duration<double>::zero() || read_elapsed < min_read) min_read = read_elapsed;
165+
if (max_read == std::chrono::duration<double>::zero() || read_elapsed > max_read) max_read = read_elapsed;
166+
read_totals += read_elapsed;
137167

138168
// Get current time and elapsed time since last read
139169
timestamp = ros::Time::now();
140170
stopwatch_now = std::chrono::steady_clock::now();
141171
period.fromSec(std::chrono::duration_cast<std::chrono::duration<double>>(stopwatch_now - stopwatch_last).count());
142172
stopwatch_last = stopwatch_now;
143173

174+
const std::chrono::steady_clock::time_point cm_update_start = std::chrono::steady_clock::now();
144175
cm.update(timestamp, period, g_hw_interface->shouldResetControllers());
176+
const std::chrono::duration<double> cm_update_elapsed = std::chrono::steady_clock::now() - cm_update_start;
177+
if (min_cm_update == std::chrono::duration<double>::zero() || cm_update_elapsed < min_cm_update) min_cm_update = cm_update_elapsed;
178+
if (max_cm_update == std::chrono::duration<double>::zero() || cm_update_elapsed > max_cm_update) max_cm_update = cm_update_elapsed;
179+
cm_update_totals += cm_update_elapsed;
145180

181+
const std::chrono::steady_clock::time_point write_start = std::chrono::steady_clock::now();
146182
g_hw_interface->write(timestamp, period);
183+
const std::chrono::duration<double> write_elapsed = std::chrono::steady_clock::now() - write_start;
184+
if (min_write == std::chrono::duration<double>::zero() || write_elapsed < min_write) min_write = write_elapsed;
185+
if (max_write == std::chrono::duration<double>::zero() || write_elapsed > max_write) max_write = write_elapsed;
186+
write_totals += write_elapsed;
187+
188+
189+
190+
191+
if (min_period.isZero() || period < min_period) min_period = period;
192+
if (max_period.isZero() || period > max_period) max_period = period;
193+
period_totals += period;
194+
++debug_loops;
195+
196+
// Check if it's time to print
197+
const std::chrono::steady_clock::time_point debug_timing_now = std::chrono::steady_clock::now();
198+
const std::chrono::duration<double> total_elapsed = debug_timing_now - debug_timing_start;
199+
if (total_elapsed > debug_timing_period) {
200+
diagnostic_msgs::DiagnosticArray dia_array;
201+
diagnostic_msgs::DiagnosticStatus robot_status;
202+
robot_status.name = "Driver Timing";
203+
robot_status.level = diagnostic_msgs::DiagnosticStatus::OK;
204+
robot_status.message = "Everything seems to be ok.";
205+
206+
diagnostic_msgs::KeyValue loop_durations_last;
207+
loop_durations_last.key = "Loop durations last (s)";
208+
loop_durations_last.value = std::to_string(total_elapsed.count());
209+
robot_status.values.push_back(loop_durations_last);
210+
diagnostic_msgs::KeyValue num_loops;
211+
num_loops.key = "Number of loops";
212+
num_loops.value = std::to_string(debug_loops);
213+
robot_status.values.push_back(num_loops);
214+
diagnostic_msgs::KeyValue min_period_kv;
215+
min_period_kv.key = "min loop period (s)";
216+
min_period_kv.value = std::to_string(min_period.toSec());
217+
robot_status.values.push_back(min_period_kv);
218+
diagnostic_msgs::KeyValue max_period_kv;
219+
max_period_kv.key = "max loop period (s)";
220+
max_period_kv.value = std::to_string(max_period.toSec());
221+
robot_status.values.push_back(max_period_kv);
222+
diagnostic_msgs::KeyValue avg_period_kv;
223+
avg_period_kv.key = "avg loop period (s)";
224+
avg_period_kv.value = std::to_string(period_totals.toSec() / debug_loops);
225+
robot_status.values.push_back(avg_period_kv);
226+
227+
diagnostic_msgs::KeyValue min_read_kv;
228+
min_read_kv.key = "min read (s)";
229+
min_read_kv.value = std::to_string(min_read.count());
230+
robot_status.values.push_back(min_read_kv);
231+
diagnostic_msgs::KeyValue max_read_kv;
232+
max_read_kv.key = "max read (s)";
233+
max_read_kv.value = std::to_string(max_read.count());
234+
robot_status.values.push_back(max_read_kv);
235+
diagnostic_msgs::KeyValue avg_read_kv;
236+
avg_read_kv.key = "avg read (s)";
237+
avg_read_kv.value = std::to_string(read_totals.count() / debug_loops);
238+
robot_status.values.push_back(avg_read_kv);
239+
240+
diagnostic_msgs::KeyValue min_cm_update_kv;
241+
min_cm_update_kv.key = "min cm_update (s)";
242+
min_cm_update_kv.value = std::to_string(min_cm_update.count());
243+
robot_status.values.push_back(min_cm_update_kv);
244+
diagnostic_msgs::KeyValue max_cm_update_kv;
245+
max_cm_update_kv.key = "max cm_update (s)";
246+
max_cm_update_kv.value = std::to_string(max_cm_update.count());
247+
robot_status.values.push_back(max_cm_update_kv);
248+
diagnostic_msgs::KeyValue avg_cm_update_kv;
249+
avg_cm_update_kv.key = "avg cm_update (s)";
250+
avg_cm_update_kv.value = std::to_string(cm_update_totals.count() / debug_loops);
251+
robot_status.values.push_back(avg_cm_update_kv);
252+
253+
diagnostic_msgs::KeyValue min_write_kv;
254+
min_write_kv.key = "min write (s)";
255+
min_write_kv.value = std::to_string(min_write.count());
256+
robot_status.values.push_back(min_write_kv);
257+
diagnostic_msgs::KeyValue max_write_kv;
258+
max_write_kv.key = "max write (s)";
259+
max_write_kv.value = std::to_string(max_write.count());
260+
robot_status.values.push_back(max_write_kv);
261+
diagnostic_msgs::KeyValue avg_write_kv;
262+
avg_write_kv.key = "avg write (s)";
263+
avg_write_kv.value = std::to_string(write_totals.count() / debug_loops);
264+
robot_status.values.push_back(avg_write_kv);
265+
266+
dia_array.status.push_back(robot_status);
267+
diagnostic_pub.publish(dia_array);
268+
269+
270+
// ROS_INFO_STREAM(
271+
// "Loop durations last " << total_elapsed.count() << "s: "
272+
// "min=" << min_period.toSec() * 1000.0 << "ms, "
273+
// "max=" << max_period.toSec() * 1000.0 << "ms, "
274+
// "avg=" << period_totals.toSec() * 1000.0 / debug_loops << "ms, "
275+
// "avgchrono=" << total_elapsed.count() * 1000.0 / debug_loops << "ms"
276+
// );
277+
min_period = ros::Duration(0);
278+
max_period = ros::Duration(0);
279+
period_totals = ros::Duration(0);
280+
std::chrono::duration<double> min_read = std::chrono::duration<double>::zero();
281+
std::chrono::duration<double> max_read = std::chrono::duration<double>::zero();
282+
std::chrono::duration<double> read_totals = std::chrono::duration<double>::zero();
283+
std::chrono::duration<double> min_cm_update = std::chrono::duration<double>::zero();
284+
std::chrono::duration<double> max_cm_update = std::chrono::duration<double>::zero();
285+
std::chrono::duration<double> cm_update_totals = std::chrono::duration<double>::zero();
286+
std::chrono::duration<double> min_write = std::chrono::duration<double>::zero();
287+
std::chrono::duration<double> max_write = std::chrono::duration<double>::zero();
288+
std::chrono::duration<double> write_totals = std::chrono::duration<double>::zero();
289+
debug_loops = 0;
290+
debug_timing_start = debug_timing_now;
291+
}
292+
147293
// if (!control_rate.sleep())
148294
if (period.toSec() > expected_cycle_time)
149295
{

0 commit comments

Comments
 (0)