🏭 工程电机控制框架对比与选型
六大工程界常用电机控制框架 —— SimpleFOC · ODrive · VESC · ST MC SDK · TI InstaSPIN-FOC · MIT Mini Cheetah 范式。
每家给一张代码流程/状态机图,讲清「电流环放在哪、状态机怎么转、优缺点是什么」,最后落到一张横向对比大表和一棵选型决策树。
六大框架
代码流程图
状态机
横向对比
选型决策
读源码路线
🎯 本页学习目标
1. 能画出 SimpleFOC「loopFOC()+move() 两段式主循环」与 ODrive「ADC 中断电流环 + 轴状态机」两种代码结构的差异
2. 能说出六大框架各自的「电流环位置、状态机形态、观测器与参数辨识方式、开源许可」
3. 能对照横向对比大表(≥12 个维度),为自己的场景(学习 / DIY / 轮足 / 产品化 / 无感 / 人形关节自研)选对框架
4. 能按「找 ISR 入口 → 电流环 → 状态机 → 通信层」四步路线,独立读懂任一框架的源码
建议用时: 约 45 分钟(通读)+ 1~2 小时(对照源码精读)
1 全景:六个框架各自是谁,差别到底在哪?
04-02 页 已经介绍过 SimpleFOC / ODrive 的基本盘;本页把镜头拉近到「代码长什么样、跑在哪个中断里」 ,并把阵容扩到工程界最常打交道的六家:两家开源社区(SimpleFOC、ODrive)、一家功率场景老将(VESC)、两家芯片原厂(ST MC SDK、TI InstaSPIN-FOC),以及一个学术开源范式(MIT Mini Cheetah 关节驱动)。
同一个 FOC,六种「装法」。它们的数学内核几乎一样(采样 → Clark → Park → PI → 逆 Park → SVPWM,见 04-19 完整流程图 ),真正的差别集中在四个问题上:
电流环放在哪? ——主循环轮询、ADC 中断、RTOS 线程,还是芯片 ROM 里的固化代码?这决定了实时性与性能天花板。
状态机长什么样? ——有没有显式的轴状态机(axis state machine)?状态转换是手写 switch 还是任务链(task chain)?这决定了可靠性与产品化程度。
参数从哪来? ——手填、Motor Profiler 自测、FAST 在线辨识,还是校准序列自动量?这决定了上手的难易。
许可绑定谁? ——MIT 随便改、GPLv3 要传染、还是专有库绑定芯片?这决定了能不能商用、能不能移植。
1.1 六框架速览表
框架 一句话定位 开源许可 典型场景 门槛
SimpleFOC 教学优先的 Arduino FOC 库,20 行让电机转起来 MIT 学习 / 云台 / 低速 ★
ODrive 高性能开源伺服驱动(板+固件+上位机) MIT(经典 v3.x) 机械臂关节 / 高性能 DIY ★★★
VESC 大功率功率电子生态(滑板到电航) GPLv3(固件) 轮足 / 滑板 / 中型关节 ★★★☆
ST MC SDK 6.x ST 官方产品化 FOC 固件库 + Workbench 专有许可 · 免费下载 家电 / 工业产品化 ★★★
TI InstaSPIN-FOC ROM 固化 FAST 观测器,参数全自动辨识 专有(ROM 黑盒) 白电 / 泵 / 风机无感 ★★
Mini Cheetah 范式 学术开源关节驱动范式 + 「MIT 模式」CAN 协议 MIT(Cheetah-Software) 足式 / 人形关节自研参照 ★★★★
💡 学习锚点: 六家其实排在一条「易用 ⇄ 性能 」的轴上:SimpleFOC 最易用但性能天花板最低;ODrive/VESC 往性能走;ST/TI 面向量产;Mini Cheetah 范式则回答「如果这些都先用,自己写一个要长什么样」。读后面每节时,始终带着第 1 节开头的四个问题去看图。
实时性低
高
实时性 / 电流环位置
① SimpleFOC(MIT)
main loop 轮询 loopFOC() + move()
无硬实时 ISR 依赖 · 电流环多数不闭环
教学 / 云台 / 低速
② ODrive(MIT)
ADC 中断跑电流环(数 kHz~数十 kHz)
轴状态机 task chain + 观测器
机械臂 / 高性能 DIY
③ VESC(GPLv3)
mcpwm_foc ISR + ChibiOS 分层
applications / comm 应用任务 + VESC Tool
轮足 / 滑板 / 大功率
④ ST MC SDK 6.x(专有)
HF 任务(电流环)+ MF 任务 + 背景
STOP→IDLE→ALIGNMENT→START→RUN
家电 / 工业产品化
⑤ TI InstaSPIN-FOC(专有)
FAST 观测器固化在 F2806x 片内 ROM
Rs/L/磁链在线自辨识 · 无感
白电 / 泵 / 风机
⑥ Mini Cheetah 范式(MIT)
关节内 STM32 电流环 + CAN 命令层
MIT 模式: kp/kd/p_des/v_des/i_des
足式 / 人形关节自研参照
图 1-1 六框架架构差异总图:纵轴大致代表"电流环离硬件有多近",沿左列自上而下是易用→性能→量产→自研的谱系。越靠下/靠右,实时性要求越高、越接近产品化或自研范式。
2 SimpleFOC:教学优先的两段式主循环
2.1 定位与代码架构
定位: 把 FOC「去神秘化」的 Arduino 库。官方目标是 Demystify FOC algorithm and make a robust but simple Arduino library ,MIT 许可,文档(docs.simplefoc.com)与社区教程是六家里最全的。它回答的问题是:怎么用最少的代码、最普通的硬件(ESP32/Arduino + 驱动板 + 磁编码器),第一次让 FOC 闭环转起来。
代码架构: 面向对象三层——Motor(BLDCMotor 等)· Driver(功率驱动)· Sensor(编码器),C++ 类互相 link。所有电机类继承自 FOCMotor 基类,核心两段式入口 loopFOC() 与 move() 就定义在基类 FOCMotor.cpp 里 (BLDCMotor/StepperMotor 继承复用);SVPWM/正弦/梯形调制在 setPhaseVoltage() 里实现。运动控制在库里抽象为 MotionControlType(力矩/速度/位置/开环),由 move() 按 controller 类型分派。
// SimpleFOC 用户视角的全部骨架(六家里最短)
#include <SimpleFOC.h>
BLDCMotor motor = BLDCMotor(7); // 极对数
BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25);
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C); // 或 Encoder/ABI
void setup() {
driver.init(); motor.linkDriver(&driver);
sensor.init(); motor.linkSensor(&sensor);
motor.controller = MotionControlType::velocity; // 力矩/速度/位置
motor.init(); motor.initFOC(); // 校准电角度零偏
}
void loop() {
motor.loopFOC(); // ① 低层 FOC: 读角度→(采样)→电流计算→SVPWM 出波
motor.move(5.0f); // ② 高层运动: 按控制模式把目标换算成电压/电流指令
}
2.2 中断结构与核心流程
中断结构: SimpleFOC 的主控制链默认跑在 Arduino 主循环的普通调用栈 里,不依赖硬实时 ISR——这正是它好懂的原因,也是它性能天花板的根源(执行周期抖动大、频率受 loop 其他代码拖累)。需要注意的例外:ABI 增量编码器的 A/B 相计数用 GPIO 中断回调;低边电流采样(LowsideCurrentSense)在某些平台会挂 ADC 中断回调。但对最常见的「电压模式 + 磁编码器」配置,整个系统就是"主循环 + 一点点中断"。
核心流程: loopFOC() 读编码器角度 → (若有电流采样则做相电流计算)→ 依据当前力矩指令经逆 Park/SVPWM 输出三相电压;move() 则按速度/位置环 PID 把目标值换算成下一拍力矩指令。关键短板: 绝大多数入门配置没有相电流采样硬件,电流环并不闭环 ——库用「电压 ≈ 力矩」的近似(或估算电流),力矩精度与电流谐波抑制天然弱于闭环电流环方案;即使加装 inline/lowside 采样,受平台定时器资源限制,电流环频率也远低于 ODrive/VESC 类方案。
setup()(上电一次)
driver / sensor / motor
.init() + link()
motor.initFOC()
电角度零偏校准
进入 loop()(周期轮询)
loop() · 每圈顺序执行(无硬实时 ISR 依赖)
① motor.loopFOC()
读编码器电角度 θ
(有电流采样→相电流计算)
逆 Park → SVPWM 出三相电压
② motor.move(target)
按 MotionControlType 分派:
力矩(电压/电流)· 速度 · 位置 · 开环
外环 PID → 输出下一拍力矩指令
下一圈循环(默认无硬件定时器节拍)
仅有的中断: 编码器 A/B 相 GPIO 中断计数
(低边电流采样时另有 ADC 回调)
控制链本身不压在硬实时中断里
图 2-1 SimpleFOC 主循环两段式流程:setup 做校准,loop 里 loopFOC()(低层出波)+ move()(高层分派)顺序轮询。结构 = 「六家里最好懂」,代价是节拍抖动与性能天花板。
2.3 优缺点与适用
✔ 优点 ✘ 缺点
20 行上手,文档/社区/示例六家最全;硬件无关(Arduino/STM32/ESP32/Teensy/RP2040…);类结构清晰,读源码是学 FOC 工程化的最佳教材;MIT 许可随便改 多数配置无相电流检测,电流环不闭环 (电压近似力矩);主循环轮询节拍抖动,速度/力矩纹波偏大;实时性与功率上限低,不适合关节级高带宽力控
适用: FOC 入门教学、云台/低速平稳运动、算法原型验证、读源码学架构。不适用: 需要高带宽电流环的关节力控。想先动手跑通的读者,直接照 04-02 页第 3 节的最小示例开工。
3 ODrive:状态机驱动的高性能开源伺服
3.1 定位与代码架构
定位: 「高性能 hobby/prosumer」路线的代表作——硬件 + 固件 + 上位机全开源(MIT),把工业伺服的三环结构塞进一块双轴板子。注意两点事实(截至本文核实):① 开源固件对应经典 v3.x 硬件,官方已标记 NRND(不再积极开发),新款 Pro/S1/Micro 的固件源码未公开; ② 虽然如此,v3.x 固件仍是学习「产品级 FOC 固件怎么组织」的最佳文本之一。
代码架构: 核心抽象是 Axis(轴) ——一块板两个 Axis,每个 Axis 聚合 Motor(FOC 电流环)、Encoder(位置/速度估计)、Controller(位置/速度环)、Trapezoidal Trajectory(轨迹规划)等组件。每个组件有各自的后台线程(FreeRTOS),而电流环独占最高实时性 :挂在 PWM 同步的 ADC 采样完成中断/最高优先级线程里,频率与 PWM 同量级——严谨地说在数 kHz 到数十 kHz 之间(依配置与硬件代次而变,不建议背具体数,面试说区间即可)。
// ODrive 固件阅读地图(v3.x 固件, 以仓库当前版本为准)
Firmware/MotorControl/
├── axis.cpp // 轴状态机: Axis::run_state_machine_loop() + task chain
├── motor.cpp // 电流环核心: Motor::FOC_current(Id_des, Iq_des, ...)
├── controller.cpp // 位置环/速度环 + 轨迹跟踪
├── encoder.cpp // 编码器计数 / 速度估计 / 校准
├── low_level.cpp // ADC 采样启动(start_adc_pwm)· 模拟量 · 母线
└── sensorless_estimator.cpp / acim_estimator.cpp // 可选无感/异步机估计
3.2 中断结构与轴状态机
中断结构: 电流环在 PWM 周期驱动的采样中断里闭环(采两相电流 → FOC → 更新比较寄存器);位置/速度环跑在低一些频率的线程里;USB/CAN 通信又是更低优先级的线程。这是典型的「三层时间尺度 」结构,几乎所有的产品级关节固件都是这个形状。
状态机: 每个 Axis 有一个显式的 AxisState 状态机,上位机通过写 requested_state 请求切换。官方定义的状态包括:UNDEFINED / IDLE / STARTUP_SEQUENCE / FULL_CALIBRATION_SEQUENCE / MOTOR_CALIBRATION / ENCODER_INDEX_SEARCH / ENCODER_OFFSET_CALIBRATION / CLOSED_LOOP_CONTROL / LOCKIN_SPIN / ENCODER_DIR_FIND / HOMING / ENCODER_HALL_POLARITY_CALIBRATION / ENCODER_HALL_PHASE_CALIBRATION 等。上电启动链(STARTUP_SEQUENCE)会按配置依次串起「电机参数测量 → 编码器索引搜索 → 编码器零偏校准 → 进入闭环」,在固件里实现为一条 task chain(任务链) 依次执行——这是 ODrive 架构里最值得抄的设计之一。
上电 · UNDEFINED
IDLE(待机)
requested_state
FULL_CALIBRATION_SEQUENCE
(首次使用 · task chain 依次展开 ↓)
MOTOR_
CALIBRATION
测 R/L
ENCODER_INDEX_
SEARCH
(增量码盘)
ENCODER_OFFSET_
CALIBRATION
电角度零偏
再次上电可直接 CLOSED_LOOP
(配置 startup)
CLOSED_LOOP_CONTROL(闭环运行)
电流环: ADC 采样中断 · 数 kHz~数十 kHz · FOC_current()
速度/位置环: 线程级低频 + 观测器(编码器 / 可选无感)
输入: input_pos / input_vel / input_torque
故障(过流/过压/超时)→ disarm → IDLE + error 码
上位机接口层
USB / UART / CAN
odrivetool(Python)
图 3-1 ODrive 轴状态机(据 v3.x 固件 AxisState 枚举整理):校准是一次性资产,任务链串完直接进闭环;运行期任何故障走 disarm 回 IDLE。上位机永远只做一件事——写 requested_state 与 input_*。
3.3 优缺点与适用
✔ 优点 ✘ 缺点
真正闭环的电流环(高带宽力控);显式轴状态机 + task chain,工程化程度高;观测器体系完整(编码器为主、可选无感/异步机);USB/UART/CAN 生态 + odrivetool 调参舒适;MIT 许可 硬件绑定(自家板卡);调参复杂(三环+编码器+滤波器全套);经典 v3.x 已 NRND、新代次固件不开源——长期项目要有心理准备;上手成本远高于 SimpleFOC
适用: 机械臂关节原型、四足/人形单腿样机、高性能 DIY(轮式平衡、云台直驱)。配置步骤见 04-02 页第 4 节 (odrivetool 校准与 Python 控制)。
4 VESC:大功率场景的 RTOS 分层架构
4.1 定位与代码架构
定位: Benjamin Vedder 的开源功率电子生态,从几十瓦的云台电机到上百千瓦的电航应用都在用(官网口径),电动滑板/EBike/轮式机器人是最大用户群。功率等级、成熟度、工具链(VESC Tool 全家桶)是它的名片。许可要如实记:固件 GPLv3 ——商用整机要考虑 GPL 传染条款,这一点和 MIT 系完全不同。
代码架构(vedderb/bldc 仓库): 跑在 ChibiOS(RTOS) 上,层次分明:
实时内核级 :motor/mcpwm_foc.c 里的 FOC 中断服务(mcpwm_foc_isr_motor())——电流采样 + FOC + SVPWM 都压在与 PWM 同步的 ISR 里,这是全系统最硬的实时部分;
应用任务层 :applications/ 目录(app_canbus、app_adc、app_uartcomm、app_nunchuk 等)——每种输入源一个任务,把「外部世界」翻译成电机目标值;
通信层 :comm/(USB/UART/CAN 包协议与终端命令),加 terminal.c 命令行;
配置与硬件抽象 :hwconf/(几十种官方/社区硬件板配置)、conf_general(参数管理)。
高级调制策略上,VESC 内置弱磁(field weakening)与 MTPA(最大转矩电流比) 一类的高速/高效策略(具体开关以所用版本固件为准),这是 SimpleFOC 完全没有、ODrive 也较少触及的功率域功能。
VESC Tool(配置/调参/固件升级)
电机向导 · 实时数据 · 示波器
comm/ 通信层 + terminal 命令行
USB 包协议 · UART · CAN 帧转发(可组网多控制器)
applications/ 应用任务(每种输入源一个任务)
app_canbus(机器人常用)· app_adc(油门)· app_uartcomm · app_ppm/nunchuk
电机目标管理 + 观测/保护(ChibiOS 线程)
目标值仲裁 · 速度/位置环 · 弱磁 / MTPA · 过流过温保护 · 状态超时
mcpwm_foc ISR(PWM 同步 · 最硬实时)
相电流采样 → Clark/Park → 电流 PI → 逆 Park → SVPWM → 比较寄存器
三相功率桥 → 电机(大功率)· hwconf/ 板级配置
图 4-1 VESC 分层架构(据 vedderb/bldc 仓库结构整理):ISR 只做电流环,其余全部下放到 RTOS 线程与任务——「最硬的尽量少、其余尽量分层」是大功率固件的通用哲学。
4.2 优缺点与适用
✔ 优点 ✘ 缺点
大功率场景久经考验(滑板→轮足→中型关节);VESC Tool 工具链全(向导/示波器/固件升级);弱磁/MTPA 等功率域策略内置;硬件配置(HW 版本)生态丰富,社区成熟 固件 GPLv3 (商用传染条款要想清楚);代码庞杂、历史包袱重,学习曲线六家里最陡;为滑板场景设计,关节伺服语义(如关节级力控接口)要自己封装
适用: 轮式/轮足机器人大功率轮毂驱动、电动滑板、中大功率关节(需自行封装力控语义)。B站搜「VESC 电机」有大量中文上手视频(见文末资源卡)。
5 ST MC SDK 6.x:芯片原厂的产品化 FOC 库
5.1 定位与代码架构
定位: ST 官方电机控制 SDK(X-CUBE-MCSDK,当前 6.x 代),面向产品化 ——家电、工业、泵类、工具。免费下载(走 ST 官网申请流程),但属专有许可 ,和开源社区的 MIT 系不同。它回答的问题是:「我要把一台未知电机做成可靠量产的产品,谁来替我把参数、代码、调试工具一次配齐?」
代码架构与工具链: 三大件——
Motor Profiler :接上未知电机自动测 Rs/Ls/反电动势常数等参数(官方叫 Motor profiler 与 one-touch tuning),解决了「参数从哪来」的问题;
Motor Control Workbench + CubeMX 集成 :图形化选电机、选功率板、配外设,直接生成工程代码——代码是「生成的」,不鼓励你手改结构;
固件库本体 :观测器支持齐全(有感编码器/霍尔 + 无感状态观测器,SMO 类),利用 STM32(G4 等)的 CORDIC/FPU 加速坐标变换与三角运算。
5.2 任务调度与状态机
任务调度: MC SDK 把工作切成三个时间尺度——高频任务 (电流环,跟随 PWM 更新节拍执行)、中频任务 (速度/位置控制与状态推进,固定毫秒级周期)、后台任务 (通信协议栈、监控、调试变量)。这套 HF/MF/背景划分与 ODrive 的「ISR/线程/通信」异曲同工,但更「库化」:入口函数、回调点、状态推进都由框架约定好。
状态机: 电机控制状态机围绕一条主链运转:STOP → IDLE → ALIGNMENT(编码器/观测器对齐)→ START(启动序列)→ RUN → STOP,另有 ICLWAIT(过流等待)、充电自举电容、故障态等辅助状态。所有启动/停止指令(MC_StartMotor1 / MC_StopMotor1)都只是向状态机发请求,真正的时序由状态机统一推进——这正是产品代码需要的「谁都不能绕过状态机乱来」的纪律。
电机控制状态机(主链)
STOP
IDLE
ALIGNMENT
对齐/观测器初始化
START
RUN
MC_StopMotor1 → 回 STOP
FAULT(过流/过压/堵转)→ 急停
三个时间尺度的任务调度
高频任务(电流环)
跟随 PWM 更新节拍执行: 采样→FOC→SVPWM
最高实时性
中频任务(速度/位置)
固定毫秒级周期: 外环 PID · 状态机推进 · 斜坡/轨迹
ms 级周期
后台任务(通信/监控)
UART/USB 协议 · 调试变量 · Motor Profiler 数据交换
图 5-1 ST MC SDK 状态机与任务调度:上半是「谁都不能绕过」的状态主链(STOP→IDLE→ALIGNMENT→START→RUN),下半是 HF/MF/后台三尺度任务。产品代码要的纪律感,这张图就是答案。
5.3 优缺点与适用
✔ 优点 ✘ 缺点
商业级文档/支持/稳定性背书;Motor Profiler + 一键整定,新电机出活快;CubeMX 代码生成,外设配置零踩坑;无感观测器与硬件加速(CORDIC)齐备;免费 代码量大、生成式代码可读性一般;深度定制受框架约束;绑定 ST 芯片生态 ;许可为专有协议(以随包协议为准),不能像 MIT 那样随意嵌入自研商业固件
适用: 家电/电动工具/工业辅助动力等产品化项目;用 ST 芯片自研关节固件时,它的状态机与任务划分也是最好的「抄作业」对象(见第 11 节)。
6 TI InstaSPIN-FOC:ROM 里的 FAST 观测器与参数自辨识
6.1 定位与架构:把「最难的脑子」焊死在芯片里
定位: TI 面向白电/泵/风机等无感(one-wire 或 zero-sensor) 量产场景的 FOC 方案。它的杀手锏是 FAST 估计器(Flux, Angle, Speed, Torque) :一个统一的电机观测器,直接固化在 TMS320F2806x(F/M)等特定 Piccolo 型号的片内 ROM 里 (TI 官方口径:FAST 仅以 ROM 形式提供于特定器件),配合 MotorWare 软件框架与引导 GUI 使用。
架构特点: 你写的应用代码调用 ROM 里的 FAST 句柄;FAST 输出磁链、角度、转速、转矩四个量,FOC 电流环用它做无感换相。参数辨识是全自动的: 上电跑一遍辨识流程,电机电阻 Rs、电感 L(以及感应电机的 Rr、额定磁链 V/Hz)直接量出来——这是它「五分钟出活」的核心卖点。代价也很明确:黑盒(ROM 代码不可读不可改)+ 绑定 TI 特定型号 ,换平台就归零。
上电 · 连接 GUI
已有参数?
是→加载
否→辨识
测电机电阻
Rs · 直流注入
测电感
L(高频激励)
测额定磁链
Flux(V/Hz)· 拖动
参数保存 → 进入无感 FOC 运行
无感运行环(每 PWM 周期)
FAST 观测器(ROM)
输入: 相电压/相电流
输出: 磁链·角度·转速·转矩
FOC 电流环
用 FAST 角度做 Park
Id/Iq PI → 逆 Park
SVPWM
→ 逆变器
→ 电机
FAST 以 ROM 形式固化于特定 F2806x 型号 · 应用代码经句柄调用
图 6-1 InstaSPIN-FOC 辨识与无感运行流程(据 TI SPRUHI9/SPRUHJ1 系列文档整理):辨识三步自动量出 Rs/L/磁链,FAST 观测器全程接管角度——「没有编码器,也没有调参地狱」。
6.2 优缺点与适用
✔ 优点 ✘ 缺点
参数辨识全自动,上电即用;无感性能在「风机/泵」这类负载画像上表现好;ROM 固化不占用户 Flash/CPU,一致性好;GUI 引导式上手,门槛低 ROM 黑盒,不可读不可改,出问题只能绕;强绑定 TI C2000 特定型号 (F2806x F/M 等),不可移植;机器人关节场景(低速大转矩、频繁正反转)不是它的设计画像
适用: 白电(空调风机/洗衣机)、泵类、风扇等标量负载的无感量产。对机器人工程师,它值得学的不是「拿来用」,而是「参数自辨识 + 统一观测器」的产品思路 ——无感观测器的算法族谱见 04-17 状态观测器全解 。
7 MIT Mini Cheetah:学术开源范式与「MIT 模式」CAN 命令
7.1 定位:不是「一个库」,而是一套被产业复刻的关节范式
定位: MIT Biomimetics Robotics Lab 的 Mini Cheetah 四足机器人展示了「准直驱关节 + 高带宽力控」能跑能跳能后空翻。其开源仓库 Cheetah-Software(MIT 许可) 包含整机控制(robot)与仿真(sim)软件栈;注意:关节内部的电流环固件并未随该仓库开源 ,但它的关节接口协议被产业界原样复刻 ——CubeMars AK 系列、T-Motor、达妙、宇树 GO 系列执行器等都提供「MIT 模式」,使它成为足式/人形关节自研绕不开的参照系。
7.2 层级结构与「MIT 模式」报文
层级: 关节内,FOC 电流环跑在 STM32 的 PWM 同步采样中断里,频率为数十 kHz 量级 (保证电流带宽);关节外,整机控制器以固定高频 (如 1kHz 量级)通过 CAN 广播每个关节的目标。命令层就是著名的「MIT 模式」: 把 5 个控制量打包进一个 8 字节 CAN 数据帧——
// 「MIT 模式」CAN 命令帧(8 字节, 产业通行的打包约定)
// 五个控制量按固定位宽压缩: 位置 16bit + 速度/Kp/Kd/前馈电流 各 12bit
p_des(16bit) | v_des(12bit) | kp(12bit) | kd(12bit) | i_des(12bit)
// 语义是「软件刚度-阻尼 + 前馈」的关节级 PD:
tau_cmd = kp * (p_des - p) + kd * (v_des - v) + i_des
// 三个量全给 0 → 纯力矩(前馈)模式,即 tau = i_des
// kp/kd 给大、i_des=0 → 变成位置伺服(刚度阻尼由 kp/kd 决定)
这条公式是理解人形/四足关节的钥匙:整机控制器在 1kHz 发「目标+刚度+阻尼」,关节内的电流环把它变成真正的电磁转矩 ——力控的「力」是两层合作出来的(整机侧的 WBC/MPC 算关节力矩,关节侧保证力矩准确,见 04-02 第 5.4 节)。宇树的执行器 SDK 就是这套模式的工程化封装。
整机控制器
步态 / MPC / WBC
每 ~1ms 算出各关节
p_des v_des kp kd i_des
(Cheetah-Software · MIT 许可)
CAN 命令帧(8B)
p_des · 16 bit
v_des · 12 bit
kp · 12 bit
kd · 12 bit
i_des · 12 bit
「MIT 模式」打包约定
关节驱动板(STM32)
电流环 ISR
数十 kHz 量级
采样→FOC→SVPWM
三相桥 → 无框电机
+ 编码器/减速器
回传帧
p · v · i(实测)
指令
回传实测 p/v/i(供状态估计)
tau_cmd = kp·(p_des − p) + kd·(v_des − v) + i_des
kp=kd=0 → 纯前馈力矩模式; i_des=0 → 纯位置伺服; 组合即「可编程关节刚度/阻尼」
图 7-1 Mini Cheetah 范式:整机 1kHz 发「MIT 模式」命令,关节内数十 kHz 电流环执行并回传实测。一条公式打通人形机器人「大脑→关节」的全部语义。
7.3 优缺点与适用
✔ 优点 ✘ 缺点
关节控制范式的事实标准(「MIT 模式」),产业模组直接兼容;接口语义干净(5 个数定义一个关节),整机算法与关节固件解耦;代码精炼(Cheetah-Software 为 MIT 许可,可自由研读) 关节内电流环固件未随仓库开源,要自己写(或用商业模组);没有现成的配置工具链/上位机;从范式到产品,中间隔着供电、保护、标定、多关节同步等所有工程细节
适用: 足式/人形机器人关节自研 的接口与架构参照。选定该范式后,第 11 节的自研建议直接可用;商业关节模组怎么按此协议使用,见 02-05 参考资料汇总 的关节模组产品清单。
8 横向对比大表:13 个维度一表定乾坤
面试与选型都靠这张表。维度看着多,记法是把它们分成四组:实时性组 (电流环位置/频率、采样要求)、算法组 (观测器、参数辨识、SVPWM)、工程组 (状态机、通信、代码规模、学习曲线)、合规组 (许可、硬件绑定、场景)。
维度 SimpleFOC ODrive VESC ST MC SDK 6.x InstaSPIN-FOC Mini Cheetah 范式
定位 教学/原型库 高性能开源伺服 大功率生态 产品化 FOC 库 无感量产方案 关节自研范式
许可 MIT MIT(v3.x 固件) GPLv3(固件) 专有 · 免费 专有(ROM 黑盒) MIT(Cheetah-Software)
电流环位置 主循环轮询 ADC 采样中断 mcpwm_foc ISR HF 任务(随 PWM) FOC 调 ROM FAST 关节内 PWM 同步 ISR
电流环频率量级 依 loop 速度,无硬节拍 数 kHz~数十 kHz 数十 kHz 量级(依板) 随 PWM 频率 随 PWM 频率 数十 kHz 量级
电流采样要求 可选(多数配置无) 低边采样电阻×2 低边/相采样(依板) 1~3 电阻可配 必需(无感依赖) 必需(力控基础)
观测器 无(编码器直读) 编码器为主 + 可选无感估计器 编码器 / 无感(观测器、HFI 低速注入) SMO 等状态观测器 FAST(ROM 固化) 编码器 + 电流环直出力矩
参数辨识 手填(可测电阻) 校准序列自动测 R/L/零偏 VESC Tool 向导检测 Motor Profiler 自测 FAST 在线自辨识 模组出厂标定/自研
SVPWM 实现 软件法(整数/浮点) 软件 + 高级定时器 软件 + 高级定时器 库内实现 + CORDIC 加速 库内实现 自实现(精炼)
状态机复杂度 无显式状态机(模式枚举) 轴状态机 + task chain 状态/超时管理(RTOS) STOP→…→RUN 主链完整 辨识/运行两段式 精简(使能/错误)
通信与上位机 Serial/Commander,SimpleFOCStudio USB/UART/CAN,odrivetool USB/UART/CAN,VESC Tool GUI/串口协议(Workbench) GUI 引导 「MIT 模式」CAN(自定)
代码规模 小(库) 中(固件工程) 大(庞杂) 大(生成式) 中(调 ROM) 小(范式级)
学习曲线 / 硬件绑定 极平缓 / 几乎不绑定 陡 / 绑定自家板 最陡 / 绑定 VESC 板 中 / 绑定 ST 芯片 平缓 / 绑定 TI 型号 陡 / 不绑定(自己造)
适用功率与场景 小功率·学习/云台 中小功率·机械臂/DIY 中大功率·轮足/滑板 家电/工业量产 白电/泵/风机无感 足式/人形关节自研
慢(10ms 级)
快(1ms 级)
最快(100μs 级)
SimpleFOC
主循环 loopFOC()+move()
(无硬节拍)
ODrive
USB/CAN 通信
位置/速度环线程
ADC 中断电流环 FOC
VESC
comm/ + VESC Tool
app_* 任务(ChibiOS)
mcpwm_foc ISR
ST MCSDK
后台: 通信/监控
中频: 速度/位置 ms 级
高频: 电流环随 PWM
InstaSPIN
GUI / MotorWare 应用层
FOC 调用 ROM 内 FAST(黑盒)
MiniCheetah
整机控制器 ~1kHz 广播 MIT 模式命令
关节内电流环 ISR
电流环实时性递增
图 8-1 六框架实时执行模型对比(示意,横向为时间尺度):每个框架都把「最硬实时」的那一小块推到最右边——电流环永远是最右边的那个色块 。SimpleFOC 是唯一的例外(最右只有主循环自己)。
9 选型决策树:六个问题定去向
选型不要背表,问自己六个问题:目标是什么 → 有没有力控要求 → 功率多大 → 要不要产品化 → 有没有编码器 → 是不是整机关节阵列。走一遍下面的树:
你的目标是什么?
先学会 FOC
SimpleFOC
理由: 20行上手·文档最全
MIT·不绑硬件
做机器人项目
按下面四个场景再分流
高性能 DIY / 机械臂关节
→ ODrive
理由: 真闭环电流环·状态机成熟
odrivetool 调参顺·MIT
(注意 v3.x NRND)
大功率轮足/滑板
→ VESC
理由: 大功率久经考验
弱磁/MTPA·VESC Tool 全
(GPLv3 商用注意)
产品化
家电/工业
→ ST MC SDK
Motor Profiler
商业支持
无编码器
无感场景
→ InstaSPIN
FAST 自辨识
绑 TI 型号
以上都不满足: 自研一批人形/足式关节?
足式 / 人形关节自研 → Mini Cheetah 范式
理由: 「MIT 模式」是关节接口事实标准, 商业模组直接兼容;
中断骨架抄 ODrive, 状态机学 MC SDK, 命令协议学 MIT 模式;
先用商业模组验证整机, 再逐关节替换自研(见第 11 节)
图 9-1 选型决策树:六片叶子各配一条「为什么」。注意分支顺序——先问目标(学习 vs 项目),再问场景(性能/功率/量产/无感),最后问是否自研。
⚠️ 选型三条反直觉忠告:
① 别用选型逃避动手 ——学习期纠结「SimpleFOC 还是 ODrive」超过一天,直接 SimpleFOC 开跑;
② 别拿教学库做关节 ——SimpleFOC 的架构天花板决定了它撑不起关节级力控,升级时是架构级重写而不是调参;
③ 别忽视许可 ——GPLv3(VESC)与专有许可(ST/TI)在商用产品的合规成本,要从立项第一天算进去。
10 如何读源码:通用四步路线 + 两个起点
读任何电机控制固件,都按同一条路线走,不要从 main.c 顺着读到尾:
1 找 ISR 入口 搜 ADC_IRQHandler / ISR / ADC callback / start_adc_pwm,电流环一定挂在 PWM 同步的采样点上
2 读电流环 确认采样→Clark/Park→PI→逆 Park→SVPWM 五步都在 ISR 里,记下执行频率
3 读状态机 找 state / run / task chain,画出状态转移图(本章每家的图就是作业答案)
4 读通信层 命令怎么进来(帧格式/校验)、数据怎么出去,注意与状态机的写入权限边界
10.1 起点一:SimpleFOC(先读懂「教学版骨架」)
入口:src/common/base_classes/FOCMotor.cpp —— FOCMotor::loopFOC() 与 FOCMotor::move()(两段式的真正定义处,BLDCMotor 只是继承);
调制:src/BLDCMotor.cpp 的 setPhaseVoltage() —— 梯形/正弦/SVPWM 三种调制怎么切换;
外环:src/common/pid.cpp(PID 实现)与 lowpass_filter.cpp(一阶低通)——最小可读的控制器参考实现;
通信:src/communication/Commander.cpp —— 串口命令协议的极简范本。
读完检验:能不看书手画「loopFOC + move」的数据流图,能说出角度 θ 从传感器到 SVPWM 的完整路径。
10.2 起点二:ODrive(再读懂「产品级骨架」)
// ODrive v3.x 固件(路径与函数名以仓库当前版本为准)
Firmware/MotorControl/
├── axis.cpp → Axis::run_state_machine_loop() // ③ 状态机: requested_state 队列 + task chain
├── motor.cpp → Motor::FOC_current(Id, Iq, ...) // ② 电流环核心
├── low_level.cpp → start_adc_pwm() // ① ISR 入口: PWM 触发 ADC 采样的启动配置
├── controller.cpp → Controller::update() // ②' 位置/速度外环
└── encoder.cpp → Encoder 校准/估计 // 观测与标定
读完检验:能说出「一条 input_torque 指令从 CAN/USB 进来,经过哪些层、变成哪几组 PWM 比较寄存器的值」;能解释 CLOSED_LOOP_CONTROL 与 IDLE 之间会经过哪些状态。这一套读下来,再看 VESC 的 mcpwm_foc.c 或 MC SDK 生成的代码,只是「换个文件夹名」而已。
💡 阅读纪律: 每次只带着一个问题读(如「电流环在哪被调用」),用 IDE 全局搜索而不是顺序阅读;把每次找到的「ISR 入口→状态机→通信层」路径记进笔记,读三个仓库后,第 11 节的自研骨架自然长出来。
11 自研建议:从哪抄架构,checklist 管住风险
11.1 三件「值得直接抄」的设计
A 中断骨架抄 ODrive 「PWM 同步 ADC 采样 → 最高优先级跑电流环 → 外环放线程 → 通信最低」的三层时间尺度,是被反复验证的形状;再加 ODrive 式 task chain 校准序列
B 状态机学 MC SDK STOP→IDLE→ALIGNMENT→START→RUN 主链 + 故障态旁挂:任何指令都只对状态机「发请求」,时序由状态机统一推进,谁都不能绕过
C 命令协议学 MIT 模式 p_des/v_des/kp/kd/i_des 五元组 + 固定位宽打包:接口语义十年不变,商业模组即插即用,整机算法换代不用动关节固件
把它们拼起来,就是一个合格的自研关节固件雏形:ODrive 的实时骨架 + MC SDK 的状态纪律 + MIT 模式的接口 。观测器与参数辨识可以后置(先用编码器 + 出厂标定,无感留给 04-17 的算法储备)。
11.2 自研工程 checklist(立项就贴墙上)
实时性: 电流环是否独占最高优先级?最坏情况执行时间(而非平均值)是否测过?电流环频率是否 ≥ 速度环 5 倍以上?
采样: ADC 是否 PWM 中心对齐同步触发?低边采样的窗口是否避开开关沿?双电阻丢一相时是否有降级策略?
安全: 过流(逐波限流+软件阈值)、过压/欠压、过温降额、超时通信丢失回 IDLE——四类保护是否全部独立于通信层生效?上电默认状态是否为 IDLE?
校准: 电角度零偏、电阻电感、编码器方向——校准序列是否有 task chain 式的顺序与失败回退?
接口: CAN 命令是否兼容「MIT 模式」语义?帧 ID/字节序/回传频率是否写进协议文档?固件版本号是否可查?
许可: 抄的代码是什么许可?GPLv3 部分是否与专有代码隔离?商用法务是否过目?
✅ 落地路线建议: 先用 SimpleFOC 验证原理 → 用商业模组(MIT 模式类,CyberGear/AK/RobStride 等)搭整机打通运动控制 → 需要降本/定制时,按「第 11.1 节三件套」自研单关节 → 一关节打通后再复制阵列。每一步都有退路,而不是一步跳进「固件 + 整机 + 结构」三线作战。
12 本节自测
1. SimpleFOC 与 ODrive 在「电流环放在哪」这一架构点上的本质区别是?
A. SimpleFOC 用电流环而 ODrive 不用
B. 两者都把电流环放在 ADC 中断里,只是语言不同
C. SimpleFOC 默认主循环轮询、多数配置无相电流检测(电流环不闭环);ODrive 把电流环压在 PWM 同步的 ADC 采样中断里真正闭环
D. ODrive 的电流环跑在 Python 上位机里
💡 解析:SimpleFOC 的 loopFOC()+move() 两段式跑在主循环轮询栈上,无硬实时 ISR 依赖,常见配置没有相电流采样、用电压近似力矩;ODrive 的电流环在 PWM 同步的 ADC 采样中断里执行,频率达数 kHz~数十 kHz 量级,是真正闭环的电流控制——这正是两者性能天花板差异的根源(第 2、3 节)。
2. 关于六个框架的开源许可,下列对应关系正确的是?
A. VESC 采用 MIT 许可,可随意闭源商用
B. SimpleFOC / ODrive / Cheetah-Software 为 MIT,VESC 固件为 GPLv3,ST MC SDK 与 TI InstaSPIN 为专有许可
C. 六个框架全部是 MIT 许可
D. ST MC SDK 是 GPL 许可,必须开源用户代码
💡 解析:经各官方仓库/文档核实:SimpleFOC(MIT)、ODrive v3.x 固件(MIT)、Cheetah-Software(MIT);VESC 固件为 GPLv3(商用有传染条款);ST X-CUBE-MCSDK 免费下载但走 ST 专有协议;TI 的 FAST 观测器更是 ROM 黑盒(专有)。许可差异直接影响商用合规(第 1、4、5、6 节)。
3. 「MIT 模式」CAN 命令帧中,五个控制量的打包与力矩语义是?
A. 只发一个 32 位力矩值,其余量由关节固件自行估计
B. p_des/v_des/kp/kd/i_des 各占 8 位,共 40 位
C. 位置直接用浮点双精度发 4 字节,其余用文本编码
D. 8 字节帧打包 p_des(16bit)+ v_des/kp/kd/i_des(各 12bit),力矩语义为 tau = kp·(p_des−p) + kd·(v_des−v) + i_des
💡 解析:「MIT 模式」把 5 个控制量按固定位宽压缩进 8 字节 CAN 帧:位置 16bit,速度/Kp/Kd/前馈电流各 12bit;关节按 tau = kp·(p_des−p)+kd·(v_des−v)+i_des 解释。kp=kd=0 退化为纯前馈力矩模式,i_des=0 则是纯位置伺服(第 7 节)。该约定被 CubeMars AK、达妙、宇树等模组广泛沿用。
4. TI InstaSPIN-FOC 最大的卖点与最大的代价分别是?
A. 卖点是 FAST 观测器固化在特定 TI 芯片 ROM 里、Rs/L/磁链在线自辨识、无感好用;代价是黑盒不可改且强绑定 TI 特定型号
B. 卖点是开源全部观测器源码;代价是文档少
C. 卖点是力控带宽高于 Mini Cheetah;代价是价格贵
D. 卖点是支持任意 MCU 移植;代价是速度慢
💡 解析:据 TI 官方文档(SPRUHI9 等):FAST(Flux/Angle/Speed/Torque)估计器仅以 ROM 形式提供于特定 F2806x(F/M)等器件,配合自动参数辨识实现「上电即用」的无感 FOC;但 ROM 代码不可读改、平台不可移植(第 6 节)。
5. 要自研一批人形机器人关节固件,按本页建议的「三件套抄法」是?
A. 全部从 SimpleFOC 改,电流环频率调高即可
B. 直接把 VESC 固件改个通信协议就能用,不用管许可
C. 中断骨架抄 ODrive(ADC 中断电流环+三层时间尺度)、状态机学 ST MC SDK(主链+故障态)、命令协议学 MIT 模式(五元组打包),观测器与无感后置
D. 六个框架各抄一部分代码混编,越复杂越好
💡 解析:第 11 节给出明确建议:实时骨架(ADC 中断电流环、ISR/线程/通信三层)抄 ODrive;状态机纪律(STOP→IDLE→ALIGNMENT→START→RUN 主链+故障态、指令只发请求)学 MC SDK;接口用「MIT 模式」五元组保证产业兼容。SimpleFOC 的架构撑不起关节级力控,VESC 需注意 GPLv3 合规(第 9、11 节)。
6. 按「如何读源码」一节,读 ODrive 固件找电流环的正确起点组合是?
A. 从 GUI 代码读起,顺着界面按钮找
B. low_level.cpp 的 start_adc_pwm()(采样入口)→ motor.cpp 的 FOC_current()(电流环)→ axis.cpp 的 run_state_machine_loop()(状态机)→ 通信层(路径以仓库当前版本为准)
C. 从 README 读到 CONTRIBUTING 再读 LICENSE
D. 先通读全部源码再做笔记,不允许跳读
💡 解析:通用四步路线是「找 ISR 入口 → 电流环 → 状态机 → 通信层」。对 ODrive v3.x 固件,对应入口即 low_level.cpp(ADC/PWM 采样启动)、motor.cpp 的 FOC_current、axis.cpp 的轴状态机循环(第 10 节;具体文件名随版本可能变化,以仓库为准)。
📌 本节小结: 六大家庭 = SimpleFOC(主循环两段式、教学、MIT)、ODrive(ADC 中断电流环 + 轴状态机/task chain、MIT)、VESC(RTOS 分层 + mcpwm ISR、大功率、GPLv3)、ST MC SDK(HF/MF/后台三尺度任务 + 状态主链 + Motor Profiler、专有免费)、TI InstaSPIN(ROM 固化 FAST、参数自辨识、无感、黑盒绑定 TI)、Mini Cheetah 范式(数十 kHz 电流环 + 「MIT 模式」五元组 CAN 命令、MIT)。它们共同的骨架都是「ISR 电流环 → 状态机 → 通信层」三件套;选型按「目标→性能→功率→量产→无感→自研」六问走决策树;自研则抄 ODrive 的骨架、MC SDK 的纪律、MIT 模式的接口。
🤔 思考题:
1. SimpleFOC 如果要升级成关节级力控,是「调参问题」还是「架构问题」?具体要动哪几层?
2. 你的团队要量产一款服务机器人腰部关节(有编码器、48V、额定 30N·m):在 VESC 方案(GPLv3)与自研(MC SDK 状态机 + MIT 模式接口)之间,你会怎么权衡许可、人力与进度?
3. 「MIT 模式」把 kp/kd 放在命令里由整机实时下发,而不是固化为关节内部参数——这种「可编程刚度」设计对步态控制(如落地缓冲)有什么好处?有什么风险?
13 参考来源与延伸资源
以下链接均经检索核实可达(2026-09 核实;其中知乎站内搜索需在浏览器中打开)。站内配套:三家简介见 04-02 固件与电机控制 ,FOC 完整流程图见 04-19 FOC 算法完全图解 ,观测器深入见 04-17,面试问法见 06-11 保研复试面试题库 。
📘
⭐ SimpleFOC 官方文档(docs.simplefoc.com)
两段式 API、控制模式、支持板卡与 SimpleFOCStudio 全说明;MIT 许可与「Demystify FOC」定位的官方出处。学习入口第一站。
官方文档 ⭐ 必读 入门
🔧
SimpleFOC 源码仓库(simplefoc/Arduino-FOC)
读源码起点:src/common/base_classes/FOCMotor.cpp(loopFOC/move 定义处)、BLDCMotor.cpp(setPhaseVoltage 调制)、communication/Commander.cpp。
GitHub 读源码
📘
ODrive 官方文档(docs.odriverobotics.com)
odrivetool、轴状态(axis states)、校准与控制接口说明(站点为 JS 渲染,请在浏览器打开);经典 v3.x 与新款 Pro/S1/Micro 资料分区。
官方文档 配置必读
🔧
⭐ ODrive 固件与硬件仓库(odriverobotics/ODrive)
v3.x 固件(MIT)阅读地图:axis.cpp 轴状态机、motor.cpp 的 FOC_current、low_level.cpp 的 ADC 启动。README 注明 v3.x 已 NRND,新款固件未开源——引用时请以仓库当前版本为准。
GitHub ⭐ 读源码起点 中级
📘
VESC Project 官网(vesc-project.com)
VESC Tool 下载、硬件文档、社区论坛;官方定位从几十瓦云台到上百千瓦电航的全功率覆盖,滑板/机器人是主力场景。
官方站点 大功率
🔧
VESC 固件仓库(vedderb/bldc · GPLv3)
阅读起点:motor/mcpwm_foc.c 的 ISR 电流环、applications/ 应用任务(app_canbus 等)、comm/ 通信层、ChibiOS RTOS。商用前务必确认 GPL 传染影响。
GitHub 高级
📘
ST X-CUBE-MCSDK 产品页(st.com)
Motor Profiler 与一键整定、FOC 库、无感状态观测器、CubeMX 集成工作流的官方说明;免费下载(需走 ST 申请流程,专有许可以随包协议为准)。
官方站点 产品化
📄
TI InstaSPIN-FOC 软件技术参考手册(SPRUHI9)
F2806xF 上 ROM 固化 FAST 估计器与软件架构的权威参考;配套 InstaSPIN 用户指南(SPRUHJ1)讲 Rs/L/磁链自辨识与无感调试全流程。
TI 官方 无感深入
📄
TI InstaSPIN-MOTION 用户指南(SPRUHJ0)
F2806xM 上的完整无感 FOC 方案(FAST + 电流/速度环在片内 ROM)用户手册,与 SPRUHI9 互为补充。
TI 官方 无感深入
🔧
⭐ MIT Cheetah-Software 仓库(mit-biomimetics · MIT 许可)
Cheetah 3 / Mini Cheetah 的整机控制与仿真开源栈(robot/sim/common);注意关节内电流环固件不在仓库内,但「MIT 模式」接口被产业广泛复刻。
GitHub ⭐ 人形关节参照 高级
📄
CubeMars AK60-6「MIT 模式」配置教程(官方)
以 AK 系列执行器为例演示 MIT 模式 CAN 配置与 C++ 控制——看「学术范式如何变成商业模组出厂功能」的最直接样本。
厂商教程 实操
🎬
B站搜索:ODrive 教程
中文视频最集中的 ODrive 上手渠道:环境搭建、固件烧写、odrivetool 调参与 FOC 讲解(如「灯哥教你入门 ODrive」系列等)。
B站搜索 视频
🎬
B站搜索:VESC 电机
VESC Tool 使用、电机参数检测、滑板/轮足改装的中文实操视频入口,配合第 4 节分层架构理解更顺。
B站搜索 视频
💬
知乎搜索:SimpleFOC ODrive 对比(需浏览器打开)
中文社区对两个开源方案选型的实战讨论集;另一个值得搜的词是「电机控制框架」。注意甄别营销内容,以官方文档交叉验证。
知乎搜索 社区讨论
🗺️
站内配套:MotorOS 核查 / FOC 流程 / 题库
站内链接 配套学习