简介:一份基于ADAMS与MATLAB的两轮机器人运动研究文档,面向机器人、机械电子及自动化方向的在校生和入门研究者,系统展示了从模型简化、控制设计到动力学仿真的完整流程。文档先借助MATLAB对机器人模型进行参数与受力分析,并基于倒立摆原理设计平衡控制方案,再通过SIMULINK仿真验证控制效果;随后在ADAMS环境中搭建两轮机器人模型、添加控制约束并模拟运动,仿真结果表明系统调节时间短、抗干扰能力强,达到了预期的平衡与运动控制目标。整个资源为1个doc文档,压缩包大小约1.79MB。文档结构完整,包含摘要、中英文摘要、绪论及详细的研究章节,并结合实际案例给出了两轮机器人的运动分析与控制设计思路,适合作为课程设计、毕业设计或机器人运动仿真入门的参考资料。目前已有181人学习下载,可作为ADAMS与MATLAB联合仿真实践的案例参照。
1. 基于ADAMS的两轮机器人运动研究:仿真到底在研究什么
基于ADAMS的两轮机器人运动研究,说白了就是先在电脑里把两轮机器人造出来,用虚拟样机代替真机去跑运动仿真,再把仿真结果用来指导结构重心设计和平衡控制参数整定。两轮机器人天生是不稳定系统,真机调试的成本很高:摔一次可能要重新校准电机、换结构件,一个传感器漂移就能让整个晚上白费。仿真环境里这些问题被集中到几个参数上——接触刚度、质心高度、PID增益,调参代价几乎为零。适合谁:正在做两轮自平衡机器人课程设计或毕业设计的学生,想做运动学与动力学预研的工程师,以及被真机调参折磨到想先建虚拟样机的人。这篇笔记只讲一件事:怎么用ADAMS把两轮机器人的运动研究做到能出结论、能指导调参。
2. 建立两轮机器人虚拟样机:几何简化、质心与转动惯量是命门
2.1 建模从CAD导入还是从零搭块:两种路线怎么选
常见做法是用三维建模软件先画好整机,再导出中间格式导入ADAMS。这个流程在地面车辆仿真里没问题,但放到两轮机器人上往往得不偿失。原因在于ADAMS算的是力学不是造型。复杂壳体导入后,每个曲面都要参与接触检测,解算速度明显下降;更麻烦的是,导入几何的质心和转动惯量完全由几何和密度决定,壳体上的沉孔、圆角、螺纹孔都会干扰质心计算,而这些细节对运动研究毫无意义。
我一般会这样做:外形导入只用于确认装配关系和干涉,随后在ADAMS里用Box、Cylinder、Link搭一套简化几何,再直接指定每个刚性部件的质量、质心位置和转动惯量。这么做的理由是,两轮机器人的运动学研究关心的物理量就三个:总质量、质心高度、绕车轴的转动惯量。几何简化之后,这三个量反而更容易对齐真实BOM表。两种路线的取舍见表。
| 对比项 | CAD几何直接导入 | 简化几何+质量属性 |
|---|---|---|
| 适合场景 | 结构干涉检查、外观确认 | 运动学/动力学仿真 |
| 质量属性精度 | 依赖几何与密度,细节特征易干扰 | 按BOM表逐件指定,精度可控 |
| 接触计算量 | 面多,解算慢 | 面少,鲁棒性好 |
| 典型用途 | 装配验证 | 运动研究、控制调参 |
需要说明的是,我不建议一上来就完全拒绝CAD导入。如果机器人外壳是异形曲面,且你后续要做轮子与地面的实际接触外观验证,那么导入一次看一眼装配关系是值得的。但看完就删,不要让复杂几何留在仿真模型里拖后腿。
2.2 单位制、材料密度与质量匹配:改密度比改外形更有效
模型建完第一步永远是核对单位制。ADAMS里长度单位常见冲突发生在毫米和米之间:三维软件里按毫米建模,导入ADAMS默认米制环境后,车长显示0.2而不是200,或者反过来。处理办法是在Settings→Units里先确认长度单位,或者在导入菜单里选择模型缩放选项。出现这种事别急着改几何,先改单位,几何缩放比重新画一遍省事得多。
接下来是密度,这是两轮机器人虚拟样机最常见的失真来源。ADAMS默认材料是钢,密度7850 kg/m³。如果所有零件都用默认密度,一台真实质量1.2 kg的两轮机器人,虚拟样机可能直接变成5 kg。质量差好几倍,PID力矩需求、接触力、加速性能会全部走样。常见做法是按真实BOM表逐件指定材料,或者直接输入质量值。
| 组件 | 常见材料 | 密度(kg/m³) |
|---|---|---|
| 底盘骨架 | 铝合金 | 2700左右 |
| 外壳/盖板 | ABS塑料 | 1050左右 |
| 车轮 | 橡胶+塑料轮毂 | 1100~1300 |
| 电机/电池 | 按件指定质量 | 不按密度算 |
电机和电池这类组件,与其靠密度让几何自动算,不如直接输入质量值,因为它们内部绕组、磁钢、电芯的密度分布根本画不出来。修改位置在每个PART的Modify Mass Properties里,可以手动填质量,也可以填密度后让ADAMS按体积计算。如果选了后者,务必复查计算出的总质量是否和实物称重一致。
2.3 质心高度与转动惯量核对:一个反直觉的仿真发现
两轮自平衡的稳定性和控制难度,核心物理量不是总质量,而是质心高度和绕车轴的转动惯量。仿真里有个反直觉的常见错误:把电池、控制板都按集中质量点放在车体几何中心,结果质心偏低,仿真里特别好平衡,真机完全控制不住。真实装配中电池通常在底层,但主控和传感器立杆在顶层,质心明显抬高。质心高度每抬高1 cm,所需Kp和稳定裕度就会有肉眼可见的差别,所以运动研究必须在建模阶段较真质心。
进ADAMS之前,先用一个小脚本按BOM表估算等效总质量与质心高度,是团队里比较通用的做法。脚本只做一件事:把每个组件的质量按真实位置累加,算出一个理论质心高度,方便和ADAMS模型的自动质心交叉核对。
# 预估两轮机器人虚拟样机的组件质量与质心高度 # 输入真实BOM表数据:名称、单件质量kg、数量、质心距车轴高度mm bom = [ {"part": "底盘骨架", "mass": 0.35, "count": 1, "height": 80}, {"part": "电池组", "mass": 0.25, "count": 1, "height": 120}, {"part": "主控板", "mass": 0.10, "count": 1, "height": 140}, {"part": "编码器电机", "mass": 0.12, "count": 2, "height": 60}, {"part": "车轮", "mass": 0.08, "count": 2, "height": 0}, ] total_mass = sum(p["mass"] * p["count"] for p in bom) moment = sum(p["mass"] * p["count"] * p["height"] for p in bom) print("预计总质量: %.2f kg" % total_mass) print("质心高度(距车轴): %.1f mm" % (moment / total_mass))脚本里height是组件质心到车轴连线的垂直高度,单位mm。电池这类贴着底盘的部件算低,主控板立杆上的传感器算高。脚本输出的数值要和ADAMS模型里Review→Mass Properties显示的质心坐标做比对,偏差超过5%就要回头查是哪个部件密度或位置给错了。等模型建完,总质量和质心两个数都对上,再往下做接触和驱动。
3. 接触与驱动建模:让两轮机器人在ADAMS里真正“站起来”
3.1 轮地接触用IMPACT还是用约束:摩擦学起来没那么简单
轮子和地面不能用旋转副加移动副直接贴死,那样机器人永远不会倒,也就失去了运动研究的意义。两轮机器人要研究的是不稳定系统的动态行为,车轮和地面之间必须用接触建模。常见做法是Solid-Solid接触:车轮几何用薄圆柱体,地面用一个大Box固定在大地。也有人用Curve-Curve接触,但两轮机器人原地转向时,车轮与地面的接触点会横向移动,曲线接触容易丢,所以Solid-Solid更稳。
接触参数是整个两轮机器人仿真里最像玄学的地方,没有厂商会给你精确值。我的经验是先按下面这张表设初值,再用「静置不穿模」作为收敛判据去微调。
| 参数 | 建议取值 | 说明 |
|---|---|---|
| Stiffness | 1e5 ~ 1e6 N/mm | 轮胎刚度;太大引发高频震荡,太小穿模 |
| Damping | 10 ~ 100 N·s/mm | 约为刚度的1/100 ~ 1/1000 |
| Penetration Depth | 0.1 mm | 穿透深度,太大会让车轮陷地 |
| Static Friction | 0.7 | 静摩擦,起步和转向主要靠它 |
| Dynamic Friction | 0.5 | 动摩擦,打滑时起作用 |
| Transition Vel | 0.1 / 1.0 mm/s | 静动摩擦切换速度阈值,太小数值抖动 |
校验方法很简单:给车一个很微小的初始倾角,静置仿真0.5秒,观察车轮不穿模、不跳起、接触力平稳,这组接触参数就可以继续用。特别提醒,不要把金属碰撞的刚度经验值照搬过来,1e8那种量级是给齿轮碰撞准备的,轮胎那么软,刚度太高会直接把积分器逼到高频振荡。
3.2 自平衡必须闭环:状态变量与力矩反馈函数
两轮机器人不倒,必须闭环控制。但ADAMS里的Motion驱动是位置驱动,它没法像真机那样读倾角再修正输出。把两轮机器人的自平衡做进ADAMS,常见做法分两种。
方案一是直接在车轴旋转副上创建Torque,力矩函数引用状态变量实时的角度和角速度。这种方式适合运动研究,迭代快,不用在两个软件之间来回切换。力矩表达式类似下面这样,写在ADAMS的力矩编辑器里:
// 施加在车轴上的反馈力矩表达式,单位 N·mm // 角度与角速度来自同一组状态变量,实时反馈 FUNCTION = -KP * VARVAL(.model.angle_state) - KD * VARVAL(.model.omega_state)KP的作用是把倾角拉回零位:车体前倾时倾角为正,需要负的补偿力矩,所以前面带负号。KD的作用是抑制角速度,增加系统阻尼。VARVAL读取的是当前积分步的状态变量值,因此这个力矩会在仿真过程中实时更新,等效于一个PD控制器。注意角度单位,ADAMS里状态变量如果直接引用角度Measure,数值通常按度走,VARVAL本身不做单位换算。如果你在控制模型里习惯用弧度,必须在函数里除以57.3,否则Kp等效增益被放大了57倍,模型第一步就会飞出去。
方案二是用ADAMS Controls插件把机械系统导出到Simulink做联合仿真,控制律在Simulink里写。这个路径适合验证LQR、滑模这类控制算法,但链路长、调试慢。运动研究阶段建议先用方案一,等模型能稳定站住,再把机械部分导出,替换控制策略做算法对比。状态变量创建时要区分类型:angle_state建议用表达式型,直接引用车体相对大地的角度Measure,让它每一步自动更新,避免出现代数环。
3.3 PID初值标定:两个必调参数和一组合理起点
PID参数在ADAMS里标定,不需要一上来就试凑。我的顺序是先Kp后Kd。把Kd先置0,Kp从小值开始加,然后用Simulate→Static Equilibrium做一次静平衡分析。静平衡能算出来,说明Kp提供的补偿力矩足以抵消重力矩,模型在第一步不会倒;静平衡失败,说明Kp太小,继续加。之后给模型一个3°左右的初始倾角,看倾角响应:能缓慢回中但带一点超调,Kp就是可用的;出现高频抖动,记录当前值作为边界,往后退30%再继续。
Kd的定位从Kp的1/10起步,主要看倾角速度的抖动是否被压下去。Kd太小,超调大、回中慢;Kd太大,模型会变得僵硬,出现低幅高频颤振。两轮自平衡一般不用Ki,积分项会引入低频晃动,只有当你发现稳态倾角明显偏离零位时才考虑加一点。
| 参数 | 作用 | 初值建议 | 调整方向 |
|---|---|---|---|
| Kp | 角度刚度,拉回倾角 | 从小到大试,先过静平衡 | 太小站不住,太大高频抖振 |
| Kd | 角速度阻尼,抑制超调 | 从Kp的1/10起步 | 太大模型僵硬、颤振 |
| Ki | 消除稳态误差 | 默认不用 | 用了易低频晃动 |
还有一件事值得较真:真机PID代码里的角度单位是弧度还是度,必须和ADAMS状态变量保持一致。这个不一致的坑会在后面所有曲线对比时反复出现,早点统一单位,后面省掉大半排错时间。
4. 典型运动工况仿真与结果提取:S曲线、原地转向与数据后处理
4.1 三个标准运动工况:直线启动、原地转向与S形轨迹
两轮机器人的运动研究,通常用三个标准工况覆盖核心能力:直线启动看平衡品质,原地转向看差速能力,S形轨迹看路径跟随。直线启动时左右轮施加等幅驱动,重点记录车体倾角的最大超调量和稳定时间;原地转向时左右轮反方向等速驱动,重点观察偏航角速度和轮地接触力是否出现打滑;S形轨迹则通过左右轮的差速阶梯变化实现。
差速驱动可以用STEP函数构造,保证速度连续、加速度没有突变。下面是典型的S形轨迹驱动写法,写在两个轮的Motion里:
// 左右轮角速度驱动之差形成S形轨迹 left_motion: STEP(time, 0, 0, 1, 30) + STEP(time, 3, 0, 4, -30) right_motion: STEP(time, 0, 0, 1, 15) + STEP(time, 3, 0, 4, -15)STEP函数的五参数含义是:在time从0到1秒内,把速度从0平滑过渡到目标值,3到4秒再平滑回0。左右轮目标速度差为15°/s时路径较平滑,差速到30°/s转弯半径明显变小。实际使用中根据你机器人的轮距和期望路径宽度去调这两个数。每个工况仿真时间给3到5秒就够,跑太久不会有新信息,只会积累数值漂移。
4.2 求解器设置:步长、误差和输出频率的搭配
求解器设置直接决定仿真结果可不可信。两轮机器人有接触、有闭环反馈,属于刚性系统,求解器用默认的GSTIFF或WSTIFF都可以,关键是积分误差和步长。积分误差Error一般设在1e-3到1e-4之间,误差设得太严,接触频繁时步长会被压到极小,仿真速度慢到无法接受;设得太松,接触力峰值会被削平。步长建议0.001到0.0005秒。仿真时间2到5秒足够出结论。
输出频率是另一个容易被忽略的坑。ADAMS默认每10步输出一次结果,如果你步长是1ms,输出间隔就是10ms,倾角峰值往往落在两个输出点之间,画出来的曲线会损失真实超调量。在仿真设置里把输出改成每步输出,或者用固定时间间隔0.001s输出。后处理时如果曲线毛刺多,先确认是不是输出间隔太大造成的假锯齿,再去动滤波器。提示:输出间隔要在仿真前设好,跑完再想加密数据只能重跑。
4.3 从后处理曲线到可写进论文的指标:数据清洗的Python脚本
仿真跑完,从后处理里导出曲线。File→Export可以把数据导出为CSV或表格文件,但导出的文件通常带单位注释行和列名行,直接pandas读取会报错或把单位行当数据。我一般用skiprows处理,再按时间窗口计算指标。
import pandas as pd import numpy as np # ADAMS导出文件常有单位注释行,按实际导出情况调整 skiprows df = pd.read_csv("run1_angle.csv", skiprows=1) t = df["time"].to_numpy() angle = df["angle"].to_numpy() # 倾角,单位:度 # 滑动平均去抖,window按导出频率调整 window = 15 angle_smooth = np.convolve(angle, np.ones(window) / window, mode="same") # 稳态窗口取仿真最后 0.5s mask = t >= t[-1] - 0.5 steady = angle_smooth[mask] print("最大倾角(deg): %.2f" % np.max(np.abs(angle_smooth))) print("稳态倾角均值(deg): %.2f" % np.mean(steady)) print("稳态标准差(deg): %.2f" % np.std(steady))滑动平均窗口15点,在1kHz导出频率下对应15ms,基本保留平衡动态又能滤掉接触抖动;如果你的导出频率是500Hz,window要相应缩小到7左右。用最大倾角衡量动态品质,用稳态均值看是否有静差,用稳态标准差看平稳性。三个指标汇总成一张表,就能直接支撑「不同参数下运动性能对比」那一节,比贴十几张曲线图说服力强得多。
5. 两轮机器人ADAMS仿真避坑:接触参数发散、穿透与平衡失败的排查
5.1 冷启动瞬间「炸机」:模型一解算就飞出去
现象:仿真从第0步开始,车体猛烈旋转,直接飞出屏幕,结果曲线全是异常大数。原因通常有三个:初始倾角超过了平衡稳定域,10°以上开环必倒;力矩反馈函数第一步就输出极大值,PID瞬间给满;角度单位错,弧度当度用,等效增益被放大57倍。解决顺序:先把初始倾角压到3°以内,再给力矩函数包一层STEP,让输出在0到0.2秒内从0渐变到满值,最后核对状态变量的角度量纲。A同学第一次遇到炸机就是单位问题,弧度当度,模型直接飞。这属于做两轮机器人仿真必经的坑,遇到一次之后就会长记性。
5.2 车轮陷进地面或频繁跳起:接触参数的边界在哪
现象:动画里车轮和地面有穿透,接触力曲线出现大量零值,说明车轮离地了。原因多为接触刚度太低、穿透深度参数设太大,或者仿真步长太粗导致接触检测漏检。解决时按顺序调:把Stiffness提高到1e5到1e6量级,穿透深度降到0.1mm量级,步长收紧到1e-4秒级别。同时检查车轮几何,不要用一条线代表轮子,车轮建薄圆柱体,至少要有真实的宽度。穿透和跳起同时出现时,优先怀疑刚度不足,其次怀疑步长太粗,这两项调完大部分情况都能解决。
5.3 倾角曲线高频抖动:这是数值震荡还是物理抖动
现象:倾角曲线以极高的频率大幅摆动,频率远远超过真实机器人能出现的任何动态。原因可能是Kp过大形成极限环,也可能是输出步长太粗造成的假振荡,更多时候是接触力数值抖动传导到了倾角上。排查先做减法:把Kp降一半,看振幅是否成比例下降;再把输出加密,区分真假。最后看接触力曲线本身,如果接触力毛糙、无规律振荡,那么倾角上的高频分量大概率是数值噪声,用滑动平均处理而不是硬上滤波器。物理抖动和数值抖动的区别是,前者有周期性且频率和车速成比例,后者杂乱无章。
5.4 导出曲线变成“欧拉角跳变”:单位与坐标系的两个旧账
现象:导出的转向角曲线在±180°之间来回跳,明明是一个连续转向过程,曲线却像锯齿。原因是ADAMS输出角度被归一化到-180°到180°范围,连续多圈转向时必然跳变;另外导出时单位制不一致会导致量级对不上,位移曲线放大1000倍。解决:对角度序列做解卷绕,Python里直接调numpy.unwrap,把跳变恢复成连续累计角度;或者在导出前改用累计转角Measure,省去后处理。单位问题则在导出前统一:长度毫米、角度度,导出文件里嵌的单位行不要忽略,先看再读。
5.5 模型越跑越慢、解算器卡死:性能与精度怎么换
现象:仿真进行到一半,步长骤减,进度条几乎不动,CPU占用拉满。原因多是接触反复建立和断开,摩擦在静摩擦与动摩擦之间频繁切换,积分器被迫把步长压到极小。解决:把积分误差放宽到1e-3,刚度降到不穿模的临界值,摩擦的静动切换速度阈值拉开一点,避免频繁切换;删掉不需要的几何细节。还不行,就把仿真拆成两段:先跑1秒平衡稳定段,从稳定点为初值再跑4秒运动段,结果拼接起来用。性能问题本质上是精度要求与接触复杂度的权衡,别追求用1e-6的误差去跑带接触的模型,那会让仿真时间膨胀到无法接受。
6. 参数化与验证技巧:把仿真结果变成可信结论
手动改PID参数再跑仿真,效率太低,而且参数之间相互影响,肉眼调参容易把方向记混。把Kp、Kd、质心高度定义成设计变量,在力矩表达式和几何坐标里引用它们,然后用批量仿真跑一组组合,每跑完一版自动导出倾角CSV,最后用一个汇总脚本收集每组参数的最大倾角与稳态标准差。下面是一个可扩展的批处理框架,run_adams的位置替换成你本机的命令行调用方式即可。
# 批量跑ADAMS仿真并汇总评价指标 runs = [ {"kp": 400, "kd": 20}, {"kp": 600, "kd": 30}, {"kp": 800, "kd": 40}, ] def run_adams(kp, kd): # 替换为你的ADAMS批处理命令/宏调用,返回导出的CSV路径 pass def summary(csv_path): # 复用4.3节的统计函数,返回(最大倾角, 稳态标准差) pass for cfg in runs: csv_path = run_adams(cfg["kp"], cfg["kd"]) print(cfg, summary(csv_path))跑完一组,把参数和指标整理成表,「运动研究」就不再是调一次看一次曲线,而是一张表看完整参数空间。验证方面,把两轮机器人简化成倒立摆模型,写出线性化方程,再把ADAMS测得的倾角响应与线性模型对照。简化模型和虚拟样机在稳定条件上定性一致,比如质心抬到某个高度后两者都要求增大Kp才能稳定,说明虚拟样机可信。与真机对照时,重点不是数值完全一致,而是调参方向一致:真机上加大Kp出现抖动,虚拟样机也要有同样趋势。做这类仿真我有个习惯:每次调参前把.cmd文件和结果CSV按日期存一份,并在一张表里记录参数值和对应现象,否则一周后改了三个参数,连自己都说不清是哪个改动让模型稳下来的。这个习惯救过我很多次。希望帮到你。
本文还有配套的精品资源,点击获取