机器人ONNX学习 ONNX 本质上是一个已经训练好的神经网络模型文件它主要负责机器人控制策略推理ONNX 在这里通常是一个模型文件不是主程序。文件扩展名.onnx内容训练完成的神经网络参数和计算结构性质数据/模型文件本身不能直接运行运行者C 主程序通过 ONNX Runtime 加载并执行它可以这样理解Controller_onnx.cpp / xsens_core.exe 主程序和执行框架 *.onnx 神经网络“大脑” ONNX Runtime 让程序运行这个“大脑”的引擎运行过程一般是主程序启动 → 加载 .onnx 文件 → 整理机器人状态和目标动作 → 输入 ONNX 模型 → 模型计算 → 输出关节目标 → 主程序发送控制命令所以它类似于“游戏程序读取存档/资源文件”ONNX 文件保存训练成果但负责通信、循环控制、动捕接收和机器人命令发送的仍然是.exe主程序。补充区别ONNX一种通用神经网络模型格式全称 Open Neural Network Exchange。.onnx具体模型文件。ONNX Runtime加载和计算模型的运行库。Controller_onnx.cpp调用模型的 C 源代码。.exe编译出来的可执行主程序。整体关系大致是Noitom 动捕 → Axis 的 BVH/TCP 数据 → 人体骨架姿态 → GMR 动作重定向 → G1 关节参考动作 → ONNX 控制策略 → 机器人最终关节指令ONNX 通常会接收G1 当前关节位置、速度IMU 姿态和角速度上一帧控制指令GMR 给出的目标动作或运动命令然后输出各关节的目标位置或动作量后续由控制器换算为电机控制指令所以它不负责接收 Axis/BVH 数据不决定InputFps不负责人体骨架解析主要负责“让 G1 稳定、自然地执行目标动作”。可以把 GMR 理解为“人体动作翻译器”把 ONNX 理解为“机器人学会如何执行这些动作的大脑”。我已经直接解析了工程中现存的3个ONNX并结合实际机器人控制器代码核对。结论是它们都是同一接口、不同权重检查点的G1全身动作跟踪/模仿策略不是GMR重定向网络也不是单纯速度指令行走策略。输入1766维的具体组成完整计算关系1766 21 × 38 38 10 × 93 798 38 930第一部分动作参考窗口798维控制器使用FURTHER_STEP_NUM 10 FURTHER_STEP_SIZE 1从动作FIFO中取过去10帧 当前1帧 未来10帧 21帧每个参考帧38维内容维度参考根部线速度机器人局部坐标系3参考根部角速度机器人局部坐标系3参考重力方向3参考G1关节位置29合计38因此21 × 38 798对应代码result.segment(..., 3) base_lin; result.segment(..., 3) base_ang; result.segment(..., 3) gravity; result.segment(..., 29) jp;第二部分当前参考命令38维21帧参考窗口后又拼接了一份当前参考状态内容维度当前参考根部线速度3当前参考根部角速度3当前参考重力方向3当前参考关节位置jp29合计38对应代码command_actor future_posvel, base_lin, base_ang, motion_gravity, jp;所以命令部分为798 38 836维第三部分机器人历史观测930维历史长度HISTORY_LEN 10; SINGLE_OBS_DIM 93;每帧机器人观测内容维度机器人IMU重力方向3机器人IMU角速度3机器人29关节位置相对默认姿态29机器人29关节速度29上一次网络动作29合计93历史部分10 × 93 930维最终动作参考命令 836 机器人历史状态 930 17664. 是否包含历史帧包含而且有两种不同意义的时间序列。机器人本体历史10帧输入中包含连续10个控制周期的机器人状态gravity ang_vel qpos qvel last_action控制周期20ms因此历史覆盖约10 × 20ms 200ms更准确地说更新后队列通常包含当前机器人观测 之前9帧程序刚启动时历史队列会使用全零初始化所以最开始几个周期并不是全部真实历史。动作参考窗口21帧还包含过去10帧 当前帧 未来10帧在50Hz下对应过去约200ms 当前 未来约200ms因此这个策略并非只根据当前动捕帧反应它利用未来动作参考进行前馈控制。缓冲区长度说明真正构建ONNX输入时需要21帧buff_len_ 1 2 * 1 * 10 21gRPC模式进入跟踪状态前代码另外要求0.5 / 0.02 1 26帧所以进入跟踪前的门槛约26帧每次网络输入实际使用前21帧每个控制周期从FIFO弹出1帧窗口随后向前滑动1帧。这正是你之前提到“约26帧buffer、一帧一帧向前推”的来源。5. 控制频率配置和控制循环都是control_dt: 0.02const std::chrono::milliseconds cycle_time(20);所以ONNX推理与目标关节更新频率是1 / 0.02 50Hz需要区分两个频率环节频率读取动作窗口、构造1766维输入50HzONNX推理50Hz产生新的29维目标关节位置50Hzlow_cmd_writeDDS重复下发线程500HzDDS发送线程创建参数是CreateRecurrentThreadEx(..., 2000, ...)周期2000微秒即500Hz。但它不是500Hz运行ONNX而是将最近一次50Hz生成的控制指令重复发送给机器人。6. 输出29维的含义模型输出output float32[1,29]读取方式act onnxPtr-outVec[0];它不是直接输出力矩也不是直接输出电机绝对位置。最终目标位置为target_pos[i] act[i] * action_scales[i] jp[i];其中act[i]网络输出action_scales[i]每个关节的动作缩放jp[i]GMR/动捕传入的当前参考关节位置。所以网络输出本质上是相对于参考动作jp的29维关节修正量最终下发q target_pos[i]; kp kps[i]; kd kds[i]; dq 0; tau 0;因此这是关节位置目标策略使用PD控制执行。7. 输出对应的G1关节当前控制器直接使用motor_cmd()[i]没有在在线控制器里使用额外的idx_out重排。因此29维输出顺序就是G1 29自由度控制顺序输出索引G1关节0left_hip_pitch_joint1left_hip_roll_joint2left_hip_yaw_joint3left_knee_joint4left_ankle_pitch_joint5left_ankle_roll_joint6right_hip_pitch_joint7right_hip_roll_joint8right_hip_yaw_joint9right_knee_joint10right_ankle_pitch_joint11right_ankle_roll_joint12waist_yaw_joint13waist_roll_joint14waist_pitch_joint15left_shoulder_pitch_joint16left_shoulder_roll_joint17left_shoulder_yaw_joint18left_elbow_joint19left_wrist_roll_joint20left_wrist_pitch_joint21left_wrist_yaw_joint22right_shoulder_pitch_joint23right_shoulder_roll_joint24right_shoulder_yaw_joint25right_elbow_joint26right_wrist_roll_joint27right_wrist_pitch_joint28right_wrist_yaw_joint8. 它到底是什么网络结论这是G1全身动作模仿/动作跟踪控制策略更准确地说是“带未来参考窗口和本体历史观测的全身动作跟踪策略”。它不是重定向网络人体到G1动作的重定向发生在ONNX之前人体Mocap → GMR/IK → G1参考关节位置和速度 → ONNX控制策略ONNX输入已经包含29维G1关节参考jp所以网络不负责人体骨架 → G1关节这个工作由GMR完成。它不是单纯行走策略普通行走策略通常输入期望vx、vy、yaw速度 机器人本体状态而这里输入的是21帧完整全身参考动作 当前全身参考动作 10帧机器人历史状态并且包括双腿腰部双臂双手腕根部运动完整29关节参考。所以它能跟踪行走动作但用途不限于行走。模型文件名中的boxing、cmd_combine也进一步支持其全身动作跟踪用途。它的实际功能GMR给出理想参考姿态jp ↓ ONNX观察参考动作窗口 机器人真实IMU/关节状态历史 ↓ 预测29维动作修正量act ↓ act × scale jp ↓ 形成更适合真实机器人保持平衡并跟踪动作的目标关节位置因此它的角色是全身模仿策略 稳定控制策略 参考动作跟踪策略而不是单纯的数据格式转换网络。