跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

轮腿机器人代码调试与运动学解算补充

轮腿机器人硬件选型包括关节与轮毂电机及开发板配置。软件层面涉及任务封装、模块封装及算法封装(VMC、PID、LQR)。调试核心在于左右腿坐标系处理、状态变量极性校准,通过一阶与二阶倒立摆模型逐步验证平衡控制。MATLAB 脚本用于计算矩阵系数,Keil 调试工具辅助观测变量数值。机械结构需优化轴系以防外八现象。

人间失格发布于 2026/4/7更新于 2026/7/2348 浏览
轮腿机器人代码调试与运动学解算补充

轮腿模型图

轮图模型图

一、硬件说明

材料选型型号数量单价
关节电机DM-J8009P-2EC41369.00(教育优惠后)
轮毂电机瓴控 MF9025V2(16T)2990.00
腿及电机固定板碳板加工900.00
车架铝管加工500.00
橡胶充气轮胎伊诺华 8x1 1/4 内外胎250.00
开发板RoboMaster C 型开发板1
关节电机 ID 分配

关节电机 ID 分配

轮毂电机 ID 分配

轮毂电机 ID 分配

C 型开发板放置实物图

c 板放置示意图

二、软件说明

轮腿建模参考哈工程建模方法,双腿分开建模。五连杆解算参考五连杆运动学解算与 VMC。MATLAB 脚本用于辅助计算。

任务封装
任务作用
INS_task.c解算陀螺仪数据,得到三轴加速度计、三轴弧度
Uart1_task.c向上位机发送数据,方便配合 vofa+ 调试 pid
chassisR_task.c调用 VMC_calc.c 函数结合 MATLAB 计算 k[12] 矩阵,计算左右轮毂电机输出力矩和车架中心轴输出力矩,最后调用 VMC_calc.c 函数得到单腿前后两个关节电机输出力矩
模块封装
模块作用
CAN_receive.c所有电机协议及电机功能的函数封装
remote_control.c遥控器 dbus 协议函数封装
算法封装
算法作用
VMC_calc.c1. 五连杆解算得到单腿的 phi0、腿长 L0、theta、dot_theta
2. 通过雅可比矩阵得到单腿的前后关节电机的输出力矩
3. 建议参考 MATLAB 文件中的 d_phi0.m 和 VMC_calc.m
arm_math.h
arm_cortexM4lf_math.lib结合 arm_math.h 提供必要的 sin、cos、tan 三角函数运算
pid.cpid 初始化函数、pid 计算函数、pid 清除函数
需要用到的 MATLAB 文件
名称作用用法
get_k_length.m根据输入的腿长(单位 m)和输入的 QR 矩阵来计算 k 矩阵在命令行窗口输入:K = get_k_length(腿长值)
get_k.m计算多项式拟合的系数点击'运行'

三、电机相关补充说明

轮毂电机

本车所使用的轮毂电机协议为转矩闭环模式。

轮毂电机驱动回复协议

轮毂电机转矩闭环模式

关节电机

笔者轮腿所使用的关节电机模式为 MIT 模式。零点设置在下限位处,当各电机处于零点处时,车子姿态如图所示。

零点示意图

四、代码调试及编写顺序

  1. 通过在 MATLAB 文件 get_k_length.m 中的命令行窗口输入(以腿长 0.24m 为例,默认 QR 矩阵的各参数权重已经调好):K = get_k_length(0.24),复制运行结果;
  2. 接着进入 while 循环,更新数据。

获取底盘 pitch 角度,此时对于右腿,车子前倾,陀螺仪 pitch 轴反馈弧度为正数。由于左右腿坐标系方向相反,所以左腿模型获取到的 pitch 前要加上负号;

update_pitch

再获取底盘 yaw 角度当前值同时转化为角度制,同时将陀螺仪反馈的数据(0180 及 -1800)映射到 0~360 度;

update_yaw

先获取 phi1 和 phi4 的角度,根据关节电机反馈的弧度值加上零点时腿所在的弧度值(零点时,phi1 弧度值为π,phi4 为 0rad);

update_phis1

进入到 void ChassisR_task(void const *pvParameters){...}中,首先进行初始化,获取到遥控器的数据指针、获取电机反馈数据、获取陀螺仪角速度指针、获取陀螺仪角度指针、给右杆长赋值、给左杆长赋值、初始化左右腿长的 pid、初始化 yaw 转向 pid:

chassisR_task 初始化

在 chassisR_task.c文件中,将结果粘贴到float LQR_KK[12]={...};中,如图所示:

LQR_KK

左右腿坐标系相反详解图解

左右腿坐标系相反详解

接下来进行右腿的循环计算环节,通过 VMC_calc_1_right(&vmc_leg_right, &INS_data,0.003f);计算 theta 和 d_theta 给 lqr 用,同时也通过计算实时得到右腿长 L0,该任务控制周期是 0.003 秒。

在底盘循环计算环节,首先通过循环限幅函数,将 yaw 目标值限制在 0~360°内,再通过过零处理函数,处理陀螺仪反馈的 yaw 值在 0 与 360 之间的突变问题。最后通过 PD 控制器计算出转向力矩赋值给 wz_set。通过左右轮的轮毂力矩加上转向力矩 wz_set,使得两轮能实现差速,最终车子能够实现转向。

计算转向力矩

在 void chassis_feedback_update(void){...}中实时获取底盘 yaw 角度当前值和计算底盘 yaw 轴的目标值;

实时更新 yaw 数据

在初始化之后,获取底盘 yaw 角度当前值;

yaw 目标值初始化

转向控制

仿照右腿模型,不作过多讲解。

左腿解算

左腿模型部分

在得到 Tp 和 F0 之后,通过 VMC_calc_2(&vmc_leg_right);函数计算出前后两关节电机输出力矩,最后转换为转矩电流;

右腿 VMC

转矩电流

接下来加入腿长控制器:vmc_leg_right.F0=10.0f/arm_cos_f32(vmc_leg_right.theta)+PID_calc(&LegR_Pid,vmc_leg_right.L0,0.24f);得到沿腿的推力 F0,方向为指向地面;

腿长控制器及 VMC

接着再计算右边中心轴髋关节输出力矩,即车体绕两关节电机连线中心点的力矩

右腿 LQR

得到 theta 和 d_theta 之后,进行右轮毂电机的 lqr 计算,得到轮毂的输出力矩;

右轮毂 LQR

右腿模型部分

根据轮毂电机反馈的速度(注意,MF9025V2 电机反馈的速度单位为 1dps,需要转换为 rpm)计算左右轮的位移速度,其中 CHASSIS_MOTOR_RPM_TO_VECTOR_SEN 为 LK9025 转子转速 (rpm) 转化成底盘速度 (m/s) 的比例即 k= 2πr/60。最后将得到的左右轮位移速度相加(右轮速度方向应取反以保证两轮反馈的速度方向最后一致)再除 2 取平均得到整车位移速度。通过对整车位移速度积分,求得整车位移;

update_整车位移速度

获取遥控器对于整车的速度目标值,其中 CHASSIS_VX_RC_SEN 为遥控器前进摇杆(max 660)转化成车体前进速度(m/s)的比例;

update_remotecontrol

chassis_move.wheel_motor[1].wheel_T+=wz_set; chassis_move.wheel_motor[0].wheel_T+=wz_set;//将 yaw 轴补偿值加到左轮力矩上

五、调试补充

一阶倒立摆(板凳模型)
  1. 调试时,应先调板凳模型(即先用位置速度模式,将腿的位置固定,然后整车当做一阶倒立摆模型来调试。)当板凳模型调好之后,轮毂的 ob_lqr.lqr[0]~ob_lqr.lqr[5] 的极性也就正确了。

ob_lqr.lqr[0]~ob_lqr.lqr[5] 的极性应该保持一致,要么全为正数要么全为负数。

//observe 结构体,方便调试极性时 debug 观测 
ob_lqr.lqr[0]=LQR_KK[0]*(vmc_leg_right.theta-0.0f); 
ob_lqr.lqr[1]=LQR_KK[1]*(vmc_leg_right.d_theta-0.0f); 
ob_lqr.lqr[2]=LQR_KK[2]*(chassis_move.x_filter-0); 
ob_lqr.lqr[3]=LQR_KK[3]*(chassis_move.v_filter-0); 
ob_lqr.lqr[4]=-LQR_KK[4]*(chassis_move.myPithR-0.0f); 
ob_lqr.lqr[5]=-LQR_KK[5]*(chassis_move.myPithGyroR-0.0f); 
chassis_move.wheel_motor[1].wheel_T=(ob_lqr.lqr[0]+ob_lqr.lqr[1]+ob_lqr.lqr[2]+ob_lqr.lqr[3]+ob_lqr.lqr[4]+ob_lqr.lqr[5]);
二阶倒立摆模型
  1. 接下来在板凳模型的基础上调试关节电机,将关节电机设置为 MIT 模式,先把 ob_leg_r.lqr[2]~ob_leg_r.lqr[5] 行注释掉,只保留 ob_leg_r.lqr[0]~ob_leg_r.lqr[1] 行。此时车子前倾,腿往前蹬,车子往后倾,腿往后蹬。vmc_leg_right.theta 是来使车子保持平稳的。

  2. 然后只保留 ob_leg_r.lqr[4]~ob_leg_r.lqr[5] 行,此时车子往前倾,腿会往后蹬,车子往后倾,腿会往前蹬。

  3. 当只保留 ob_leg_r.lqr[0]~ob_leg_r.lqr[1] 和 ob_leg_r.lqr[4]~ob_leg_r.lqr[5] 行时,即去掉位移项和速度项时,结合轮毂部分的 lqr,此时车子可以保持平稳。

//ob_leg_r.lqr[0]=LQR_KK[6]*(vmc_leg_right.theta-0.0f);//ob_leg_r.lqr[1]=LQR_KK[7]*(vmc_leg_right.d_theta-0.0f);//ob_leg_r.lqr[2]=LQR_KK[8]*(-chassis_move.x_filter-0);//ob_leg_r.lqr[3]=LQR_KK[9]*(-chassis_move.v_filter-0); 
ob_leg_r.lqr[4]=-LQR_KK[10]*(chassis_move.myPithR-0.0f); 
ob_leg_r.lqr[5]=-LQR_KK[11]*(chassis_move.myPithGyroR-0.0f); 
//右边中心轴髋关节输出力矩,车体绕两关节电机连线中心点的力矩 
vmc_leg_right.Tp=(ob_leg_r.lqr[0]+ob_leg_r.lqr[1]+ob_leg_r.lqr[2]+ob_leg_r.lqr[3]+ob_leg_r.lqr[4]+ob_leg_r.lqr[5]);
//只有 vmc_leg_right.theta 和 vmc_leg_right.d_theta 时,腿往前蹬;只有 chassis_move.myPithR 和 chassis_move.myPithGyroR 时,腿往后蹬。 
ob_leg_r.lqr[0]=LQR_KK[6]*(vmc_leg_right.theta-0.0f); 
ob_leg_r.lqr[1]=LQR_KK[7]*(vmc_leg_right.d_theta-0.0f); 
ob_leg_r.lqr[2]=LQR_KK[8]*(-chassis_move.x_filter-0); 
ob_leg_r.lqr[3]=LQR_KK[9]*(-chassis_move.v_filter-0); 
ob_leg_r.lqr[4]=-LQR_KK[10]*(chassis_move.myPithR-0.0f); 
ob_leg_r.lqr[5]=-LQR_KK[11]*(chassis_move.myPithGyroR-0.0f);
//右边中心轴髋关节输出力矩,车体绕两关节电机连线中心点的力矩 
vmc_leg_right.Tp=(ob_leg_r.lqr[0]+ob_leg_r.lqr[1]+ob_leg_r.lqr[2]+ob_leg_r.lqr[3]+ob_leg_r.lqr[4]+ob_leg_r.lqr[5]);

注意!vmc_leg_right.theta 与陀螺仪的放置方向有关,建议使用 keil 的 debug 调试工具调试一下,观测腿长 L0、phi0、phi1、phi2、phi3、phi4 和 vmc_leg_right.theta 是否正确,观测 vmc_leg_right.theta 时,不能只看其是否增加减小,建议代入两三组数据手动解算一下数值。

关节电机的速度项和位移项的极性一开始较为难确定,总的来说,关节电机的位移项的极性与速度项一致。关节电机的速度项的极性与 chassis_move.myPithR 的极性一致。

各状态变量的极性说明(极性的确定非常重要!!!)
轮毂极性部分
//observe 结构体,方便调试极性时 debug 观测 
ob_lqr.lqr[0]=LQR_KK[0]*(vmc_leg_right.theta-0.0f); 
ob_lqr.lqr[1]=LQR_KK[1]*(vmc_leg_right.d_theta-0.0f); 
ob_lqr.lqr[2]=LQR_KK[2]*(chassis_move.x_filter-0); 
ob_lqr.lqr[3]=LQR_KK[3]*(chassis_move.v_filter-0); 
ob_lqr.lqr[4]=-LQR_KK[4]*(chassis_move.myPithR-0.0f); 
ob_lqr.lqr[5]=-LQR_KK[5]*(chassis_move.myPithGyroR-0.0f); 
chassis_move.wheel_motor[1].wheel_T=(ob_lqr.lqr[0]+ob_lqr.lqr[1]+ob_lqr.lqr[2]+ob_lqr.lqr[3]+ob_lqr.lqr[4]+ob_lqr.lqr[5]);

ob_lqr.lqr[0]~ob_lqr.lqr[5] 的极性应该保持一致,要么全为正数要么全为负数。

vmc_leg_right.d_theta 的极性应与 vmc_leg_right.theta 保持一致。

chassis_move.myPithGyroR 的极性应与 chassis_move.myPithR 保持一致。

关节极性部分
//只有 vmc_leg_right.theta 和 vmc_leg_right.d_theta 时,腿往前蹬;只有 chassis_move.myPithR 和 chassis_move.myPithGyroR 时,腿往后蹬。 
ob_leg_r.lqr[0]=LQR_KK[6]*(vmc_leg_right.theta-0.0f); 
ob_leg_r.lqr[1]=LQR_KK[7]*(vmc_leg_right.d_theta-0.0f); 
ob_leg_r.lqr[2]=LQR_KK[8]*(-chassis_move.x_filter-0); 
ob_leg_r.lqr[3]=LQR_KK[9]*(-chassis_move.v_filter-0); 
ob_leg_r.lqr[4]=-LQR_KK[10]*(chassis_move.myPithR-0.0f); 
ob_leg_r.lqr[5]=-LQR_KK[11]*(chassis_move.myPithGyroR-0.0f);
//右边中心轴髋关节输出力矩,车体绕两关节电机连线中心点的力矩 
vmc_leg_right.Tp=(ob_leg_r.lqr[0]+ob_leg_r.lqr[1]+ob_leg_r.lqr[2]+ob_leg_r.lqr[3]+ob_leg_r.lqr[4]+ob_leg_r.lqr[5]);

六、轮腿圣经图解补充

轮腿模型图解补充

轮腿圣经模型图补充

五连杆及 VMC 图解补充

VMC 图解

mp 摆杆质量(腿的质量)在实物中为:m_p = (m_l1 + m_l2 + m_l3 + m_l4) / 2

未来展望

在电控方面,由于时间问题,本车只完成了轮腿的基础功能:平衡、前后平移、左右转向。未来还可以添加跳跃、不同腿长下的拟合、roll 轴补偿、打滑检测、离地检测、左右摇摆、太空漫步等动能的算法。

在机械方面,轮腿关节轴系需要进一步优化,笔者所使用的关节处的轴系为传统形式,好处就是结构简单,方便设计,零件均为标件价格便宜。但是弊端也非常严重:(1)高强度跳跃下自锁螺母容易松开,时不时需要用开口扳手与内六角扳手进行拧紧、(2)拧的太死又会出现两个连杆无法相对旋转、(3)在轮电机输出面与关节电机输出面距离较远且轮组重的情况下容易出现外八的情况。所以在未来可参考使用自行车碗组的结构,能有效减少车轮外八的现象。

目录

  1. 轮腿模型图
  2. 一、硬件说明
  3. 关节电机 ID 分配
  4. 轮毂电机 ID 分配
  5. C 型开发板放置实物图
  6. 二、软件说明
  7. 任务封装
  8. 模块封装
  9. 算法封装
  10. 需要用到的 MATLAB 文件
  11. 三、电机相关补充说明
  12. 轮毂电机
  13. 关节电机
  14. 四、代码调试及编写顺序
  15. 左右腿坐标系相反详解图解
  16. 转向控制
  17. 左腿模型部分
  18. 右腿模型部分
  19. 五、调试补充
  20. 一阶倒立摆(板凳模型)
  21. 二阶倒立摆模型
  22. 各状态变量的极性说明(极性的确定非常重要!!!)
  23. 轮毂极性部分
  24. 关节极性部分
  25. 六、轮腿圣经图解补充
  26. 轮腿模型图解补充
  27. 五连杆及 VMC 图解补充
  28. 未来展望
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Spring Boot 考试安排管理系统设计与实现
  • SketchUp STL 插件实战:优化 3D 打印模型导出流程
  • Python 金融数据 API 实战:Finnhub 接入与优化
  • 项目实战:使用 three.js+vue3+ts 完成 VR 全景看房应用
  • Java static 避坑:静态与非静态访问规则全解析
  • Python 从入门到精通的学习计划与进阶指南
  • 蓝桥杯 C/C++ 组备考:C++ 基础知识入门(上)
  • Amazon Q 深度解析:生成式 AI 驱动的企业级智能助手与开发辅助
  • 华为 OD 机试:补种未成活胡杨
  • Git 原理与使用详解(上):版本控制核心架构与基础操作
  • 使用 Metasploit 制作 Linux 可执行文件及恶意 deb 包获取 Shell
  • 前端开发:如何使用浏览器工具查看接口请求与响应
  • Home Assistant 主题定制指南:打造专属智能家居界面
  • Python 异步编程与协程实战指南
  • Spring Boot 中接入 MQ 与异步处理
  • C++ 高性能内存池设计与实现
  • Python Pygame 实战:打地鼠小游戏开发指南
  • C++ 实现 DLL 注入原理与源码示例
  • NestJS 接口响应 message 编写规范与 API 提示标准化
  • OpenClaw 全平台安装与 Telegram/飞书集成部署指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online