1.0
This commit is contained in:
@@ -1,47 +1,180 @@
|
||||
#ifndef __F4_CAN_APP_H
|
||||
#define __F4_CAN_APP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "can.h" // CubeMX生成的CAN头文件,提供 hcan1 句柄
|
||||
#include "can.h"
|
||||
|
||||
// ---------------- 1. CAN ID 定义 (标准11位) ----------------
|
||||
#define CAN_ID_EMCY_F4 0x010 // 紧急故障 (最高优先级)
|
||||
#define CAN_ID_HEARTBEAT_H7 0x080 // 上位机心跳
|
||||
#define CAN_ID_HEARTBEAT_F4 0x081 // 下位机心跳
|
||||
#define CAN_ID_RXPDO_CTRL 0x100 // 控制下发 (H7 -> F4)
|
||||
#define CAN_ID_TXPDO1_ODOM 0x200 // 里程计遥测1 (F4 -> H7)
|
||||
#define CAN_ID_TXPDO2_LADRC 0x201 // LADRC状态2 (F4 -> H7)
|
||||
/*
|
||||
* 这个文件定义“上位机 CAN 协议 + 底盘状态机 + 故障/诊断上报”的公共接口。
|
||||
*
|
||||
* 设计原则:
|
||||
* 1) 10ms TIM6 中断只做硬实时内容:看门狗、速度解算、LADRC、故障判定。
|
||||
* 2) CAN 接收中断只解析帧,不做复杂浮点运算。
|
||||
* 3) 主循环只做低实时性的周期发送:状态帧、诊断帧、里程计。
|
||||
* 4) 运动安全只依赖“新鲜合法的 0x100 控制帧”,0x080 心跳不再允许底盘继续沿用旧速度运动。
|
||||
*/
|
||||
|
||||
// ---------------- 2. 机器人底盘物理参数 ----------------
|
||||
// 【注意】请根据你实际测量的小车物理尺寸修改以下参数
|
||||
#define ROBOT_TRACK_WIDTH_M 0.195f // 左右轮距 23.6 cm (0.236 m)
|
||||
#define ROBOT_WHEEL_RADIUS_M 0.040f // 车轮半径 (假设65mm轮子,即 0.0325 m)
|
||||
#define ICR_COEFFICIENT 1.0f // 瞬时旋转中心漂移系数 (默认1.0,根据场地摩擦力微调)
|
||||
#define PI_VALUE 3.1415926535f
|
||||
/* ================== 系统状态机定义 ================== */
|
||||
typedef enum
|
||||
{
|
||||
SYSTEM_BOOTING = 0, /* 上电启动,尚未收到第一帧合法速度命令。 */
|
||||
SYSTEM_OPERATIONAL, /* 正常工作,允许按目标速度运动。 */
|
||||
SYSTEM_SAFE_FAULT /* 安全保护:目标速度已被强制清零。 */
|
||||
} System_State_t;
|
||||
|
||||
// ---------------- 3. 状态机枚举 ----------------
|
||||
typedef enum {
|
||||
F4_STATE_FAULT = 0, // 故障/急停状态
|
||||
F4_STATE_OPERATIONAL = 1 // 正常运行状态
|
||||
} F4_SystemState_t;
|
||||
/* ================== 健康等级定义 ================== */
|
||||
typedef enum
|
||||
{
|
||||
SYSTEM_HEALTH_OK = 0, /* 当前没有活动中的告警/故障。 */
|
||||
SYSTEM_HEALTH_WARNING = 1, /* 有警告,但系统还可继续工作。 */
|
||||
SYSTEM_HEALTH_FAULT = 2 /* 有明确故障,通常已经或应当进入保护。 */
|
||||
} System_Health_t;
|
||||
|
||||
// ---------------- 4. 数据解包联合体 (处理浮点数字节序) ----------------
|
||||
typedef union {
|
||||
uint8_t bytes[8];
|
||||
struct {
|
||||
float target_vx; // 目标线速度 (m/s)
|
||||
float target_wz; // 目标角速度 (rad/s)
|
||||
} data;
|
||||
} RxCtrlPayload_t;
|
||||
/* ================== 诊断位图定义 ================== */
|
||||
typedef enum
|
||||
{
|
||||
DIAG_COMM_TIMEOUT = (1UL << 0), /* 速度控制帧超时。属于故障。 */
|
||||
DIAG_CAN_BUS_OFF = (1UL << 1), /* CAN Bus-Off。属于故障。 */
|
||||
DIAG_CMD_CRC_STORM = (1UL << 2), /* 连续 CRC 错误过多。属于故障。 */
|
||||
DIAG_CMD_CNT_STORM = (1UL << 3), /* 连续 rolling counter 错误过多。属于故障。 */
|
||||
DIAG_MOTOR_FL_STALL = (1UL << 4), /* 左前轮堵转/失效趋势。属于故障。 */
|
||||
DIAG_MOTOR_RL_STALL = (1UL << 5), /* 左后轮堵转/失效趋势。属于故障。 */
|
||||
DIAG_MOTOR_FR_STALL = (1UL << 6), /* 右前轮堵转/失效趋势。属于故障。 */
|
||||
DIAG_MOTOR_RR_STALL = (1UL << 7), /* 右后轮堵转/失效趋势。属于故障。 */
|
||||
DIAG_CONTROL_SATURATION = (1UL << 8) /* 控制输出长时间顶满。属于警告。 */
|
||||
} Chassis_DiagBits_t;
|
||||
|
||||
// ---------------- 5. 全局变量与函数声明 ----------------
|
||||
extern volatile F4_SystemState_t f4_fsm_state;
|
||||
extern RxCtrlPayload_t rx_ctrl_cmd;
|
||||
/*
|
||||
* 便于快速区分“只是提醒”还是“必须当故障处理”的位掩码。
|
||||
* 上位机解析时可以直接用这两个宏做分类。
|
||||
*/
|
||||
#define CHASSIS_DIAG_FATAL_MASK (DIAG_COMM_TIMEOUT | DIAG_CAN_BUS_OFF | DIAG_CMD_CRC_STORM | \
|
||||
DIAG_CMD_CNT_STORM | DIAG_MOTOR_FL_STALL | DIAG_MOTOR_RL_STALL | \
|
||||
DIAG_MOTOR_FR_STALL | DIAG_MOTOR_RR_STALL)
|
||||
#define CHASSIS_DIAG_WARN_MASK (DIAG_CONTROL_SATURATION)
|
||||
|
||||
// 填平 CubeMX 坑的初始化函数
|
||||
void F4_CAN_Filter_And_Start(void);
|
||||
/* ================== 核心控制结构体 ================== */
|
||||
typedef struct
|
||||
{
|
||||
float target_vx; /* 目标线速度,单位 m/s。 */
|
||||
float target_wz; /* 目标角速度,单位 rad/s。 */
|
||||
uint8_t ctrl_flags; /* 上位机附带的控制标志位,当前透传保存。 */
|
||||
uint8_t rolling_cnt; /* 最近一次接受的速度控制帧 rolling counter。 */
|
||||
System_State_t state; /* 当前系统状态机状态。 */
|
||||
} Robot_Control_t;
|
||||
|
||||
// 核心任务调度函数 (需放在 TIM6 10ms 中断内调用)
|
||||
void F4_CAN_Task_10ms(void);
|
||||
/* ================== 上位机可读的状态快照 ================== */
|
||||
typedef struct
|
||||
{
|
||||
System_State_t state; /* 当前状态机状态。 */
|
||||
System_Health_t health; /* 当前健康等级。 */
|
||||
uint32_t diag_bits; /* 当前活动中的诊断位图。 */
|
||||
uint8_t cmd_age_10ms; /* 距最近一次合法 0x100 已过去多少个 10ms tick。 */
|
||||
uint8_t last_cmd_counter; /* 最近一次接受的 rolling counter。 */
|
||||
} Chassis_StatusSnapshot_t;
|
||||
|
||||
#endif /* __F4_CAN_APP_H */
|
||||
/*
|
||||
* g_robot_ctrl 会在 CAN 接收中断里更新,也会在控制中断里读取,
|
||||
* 因此这里声明为 volatile,避免编译器把它优化成寄存器缓存。
|
||||
*/
|
||||
extern volatile Robot_Control_t g_robot_ctrl;
|
||||
|
||||
/* ================== CAN 协议说明 ==================
|
||||
*
|
||||
* Rx: 0x080 心跳帧
|
||||
* - 仅用于链路存在性,不参与运动看门狗
|
||||
*
|
||||
* Rx: 0x100 速度控制帧(8 字节)
|
||||
* Byte0~1 : int16_t vx * 1000, 单位 m/s,小端
|
||||
* Byte2~3 : int16_t wz * 1000, 单位 rad/s,小端
|
||||
* Byte4 : ctrl_flags
|
||||
* Byte5 : 预留
|
||||
* Byte6 : rolling counter
|
||||
* Byte7 : CRC8-SAE J1850(前 7 字节)
|
||||
*
|
||||
* Tx: 0x181 状态帧(20ms)
|
||||
* Byte0 : system_state
|
||||
* Byte1 : system_health
|
||||
* Byte2~5 : diag_bits, uint32 little-endian
|
||||
* Byte6 : cmd_age_10ms
|
||||
* Byte7 : status rolling counter
|
||||
*
|
||||
* Tx: 0x182 实际轮速帧(20ms)
|
||||
* Byte0~1 : FL 实际 RPM, int16 little-endian
|
||||
* Byte2~3 : RL 实际 RPM
|
||||
* Byte4~5 : FR 实际 RPM
|
||||
* Byte6~7 : RR 实际 RPM
|
||||
*
|
||||
* Tx: 0x183 目标轮速帧(20ms)
|
||||
* Byte0~1 : FL 目标 RPM, int16 little-endian
|
||||
* Byte2~3 : RL 目标 RPM
|
||||
* Byte4~5 : FR 目标 RPM
|
||||
* Byte6~7 : RR 目标 RPM
|
||||
*
|
||||
* Tx: 0x184 通信诊断帧(100ms)
|
||||
* Byte0 : valid_cmd_total 低 8 位
|
||||
* Byte1 : crc_error_total 低 8 位
|
||||
* Byte2 : counter_reject_total 低 8 位
|
||||
* Byte3 : can_tx_drop_total 低 8 位
|
||||
* Byte4 : busoff_total 低 8 位
|
||||
* Byte5 : rx_overrun_total 低 8 位
|
||||
* Byte6 : last accepted rolling counter
|
||||
* Byte7 : [7:4] 连续 counter 错误计数(饱和到15), [3:0] 连续 CRC 错误计数(饱和到15)
|
||||
*
|
||||
* Tx: 0x200 里程计增量帧(20ms)
|
||||
* Byte0~1 : FL delta ticks, int16 little-endian
|
||||
* Byte2~3 : RL delta ticks
|
||||
* Byte4~5 : FR delta ticks
|
||||
* Byte6~7 : RR delta ticks
|
||||
*/
|
||||
|
||||
/* ================== 对外接口 ================== */
|
||||
|
||||
/*
|
||||
* 初始化 CAN 应用层:
|
||||
* - 配置硬件滤波器,仅接收 0x080 / 0x100
|
||||
* - 启动 CAN 外设
|
||||
* - 打开 FIFO0 接收中断
|
||||
* - 清空通信诊断状态
|
||||
*/
|
||||
void CAN_App_Init(void);
|
||||
|
||||
/*
|
||||
* 10ms 周期调用:
|
||||
* - 维护速度控制命令看门狗
|
||||
* - 合法控制帧超时则进入 SAFE_FAULT
|
||||
*/
|
||||
void CAN_Safety_Watchdog_Tick(void);
|
||||
|
||||
/*
|
||||
* 10ms 周期调用:
|
||||
* - 从最近一次完整一致的目标命令快照进行差速解算
|
||||
* - 在 SAFE_FAULT / BOOTING 下强制目标轮速为 0
|
||||
*/
|
||||
void Kinematics_Update_LADRC(void);
|
||||
|
||||
/*
|
||||
* 10ms 周期调用:
|
||||
* - 根据目标 RPM、实际 RPM、控制输出做堵转/饱和诊断
|
||||
* - 该函数应放在 LADRC 控制环执行之后,以便读取最新反馈
|
||||
*/
|
||||
void Chassis_Diagnostics_10ms_Tick(void);
|
||||
|
||||
/*
|
||||
* 20ms 周期调用:
|
||||
* - 发送 0x181 状态帧
|
||||
* - 发送 0x182 实际轮速帧
|
||||
* - 发送 0x183 目标轮速帧
|
||||
* - 发送 0x200 里程计帧
|
||||
* - 内部每 5 次额外发送 1 次 0x184 通信诊断帧
|
||||
*/
|
||||
void CAN_Send_Telemetry_20ms(void);
|
||||
|
||||
/*
|
||||
* 获取当前快照,便于未来扩展到 USB/串口调试打印或上位机测试。
|
||||
*/
|
||||
void Chassis_Get_StatusSnapshot(Chassis_StatusSnapshot_t *snapshot);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,15 +35,19 @@ float LADRC_Calc(LADRC_TypeDef *ladrc, float actual_val);
|
||||
/* ================= 针对四轮底盘的 LADRC 扩展调度层 ================= */
|
||||
|
||||
// 将 4 个控制器暴露出来,方便 main.c 里面调取数据用 VOFA+ 打印波形
|
||||
extern LADRC_TypeDef ladrc_motors[4];
|
||||
extern LADRC_TypeDef ladrc_motors[4];
|
||||
|
||||
// 1. 初始化:一键初始化底层定时器和4个LADRC控制器
|
||||
/* 1. 初始化:一键初始化底层定时器和4个LADRC控制器 */
|
||||
void FourWheel_LADRC_Init(void);
|
||||
|
||||
// 2. 设定目标转速:给四个轮子下发指令
|
||||
/* 2. 设定目标转速:给四个轮子下发指令 */
|
||||
void FourWheel_Set_Target_RPM(float fl_rpm, float rl_rpm, float fr_rpm, float rr_rpm);
|
||||
|
||||
// 3. 核心闭环运算:必须且只能在 10ms 基础定时器中断里调用
|
||||
/* 3. 核心闭环运算:必须且只能在 10ms 基础定时器中断里调用 */
|
||||
void FourWheel_LADRC_Control_Loop(void);
|
||||
|
||||
/* 4. 诊断/状态上报接口:读取每个轮子的目标转速和控制输出 */
|
||||
float FourWheel_Get_Target_RPM(Motor_ID_t id);
|
||||
float FourWheel_Get_Control_Output(Motor_ID_t id);
|
||||
|
||||
#endif /* __LADRC_H */
|
||||
@@ -56,6 +56,7 @@ void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void CAN1_RX0_IRQHandler(void);
|
||||
void CAN1_SCE_IRQHandler(void);
|
||||
void TIM6_DAC_IRQHandler(void);
|
||||
void OTG_FS_IRQHandler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
Reference in New Issue
Block a user