-
前言
MIT Cheetah 是 MIT 仿生机器人实验室在金相培(Sangbae Kim)教授主持下发展的电动四足机器人系列(Cheetah 1/2/3 与 Mini Cheetah)。它用可反驱、高转矩密度的本体感受执行器取代液压,使机器人在高速奔跑、越障跳跃乃至后空翻的同时,把运输成本做到与动物相当,并证明动态步态可用机载凸模型预测控制实时求解。2019 年开源的 Cheetah-Software 把仿真与真机控制打成同一套可复现框架,Mini Cheetah 则把大型样机“不敢试、坏一次修一个月”变成可日复一日迭代的研究平台。该项目改写了“高性能腿足必须用液压”的默认路径,成为后来准直驱四足、高校课程与 Unitree 等开源生态的重要基线,并向 Boston Dynamics、人形公司及多所高校输送了核心人才,是当代腿足机器人从实验室样机走向可复制研究基础设施的标志性工作。
Cheetah-Software 是 MIT Biomimetics 实验室为 Mini Cheetah 与 Cheetah 3 写的机器人控制与仿真软件。它把「高层运动控制」和「底层硬件/仿真」拆开:同一套 RobotController 既能挂到 Qt 仿真器,也能挂到真实机载电脑。本文将用Kruchten 4+1 架构视图模型来分析Cheetah-Software架构。
-
Kruchten 4+1 架构视图模型简介
Kruchten 4+1 视图模型(Philippe Kruchten,1995,IEEE Software)用来解决一件事:软件架构很难用一张图说清,因为用户、开发者、系统工程师、项目经理关心的不是同一件事。于是用四个并列视图分别写架构,再用一组场景把它们串起来、验证起来,所以叫 4+1。
Kruchten 4+1 架构视图模型包括四个视图,即逻辑视图、进程视图、开发视图 、物理视图;
“+1”:场景 / 用例视图。
选少量关键用例(场景),画出对象之间、进程之间的交互。它用来发现架构元素、说明四个视图如何协同、校验设计是否站得住。因为内容和另外四个有重叠,所以不是第五根并列的柱子,而是粘合剂,所以写作 +1。
(1)逻辑视图(Logical View):描述系统静态结构,解决功能如何分解。聚焦软件内部的功能模块、领域对象、职责划分,是架构最核心的业务蓝图。面向对象时就是类/对象及其关系。
(2)进程视图(Process View):运行时谁在跑、如何并发与通信。关注性能、可用性、伸缩,对应非功能需求。
(3)开发视图(Development View):代码、模块、包、库在开发环境里怎么组织,面向程序员和配置管理。
(4)物理视图 (Physical View):软件如何落到机器和网络上,面向系统工程师,关心分布、拓扑、容错。
下文将以这四个视图为视角,对Cheetah-Software展开介绍。
1. 逻辑视图
逻辑视图描述功能分解:谁负责感知、谁负责决策、谁负责执行。本项目的核心抽象是「同一套控制代码,对仿真和真机长得一样」。
1.1 分层功能结构
1.1.1 应用控制层(user)
- 用户写一个继承 RobotController 的类,实现 initializeController()、runController()。
- 主控制器是 MIT_Controller;另外还有 JPos_Controller、Example_Leg_InvDyn、MiniCheetahSpi_Controller 这类示例。
- MIT_Controller 内部用 ControlFSM 调度行为,而不是把所有算法堆在一个 run() 里。
1.1.2 运行框架层(robot)
- RobotRunner 以固定周期调用估计器、腿部接口、用户控制器。
- SimulationBridge / HardwareBridge 把「仿真共享内存」或「真机总线」适配成同一套指针:IMU、腿数据、手柄、可视化。
- main_helper() 根据命令行 m|3(机型)和 s|r(仿真/真机)选择桥接。
1.1.3 公共算法层(common,库名 biomimetics)
- 动力学:Quadruped、FloatingBaseModel、DynamicsSimulator。
- 腿控制:LegController 屏蔽 Mini Cheetah 的 SPI Spine 与 Cheetah 3 的 TI Board。
- 状态估计:StateEstimatorContainer 可插拔多个 GenericEstimator。
- 步态与足端轨迹:GaitScheduler、FootSwingTrajectory。
1.1.4 仿真表现层(sim)
- Simulation 做刚体积分、碰撞、低层板卡仿真。
- Graphics3D + SimControlPanel 提供 Qt 界面、手柄、参数面板。
1.1.5 逻辑视图:功能分层图

1.2 控制闭环中的关键对象
一次控制周期(RobotRunner::run())的逻辑顺序如下。
1.2.1 状态估计
1)StateEstimatorContainer::run() 依次跑已注册的估计器。
2)真机/正常仿真:VectorNavOrientationEstimator(姿态来自 IMU 四元数)+ LinearKFPositionVelocityEstimator(18 维卡尔曼滤波,估计位置/速度)。
3)cheater_mode 打开时:改用 CheaterOrientationEstimator 与 CheaterPositionVelocityEstimator,直接读仿真真值。
4)ContactEstimator 始终参与,提供足端接触相位。
1.2.2 传感同步(setupStep)
1)Mini Cheetah:LegController::updateData(SpiData*)。
2)Cheetah 3:LegController::updateData(TiBoardData*)。
3)得到每条腿的 q, qd, p, v, J(关节角/角速度、髋坐标系足端位置/速度、雅可比)。
1.2.3 用户控制
1)前若干周期先禁腿、再由 JPosInitializer 把关节收到初始姿态。
2)之后调用 _robot_ctrl->runController()。对 MIT 控制器即:步态调度 → 期望状态转换 → ControlFSM::runFSM()。
1.2.4 指令下发(finalizeStep)
1)LegController::updateCommand() 把关节 PD、笛卡尔 PD、力矩前馈、力前馈叠加后写入 SpiCommand 或 TiBoardCommand。
2)同时用 LCM 发布 leg_control_data、leg_control_command、state_estimator。
1.2.5 逻辑视图:单周期控制数据流图

1.3 MIT 控制器有限状态机
control_mode(仿真面板或 RC)决定当前行为。状态定义见 FSM_State.h。
| 0 | PASSIVE | 不出力,安全默认态 |
| 1 | STAND_UP | 关节插值站起 |
| 3 | BALANCE_STAND | 平衡站立(QP 平衡控制器) |
| 4 | LOCOMOTION | 凸优化 MPC 步态行走 |
| 6 | RECOVERY_STAND | 跌倒后恢复站立 |
| 8 | VISION | 视觉 MPC(高度图/障碍) |
| 9 | BACKFLIP | 后空翻开环/数据回放 |
| 11 | FRONTJUMP | 前跳 |
| 51 | JOINT_PD | 关节空间 PD 调试 |
| 52 | IMPEDANCE_CONTROL | 笛卡尔阻抗调试 |
1.3.1 状态对象共性
- 每个状态实现 onEnter / run / checkTransition / transition / onExit。
- 共享 ControlFSMData:四足模型、估计器、腿控制器、步态、期望状态、机器人参数、用户参数。
- SafetyChecker 在 FSM 前后做姿态安全、足端期望位置、前馈力限幅。
1.3.2 行走状态的两级优化
- ConvexMPCLocomotion:用 qpOASES / OSQP / JCQP 解凸 MPC,得到未来地反力和落足。
- WBC_Ctrl + WBIC:在动力学约束下把任务(机身位姿、足端)映射成关节力矩;任务集包括 BodyPosTask、BodyOriTask、LinkPosTask、JPosTask 等。
- GaitScheduler 提供 STAND / TROT / BOUND / GALLOP / PRONK 等相位表。
1.3.3 逻辑视图:ControlFSM 状态机

1.4 动力学与仿真对象
1.4.1 机器人模型
- MiniCheetah.h / Cheetah3.h 填几何、惯量、减速比,生成 Quadruped。
- FloatingBaseModel 是 Featherstone 浮动基刚体树,每个关节还带转子(gear constraint)。
- FBModelState 存机身位姿/速度与关节 q, qd。
1.4.2 仿真器
- DynamicsSimulator 用 ABA(Articulated Body Algorithm)求加速度,再积分。
- 碰撞:CollisionPlane / CollisionBox / CollisionMesh,接触可用冲量或弹簧阻尼(use_spring_damper)。
- ImuSimulator 按 yaml 噪声参数伪造 VectorNav 数据。
- SpineBoard / TI_BoardControl 在仿真里复现真机底层板卡,使控制器面对的接口与真机一致。
1.4.3 腿部控制语义(髋坐标系)
- 机体系:x 向前、y 向左、z 向上。
- 腿序号:右前 0、左前 1、右后 2、左后 3。
- (q_abad, q_hip, q_knee) = (0,0,0) 表示腿竖直向下。
- 关节 PD 在电机驱动器上以约 40 kHz 执行;高层 runController 约 1 kHz(Cheetah 3 为 1 ms,Mini Cheetah 默认 2 ms)。
1.5 逻辑视图小结
逻辑上这是一条经典的「估计 → 规划 → 全身控制 → 腿级 PD」管道,外加 FSM 把站立、行走、特技、急停切开。RobotController 是唯一对用户开放的扩展点,仿真与真机在这一层不可区分。
2. 进程视图
进程视图描述运行时并发:几个进程、哪些线程、周期多少、如何同步。本项目有两条主部署路径:开发仿真、真机。
2.1 仿真模式:双进程 + 共享内存握手
启动方式:先 ./sim/sim,再 ./user/MIT_Controller/mit_ctrl m s(m = Mini Cheetah,s = simulation)。
2.1.1 进程 A:sim(仿真器)
- Qt 主线程:SimControlPanel、手柄(Qt Gamepad)、OpenGL 可视化。
- 仿真循环 Simulation::runAtSpeed():按 dynamics_dt 积分,按 low_level_dt 跑板卡仿真,按 high_level_dt 唤醒控制器。
- 通过 POSIX 共享内存对象 development-simulator 与控制器交换 SimulatorSyncronizedMessage。
- 可选向 LCM 频道 simulator_state 发状态,供 lcm-spy 调试。
2.1.2 进程 B:控制器(如 mit_ctrl)
- SimulationBridge::run() 死循环:waitForSimulator() → 按 SimulatorMode 办事 → robotIsDone()。
- 模式包括:RUN_CONTROL_PARAMETERS(改参数)、RUN_CONTROLLER(跑 RobotRunner)、DO_NOTHING、EXIT。
- 第一次 RUN_CONTROLLER 时完成 RobotRunner::init(),之后每个高层步调用一次控制。
2.1.3 同步语义(避免双边同时写共享内存)
- 两个 POSIX 信号量:simToRobotSemaphore、robotToSimSemaphore。
- 约定顺序:机器人等待仿真 → 仿真积分并写 IMU/腿数据 → simulatorIsDone() → 仿真等待机器人 → 机器人读数据跑控制并写指令/可视化 → robotIsDone()。
- 调试日志不走共享内存,走 LCM,避免拖慢控制节拍。
2.1.4 进程视图:仿真双进程握手

2.1.5 仿真默认时间步(config/simulator-defaults.yaml):
| dynamics_dt | 0.001 s | 刚体积分步长(1 kHz) |
| low_level_dt | 0.0002 s | 仿真 Spine/TI 板卡(5 kHz) |
| high_level_dt | 0.002 s | 唤醒高层控制器(500 Hz,与 Mini Cheetah controller_dt 对齐) |
| simulation_speed | 1.0 | 墙钟倍率;按住 t 可尽量快放 |
2.2 真机模式:单进程多周期任务
真机上 main_helper 走 MiniCheetahHardwareBridge::run() 或 Cheetah3HardwareBridge::run()。框架是 PeriodicTask:每个任务独立 std::thread,由 PeriodicTaskManager 统计超时。
启动前会做实时准备:
Mini Cheetah 线程表
| robot-control | controller_dt(默认 2 ms) | PeriodicTask | RobotRunner:估计 + 用户控制 |
| spi | 2 ms | PeriodicMemberFunction | runSpi():拷命令、驱动 SPI、发 spi_data / spi_command |
| lcm-vis | 16.7 ms(约 60 Hz) | PeriodicMemberFunction | 发布 main_cheetah_visualization |
| rc_controller | 5 ms | PeriodicMemberFunction | SBUS 遥控 |
| microstrain-logger | 1 ms | PeriodicMemberFunction | 发布 microstrain LCM |
| (无名)IMU | 连续循环 | std::thread | LordImu::run() 填 _vectorNavData |
| interface LCM | 阻塞 handle() | std::thread | 订阅 interface(手柄)、interface_request(参数) |
| print-tasks | 0.5 s | PrintTaskStatus | 任务超时监控 |
Cheetah 3 线程表
| robot-control | 1 ms | 高层控制 |
| ecat | 1 ms | SOEM EtherCAT:rt_ethercat_run(),发布 ecat_cmd / ecat_data |
| lcm-vis | 16.7 ms | 可视化 |
| VectorNav 驱动 | 传感器侧约 1 kHz | rt_vectornav 写 IMU |
| interface LCM | 同 Mini Cheetah | 手柄与参数 |
进程视图:Mini Cheetah 机载进程内线程

2.3 进程间消息一览
| 共享内存 SimulatorSyncronizedMessage | sim ↔ 控制器 | IMU、腿、手柄、参数、可视化(仅仿真) |
| LCM interface | 开发机 → 机器人 | gamepad_lcmt |
| LCM interface_request / interface_response | 双向 | 按名读写控制参数 |
| LCM spi_data / spi_command | 机器人 → 调试端 | Mini Cheetah 原始 SPI |
| LCM ecat_cmd / ecat_data | 机器人 → 调试端 | Cheetah 3 EtherCAT |
| LCM microstrain / vectornav | 机器人 → 调试端 | IMU |
| LCM state_estimator_lcmt | 控制器 → 调试端 | 位姿速度估计 |
| LCM leg_control_* | 控制器 → 调试端 | 腿指令与反馈 |
| LCM main_cheetah_visualization | 机器人 → sim GUI | 12 关节 + 机身位姿 |
| LCM simulator_state | sim → 调试端 | 仿真真值状态 |
2.4 进程视图小结
仿真用「双进程 + 信号量互斥共享内存」复现真机的「控制节拍与物理节拍分离」。真机把同一 RobotRunner 放进实时 FIFO 线程,用更短周期的 SPI/EtherCAT 任务喂数据。LCM 一律旁路,专管人机界面和日志,不进入力矩闭环临界路径。
3. 开发视图
开发视图描述源码模块、库依赖、构建产物。顶层 CMakeLists.txt 按子目录组织,C++14,默认 -O3 -Werror(Linux)。
3.1 顶层目录职责
| common/ | 共享库 biomimetics | 动力学、估计、腿接口、碰撞、共享内存、参数 |
| robot/ | 共享库 robot | RobotRunner、Bridge、rt_* 驱动 |
| sim/ | 可执行文件 sim | 唯一依赖 Qt5 的程序 |
| user/ | mit_ctrl、jpos_ctrl 等 | 具体控制器,链接 robot + biomimetics |
| third-party/ | 静态/内部库 | OSQP、qpOASES、SOEM、lord_imu、vectornav 等 |
| lcm-types/ | lcm-gen 出的 hpp/java/py | 进程间契约 |
| config/ | yaml | 仿真、地形、机器人、用户参数默认值 |
| scripts/ | shell | 生成类型、部署到 Mini Cheetah、配 LCM 网卡 |
| resources/ | obj 网格 | 可视化 CAD |
| documentation/ | md / doxygen | 入门与真机流程 |
| common/test/ | test-common | gtest(CMake 自动拉 googletest) |

3.2 common 内部包结构
按头文件目录,逻辑包如下。
1)spatial.h、SpatialInertia:空间向量。
2)FloatingBaseModel:运动学/动力学树
3)MiniCheetah / Cheetah3:机型参数工厂。
4)ActuatorModel:电机/减速器。
5)DynamicsSimulator:积分 + 接触。
1)LegController、StateEstimatorContainer。
2)OrientationEstimator、PositionVelocityEstimator、ContactEstimator。
3)DesiredStateCommand、GaitScheduler、FootSwingTrajectory。
CollisionPlane/Box/Mesh、ContactImpulse、ContactSpringDamper。
反射式参数表:代码里 DECLARE_PARAMETER,yaml 必须字段完全一致,增删参数要重编译。
仿真专用但控制器也要链接的结构:SimulatorMessage、SpineBoard、ti_boardcontrol、GamepadCommand、ImuSimulator。
PeriodicTask、SharedMemory、Timer、滤波器、Bezier 等。
稀疏 MPC、落足规划、姿态工具。
3.3 user/MIT_Controller 源码树
user/MIT_Controller/ ← 树根
├── main.cpp ← 入口
├── MIT_Controller.cpp/.hpp
├── FSM_States/ ← 行为状态机
│ ├── ControlFSM
│ ├── FSM_State_*
│ ├── SafetyChecker
│ └── ControlFSMData
└── Controllers/
├── convexMPC/ ← 行走 MPC
├── WBC/ 与 WBC_Ctrl/ ← 全身控制
├── VisionMPC/ ← 视觉 MPC
├── BalanceController/ ← 站立平衡
└── BackFlip/ ← 后空翻等特技
3.4 构建与配置要点
1)scripts/make_types.sh:lcm-gen -jxp *.lcm,生成 C++/Java/Python 类型。
2)cmake … && make -j4。
3)产物:common/libbiomimetics.so、robot/librobot.so、sim/sim、user/…/mit_ctrl。
1)cmake -DMINI_CHEETAH_BUILD=TRUE:关掉 -march=native,THIS_COM 改成相对路径 …/,以便拷到机载目录后仍能读 config/。
2)NO_SIM=ON 可在机载上不编 Qt 仿真器。
Qt 5.10+(含 Gamepad)、LCM 1.3.1、Eigen、BLAS/LAPACK、freeglut、mesa;可选 Ipopt(-DIPOPT_OPTION=ON)。
1)在 user/ 新建目录并加入 user/CMakeLists.txt。
2)继承 RobotController,getUserControlParameters() 返回参数对象或 nullptr。
3)main 必须调用 main_helper(argc, argv, &controller)。
4)不改 robot/ 与 common/ 即可在仿真和真机上跑。

3.5 开发视图小结
仓库按「共享算法库 / 运行时与驱动 / 仿真 GUI / 可插拔用户控制器 / 第三方求解器」切开。控制器的稳定接口是 RobotController + LegController + StateEstimate;LCM 类型是跨语言调试契约;yaml 与 C++ 参数表必须同步,这是本项目刻意的编译期一致性检查。
4. 物理视图
物理视图描述软件部署到哪些计算机、传感器、执行器和网络。有三种物理拓扑。
4.1 拓扑 A:纯仿真(单台开发机)
一台 Linux PC(也支持 macOS 编仿真)、Logitech F310(拨到 X 模式)。
同一台机器上:sim + mit_ctrl m s(或 3 s)。共享内存要求同机。
左栏:仿真器参数(速度、地形摩擦等)。
中栏:机器人参数(controller_dt、cheater_mode)。
右栏:MIT 用户参数。
画面里灰色机体 = 仿真真值,红色 = 状态估计。


物理视图:开发机纯仿真部署图

4.2 拓扑 B:Mini Cheetah 真机
4.2.1 机器人本体
- 俯视前方两开关:中间 = 电机电源,右侧 = 电脑电源,拨向机尾为开。
- 电脑约 2 分钟启动。
- 12 个关节电机,经 4 块 Spine 板做腿级控制;关节 PD 在驱动器上约 40 kHz。
- IMU:代码默认 USE_MICROSTRAIN,Lord Microstrain;也可编 VectorNav。
- 可选 SBUS 遥控。
4.2.2 机载计算机
- 默认 SSH:user@10.0.0.34。多机时脚本支持 10.0.0.4x。
- 开发机网卡需配 10.0.0.xxx。
- 运行 cmake -DMINI_CHEETAH_BUILD=TRUE 编出的控制器,由 scripts/send_to_mini_cheetah.sh 把可执行文件、.so、config/、run_mc.sh 拷到 ~/robot-software。
- 机上 ./configure_network_lcm.sh mc-top 配顶部以太网的 LCM 组播。
- sudo nohup 跑 run_mc.sh;程序会等到开发机 sim 以 Robot 模式点 Start,参数经 LCM 下完再进控制。
4.2.3 开发机角色
- 仍跑 sim,模式选 Mini Cheetah + Robot(RobotInterface)。
- 手柄、参数面板、估计可视化都走 LCM,不走共享内存。
- 以太网既是 SSH 部署通道,也是 LCM 调试总线。
4.2.4 控制链路时延分层
- 电机驱动器:40 kHz 电流/关节 PD。
- SPI 任务:2 ms,约 500 Hz,与高层 controller_dt=0.002 对齐(文档亦写腿数据约 700 Hz 量级)。
- 高层 MPC/WBC:同一 2 ms 线程内。
- GUI/可视化:60 Hz,允许丢帧。
物理视图:Mini Cheetah 真机部署图

4.3 拓扑 C:Cheetah 3 真机
- 不用 SPI Spine,而用 EtherCAT(第三方库 SOEM)。
- 每腿一块 TI 控制板 TiBoardCommand/Data,支持关节与笛卡尔指令、max_torque。
- ecat 任务 1 ms,与 controller_dt=0.001(config/cheetah-3-defaults.yaml)对齐。
rt_vectornav.cpp 初始化 VectorNav;失败时打印 IMU DISABLED,不直接 exit。
开发机仍用 LCM 下发手柄和参数;Cheetah3HardwareBridge 同样 mlockall + FIFO。SBUS 在 Cheetah 3 路径里目前注释掉。
物理视图:Cheetah 3 真机部署图

4. 两款机器人物理栈对比
| 高层周期 | 2 ms | 1 ms |
| 腿总线 | SPI → Spine Board | EtherCAT → TI Board |
| 总线任务周期 | 2 ms | 1 ms |
| IMU | Microstrain(默认)或 VectorNav | VectorNav |
| 机载构建 | 必须 MINI_CHEETAH_BUILD | 普通 Linux 构建即可 |
| 典型 IP | 10.0.0.34 | 文档未写死,同样走 LCM 局域网 |
| 关节 PD | 电机侧 ~40 kHz | TI 板底层环 |
4.4 物理视图小结
软件故意做成「开发机算仿真、机载只跑控制」。仿真同机用共享内存追求确定性握手;真机用千兆以太网跑 LCM,用机器人内部 SPI/EtherCAT 跑力矩闭环。Qt 仿真器跨两种物理拓扑复用:既是动力学沙盒,也是真机遥控台。
网硕互联帮助中心




评论前必须登录!
注册