roch_diagnostics.cpp
Go to the documentation of this file.
1 
33 
34 
35 namespace
36 {
37  const int UNDERVOLT_ERROR = 18;
38  const int UNDERVOLT_WARN = 19;
39  const int OVERVOLT_ERROR = 30;
40  const int OVERVOLT_WARN = 29;
41  const int DRIVER_OVERTEMP_ERROR = 50;
42  const int DRIVER_OVERTEMP_WARN = 30;
43  const int MOTOR_OVERTEMP_ERROR = 80;
44  const int MOTOR_OVERTEMP_WARN = 70;
45  const double LOWPOWER_ERROR = 0.2;
46  const double LOWPOWER_WARN = 0.3;
47  const int CONTROLFREQ_WARN = 90;
48  const unsigned int SAFETY_TIMEOUT = 0x1;
49  const unsigned int SAFETY_LOCKOUT = 0x2;
50  const unsigned int SAFETY_ESTOP = 0x8;
51  const unsigned int SAFETY_CCI = 0x10;
52  const unsigned int SAFETY_PSU = 0x20;
53  const unsigned int SAFETY_CURRENT = 0x40;
54  const unsigned int SAFETY_WARN = (SAFETY_TIMEOUT | SAFETY_CCI | SAFETY_PSU);
55  const unsigned int SAFETY_ERROR = (SAFETY_LOCKOUT | SAFETY_ESTOP | SAFETY_CURRENT);
56 } // namespace
57 
58 namespace roch_base
59 {
60 
61  template<>
63  :
64  DiagnosticTask("system_status"),
65  msg_(msg)
66  {
67  }
68 
69  template<>
73  {
74  msg_.uptime = system_status->getUptime();
75 
76  msg_.battery_voltage = system_status->getVoltage(0);
77  msg_.left_driver_voltage = system_status->getVoltage(1);
78  msg_.right_driver_voltage = system_status->getVoltage(2);
79 
80  msg_.mcu_and_user_port_current = system_status->getCurrent(0);
81  msg_.left_driver_current = system_status->getCurrent(1);
82  msg_.right_driver_current = system_status->getCurrent(2);
83 
84  msg_.left_driver_temp = system_status->getTemperature(0);
85  msg_.right_driver_temp = system_status->getTemperature(1);
86  msg_.left_motor_temp = system_status->getTemperature(2);
87  msg_.right_motor_temp = system_status->getTemperature(3);
88  stat.add("Uptime", msg_.uptime);
89 
90  stat.add("Battery Voltage", msg_.battery_voltage);
91  stat.add("Left Motor Driver Voltage", msg_.left_driver_voltage);
92  stat.add("Right Motor Driver Voltage", msg_.right_driver_voltage);
93 
94  stat.add("MCU and User Port Current", msg_.mcu_and_user_port_current);
95  stat.add("Left Motor Driver Current", msg_.left_driver_current);
96  stat.add("Right Motor Driver Current", msg_.right_driver_current);
97 
98  stat.add("Left Motor Driver Temp (C)", msg_.left_driver_temp);
99  stat.add("Right Motor Driver Temp (C)", msg_.right_driver_temp);
100  stat.add("Left Motor Temp (C)", msg_.left_motor_temp);
101  stat.add("Right Motor Temp (C)", msg_.right_motor_temp);
102  ROS_DEBUG_STREAM("Received Uptime:"<<msg_.uptime<<", Battery Voltage:"<<msg_.battery_voltage<<", Left Motor Driver Voltage:"<<msg_.left_driver_voltage<<", Right Motor Driver Voltage:"<<msg_.right_driver_voltage<<", "
103  "MCU and User Port Current:"<<msg_.mcu_and_user_port_current<<", Left Motor Driver Current:"<<msg_.left_driver_current<<",Right Motor Driver Current:"<<msg_.right_driver_current<<", "
104  "Left Motor Driver Temp (C):"<<msg_.left_driver_temp<<", Right Motor Driver Temp (C):"<<msg_.right_driver_temp<<", Left Motor Temp (C):"<<msg_.left_motor_temp<<", Right Motor Temp (C):"<<msg_.right_motor_temp<<" .");
105 
106  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "System Status OK");
107  if (msg_.battery_voltage > OVERVOLT_ERROR)
108  {
109  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Main battery voltage too high");
110  }
111  else if (msg_.battery_voltage > OVERVOLT_WARN)
112  {
113  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, "Main battery voltage too high");
114  }
115  else if (msg_.battery_voltage < UNDERVOLT_ERROR)
116  {
117  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Main battery voltage too low");
118  }
119  else if (msg_.battery_voltage < UNDERVOLT_WARN)
120  {
121  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, "Main battery voltage too low");
122  }
123  else
124  {
125  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::OK, "Voltage OK");
126  }
127 
128  if (std::max(msg_.left_driver_temp, msg_.right_driver_temp) > DRIVER_OVERTEMP_ERROR)
129  {
130  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Motor drivers too hot");
131  }
132  else if (std::max(msg_.left_driver_temp, msg_.right_driver_temp) > DRIVER_OVERTEMP_WARN)
133  {
134  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, "Motor drivers too hot");
135  }
136  else if (std::max(msg_.left_motor_temp, msg_.right_motor_temp) > MOTOR_OVERTEMP_ERROR)
137  {
138  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Motors too hot");
139  }
140  else if (std::max(msg_.left_motor_temp, msg_.right_motor_temp) > MOTOR_OVERTEMP_WARN)
141  {
142  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, "Motors too hot");
143  }
144  else
145  {
146  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::OK, "Temperature OK");
147  }
148  }
149 
150  template<>
152  :
153  DiagnosticTask("power_status"),
154  msg_(msg)
155  { }
156 
157  template<>
161  {
162  msg_.charge_estimate = power_status->getChargeEstimate(0);
163  msg_.capacity_estimate = power_status->getCapacityEstimate(0);
164 
165  stat.add("Charge (%)", msg_.charge_estimate);
166  stat.add("Battery Capacity (Wh)", msg_.capacity_estimate);
167  ROS_DEBUG_STREAM("Received Charge (%%): "<<msg_.charge_estimate<<", Battery Capacity (Wh): "<<msg_.capacity_estimate<<" .");
168 
169  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Power System OK");
170  if (msg_.charge_estimate < LOWPOWER_ERROR)
171  {
172  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Low power");
173  }
174  else if (msg_.charge_estimate < LOWPOWER_WARN)
175  {
176  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, "Low power");
177  }
178  else
179  {
180  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::OK, "Charge OK");
181  }
182  }
183 
184  template<>
186  roch_msgs::RochStatus &msg)
187  :
188  DiagnosticTask("safety_status"),
189  msg_(msg)
190  { }
191 
192  template<>
196  {
197  uint16_t flags = safety_status->getFlags();
198  msg_.timeout = (flags & SAFETY_TIMEOUT) > 0;
199  msg_.lockout = (flags & SAFETY_LOCKOUT) > 0;
200  msg_.e_stop = (flags & SAFETY_ESTOP) > 0;
201  msg_.ros_pause = (flags & SAFETY_CCI) > 0;
202  msg_.no_battery = (flags & SAFETY_PSU) > 0;
203  msg_.current_limit = (flags & SAFETY_CURRENT) > 0;
204 
205  stat.add("Timeout", static_cast<bool>(msg_.timeout));
206  stat.add("Lockout", static_cast<bool>(msg_.lockout));
207  stat.add("Emergency Stop", static_cast<bool>(msg_.e_stop));
208  stat.add("ROS Pause", static_cast<bool>(msg_.ros_pause));
209  stat.add("No battery", static_cast<bool>(msg_.no_battery));
210  stat.add("Current limit", static_cast<bool>(msg_.current_limit));
211  ROS_DEBUG_STREAM("Received Safety System Status, Timeout:"<<msg_.timeout<<", Lockout:"<<msg_.lockout<<", Emergency Stop:"<<msg_.e_stop<<", ROS Pause:"<<msg_.ros_pause<<", No battery:"<<msg_.no_battery<<", Current limit:"<<msg_.current_limit<<" .");
212 
213  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Safety System OK");
214  if ((flags & SAFETY_ERROR) > 0)
215  {
216  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Safety System Error");
217  }
218  else if ((flags & SAFETY_WARN) > 0)
219  {
220  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, "Safety System Warning");
221  }
222  }
223 
224  rochSoftwareDiagnosticTask::rochSoftwareDiagnosticTask(roch_msgs::RochStatus &msg, double target_control_freq)
225  :
226  DiagnosticTask("software_status"),
227  msg_(msg),
228  target_control_freq_(target_control_freq)
229  {
230  reset();
231  }
232 
234  {
235  // Keep minimum observed frequency for diagnostics purposes
236  control_freq_ = std::min(control_freq_, frequency);
237  }
238 
240  {
241  msg_.ros_control_loop_freq = control_freq_;
242  stat.add("ROS Control Loop Frequency", msg_.ros_control_loop_freq);
243 
244  double margin = control_freq_ / target_control_freq_ * 100;
245 
246  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Software OK");
247  if (margin < CONTROLFREQ_WARN)
248  {
249  std::ostringstream message;
250  message << "Control loop executing " << 100 - static_cast<int>(margin) << "% slower than desired";
251  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, message.str());
252  }
253 
254  reset();
255  }
256 
258  {
259  control_freq_ = std::numeric_limits<double>::infinity();
261  }
262 } // namespace roch_base
void summary(unsigned char lvl, const std::string s)
void update(diagnostic_updater::DiagnosticStatusWrapper &stat, typename core::Channel< T >::Ptr &status)
void updateControlFrequency(double frequency)
rochSoftwareDiagnosticTask(roch_msgs::RochStatus &msg, double target_control_freq)
rochHardwareDiagnosticTask(roch_msgs::RochStatus &msg)
void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
def message(msg, args, kwargs)
#define ROS_DEBUG_STREAM(args)
void mergeSummary(unsigned char lvl, const std::string s)
DiagnosticTask(const std::string name)
void add(const std::string &key, const T &val)


roch_base
Author(s): Mike Purvis , Paul Bovbel , Chen
autogenerated on Mon Jun 10 2019 14:41:14