ExoCode.ino - OpenExo
ExoCode.ino
- 1. 总体结构和平台区分
- 2. Teensy 主控部分(主功能)
- 2.1 文件顶部说明
- 2.2 头文件和配置
- 2.3 配置数据缓存
- 2.4 setup() 初始化流程
- 2.5 loop() 主循环流程
- 2.5.1 首次运行:系统和各关节的“冷启动”
- 2.5.2 HEADLESS模式校准和自动切换控制器
- 2.5.3 实时主运算
- 2.5.4 主循环周期性调试输出
- 3. Nano 辅控部分
- 4. 未知平台兜底
- 5. 总结
1. 总体结构和平台区分
代码首先用宏判断当前运行的平台(主控Teensy or 辅控Nano BLE),并根据不同的主控硬件,执行不同初始化和主循环。
-
Teensy 3.6/4.1(主控,负责所有运动学、控制等核心运算)
-
Nano BLE/RP2040(辅控,主要负责通讯、辅助采样、LED等)
2. Teensy 主控部分(主功能)
2.1 文件顶部说明
// Code used to run the exo from the teensy. This communicates with the nano over UART.
// P. Stegall Jan 2022`
说明本文件用于 Teesny 主控,通过 UART 与 Nano 进行通信。
2.2 头文件和配置
// 1. 包含所有核心库和模块,包括外设、数据结构、参数管理、通信、日志等
#include "src/Board.h"
#include "src/ExoData.h"
#include "src/Exo.h"
#include "src/Utilities.h"
#include "src/StatusDefs.h"
#include "src/ParseIni.h"
#include "src/ParamsFromSD.h"
#include "src/UARTHandler.h"
#include "src/uart_commands.h"
#include "src/UART_msg_t.h"
#include "src/Logger.h" #include "src/PiLogger.h"`
2.3 配置数据缓存
namespace config_info
{ uint8_t (config_to_send)[ini_config::number_of_keys];
}
- 缓存所有从SD卡或主控读取到的配置参数。
- 定义了一个叫
config_info
的命名空间,可以理解为“配置数据的容器”。 - 定义了一个无符号8位整型数组,名叫
config_to_send
。 ini_config::number_of_keys
是这个数组的长度,意味着有多少配置项就有多大
2.4 setup() 初始化流程
void setup()
{ analogReadResolution(12); Serial.begin(115200); delay(100); // 读取SD卡的配置数据,写入config_info::config_to_send ini_parser(config_info::config_to_send); // 可选: 打印所有读取到的配置,便于调试 // 可选: 打印信号标签(如用于Serial Plot) }`
作用:
-
初始化模拟精度、串口通讯;
-
读取SD卡参数(如舵机、传感器、控制参数等),保存在 config_info;
-
打印调试信息/信号名标签。
2.5 loop() 主循环流程
主循环分为“首次运行”和“正常循环”两个阶段。
2.5.1 首次运行:系统和各关节的“冷启动”
-
静态创建并初始化核心对象:
-
static ExoData exo_data(...)
-
static Exo exo(&exo_data)
-
static UARTHandler* uart_handler = UARTHandler::get_instance();
-
-
首次启动配置:
-
等待配置同步完成(
wait_for_get_config()
)。 -
根据每个关节(hip/knee/ankle/elbow)是否被使用(is_used),依次做:
-
启动电机,设初始参数为0
-
如果是“无头模式”(不依赖上位机),则调用默认控制器参数
-
等待标定完成并设置控制器
-
控制器初始设置为“zero_torque”
-
-
设置电机启动状态
-
电机上电延迟/LED状态提示
-
-
首次运行完成后,各关节进入“可控状态”,并做基础校准(如力传感器校准)等操作。
2.5.2 HEADLESS模式校准和自动切换控制器
如果为 HEADLESS(无App/上位机),则:
-
先依次自动校准所有已用关节的力传感器
-
动态校准阶段,自动完成 FSR 等校准,并在全部校准完成后将控制器切到 config.ini 设定的默认控制器(而非zero_torque)
2.5.3 实时主运算
bool ran = exo.run();
调用 Exo 类的 run()
方法,实际驱动所有数据采集、状态判断、控制器运算、电机控制等一切核心运算。
2.5.4 主循环周期性调试输出
每隔一定时间向串口输出点,提示主循环未死锁。
3. Nano 辅控部分
若在 Nano BLE 或 RP2040 运行,则进入此分支。
主要完成:
-
UART 配置同步
-
LED 状态提示
-
实时I2C采集、蓝牙、GUI、错误处理
4. 未知平台兜底
如果不是以上指定平台,串口提示“Unknown Microcontroller”,代码进入死循环报错。
5. 总结
-
入口文件ExoCode.ino 只负责顶层调度和初始化,所有“核心功能”都被封装到 ExoData/Exo/UARTHandler 等类中。
-
首次运行时会做全面的参数配置与安全检查(如控制器置零、校准)。
-
正式运行时主循环极为简洁,仅仅不断调用 exo.run(),所有底层细节都已被面向对象封装到 src 文件夹各模块。