Chassis::Steering4
cpkg add Chassis::Steering4文档
Steering4
Steering4 是四舵轮底盘的 Motion 实现。它和 Mecanum4 / Omni4 的差别不在于对外接口,而在于“底盘能否立即进入可控状态”这件事上存在明显的启动阶段。
主 README 只要求上层理解 IChassisMotion::isReady() 的意义;如果具体使用 Steering4,则需要额外理解这里的校准和轮组行为。
适用场景
- 四个轮组都同时具备驱动轴和舵向轴。
- 上层希望仍然把整个底盘当作统一
Motion使用,而不是自己分别控制四个舵轮。 - 启动时可能需要先完成舵向零点校准,再允许控制器接管。
对外仍然暴露的统一语义
Steering4 仍然遵守 IChassisMotion 语义:
enable()/disable():使能或失能四个轮组。forwardGetVelocity():返回当前估算到的车体速度。isReady():在未启用校准时恒为true;启用校准时只有全部轮组校准完成后才为true。
这也是为什么上层应依赖 isReady(),而不是假设“底盘一旦 enable 就一定可控”。
配置结构
Steering4::Config 分成两部分:
- 底盘公共几何参数:
radius、distance_x、distance_y - 每个轮组自己的
Wheel配置:SteeringWheel::Config和SteeringWheel::CalibrationConfig
几何参数单位如下:
radius:驱动轮半径,单位mmdistance_x:前后轮距,单位mmdistance_y:左右轮距,单位mm
每个轮组都包含两类底层对象:
drive_motor:轮向速度控制器steer_motor:舵向位置控制器
如果启用校准,还要提供:
calib_cfg.steer_motor:校准阶段用于慢速寻零的舵向速度控制器calib_cfg.photogate:光电门 GPIOcalib_cfg.photogate_active_state:光电门有效电平
如果使用光电门校准,photogate 对应的 EXTI 需要在 CubeMX 中配置为双边沿触发。当前实现默认“进入光电门区域”和“离开光电门区域”这两个边缘都会产生回调,否则下面的两次触发状态机假设就不成立。
启动与校准流程
推荐接入顺序:
- 构造
Steering4 - 调用
enable() - 如果
enable_calibration == true,调用startCalibration() - 周期调用
update() - 等待
isReady()返回true - 再交给
Controller正常发速度或位姿目标
当前校准逻辑的实际行为:
- 若一开始光电门已触发,轮组直接进入低速精捕阶段。
- 若一开始未触发,轮组先高速寻门,再在第一次触发后降速精捕。
- 第二次触发时,校准电机停下,舵向电机角度被复位到零点,随后重新使能舵向位置环和轮向速度环。
之所以不是“命中一次光电门就立刻完成校准”,是因为光电门通常对应一个有宽度的遮挡区,轮组转过该区域时会先后遇到两个边缘。当前实现用第一次触发说明“已经找到门”,随后降速继续转动,并把第二次触发固定为真正记零的边缘。这样可以避免零点有时取在进入边缘、有时取在离开边缘,减少重复上电后的零点漂移。
因此,如果使用 STM32 + CubeMX 接线方式,光电门 EXTI 不应只配上升沿或只配下降沿,而应配置为 Rising/Falling 双边沿触发。否则当前状态机拿不到完整的两个边缘事件,可能导致校准流程停在中间状态,或者零点边缘定义与预期不一致。
Steering4::applyVelocity() 在 !isReady() 时会直接返回,不会下发速度。这是有意设计,不是“忘记控制”。它的目的是防止校准期间被上层误发运动指令。
轮组速度与舵向优化
每个轮组的目标由一个平面速度向量计算得到:
- 目标角度
angle:轮子应该指向的行进方向,单位deg - 目标速度
speed:轮向速度,单位rpm
为了减少舵向电机无意义的大角度旋转,SteeringWheel::toBestVelocity() 会自动选择更短的等效解:
- 如果把舵向多转接近 180 度更慢,就直接改为反向驱动轮向速度
- 如果跨整圈更近,就会自动给目标角度加减
360度
这意味着上层不需要自己实现“翻轮”或“最短转角”逻辑,只要按普通底盘速度输入即可。
还有一个故意保守的处理:
- 当某个轮组的目标线速度接近零时,当前实现会保留该轮组现有舵向角,只把轮向速度设为零,避免静止时来回摆头。
轮序和几何方向
轮序在 Steering4::WheelType 中固定为:
FrontRightFrontLeftRearLeftRearRight
坐标方向与主 README 一致:
x指向车体前方y指向车体左侧yaw/wz逆时针为正
底层配置和线速度分解都基于这套方向约定,接线或建模时不要自行换轴而不改配置。
周期调用建议
update():放在运动控制快环中。它不仅负责驱动各轮控制器更新,也负责在非校准阶段刷新底盘反馈速度。startCalibration():只应在enable()成功后调用,且当前实现只打算执行一次启动校准。
如果上层已经有别的绝对零点建立方式,也可以把 enable_calibration 设为 false,让 Steering4 退化成“始终 ready 的四舵轮运动学层”。
一个常见例子是:舵向电机本身采用带双编码器的云台电机,掉电后能够依赖内部绝对参考完成零点恢复。此时本仓库不必再额外接入光电门做启动校准,只需要保证 steer_offset 与这套硬件恢复出来的绝对零点定义一致即可。
与主 README 的边界
主 README 负责告诉你“为什么 Motion 允许 not-ready”。本文件负责告诉你 Steering4 具体在什么情况下 not-ready、什么时候会忽略速度命令、以及校准阶段到底在做什么。