Skip to content

Commit 8d7ce0e

Browse files
authored
Added MCU alerts to diagnostics (#248)
* Added MCU alerts to diagnostics * Linting
1 parent 45b6b9d commit 8d7ce0e

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

clearpath_diagnostics/include/clearpath_diagnostics/clearpath_diagnostic_labels.hpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI
2727
#define CLEARPATH_DIAGNOSTIC_LABELS_HPP
2828

2929
#include <map>
30+
#include <string>
3031
#include <vector>
3132

3233
#include "sensor_msgs/msg/battery_state.hpp"
@@ -64,6 +65,59 @@ class DiagnosticLabels {
6465
// Genric Robot
6566
inline static const std::string GENERIC = "generic";
6667

68+
//--------------------------------------------------------
69+
// Labels for Firmware Alert Codes
70+
// Format is {alert_code, {"Alert Title", "Troubleshooting/Description"}}
71+
//--------------------------------------------------------
72+
inline static const std::map<std::string, std::vector<std::string>> FIRMWARE_ALERTS = {
73+
{"E110", {"Main Contactor Error!", ""}},
74+
{"E113", {"Battery Out of Range!", ""}},
75+
{"E116", {"E-Stop Contactor Error!", ""}},
76+
{"E117", {"Brake Contactor Error!", ""}},
77+
{"E120", {"Motor 1 Voltage Range Error!", ""}},
78+
{"E121", {"Motor 2 Voltage Range Error!", ""}},
79+
{"E122", {"Motor 3 Voltage Range Error!", ""}},
80+
{"E123", {"Motor 4 Voltage Range Error!", ""}},
81+
{"E124",
82+
{"Motor Voltage Range Error!", "This is a general error for a voltage issue on any motor."}},
83+
{"E140", {"User Power Contactor Error!", ""}},
84+
{"E150", {"24V Aux Power Fail!", ""}},
85+
{"E151", {"12V Aux Power Fail!", ""}},
86+
{"E152", {"12V1 Sys Power Fail!", ""}},
87+
{"E153", {"12V2 Sys Power Fail!", ""}},
88+
{"E154", {"12V A User Power Fail!", ""}},
89+
{"E155", {"12V B User Power Fail!", ""}},
90+
{"E156", {"VBAT User Power Fail!", ""}},
91+
{"E157", {"24V User Power Fail!", ""}},
92+
{"E160",
93+
{"Power Supply Failure!",
94+
"This is a general error which is set for any of the power fail errors."}},
95+
{"E170", {"VBAT User Power Fuse Tripped!", ""}},
96+
{"E171", {"24V User Power Fuse Tripped!", ""}},
97+
{"E172", {"12V A User Power Fuse Tripped!", ""}},
98+
{"E173", {"12V B User Power Fuse Tripped!", ""}},
99+
{"E174", {"Expansion Power Fuse Tripped!", ""}},
100+
{"E810", {"Fan 1 Below Minimum Speed!", ""}},
101+
{"E811", {"Fan 2 Below Minimum Speed!", ""}},
102+
{"E812", {"Fan 3 Below Minimum Speed!", ""}},
103+
{"E813", {"Fan 4 Below Minimum Speed!", ""}},
104+
{"E814", {"Fan 5 Below Minimum Speed!", ""}},
105+
{"E815", {"Fan 6 Below Minimum Speed!", ""}},
106+
{"E816", {"Fan 7 Below Minimum Speed!", ""}},
107+
{"E817", {"Fan 8 Below Minimum Speed!", ""}},
108+
{"E820", {"Fan Below Minimum Speed!", "This is a general error for any fan."}},
109+
{"E830", {"Fan 1 Above Maximum Speed!", ""}},
110+
{"E831", {"Fan 2 Above Maximum Speed!", ""}},
111+
{"E832", {"Fan 3 Above Maximum Speed!", ""}},
112+
{"E833", {"Fan 4 Above Maximum Speed!", ""}},
113+
{"E834", {"Fan 5 Above Maximum Speed!", ""}},
114+
{"E835", {"Fan 6 Above Maximum Speed!", ""}},
115+
{"E836", {"Fan 7 Above Maximum Speed!", ""}},
116+
{"E837", {"Fan 8 Above Maximum Speed!", ""}},
117+
{"E840", {"Fan Above Maximum Speed!", "This is a general error for any fan."}},
118+
};
119+
120+
67121
//--------------------------------------------------------
68122
// Labels for clearpath_platform_msgs::msg::Power
69123
//--------------------------------------------------------

clearpath_diagnostics/include/clearpath_diagnostics/clearpath_diagnostic_updater.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI
4040
#include "sensor_msgs/msg/nav_sat_fix.hpp"
4141
#include "sensor_msgs/msg/point_cloud2.hpp"
4242
#include "std_msgs/msg/bool.hpp"
43+
#include "std_msgs/msg/string.hpp"
4344

4445
#include "clearpath_diagnostics/clearpath_diagnostic_labels.hpp"
4546
#include "clearpath_platform_msgs/msg/power.hpp"
@@ -63,6 +64,7 @@ class ClearpathDiagnosticUpdater : public rclcpp::Node
6364

6465
// Callbacks
6566
void mcu_status_callback(const clearpath_platform_msgs::msg::Status & msg);
67+
void mcu_alerts_callback(const std_msgs::msg::String & msg);
6668
void mcu_power_callback(const clearpath_platform_msgs::msg::Power & msg);
6769
void bms_state_callback(const BatteryState & msg);
6870
void stop_status_callback(const clearpath_platform_msgs::msg::StopStatus & msg);
@@ -71,6 +73,7 @@ class ClearpathDiagnosticUpdater : public rclcpp::Node
7173
// Diagnostic Tasks
7274
void firmware_diagnostic(DiagnosticStatusWrapper & stat);
7375
void mcu_status_diagnostic(DiagnosticStatusWrapper & stat);
76+
void firmware_alerts_diagnostic(DiagnosticStatusWrapper & stat);
7477
void mcu_power_diagnostic(DiagnosticStatusWrapper & stat);
7578
void bms_state_diagnostic(DiagnosticStatusWrapper & stat);
7679
void stop_status_diagnostic(DiagnosticStatusWrapper & stat);
@@ -94,6 +97,7 @@ class ClearpathDiagnosticUpdater : public rclcpp::Node
9497

9598
// Topic names and rates
9699
std::string mcu_status_topic_;
100+
std::string mcu_alerts_topic_;
97101
std::string mcu_power_topic_;
98102
std::string bms_state_topic_;
99103
std::string stop_status_topic_;
@@ -112,6 +116,7 @@ class ClearpathDiagnosticUpdater : public rclcpp::Node
112116
// Message Data
113117
std::string mcu_firmware_version_;
114118
clearpath_platform_msgs::msg::Status mcu_status_msg_;
119+
std_msgs::msg::String mcu_alerts_msg_;
115120
clearpath_platform_msgs::msg::Power mcu_power_msg_;
116121
BatteryState bms_state_msg_;
117122
clearpath_platform_msgs::msg::StopStatus stop_status_msg_;
@@ -126,6 +131,7 @@ class ClearpathDiagnosticUpdater : public rclcpp::Node
126131

127132
// Subscriptions
128133
rclcpp::Subscription<clearpath_platform_msgs::msg::Status>::SharedPtr sub_mcu_status_;
134+
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_mcu_alerts_;
129135
rclcpp::Subscription<clearpath_platform_msgs::msg::Power>::SharedPtr sub_mcu_power_;
130136
rclcpp::Subscription<BatteryState>::SharedPtr sub_bms_state_;
131137
rclcpp::Subscription<clearpath_platform_msgs::msg::StopStatus>::SharedPtr sub_stop_status_;

clearpath_diagnostics/src/clearpath_diagnostic_updater.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ ClearpathDiagnosticUpdater::ClearpathDiagnosticUpdater()
5353
// Get optional parameters from the config
5454
mcu_status_topic_ = get_string_param("mcu_status_topic");
5555
mcu_status_topic_ = (mcu_status_topic_ == UNKNOWN) ? "platform/mcu/status" : mcu_status_topic_;
56+
mcu_alerts_topic_ = get_string_param("mcu_alerts_topic");
57+
mcu_alerts_topic_ = (mcu_alerts_topic_ ==
58+
UNKNOWN) ? "platform/mcu/status/alerts" : mcu_alerts_topic_;
5659
mcu_power_topic_ = get_string_param("mcu_power_topic");
5760
mcu_power_topic_ = (mcu_power_topic_ == UNKNOWN) ? "platform/mcu/status/power" : mcu_power_topic_;
5861
bms_state_topic_ = get_string_param("bms_state_topic");
@@ -100,12 +103,20 @@ ClearpathDiagnosticUpdater::ClearpathDiagnosticUpdater()
100103
rclcpp::SensorDataQoS(),
101104
std::bind(&ClearpathDiagnosticUpdater::mcu_status_callback, this, std::placeholders::_1));
102105

106+
sub_mcu_alerts_ =
107+
this->create_subscription<std_msgs::msg::String>(
108+
mcu_alerts_topic_,
109+
rclcpp::SensorDataQoS(),
110+
std::bind(&ClearpathDiagnosticUpdater::mcu_alerts_callback, this, std::placeholders::_1));
111+
103112
// Create MCU Frequency Status tracking objects
104113
mcu_status_freq_status_ = std::make_shared<FrequencyStatus>(
105114
FrequencyStatusParam(&mcu_status_rate_, &mcu_status_rate_, mcu_status_tolerance_, 10));
106115

107116
// Add diagnostic tasks for MCU data
108117
updater_.add("MCU Status", this, &ClearpathDiagnosticUpdater::mcu_status_diagnostic);
118+
updater_.add("MCU Firmware Alerts", this,
119+
&ClearpathDiagnosticUpdater::firmware_alerts_diagnostic);
109120
updater_.add("MCU Firmware Version", this, &ClearpathDiagnosticUpdater::firmware_diagnostic);
110121
RCLCPP_INFO(this->get_logger(), "MCU diagnostics started.");
111122
}
@@ -228,6 +239,71 @@ void ClearpathDiagnosticUpdater::firmware_diagnostic(DiagnosticStatusWrapper & s
228239
stat.add("Firmware Version on MCU", mcu_firmware_version_);
229240
}
230241

242+
/**
243+
* @brief Helper function to split a string into a vector of strings by delimiter
244+
*
245+
* @param s String to split
246+
* @param delimiter Delimiter to split with
247+
* @return std::vector<std::string> Vector of split string
248+
*/
249+
static std::vector<std::string> split(std::string s, std::string delimiter)
250+
{
251+
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
252+
std::string token;
253+
std::vector<std::string> res;
254+
255+
while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
256+
token = s.substr(pos_start, pos_end - pos_start);
257+
pos_start = pos_end + delim_len;
258+
res.push_back(token);
259+
}
260+
261+
res.push_back(s.substr(pos_start));
262+
return res;
263+
}
264+
265+
/**
266+
* @brief Report Firmware Alerts to diagnostics
267+
*/
268+
void ClearpathDiagnosticUpdater::firmware_alerts_diagnostic(DiagnosticStatusWrapper & stat)
269+
{
270+
if (mcu_alerts_msg_.data.empty() || mcu_alerts_msg_.data == "None") {
271+
stat.summary(DiagnosticStatus::OK, "No firmware alerts reported");
272+
} else {
273+
unsigned char diagnostic_status = DiagnosticStatus::OK;
274+
std::vector<std::string> alerts = split(mcu_alerts_msg_.data, ",");
275+
276+
for (const auto & a : alerts) {
277+
std::string alert_title = "Firmware Alert " + a;
278+
std::string alert_message;
279+
unsigned char alert_status = DiagnosticStatus::OK;
280+
try {
281+
alert_message = DiagnosticLabels::FIRMWARE_ALERTS.at(a)[0];
282+
// Add the troubleshooting message if it exists
283+
if (DiagnosticLabels::FIRMWARE_ALERTS.at(a)[1].size() > 1) {
284+
alert_message += ": " + DiagnosticLabels::FIRMWARE_ALERTS.at(a)[1];
285+
}
286+
} catch (const std::out_of_range &) {
287+
alert_message = "Unknown firmware alert code";
288+
}
289+
stat.add(alert_title, alert_message);
290+
291+
// Warning for W alerts, Error for E alerts
292+
if (a.find('W') != std::string::npos) {
293+
alert_status = DiagnosticStatus::WARN;
294+
} else if (a.find('E') != std::string::npos) {
295+
alert_status = DiagnosticStatus::ERROR;
296+
}
297+
298+
if (alert_status > diagnostic_status) {
299+
diagnostic_status = alert_status;
300+
}
301+
}
302+
303+
stat.summary(diagnostic_status, "Firmware alerts reported");
304+
}
305+
}
306+
231307
/**
232308
* @brief Save data from MCU Status messages
233309
*/
@@ -239,6 +315,15 @@ void ClearpathDiagnosticUpdater::mcu_status_callback(
239315
mcu_status_freq_status_->tick();
240316
}
241317

318+
/**
319+
* @brief Save data from MCU Alerts messages
320+
*/
321+
void ClearpathDiagnosticUpdater::mcu_alerts_callback(
322+
const std_msgs::msg::String & msg)
323+
{
324+
mcu_alerts_msg_ = msg;
325+
}
326+
242327
/**
243328
* @brief Report MCU Status message information to diagnostics
244329
*/

0 commit comments

Comments
 (0)