feat(motor_state): 支持多通道电机状态管理并添加推送周期动态调节功能

- 实现 node×channel 双键槽位管理,支持同一节点号在不同CAN通道独立缓存
- 扩展电机状态表容量从9个槽位到27个槽位(9节点×3通道)
- 添加SPI命令子命令0xFE用于动态设置0xC5推送周期(50-5000ms)
- 增加运行时可调推送周期功能,默认250ms,支持50ms-5s范围调节
- 更新CAN通道配置,启用CH1和CH2通道支持
- 版本号更新至1.5.4
This commit is contained in:
cbb
2026-07-30 02:11:49 +08:00
parent 46ef19d882
commit e06f5eb9a9
8 changed files with 107 additions and 34 deletions
+17 -2
View File
@@ -27,9 +27,19 @@ static constexpr uint32_t kMotorStatusIdMask = 0xFFF0FFFFU; /* 屏蔽 node nibb
static constexpr uint32_t kMotorStatusIdMatch = 0x00000100U; /* STATUS 类型码 */
static constexpr uint8_t kMotorMaxNodes = CONFIG_MOTOR_MAX_NODES;
/* 同一节点号可能同时挂在多个 CAN 通道上(两台电机同号异线),
* 状态表按 node×channel 双键存储,各通道独立槽位互不覆盖。 */
static constexpr uint8_t kMotorChannels = 3U;
static constexpr uint8_t kMotorSlotCount = kMotorMaxNodes * kMotorChannels; /* 9×3 = 27 */
static constexpr uint8_t kMotorStatusDlc = 32U;
static constexpr uint16_t kMotorOfflineSec = CONFIG_MOTOR_OFFLINE_MS / 1000U;
/* ── 0xC5 推送周期运行时可调(ESP32 经 0xC5 子命令 0xFE 下发)── */
static constexpr uint16_t kMotorPeriodMinMs = 50U; /* 最快 20Hz */
static constexpr uint16_t kMotorPeriodMaxMs = 5000U; /* 最慢 0.2Hz */
static constexpr uint16_t kMotorTicksPerMs = 10U; /* 100us/tick → 每 ms 10 tick */
static constexpr uint8_t kMotorSubCmdSetPeriod = 0xFEU; /* 0xC5 请求 payload[0]=0xFE:设推送周期 */
/* ── BOOT 心跳(0x103)──
* 电机在 Bootloader IDLE 每 ~10ms 发一次 0x00000103(固定 ID,不带节点号)。
* 网页据此显示一个独立 BOOT 状态(不归属任何 Nx)。 */
@@ -41,7 +51,8 @@ static constexpr uint8_t kMotorActiveBootBit = 0x80U; /* 0xC5 page0 header
static constexpr uint8_t kMotorEntrySize = 44U; /* 1+1+1+1+4+4+32 */
static constexpr uint8_t kMotorPageHeaderLen = 4U; /* page+total+count+active */
static constexpr uint8_t kMotorEntriesPerPage = 5U; /* (236-4)/44 = 5.27 → 5 */
static constexpr uint8_t kMotorTotalPages = 2U; /* ceil(9/5) = 2 */
static constexpr uint8_t kMotorTotalPages =
(kMotorSlotCount + kMotorEntriesPerPage - 1U) / kMotorEntriesPerPage; /* ceil(27/5) = 6 */
/// 单电机状态槽
struct MotorSlot {
@@ -57,7 +68,7 @@ struct MotorSlot {
/// 全局电机状态表
struct MotorStateTable {
MotorSlot slots[kMotorMaxNodes]; ///< 按 node_id-1 索引
MotorSlot slots[kMotorSlotCount]; ///< 按 (node_id-1)*kMotorChannels+channel 索引
uint32_t global_seq; ///< 全局刷新序号
uint32_t last_push_sec; ///< 上次推送完成时间
uint8_t active_count; ///< 当前在线电机数
@@ -82,6 +93,10 @@ void checkOffline();
/// @return 实际写入字节数, 0=参数错误
uint16_t buildPayload(uint8_t page, uint8_t *buf, uint16_t maxLen);
/// 设置 0xC5 主动推送周期(毫秒,钳制到 [kMotorPeriodMinMs, kMotorPeriodMaxMs])。
/// @return 实际应用的毫秒值。
uint16_t setPushPeriodMs(uint16_t ms);
} // namespace MotorState
#endif /* DEVICE_MOTOR_STATE_H */