设备状态监控
本例程演示如何使用 librm 中的 Device 基类和 DeviceManager 设备管理器来监控设备的在线状态和工作状态。
设备状态监控框架通过心跳机制自动检测设备是否离线,并在设备故障或离线时触发回调函数。设备有三种状态:kOk(正常)、kFault(故障)、kOffline(离线,超过超时时间未收到状态上报)。
librm 中的大部分设备驱动类都基于这套机制实现了状态上报逻辑,可以直接添加到 DeviceManager。
代码示例
基本用法
#include "cmsis_os.h"
#include <librm.hpp>
extern "C" void DeviceMonitorTask(const void *pv_arg) {
rm::hal::Can can1(hcan1);
rm::device::M3508 motor1(can1, 1);
rm::device::M3508 motor2(can1, 2);
rm::device::GM6020 motor3(can1, 3);
can1.Begin();
// 创建设备管理器,最多可以添加 10 个设备
rm::device::DeviceManager<10> device_manager;
// 将设备添加到管理器
device_manager << &motor1 << &motor2 << &motor3;
// 注册设备故障或离线回调
device_manager.OnDeviceFaultOrOffline([](rm::device::Device *device) {
// 设备故障或离线时的处理逻辑
// 例如:停止所有运动、触发蜂鸣器报警、LED 指示等
});
for (;;) {
// 更新所有设备状态并检查
bool all_ok = device_manager.Update();
if (all_ok) {
// 所有设备正常
} else {
// 存在故障或离线设备
}
osDelay(100); // 100ms 检查一次
}
}
自定义设备类
如果新编写了一个设备驱动,想要整合进这套状态监控框架,继承 Device 基类并在适当时机调用 ReportStatus 方法报告设备状态:
#include <librm.hpp>
// 自定义传感器设备
class CustomSensor : public rm::device::Device {
public:
void Update() {
// 读取传感器数据
bool data_valid = ReadSensorData();
if (data_valid) {
// 数据有效,报告设备正常
ReportStatus(Status::kOk);
} else {
// 数据异常,报告设备故障
ReportStatus(Status::kFault);
}
}
float GetValue() const { return value_; }
private:
bool ReadSensorData() {
// 实际的传感器读取逻辑
// 返回 true 表示数据有效,false 表示数据异常
return true;
}
float value_{0.0f};
};
// 使用自定义传感器
CustomSensor imu_sensor;
imu_sensor.SetHeartbeatTimeout(std::chrono::milliseconds(500)); // 设置500ms超时
rm::device::DeviceManager<5> sensors;
sensors << &imu_sensor;
extern "C" void SensorTask(const void *pv_arg) {
for (;;) {
// 更新传感器数据
imu_sensor.Update();
// 检查传感器状态
if (imu_sensor.Ok()) {
float value = imu_sensor.GetValue();
// 使用传感器数据
}
osDelay(10);
}
}
分组管理
tip
实际应用中可以像下面这样将不同区域的设备分组管理,例如底盘、云台等,从而实现更灵活的状态监控和保护逻辑。
#include "cmsis_os.h"
#include <librm.hpp>
rm::device::DeviceManager<8> chassis_motors;
rm::device::DeviceManager<4> gimbal_motors;
extern "C" void SafetyMonitorTask(const void *pv_arg) {
chassis_motors.OnDeviceFaultOrOffline([](rm::device::Device *device) {
// 停止所有底盘电机
});
gimbal_motors.OnDeviceFaultOrOffline([](rm::device::Device *device) {
// 停止云台运动
});
for (;;) {
bool chassis_ok = chassis_motors.Update();
bool gimbal_ok = gimbal_motors.Update();
// 根据状态执行保护逻辑
osDelay(50);
}
}
主要 API
Device 基类
void SetHeartbeatTimeout(duration timeout)- 设置心跳超时时间(默认 1 秒)bool Ok()- 检查设备是否在线且正常工作time_point last_seen() const- 获取设备最后一次上报状态的时间点protected void ReportStatus(Status status)- 由设备驱动Device类调用,报告当前的设备状态
DeviceManager 设备管理器
DeviceManager& operator<<(Device *device)- 添加设备bool Update()- 更新所有设备状态,返回是否所有设备都正常void OnDeviceFaultOrOffline(CallbackType callback)- 注册故障/离线回调bool all_device_ok() const- 获取所有设备是否正常