新闻详情

新闻详情

首页 / 资讯中心 / 详情

RK3566四足机器人强化学习部署:从训练到实机行走

发布时间:2026/9/7 1:35:32来源:尧图网络
RK3566四足机器人强化学习部署:从训练到实机行走
这篇内容打算聊一次完整的部署经历从在英伟达 GPU 工作站上训练强化学习步态策略到把策略搬进一台 25 厘米高的 Microduck 四足机器人用一块 RK3566 驱动整机站起来、走出去。整件事最花时间的不是训练也不是调参而是“部署”这两个字背后的工程细节。1. 为什么选 RK356625 厘米小机器人的算力与功耗账1.1 先说说 Microduck 整机的情况Microduck 是一台 25 厘米左右高度的四足机器人和常见的 Mini Cheetah 那种研究平台相比它工艺上更像消费级工程样机12 个关节每条腿 3 个自由度机体内部预留给主控板的空间不大。唤醒赛道的无人机和机器狗都在往紧凑方向走25 厘米级机体要在有限空间里塞进电池、电机驱动板、IMU 和主控制板所以主控选型相当关键。在做部署之前得先想明白一个问题这台机器人要承担多少计算强化学习推理的量级其实没有大家想象中大策略网络往往是多层 MLP输入维度在几十到一百上下输出 12 个关节动作参数量几千到几十万级别。真正消耗算力的是高频控制回路电机力矩指令的生成频率最低也要 200Hz 以上控制器要在几毫秒内完成“传感器读取、状态估计、策略推理、力矩输出”一整条链路这个才考验主控的实时性。1.2 RK3566 和树莓派 / Jetson Nano 的取舍我之前在别的项目上用过树莓派 4B 和 Jetson Nano拿来推过强化学习模型。树莓派的 CPU 是四核 Cortex-A72单核性能尚可但 GPIO、I2C、SPI 和 CAN 的调度不够硬实时在线控制循环里很容易出现周期抖动。Jetson Nano 的 GPU 算力强跑 CUDA 肯定没有压力但它功耗高、启动慢、体积大塞进 25 厘米的小机身有点杀鸡用牛刀而且整个部署链路的镜像尺寸也不太友好。RK3566 是瑞芯微推出的一颗四核 Cortex-A55 SoC集成 Mali-G52 GPU 和 0.8 TOPS 级别的 NPU整体功耗可以压在 3W 到 6W 的范围内。A55 的性能跑 MLP 推理完全够用NPU 虽然算力不高但用来推这类小网络反而有优势。再加上 RK3566 原生支持 CAN、SPI、UART、I2C电机控制板走 CAN 总线还是 SPI都留了余地。存储可以用 eMMC 加 TF 卡系统启动到完全运行状态大概 10 秒内开机即用非常适合这种嵌入型机器人。1.3 算力需求和功耗预算怎么算我按实际需要做了个粗略预算。控制主频跑在 1.8GHz 时RK3566 CPU 的持续算力大约是 10000 Dhrystone MIPS 的几分之一这个数字看起来不亮眼但策略网络单次推理也就几百万次浮点运算。按 400Hz 控制频率每秒需要 1.6 亿次浮点运算量A55 是可以轻松承受的。真正不能忽略的是 DDR 带宽和缓存命中率推理时如果频繁做动态内存分配带宽会拖后腿。功耗方面整机电池如果是 2S 锂电池容量大约 1200mAh主控板加电机驱动板的总电流预算大概在 1.5A 到 2A 之间。RK3566 与电机驱动、IMU 加在一起能够控制在 5W 附近剩余的功耗全部要留给关节电机。综合来看RK3566 在 25 厘米这个尺寸等级的机器人上是一个比较合理的“甜点”选择。2. 训练侧准备别等训练完了才考虑部署2.1 策略网络结构与输入输出很多人在训练阶段完全不考虑部署训练完了做导出才发现模型里塞满了自定义算子或者输出层带了额外处理逻辑跑到嵌入式设备上不是性能差就是直接不支持。我这次的策略网络结构比较常规动作空间和观测空间设计如下表模块维度说明观测输入大约 70 维关节角度、关节角速度、IMU 四元数、角速度、上一时刻动作隐藏层[256, 256]MLP激活函数用 ReLU导出友好动作输出12 维每条腿 3 个关节位置增量或目标位置控制频率250Hz 到 400Hz训练时固定为 250Hz实机根据电机驱动能力调整训练用的框架是 Isaac Gym 这类 GPU 并行环境单张 RTX 4090 跑了大概三个小时大概 12000 个仿真环境并行采样拿到了一个能稳定走路的策略。训练阶段零零散散也会用 MuJoCo 导出验证但最终真机部署用的还是 Isaac Gym 产出的 ONNX。有一点必须强调策略网络的输出一定要保持“纯网络输出”不要在后处理里加滤波或者限幅。这些逻辑放到嵌入式端代码里做一旦写进网络导出后处理算子会非常痛苦一些轻量推理引擎根本不支持。所以我训练时网络输出就是 12 个动作的原始值所有动作缩放、限幅、平滑全放到部署侧代码实现。2.2 域随机化其实是给部署减负单独说说域随机化。很多做强化学习的朋友在训练时喜欢把摩擦、质量、电机力矩上限这些参数全部固定仿真里跑得很好一上真机就摔。Microduck 这类小尺寸机器人在实机上受电池电压波动、地面摩擦差异、IMU 噪声的影响比大型平台更大所以训练时必须做域随机化。我在 Isaac Gym 里随机化的参数包括地面摩擦系数0.4 到 1.2、电机力矩常数±15%、机身质量±10%、IMU 角速度噪声±0.2 rad/s、动作延迟1 到 2 个控制步。这些随机化参数直接决定了 sim-to-real 迁移是否顺利本质上是在训练侧就把部署端可能遇到的误差提前纳入考虑。训练结束后的关键指标有两个。一是仿真内平均奖励和成功率二是策略对不同随机种子的鲁棒性。我会在训练环境里换几组极端摩擦参数跑测试如果策略在这些条件下还能维持一定速度前进才敢往真机走。只要训练侧把域随机化做好RK3566 部署端就能少做很多补偿。2.3 训练到什么程度算“能导出”“能导出”这件事需要提前 10 分钟思考而不是最后才做。我的要求包括网络必须写成继承torch.nn.Module的标准模块尽量不用torch.jit.script也不在 forward 里用 Python 控制流。只保留 policy 部分也就是纯 actor 网络critic 在导出时直接丢弃。所有输入输出必须是连续张量不要用字典、tuple 或者自定义类。训练时需要保存跑得最好的 checkpoint而不是最后一步的 checkpoint。强化学习训练到后期可能 policy 会退化保存的 checkpoint 要确保在评测里能连续走完几十秒。我用 PyTorch 训练最终导出时调用torch.onnx.export。导出之前先写好一个 wrapper 类把输入张量的维度和名字固定下来。例如输入命名obs输出命名action这个命名在 RK3566 上初始化 session 时会直接用。提前把导出脚本写好每次训练结束后跑一次确认 ONNX 能正常输出。还有一点训练时控制频率和实机控制频率如果有差异最好在导出前通过动作时间常数匹配。比如训练用 250Hz实机跑 400Hz那么动作平滑参数要按时间常数重新算否则机器人的步态频率和训练时的频率感完全不同关节会发飘。3. ONNX 导出与算子梳理部署路上最容易堵车的路段3.1 固定动态轴把 ONNX 输出形状钉死接触过 ONNX 的人都知道PyTorch 默认导出的模型经常带dynamic_axes参数能导出一个 batch 维度可变的图。灵活是好事但在嵌入式推理引擎上动态 shape 反而容易触发额外的内存分配和算子优化失效。我这边直接固定 batch size 为 1。torch.onnx.export( actor, (obs_tensor,), microduck_policy.onnx, input_names[obs], output_names[action], opset_version11, do_constant_foldingTrue, dynamic_axesNone, )dynamic_axesNone这个参数很关键意味着所有输入输出张量都是静态 shape。RK3566 上用 ONNXRuntime 初始化 session 的时候静态图能够直接做算子融合和内存规划推理延迟比动态图稳定得多。固定完 shape 之后用onnx.checker校验一遍图结构确认所有节点输入输出匹配。3.2 算子检查和 FP16 转换RK3566 CPU 默认跑 FP32如果转成 RKNN 用 NPU则要考虑量化。但在最初的 CPU 版本里FP32 就够了。检查算子的方法有两种一是用onnxruntime直接加载跑一次推理二是用onnx.shape_inference做完整推断。只要能跑通的算子后面转 RKNN 时才有参考。有一个小坑是opset_version。我一开始用了 opset 17里面有些算子比如ReduceSum的 axes 行为变了ONNXRuntime 老版本解析会有问题。后来统一改用 opset 11兼容性最好RKNN 转换工具对 opset 11 的支持也最成熟。如果训练代码里用到了较新的层尽可能在导出时先简化到 opset 11 能表达的范围内。FP16 转换的做法是先用onnxconverter_common里的float16工具把模型转成 FP16再用onnxruntime在 x86 CPU 上比较原模型和 FP16 模型的输出差异。但实际测试下来 RK3566 的 CPU 跑 FP16 并没有性能优势所以最终实机用的是 FP32FP16 没有采用。不过在做 RKNN 量化时这个 FP16 版本能作为调试参考。3.3 用 ONNXRuntime 在本地先验证本地验证这一步一定不能省。我通常会在训练机上直接跑一段模拟在线控制的循环用 ONNXRuntime 加载导出的模型输入随机的观测张量检查输出维度、数值范围是否和 PyTorch 原模型一致。更严格的做法是把一段真实 rollout 的观测数据全部回放对比每一步的动作输出误差。import onnxruntime as ort import numpy as np sess ort.InferenceSession( microduck_policy.onnx, providers[CPUExecutionProvider], ) obs np.random.randn(1, 70).astype(np.float32) action sess.run([action], {obs: obs})[0] print(action.shape, action)如果这一步数值与 PyTorch 输出误差在 1e-4 以内就可以进入 RK3566 实机阶段。很多人在这一步漏了验证结果到板子上发现输出全是 NaN回溯了很久才发现是 ONNX 导出时某个输入没有归一化。所以请在进入硬件之前先把软件环境排查干净。4. RK3566 实机部署先跑 CPU 再考虑 NPU4.1 开发环境与交叉编译RK3566 的板子我用的是一块标准的 Radxa 或者类似量产板系统是 Debian 系的 ARM64 镜像。开发机上先安装好交叉编译工具链也可以用板子直接编译但板子上编译一次很费时间我建议代码量不大就直接在开发机交叉编译代码量大就先在板子上把环境写好再同步代码。推理引擎优先选 ONNXRuntime 的 ARM64 版本。RK3566 是 ARMv8 架构ONNXRuntime 官方仓库里没有直接提供这么具体的 release但可以自己在板子上跑pip install onnxruntime或者用 RKNN-Toolkit2 附带的部分依赖。实测下来直接安装 ARM64 Linux 版本的 ONNXRuntime 是可行路径。控制主循环我用 C 写方便做高优先级实时线程。Python 绑定的 ONNXRuntime 用来做功能验证实机控制不用 Python因为 Python 的 GC 和 GIL 会在一个控制周期里造成随机性这个不确定性对步态控制是致命的。4.2 控制循环的主线程优先级RK3566 虽然是四核 A55但是 Linux 默认调度器并不严格保证某线程的周期性。为了跑 400Hz 的控制循环我用了pthread_setschedparam把控制线程设置成SCHED_FIFO优先级设到 80 左右。同时把控制线程绑定到 CPU2 或 CPU3避免和其他系统进程争抢。这里不要绑 CPU0因为内核很多进程和中断都跑在 CPU0 上绑上去会发生周期抖动。控制循环的整体结构大概是从电机驱动板读取 12 个关节的角度和角速度读取 IMU 数据。拼接观测向量状态估计结果、关节信息、IMU 数据、上一帧动作。调用 ONNXRuntime session 做一次推理。对输出动作做缩放与限幅生成目标位置或目标力矩。通过 CAN 或 SPI 总线把力矩指令发给电机驱动板。有一个细节值得注意控制线程里绝对不能做任何动态内存分配。ONNXRuntime 的 session 在初始化时已经分配好了所有中间张量缓存运行时推理只要保证输入输出张量的内存地址和大小不变就不会触发新的分配。我在初始化阶段创建一个固定的输入缓冲区std::vectorfloat obs(70)每次推理直接填充这个缓冲区再把指向该缓冲区的指针传给 ONNXRuntime。4.3 RKNN 的诱惑与陷阱RK3566 的 NPU 算力大约是 0.8 TOPS对一个小 MLP 来说理论上可以跑得很快。但直接用 RKNN 需要把 ONNX 转成 RKNN 格式量化成 INT8 或者 FP16。这个过程中最大的麻烦不是转换本身而是量化误差。强化学习策略对动作的精度其实很敏感尤其是关节位置增量这种连续量。INT8 量化后动作输出可能会从原来的连续值变成几个离散档位机器人跑步时关节会明显抖动。解决方法是做混合量化把敏感层保留 FP16 或者 FP32但这样一来 NPU 的加速收益就打了折扣。我最终的方案是RK3566 CPU 跑 ONNXRuntime FP32。实测推理延迟约 2 到 3 毫秒加上状态读取和电机指令下发整个控制循环能稳定在 1ms 到 2ms 内完成跑到 500Hz 也没有压力。RKNN 留给后续有时间再做优化。如果你确实考虑用 NPU建议多准备一组带标签的观测数据作为量化校准集量化后必须在实机上对比步态稳定性不要只看模型输出的数值误差。另外需要留意的是 RKNN-Toolkit2 版本和板子固件的匹配问题不同版本转出来的模型在驱动上兼容性不一致建议直接使用开发板供应商推荐的版本组合。5. 实机联调从关节回中到站立的演进过程5.1 关节回中和编码器校准第一次上电千万不要直接把策略跑起来。先做电机零位校准。Microduck 的每个关节电机通常带磁编码器或者 AB 相编码器断电后再上电编码器读数会丢失绝对位置。需要把每个关节手动拨到机械零位附近然后让驱动板记录当前编码器值作为零位偏移。我写了个简单的测试程序逐关节发送零位力矩观察电机是否缓慢回到机械位置然后手动把目标角度设为 0记录编码器读数。这个步骤虽然枯燥但直接影响后续所有控制。零位不准后续的 PD 控制目标角度和实际机械角度会存在恒定偏差机器人站起来的时候会像喝醉了一样往一边倒。校准完成后把 12 个零位偏移值存成配置文件每次开机读取。注意不同批次的电机在安装时机械零位可能不同不要把这些偏移硬编码进程序里。5.2 单腿 PD 测试别急着全机跑整机站立之前先做单腿测试。把机器人侧躺或者固定在支架上单独对其中一条腿的三个关节发送位置指令验证电机方向、速度反馈和 PD 控制是否正常。这一步能暴露很多方向性问题比如电机正反方向接反、编码器读数正负相反、CAN 通信偶发丢包等。我实际踩过一个坑个别关节的编码器读数的正方向与其他关节相反这会导致强化学习的观测值直接是反的机器人会觉得某个关节已经到位实际电机已经转过了。解决方法是逐关节测试位置跟随给一个正弦波目标观察实际反馈是否同相位。单腿测试通过的标志是给定一个固定角度电机能在 300ms 内到达并且不震荡给定正弦波轨迹实际角度和指令角度的相位差不超过一两个控制周期。这一步全部通过后再解锁其他三条腿。5.3 站立、试探、行走——第一次跑起来的经验当 12 个关节的 PD 都稳定后先不要加载神经网络。我会有另一个环节直接用一组固定的关节角度让机器人站起来确认它能维持平衡而不倒。这个时候 PD 增益需要够大但也不能太大否则会产生高频振荡。Microduck 这种小机器人在桌面或者地板上站立时机身的轻微抖动是很正常的。如果发生明显的身体抖动先降低 PD 增益里的微分项或者降低动作转换时间常数而不是上来就改动策略网络。第一次加载策略时我会把策略输出乘以一个缩放系数 0.3让机器人的动作幅度非常小观察它是否试图做出步态动作而不是直接倒下。确认没有剧烈异常后逐渐放大缩放系数到 1.0。这个过程类似于电机调试时的安全边际能在有问题时减小物理损伤概率。真正跑起来之后的经验是训练时的动作延迟如果和实机不一致步态会很难看。比如训练时动作延迟 1 个控制周期实机如果不做延迟匹配关节目标位置和实际位置会有一个周期偏移等效于增加了相位滞后。为了消除这个差异我在部署代码里手动加入了动作延迟缓冲缓存两帧之前的动作作为当前实际执行的动作这样和训练的时序对应起来走路的稳定性和姿态会明显改善。6. 实测数据复盘步态频率、延迟和能耗6.1 推理延迟和控制频率实机联调结束后我做了一轮性能测试把数据整理成表格方便后续定位问题。测试环境是 RK3566 四核 A55 跑 1.8GHz系统大概占用一个核控制线程绑定在 CPU2ONNXRuntime FP32 单次推理关掉所有打印输出。测量项数据说明控制循环平均周期约 2.1ms对应约 476Hz实际跑 400Hz 留有余量控制循环最大周期约 3.5ms出现在系统中断占用 CPU 时ONNXRuntime 单次推理延迟约 2.3ms输入 70 维输出 12 维256x256 网络整机功耗约 7W主控加电机空载不包含高强度行走电池续航约 18 到 22 分钟2S 1200mAh 电池混合步态实测推理延迟 2.3ms 是这组网络规模下的正常水平。如果你把网络压缩到 [128, 128]延迟可以降到 1ms 左右但步态质量可能会下降。控制周期稳定在 2.5ms 以内对 400Hz 控制频率来说没问题。如果哪天看到最大周期超过 4ms要先检查是不是有别的线程频繁抢占 CPU、DDR 带宽是否被占满、或者板子上 TF 卡读写拖了后腿。6.2 稳定性优化的几个细节跑动过程中出现过几次不稳定现象排查下来原因各不相同这里分享三个比较典型的经验。第一个是 CAN 总线丢包。RK3566 与电机驱动板之间如果用 SPI 转 CAN 模块在高负载时可能出现偶发丢帧表现为某条腿瞬间失去力矩指令然后又开始动作。我最后在代码里加了一个通信超时保护如果连续 20ms 没有收到电机反馈就让所有电机进入安全模式输出零力矩并停止步态。同时把 CAN 波特率从 500k 调整到 1M丢包率明显下降。第二个是 IMU 数据的预处理。RK3566 的 I2C 读取 IMU 数据如果直接在控制线程里做阻塞读取偶尔会拖慢整个循环。我的办法是开一个独立的 IMU 读取线程使用 I2C 轮询加 FIFO 缓存控制线程拿到的始终是最近一次完整 IMU 数据不会因为在控制循环里等 I2C 而卡住。实测下来这能让控制周期抖动降低一半。第三个是打印日志对实时性的影响。开发阶段大家喜欢在控制循环里加printf在 RK3566 上这会让周期变得非常不稳定串口打印一次可能消耗几百微秒到几毫秒。我的做法是所有日志通过环形缓冲区记录到内存再通过另一个低优先级线程定期输出控制线程保持干干净净零打印。还有一个容易被忽略的点是 CPU 频率调节。Debian 系统的默认 CPU 调度可能是ondemand或者schedutil在负载突增时频率切换会产生延迟尖峰。建议把 RK3566 的 CPU governor 固定到performance用cpufreq-set -g performance确保控制线程所在核心始终跑在最高频率。最后说一点关于后续优化方向RK3566 上 NPU 跑 INT8 量化策略是可以尝试的但一定要用校准集做精度验证并且在实际步态中评估如果你的目标只是稳定运行ONNXRuntime FP32 400Hz 控制循环已经是一个足够好的组合。还有一个很实用的扩展方向是把策略换成稀疏化版本去掉网络中权重接近 0 的神经元A55 上的推理延迟可以进一步压缩不过这属于锦上添花先把当前版本跑稳定比什么都重要。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

酒店管理系统多端联动实战:从架构到排坑的完整记录 2026/9/7 4:11:56

酒店管理系统多端联动实战:从架构到排坑的完整记录

简介:一套开箱即用的酒店管理系统,完整覆盖后台管理、官方网站与微信小程序三大版块,面向中小型酒店及民宿运营者,解决房态管理、订单流转、餐饮预订与移动支付等日常经营问题,适合需要快速上线数字化系统的团队参考或…

阅读更多 →
数据结构大作业实战:C语言构建教务管理系统全解析 2026/9/7 4:11:56

数据结构大作业实战:C语言构建教务管理系统全解析

简介:面向高校数据结构课程设计的一份完整教务管理系统实现,包含教师端、学生端与教务员端三大模块,能够覆盖学生信息管理、课程维护、选课处理等常见教务场景,适合完成数据结构课程后需要撰写大作业或课程设计的本科学生参考。压…

阅读更多 →
相位梯度超表面:从广义斯涅耳定律到10GHz波束偏转设计 2026/9/7 4:11:56

相位梯度超表面:从广义斯涅耳定律到10GHz波束偏转设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
不会电脑也能用!手机扫码云进销存选型指南 2026/9/7 4:11:56

不会电脑也能用!手机扫码云进销存选型指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
基于Spring Boot的转账系统:事务、幂等与并发控制实践 2026/9/7 4:11:56

基于Spring Boot的转账系统:事务、幂等与并发控制实践

简介:这是一份用于教学演示的模拟银行账户转账系统源码,面向正在学习图形界面编程和多线程开发的初学者。系统设有两个初始余额为一千元的账户,随机向对方转账,转账金额不能超过当前余额,余额为零则停止交易&#xff1…

阅读更多 →
career-ops 西班牙语模式深度解析:modes/es/_shared.md 如何用“事实源 + 防虚构护栏 + 西语市场规则”约束 AI 求职 Agent 2026/9/7 4:08:55

career-ops 西班牙语模式深度解析:modes/es/_shared.md 如何用“事实源 + 防虚构护栏 + 西语市场规则”约束 AI 求职 Agent

career-ops 西班牙语模式深度解析:modes/es/_shared.md 如何用“事实源 防虚构护栏 西语市场规则”约束 AI 求职 Agent 【免费下载链接】career-ops Open-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞