ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Solidworks模型转ROS URDF:履带机器人仿真配置全流程踩坑指南

Solidworks模型转ROS URDF:履带机器人仿真配置全流程踩坑指南 搞过履带机器人的应该都有体会Solidworks转URDF这条链路听起来就是把三维模型换个格式真到动手的时候坑比想象中多得多。我这台履带巡检机器人结构设计在Solidworks里改了三版等真要把模型接进ROS仿真里跑通又花了大半个星期。今天把完整的配置流程和踩过的坑整理出来给正在做履带机器人、或者准备把机械结构搬进ROS仿真的朋友做个参考。这篇东西不是什么官方教程就是一次真实项目复盘从Solidworks装配体导出URDF到Rviz里看模型、Gazebo里控制差速驱动再到CoppeliaSim做对照仿真全过程怎么配、哪些地方千万不能省、踩坑了怎么定位。适合手里已经有一套履带机器人三维模型、正打算在ROS里做运动仿真或算法验证的机械、控制、算法方向的工程师。1. 项目概述与整体设计思路1.1 为什么非要用URDF先说清楚一个基础问题URDF到底是个什么东西。URDF全称Unified Robot Description Format是ROS生态里描述机器人模型的XML格式。它不单纯存一个三维网格而是把机器人拆成一个个叫link的刚体部件再用joint把这些link连接起来形成一个树状结构。link负责存视觉网格、碰撞几何、惯性参数joint负责存父子关系、运动类型、旋转轴方向和关节原点。举个不太恰当的例子URDF就像一份乐高说明书每个零件长什么样、装在哪个位置、能怎么动全都写得清清楚楚。有了这份“说明书”Rviz才能把你的机器人画出来Gazebo才能把机器人按物理规律跑起来move_base、navigation、moveit这些上层模块才认得你的机器人。做履带机器人尤其绕不开这步因为履带机器人最常见的控制就是左右差速你得把主动轮、从动轮的关节关系定义清楚后续才能接上差速驱动控制器做速度闭环。为什么不直接拿Solidworks导出的STL、OBJ到Rviz里显示因为Rviz和Gazebo认的是link和joint这种语义信息不是光秃秃的网格。你丢一个STL进去它能显示但不知道哪里是轮子、哪里能转、重心在哪、该用哪个坐标系。URDF就是在三维模型和仿真环境之间搭的一座桥。1.2 技术选型与版本搭配这个项目我用的是Solidworks 2021 sw_urdf_exporter插件ROS侧用的Ubuntu 20.04 ROS Noetic。如果你用2022年以后的Solidworks版本可能会遇到插件兼容性问题需要用RosTeam维护的最新版sw_urdf_exporter插件本身没随Solidworks版本自动更新这点后面会说。关于ROS版本我强烈建议新手先用ROS Noetic而不是ROS 2 Humble。不是说Humble不好而是Noetic的教程、社区答案、gazebo插件生态都更成熟sw_urdf_exporter导出的URDF直接就能用不需要额外适配。等跑通一遍流程、理解了URDF结构之后再迁移到ROS 2也不迟。如果实在不想在环境搭建上花时间可以直接用鱼香ROS的一键安装脚本几条命令就能装好ROS发行版和常用工具实测比手动编译源码省事太多这个话题网上资料很多本文就不展开了。整个流程的技术路线是这样Solidworks装配体 → sw_urdf_exporter导出URDFSTL → 本地用check_urdf做语法校验 → Rviz显示验证模型和坐标系 → Gazebo加载URDF做物理仿真 → 如果还想做更复杂的履带物理效果再导入CoppeliaSim做对照。每一步验证通过再走下一步这是后面所有避坑经验的总原则。2. 导出前的准备工作2.1 工具链完整清单动手之前先把工具备齐省得中途卡壳。Solidworks 2021及以上版本建议用SP5这种稳定版sw_urdf_exporter插件从RosTeam官方仓库下载注意校对版本Ubuntu 20.04 ROS Noetic装好urdfdom-tools这是后续做URDF校验的关键工具一个代码编辑器比如VS Code装XML插件方便手改URDFRViz和GazeboROS Noetic里默认都有不用额外装安装命令很简单sudo apt update sudo apt install liburdfdom-tools装完以后check_urdf和urdf_to_graphiz两个命令行工具就能用了。前者检查URDF语法和逻辑错误后者把URDF的link/joint树画成一张图排查结构关系非常直观。2.2 Solidworks模型规范导出前必须检查的几件事很多朋友一上来就直接开插件导出结果模型在ROS里要么是歪的、要么是巨大的、要么压根没轮子折腾半天发现是Solidworks那边没弄规范。这部分我踩过不少坑整理成几条硬性检查项。第一单位必须是MMGS毫米克秒。Solidworks新建零件时默认就是这个单位但有些从网上下载的模型或外包模型会改成英寸导出URDF时所有尺寸都会错乱。检查路径工具→选项→文档属性→单位确保是MMGS。第二坐标系方向要统一。ROS里约定base_link的X轴朝前、Z轴朝上、Y轴遵右手定则指向左侧。而Solidworks的默认坐标系经常是X朝右、Z朝上、Y朝后直接导出的URDF默认把装配体原点当作base_link原点会导致机器人在Rviz里“侧躺”或者“倒挂”。后面会说怎么处理坐标系但建模时就要有意识地把车头方向对齐到装配体的前后方向。第三命名规则。所有零件名、装配体名、特征名一律不能用中文、不能有空格、不能以数字开头。比如左托带轮.SLDPRT这种名字导入URDF后极大概率出问题。我习惯全部用英文下划线命名left_track_wheel、right_track_wheel。这一步偷懒后面就要花成倍的时间去改URDF文件。第四给每个零件设置材质。这一步很多人忽略但它决定了URDF里的inertial标签能不能正确生成。插件导出质量属性时如果零件没设材质密度是默认的惯性矩阵算出来要么全零要么异常Gazebo一加载就报错。检查路径右键零件→材质→编辑材料选个密度合理的材料比如结构钢、铝合金都行。2.3 模型减负先把钻孔、圆角、螺纹藏起来真实机械结构里充满了装饰性特征安装孔倒角、螺丝沉头孔、密封槽、螺纹装饰线。这些特征在Solidworks里看着很专业但对于URDF导出和ROS仿真来说纯粹是负担。原因有三一是特征越精细导出的STL网格面片数越多Rviz加载卡、Gazebo物理计算更卡二是碰撞检测在面对几万个三角面片时计算量会爆炸三是网格文件越大之前我说的单位、路径问题排查起来越麻烦。我的做法是在Solidworks里给每个零件建一个“仿真配置”Configuration把圆角、倒角、螺纹、logo浮雕这些装饰特征全部压缩掉只保留主要外形和安装孔。在装配体层面也做一个简化配置隐藏掉螺丝、垫片、螺母这些紧固件这些零件体积小、数量多但URDF导出时一个不落全给你导出来link数量直接翻倍。有个关键点不是所有零件都要简化。主动轮、从动轮这些将来要参与物理碰撞和驱动的部件外形必须保留得相对完整轮缘和胎面的形状会影响接触力学。壳体、支撑架、电池舱这些外观件则可以大刀阔斧地简化。3. Solidworks导出URDF实操全记录3.1 插件安装与启动sw_urdf_exporter插件的安装不复杂但有几个容易踩的细节。从RosTeam的GitHub仓库下载插件包后解压得到solidworks_urdf_exporter目录。这个目录不能直接双击运行需要放到Solidworks的插件目录下一般是C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\extensions或者用户文档目录下的SolidWorks\extensions。不同版本路径略有差异最简单的方法是在Solidworks里打开工具→插件点浏览直接选中解压出的那个.dll文件它会自动注册。注册成功后菜单栏或者右侧任务窗格里会出现一个“Export as URDF”的按钮。打开你的总装配体在保持装配体处于活动状态的情况下点这个按钮会弹出一个导出面板。面板左侧是link树右侧是属性设置区。这里提醒一句如果按钮是灰的九成是Solidworks版本和插件版本不匹配。比如2023版本配了2020年的老插件基本必翻车。去仓库看一眼releases列表下载对应你Solidworks版本的插件或者直接下最新的main分支实测2021和2023都能用。3.2 坐标系配置是成败关键导出面板打开后第一件事就是确定base_link和它的坐标系。在Solidworks的“参考几何体”里可以新建坐标系点“坐标系”然后依次选原点、X轴方向、Y轴方向、Z轴方向。这里我强烈建议手动建一个坐标系名字就叫base_link_frame而不使用装配体的默认坐标系。怎么建先在装配体里用3D草图画几条辅助线或者直接选已有零件的边线。原点选在车体底面中心X轴方向指向车头Z轴指向上方。这样建出来的坐标系正好符合ROS约定。导出时把这个坐标系绑定到base_link上URDF里base_link的origin就会落在正确位置机器人在Rviz里能平稳地站在地面上而不是歪歪扭扭地躺倒。很多新手在这里图省事直接用了默认坐标系结果Rviz一加载车是竖着的或者车头朝侧面。排查起来还很费劲因为你不是一眼能看出坐标系问题还是网格问题。所以导出前花两分钟把坐标系建对比事后改RPY要高效得多。建坐标系的技巧是先选原点它决定了base_link在空间中的位置再选X轴边线它决定了车头朝向Y轴和Z轴Solidworks会自动用右手定则补齐不需要额外指定。3.3 关节树配置与履带特殊处理坐标系建好之后回到导出面板开始搭建link和joint树。面板左侧默认会列出装配体里所有的零件你需要手动把它们组织成树状结构。根节点是base_link一般是车体。然后把左右主动轮、诱导轮、负重轮、托带轮、其他附件依次挂到base_link下面。每创建一个joint要设置这几项信息Joint Type关节类型。URDF支持fixed、revolute、continuous、prismatic。固定件用fixed轮子用continuous绕轴无限旋转如果要表达关节限位就选revolute并填入limit。Parent Link和Child Link父子关系注意方向Parent是靠近base_link的一端。Origin子link相对父link的坐标变换包含xyz和rpy。在插件里可以直接从Solidworks模型里拾取参考坐标系或者输入数值。Axis关节旋转轴方向。对轮子来说如果主动轮的旋转轴沿车体横向左右方向那么axis是(0, 1, 0)或者(0, -1, 0)具体方向取决于你希望哪个方向旋转为正。履带机器人的关节树设计有它的特殊性。一条履带通常包含一个主动轮驱动轮、一个诱导轮张紧轮、若干负重轮和一个托带轮。如果把这些轮子全部做成active jointURDF会非常碎而且每个轮子都要有独立的inertial仿真的计算量和调试难度都会上升。我的方案是左右主动轮设置成continuous类型的驱动关节左右诱导轮、负重轮、托带轮全部设置成fixed固定到车体上。履带链板则干脆不参与物理仿真只保留视觉显示。这在绝大多数运动学层面的仿真场景下完全够用差速转向、速度控制、路径规划都不受影响。如果你特别想模拟履带打滑、履带张紧这种接近真实物理的效果那就不是标准URDF能解决的了需要引入SDF模型或第三方履带插件。对刚开始做ROS仿真的团队我强烈建议先用简化方案把整条链路跑通物理细节后面再逐步加。3.4 导出参数设置单位比例必须改所有关节配置完成后点击“Preview and Export”按钮。这时会弹出一个保存对话框你需要选择导出目录并设置导出参数。最关键的一项就是单位比例Unit Scale。Solidworks默认单位是毫米导出的STL文件里所有尺寸数值单位也是毫米。而URDF和ROS里的几何单位约定是米。如果直接按默认值导出一个长600mm的车体在ROS里会被读成600米模型大到视角都拉不回来。正确的设置是在导出时把单位比例设为0.001也就是毫米转米的缩放。有的插件版本里这个参数叫Scale或Unit Scale Factor务必确认它是0.001。保存后插件会生成一个文件夹里面包含URDF文件和meshes子目录所有STL网格都会放在里面。文件名建议全英文路径也不能带中文否则后续ROS加载时会报路径无法解析的错误。4. 导出后的ROS侧验证与调试4.1 导出文件结构检查导出完成后你会得到这样一个文件夹结构my_tracked_robot/ ├── robot.urdf └── meshes/ ├── base_link.STL ├── left_track_wheel.STL ├── right_track_wheel.STL └── ...第一件事不要急着开Rviz先打开robot.urdf看看内容。重点检查几点一是mesh路径。URDF里的filename要么是package://格式要么是相对路径。插件默认导出的是相对路径比如meshes/left_track_wheel.STL那你在用的时候就得保持URDF和meshes目录的相对位置不变。二是单位缩放检查每个mesh标签里的scale属性插件通常会在导出时自动加上scale1 1 1但如果你之前手动改过模型单位这个值需要你再确认。三是每个link是否都有visual、collision、inertial三个标签缺一不可。4.2 check_urdf与Rviz快速验证然后运行URDF校验工具这一步能帮你拦截一大半低级错误。cd ~/my_tracked_robot check_urdf robot.urdf如果输出正常你会看到类似这样的信息robot name is: my_tracked_robot ---------- Successfully Parsed XML ---------- root Link: base_link has 6 child(ren)如果哪个joint的父link或子link没对上check_urdf会直接报错告诉你哪一行有问题。此时别急着去改URDF返回Solidworks重新组织一下关节树再导出效率更高。接下来用Rviz做可视化验证rosrun urdf_tutorial display.launch model:$(rospack find my_tracked_robot)/robot.urdf如果是ROS 2用ros2 launch urdf_tutorial display.launch.py model:/path/to/robot.urdf打开Rviz后把Fixed Frame设置为base_link然后在Add面板里添加RobotModel显示组件就能看到机器人了。这时重点观察两件事一是机器人是否平稳“站”在地平面上Z轴是否朝上二是主动轮是否在正确位置车体是否对称。4.3 单位问题的一次深度排查我在这上面栽过一次印象非常深。第一次导出后Rviz里机器人整个大得惊人摄像机拉远了还是一团模糊。我第一反应是Rviz的视角问题调了半天后来用Ruler测量发现一个轮子直径显示600米才意识到是单位搞错了。为什么很多人导出的URDF会大1000倍根源就在Solidworks的毫米单位和ROS的米单位。如果你在导出时没设置0.001的缩放URDF里所有link的origin值会按毫米数值被记录比如轴距350会被记成350米。STL网格里的顶点坐标同理全部放大了1000倍。更麻烦的是如果你在Solidworks里不是用MMGS而是用MKS米千克秒建的模型情况又不同了STL顶点单位是米URDF的scale设置需要是1.0。这就是为什么总有人问“为什么我的模型大了1000倍”或者“为什么我的模型小了1000倍”。排查方法很简单用文本编辑器打开URDF随便找一个link的origin看坐标值和你Solidworks里的实际尺寸差多少倍。如果差了1000倍或者0.001倍就知道是缩放设置错了。改法有两个一是在Solidworks重新导出把单位比例设置成0.001二是手动修改URDF里所有link的origin和mesh的scale。但手动改容易漏尤其当一个URDF有几十个link时我建议直接重新导出一劳永逸。5. 从URDF到物理仿真Gazebo与CoppeliaSim5.1 Gazebo里的碰撞体与惯性处理URDF能在Rviz里正常显示只是第一步。想要在Gazebo里做物理仿真还需要处理碰撞体、惯性和传感器这几件事。碰撞体collision是物理引擎真正用来算碰撞的东西。直接用STL网格当碰撞体会让物理引擎在每一个三角面片上都做碰撞检测履带机器人这种零件多的模型Gazebo跑起来会一卡一卡还会出现车轮抖动、弹跳等怪现象。我的经验是给每个link用简单几何体替代碰撞体。车体碰撞用一个长方体轮子碰撞用圆柱体轴就用小圆柱。URDF里collision支持box、cylinder、sphere这些基础几何体配置很简单但物理计算效率提升一个数量级。inertial标签是另一个高频报错点。Gazebo加载URDF时如果发现某个link没有inertial直接报错Link X does not have an inertial tag。sw_urdf_exporter插件理论上会根据Solidworks里的质量属性自动生成inertia但如果你在建模时没给零件设材质导出的惯性矩阵可能就是占位值或者全零。手动补的办法是给每个link加一个合理的质量估计值和近似惯性矩阵。我一般先用Solidworks里的质量属性算一遍然后把数值填进URDF。Gazebo里还会有一个常见的显示问题所有零件都变成灰色。这是因为默认没有给link指定材质颜色。URDF的visual标签可以填material但Gazebo的渲染需要gazebo referencelink_name标签来指定颜色。比如gazebo referencebase_link materialGazebo/DarkGrey/material /gazebo5.2 差速驱动控制器配置履带机器人在Gazebo里跑起来靠的是差速驱动。这里需要在URDF里加入transmission标签把关节映射到执行器上然后配置ros_control的控制器。首先在URDF里加transmission左右主动轮各配一个transmission nameleft_track_trans typetransmission_interface/SimpleTransmission/type joint nameleft_track_wheel_joint hardwareInterfacehardware_interface/EffortJointInterface/hardwareInterface /joint actuator nameleft_track_motor mechanicalReduction1/mechanicalReduction /actuator /transmission然后在URDF里添加gazebo_ros_control插件Noetic版本gazebo plugin namegazebo_ros_control filenamelibgazebo_ros_control.so robotNamespace//robotNamespace /plugin /gazebo最后配置一个差速驱动控制器的YAML文件mobile_base_controller: type: diff_drive_controller/DiffDriveController left_wheel: [left_track_wheel_joint] right_wheel: [right_track_wheel_joint] publish_rate: 50.0 wheel_separation: 0.35 wheel_radius: 0.06 cmd_vel_timeout: 0.5这里的wheel_separation和wheel_radius必须跟你实际模型尺寸一致。我一开始随手填了数值结果Gazebo里机器人转圈半径和真实模型差了一大截。正确做法是回到Solidworks里量一下左右主动轮中心距以及主动轮的半径。量完填进去再启动控制器。测试方法很简单在终端发布一个线速度和角速度指令看机器人有没有按预期前进和转向rostopic pub -r 10 /cmd_vel geometry_msgs/Twist linear: x: 0.2 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.1如果机器人能按0.2m/s前进、0.1rad/s转弯这条链路就算是彻底通了。5.3 CoppeliaSim作为备选仿真端除了GazeboCoppeliaSim以前叫V-REP也是不少团队的选择。它的优势在于内置了履带track实体可以做出更逼真的履带物理效果。从URDF导入CoppeliaSim非常简单菜单栏File → Import → URDF选择你的robot.urdf就行。CoppeliaSim会自动解析link和joint把URDF的mesh转换为对应的shape关节转换为对应joint。但有几个注意点。一是单位CoppeliaSim内部默认也是米导入时它会按URDF里的单位处理之前如果在Solidworks导出时没有正确缩放到这里同样会出问题。二是材质颜色URDF里没有专门的颜色属性CoppeliaSim导入后所有模型默认白色需要手动刷颜色或贴材质。三是履带CoppeliaSim的Track实体不是URDF直接支持的导入后你需要在车体上重建履带在左侧模型浏览器里找到SimulationModels→components→locomotion→trackedVehicle里面有现成的履带组件把轮子替换成URDF导出的轮子模型即可。履带机器人在CoppeliaSim里调试时最常见的问题是履带链节之间的碰撞会产生高频抖动跑一会儿模型就散架了。这通常不是你的设计问题而是物理引擎迭代步长和碰撞容差设置不当。把仿真步长调小到10ms以内或者给履带链节之间的joint加阻尼就能明显改善。6. 常见问题速查与实操心得6.1 常见问题排查表把这段时间遇到的典型问题整理成一张速查表照着排查能省不少时间现象大概率原因解决办法Rviz里模型巨大到看不到Solidworks毫米单位没转米重新导出时设置单位比例0.001机器人侧躺或倒立base_link坐标系方向不对在Solidworks里重建设置好X前Z上的坐标系只有车体没有轮子meshes路径错误或STL缺失检查URDF里的mesh相对路径确认meshes目录在正确位置轮子不动joint type设成了fixed把主动轮关节改成continuous或revolute轮子旋转方向反了axis方向填反取反axis向量例如把(0,1,0)改成(0,-1,0)Gazebo报没inertial零件没设材质或插件没生成在Solidworks里设材质重新导出或手动补充inertialGazebo物理抖动严重collision用了太精细的网格用box、cylinder等基础几何体代替STL做碰撞体履带链节乱飞每个链节都做了独立link但没固定把履带链节视觉化用fixed依附车体不做物理参与Rviz找不到mesh文件path是package://但没有包改用绝对路径或正确配置package除了表格里的问题还有一个隐性坑想单独说URDF里关节的limit参数。如果差速驱动控制器下发速度指令后轮子转起来僵硬或者直接不动先检查limit里的velocity值。插件导出的关节有时默认速度上限特别小只有0.1控制器发多大的指令都会被限制在0.1以内看起来就像机器人卡住了。把velocity那个值调大比如10问题立刻就没了。6.2 我的几点实操心得最后分享几条偏“心法”层面的建议这些是我反复折腾之后总结出来的。第一个建议每次导出前把Solidworks模型另存一份简化版。我导第一版的时候整个装配体有七八十个零件导出STL花了近十分钟URDF文件大得编辑器都卡。后来我把装饰特征全部压缩隐藏了所有标准件link数量从七十多个降到十几个导出只用了十几秒仿真的运行流畅度也明显提升。我做成了习惯每次模型有结构改动都在原图上标好版本号再另存一份干净的导出专用文件坚决不在原始装配体上直接导出。第二个建议一次只改一个东西。我之前总想着一次把所有问题都修完结果模型又大又歪、轮子还不转三个问题交叠在一起根本不知道从何查起。后来改成先解决单位问题模型大小正常了再解决坐标系问题车正了最后解决关节问题轮子转了。每改一步就重新check_urdf Rviz验证定位问题的效率高很多。第三个建议导出后的URDF文件夹打包压缩存档。每次仿真跑通一版就把URDF和meshes目录整体打个压缩包命名带上日期和状态比如robot_v1_20250120_ok。这个习惯在一次迭代中救过我新改了一版结构结果怎么调都不对最后翻回去对比旧版本才发现是某个joint的axis方向被我不小心改反了。没有存档的话这种问题排查起来非常绝望。从Solidworks到URDF再到ROS仿真这条链路最大的门槛不在工具而在对模型结构、坐标系统一、物理参数这三件事的理解。把每一步都踏踏实实走完履带机器人跑到仿真环境里真的会给你带来非常大的成就感。我至今保留着导出一版完整URDF后先打个包再继续调的习惯这个习惯值得每一个搭机器人仿真链路的人养成。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进