ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SolidWorks到ROS:KUKA KR16机械臂URDF导出与夹爪集成实战

SolidWorks到ROS:KUKA KR16机械臂URDF导出与夹爪集成实战 1. 从SolidWorks模型到ROS可动夹爪这条链路到底卡在哪把一台KUKA KR16机械臂从SolidWorks里的静态装配体变成ROS里能被MoveIt!规划、能在Gazebo里动起来的仿真模型再给它装上一副自己设计的夹爪——这件事听起来是一条直线实际做起来是一堆断点。我前后折腾过好几台机械臂的URDF导出KR16这套流程踩的坑尤其典型因为它的本体模型往往来自厂商提供的STEP文件而夹爪又是自己画的两边的坐标系、单位、装配关系全都要重新对齐。先说清楚这篇内容适合谁看。如果你手上已经有一台KUKA KR16的SolidWorks模型不管是自己建的还是厂商给的想把它导入ROS做运动规划或者仿真同时还要挂一个自定义夹爪上去那这篇就是给你写的。如果你连SolidWorks和ROS都还没装建议先把环境搭起来再回来看否则中间很多细节会没有体感。整条链路的核心关键词就是SolidWorks、ROS、KUKA KR16、URDF、MoveIt!这五个词基本覆盖了从建模到规划的全部环节。大多数人卡住的地方其实不是URDF语法本身而是三个隐蔽的断点。第一个断点是SolidWorks装配体的坐标系和URDF的link坐标系不是一回事导出插件只会机械地把每个零件的原点搬过去结果就是机械臂在RViz里姿态全乱。第二个断点是夹爪作为末端执行器它的安装坐标系必须和KR16第六轴的法兰坐标系严格对齐差一点点MoveIt!规划出来的抓取位姿就是错的。第三个断点是质量和惯性参数SolidWorks能算但导出的数值经常因为单位制混乱而离谱导致Gazebo里机械臂要么飘要么抖。我见过太多人在这三步上反复返工先在SolidWorks里改坐标系导出进RViz发现不对回去改再导出来回五六次。其实只要在动手之前把坐标系的规划想清楚后面就是顺水推舟。下面我按实际操作的顺序把整条链路拆开讲每一步都告诉你为什么这么做以及我踩过的具体坑。2. 导出前的坐标系规划决定后面返工次数的关键一步2.1 为什么不能直接点“导出URDF”SolidWorks转URDF的插件常用的有SW2URDF和几个社区版本工作原理很朴素它遍历装配体里的每个零件把每个零件的原点当成URDF里对应link的原点把装配关系转成joint。问题在于你在SolidWorks里建模时零件的原点大概率是随手放的——画个方块原点可能在角上也可能在中心甚至可能在某个草图基准面上。这些原点对建模没影响但对URDF是致命的因为URDF里link的坐标系决定了惯性张量的参考点也决定了joint轴线的位置。KR16这种六轴机械臂每个关节的旋转轴线必须精确落在link坐标系的一个轴上。如果导出后发现RViz里机械臂的关节转起来是歪的八成就是零件原点没对齐旋转轴线。我的做法是在导出之前先在SolidWorks里给每个要作为独立link的零件重新定义坐标系让坐标系的原点落在关节轴线上Z轴或者X轴对齐旋转方向。这一步在SolidWorks里叫“新建坐标系”在“参考几何体”菜单里。具体到KR16它的六个关节轴线关系是这样的J1绕竖直轴转J2、J3、J5是俯仰J4、J6是绕臂的滚转。你在给每个link建坐标系时要让坐标系的某个轴和对应的关节轴线重合。我一般统一让Z轴对齐关节轴线这样在URDF里joint的axis就是0 0 1写起来干净后面调试也直观。2.2 夹爪的安装坐标系怎么定夹爪是挂在KR16第六轴法兰上的所以夹爪的基座坐标系必须和法兰坐标系建立固定的变换关系。这里有个很容易忽略的点法兰坐标系的原点通常在法兰端面中心Z轴指向外侧。你设计夹爪时如果夹爪的安装面就是贴着法兰端面的那夹爪基座坐标系的原点也应该在安装面中心Z轴同样指向外侧这样两个坐标系之间就是一个纯平移可能还有绕Z的旋转没有复杂的旋转矩阵。我建议在SolidWorks里单独给夹爪装配体建一个坐标系命名成gripper_base原点放在夹爪和法兰的接触面中心。然后在KR16的装配体里把夹爪装上去之后再建一个坐标系tool0位置和gripper_base重合。导出的时候tool0就会成为URDF里夹爪link的父坐标系参考点。这样做的好处是后面如果你要换夹爪只需要改夹爪那部分的URDFKR16本体不用动。提示夹爪的张开闭合如果是用气缸或者电机驱动的URDF里可以用mimic标签让两个手指联动只需要给一个主动关节写驱动另一个用mimic joint主动关节名 multiplier1 offset0/跟着动。这个在后面的章节会详细说。2.3 单位制统一毫米和米的血泪教训SolidWorks默认单位是毫米ROS默认单位是米。导出插件一般会做转换但转换得对不对取决于你在SolidWorks里用的单位设置和插件版本。我遇到过最坑的一次是导出的URDF里link的视觉模型尺寸是对的因为插件按比例缩放了mesh但惯性参数里的质量单位没转结果Gazebo里机械臂重了1000倍直接穿模飞出去。所以导出前一定要确认两件事第一SolidWorks的文档单位设置里长度是毫米还是米质量是千克还是克第二导出插件里有没有单位转换的选项如果有选“自动转换到米和千克”。导出之后打开URDF文件随便找一个link的mass值KR16这种级别的机械臂单个大臂的质量大概在几十千克量级如果你看到的是几万那就是克没转如果看到的是零点零几那就是千克转错了。惯性矩阵的对角线元素对于KR16的臂大概在0.1到10这个量级如果差了好几个数量级也要回头查。3. SW2URDF插件的实操细节与导出参数3.1 插件安装与版本匹配的坑SW2URDF这个插件在GitHub上有开源版本但它的兼容性比较挑。我实测下来SolidWorks 2020到2023这几个版本配合对应的插件版本比较稳2024之后的版本有时候会出现导出时崩溃尤其是装配体里零件数量多的时候。如果你用的是比较新的SolidWorks导出前先把装配体里不参与运动的零件比如螺栓、垫片、装饰件压缩掉只留运动链上的核心零件能大幅降低崩溃概率。安装插件的方式很简单把下载的DLL文件放到SolidWorks的插件目录然后在SolidWorks里通过“工具-插件”勾选启用。但这里有个细节插件启用后菜单栏里会出现一个“Tools”或者“Export as URDF”的选项如果没出现检查一下是不是以管理员权限运行的SolidWorks权限不够的时候插件加载会静默失败。3.2 导出时的link和joint配置插件启动后会弹出一个树形界面左边是装配体的零件树右边是URDF的link和joint结构。你需要手动指定哪些零件合并成一个link哪些零件之间是joint关系。对于KR16我的建议是base_link底座固定不动作为URDF的根link。link_1到link_6六个运动臂每个对应一个旋转关节。gripper_base、finger_left、finger_right夹爪的三个部分其中两个手指各是一个独立的link通过移动关节和gripper_base连接。在插件里配置joint的时候要指定joint的类型revolute还是prismatic、轴线方向、以及运动的上下限。KR16的六个关节都是revolute轴线方向根据你在SolidWorks里建的坐标系来定如果坐标系Z轴对齐了关节轴线这里就填0 0 1。上下限从KUKA的官方手册里查KR16的J1一般是正负185度J2是正负155度J3是正负130度J4是正负350度J5是正负130度J6是正负350度。这些数值填错的话MoveIt!规划时会报“joint out of bounds”。夹爪的两个手指关节是prismatic行程取决于你的夹爪设计比如每个手指行程20毫米那上下限就是0到0.02单位米。这里要注意prismatic joint的axis方向要指向手指张开的方向如果方向反了夹爪会往里面夹。3.3 导出后的文件结构检查导出完成后你会得到一个文件夹里面有urdf文件、meshes文件夹存放STL或者DAE格式的模型文件、以及launch文件夹如果插件生成了的话。先别急着往ROS里放在本地做几个检查第一打开URDF文件看robot标签的name属性改成你想要的机器人名字比如kuka_kr16_gripper。第二检查每个link的visual和collision标签visual用的是导出的mesh文件collision有时候插件会简化成包围盒如果你要做精确碰撞检测可以把collision也指向同一个mesh但会拖慢仿真速度折中方案是用简化的几何体。第三检查inertial标签确认质量和惯性矩阵的数值在合理范围。我一般还会在URDF里手动加一个gazebo标签给每个link指定材质颜色不然在Gazebo里全是灰的调试的时候分不清哪个是哪个臂。比如给link_1加红色link_2加绿色以此类推夹爪的手指加个醒目的黄色。4. URDF里夹爪的mimic联动与传动配置4.1 mimic标签的正确写法夹爪的两个手指如果是同步运动的用mimic标签最省事。假设左手指的关节叫finger_left_joint右手指叫finger_right_joint你希望右手指跟着左手指动方向相反一个张开另一个也张开那就在finger_right_joint里写joint namefinger_right_joint typeprismatic parent linkgripper_base/ child linkfinger_right/ axis xyz-1 0 0/ limit lower0 upper0.02 effort100 velocity0.1/ mimic jointfinger_left_joint multiplier-1 offset0/ /joint这里的multiplier-1表示右手指的运动方向和左手指相反因为两个手指是相向运动的。如果两个手指是同向运动比如平行夹爪那multiplier就是1。offset一般是0除非你有特殊的初始偏移。注意mimic关节在MoveIt!里默认是不被规划的也就是说规划器只会规划主动关节被动关节跟着动。如果你在RViz里拖动主动关节被动关节会跟着走但如果你在MoveIt!的规划组里把被动关节也加进去了可能会报错。正确的做法是规划组里只放主动关节被动关节通过mimic自动联动。4.2 传动标签transmission的配置如果你要在Gazebo里用ros_control控制夹爪那还需要在URDF里加transmission标签。这个标签告诉Gazebo哪个joint对应哪个传动接口。对于夹爪的主动关节写法大概是transmission namefinger_left_trans typetransmission_interface/SimpleTransmission/type joint namefinger_left_joint hardwareInterfacehardware_interface/PositionJointInterface/hardwareInterface /joint actuator namefinger_left_motor hardwareInterfacehardware_interface/PositionJointInterface/hardwareInterface mechanicalReduction1/mechanicalReduction /actuator /transmissionKR16的六个关节也要加类似的transmissionhardwareInterface根据你的控制方式选Position、Velocity或者Effort。我一般用Position因为位置控制最直观调试的时候不容易出幺蛾子。4.3 夹爪的碰撞体和视觉体分离夹爪的手指在抓取物体时碰撞检测的精度直接影响抓取是否成功。如果collision用的是完整的mesh手指和物体之间的接触计算会很慢而且容易因为mesh的三角面片太细导致穿透。我的做法是给手指的collision用一个简化的长方体尺寸和手指的实际包络尺寸一致visual还是用精细的mesh。这样在Gazebo里看起来是精细的模型但物理计算用的是简单的几何体速度快很多。具体操作是在URDF里手指link的collision标签里引用一个简单的box几何体而不是mesh文件collision origin xyz0 0 0.01 rpy0 0 0/ geometry box size0.02 0.04 0.02/ /geometry /collision这个box的尺寸要根据你手指的实际尺寸来调origin的偏移要让box包住手指的实体部分。5. 在RViz和Gazebo里验证模型从能显示到能动的距离5.1 RViz里的第一轮检查把URDF放到ROS的包目录下写一个简单的launch文件用robot_state_publisher和joint_state_publisher把模型显示出来。第一轮检查看三件事模型的位置对不对、关节能不能拖动、夹爪的手指能不能联动。模型位置不对的典型表现是机械臂悬空或者陷到地面以下。这是因为URDF的根linkbase_link的原点在世界坐标系的原点而你的模型在SolidWorks里的原点可能不在底座中心。解决办法是在URDF的根link上加一个origin偏移或者在launch文件里用static_transform_publisher把base_link抬到合适的高度。关节拖动的时候如果某个关节转动的方向和你预期相反把joint的axis取反就行。如果关节转动的轴线不对比如应该是绕Z转结果绕X转了那说明SolidWorks里的坐标系没对齐得回去改模型重新导出。这一步没有捷径只能耐心调。夹爪手指的联动在RViz里拖动主动关节看被动关节是不是跟着动。如果不动检查mimic标签的joint名字有没有写错multiplier的正负号对不对。5.2 Gazebo里的物理验证RViz里显示正常不代表Gazebo里能动。Gazebo会加载物理引擎质量、惯性、碰撞体、传动这些参数不对的话机械臂要么瘫在地上要么疯狂抖动。我第一次把KR16放进Gazebo的时候机械臂直接像面条一样软下去了原因是惯性矩阵没填对物理引擎算出来的力矩完全不对。验证的步骤是先不加控制器只把模型spawn到Gazebo里看它能不能稳定地站在地面上。如果它自己往下掉或者抖动检查base_link是不是固定住了加一个gazebo标签里的statictrue/static或者用fixedjoint把它焊在世界坐标系上。然后加载控制器用ros_control的joint_trajectory_controller发一条简单的轨迹看六个关节能不能按轨迹动。最后测试夹爪发一个位置指令看手指能不能张开闭合。Gazebo里还有一个常见问题是模型穿透就是机械臂的某个臂和另一个臂穿在一起了。这通常是collision的几何体太大或者位置偏了。把collision的box或者cylinder调小一点或者把origin的偏移调准。5.3 和MoveIt!的对接模型在Gazebo里能动之后下一步是配MoveIt!。用MoveIt! Setup Assistant加载URDF它会自动识别运动链和规划组。KR16的六个关节作为一个规划组夹爪的两个手指作为另一个规划组或者一个独立的group取决于你的抓取策略。Setup Assistant里要特别注意自碰撞矩阵的配置。默认的自碰撞矩阵会采样很多次对于KR16这种六轴臂采样时间可能比较长。我一般把采样密度调低一点比如默认的10000次降到5000次精度够用时间省一半。另外夹爪的手指和KR16的第六轴之间要设置成“从不碰撞”因为它们在实际中就是装在一起的如果自碰撞矩阵把它们标成可能碰撞规划时会一直报错。配置完成后在RViz里用MoveIt!的MotionPlanning面板拖动目标位姿点Plan看能不能规划出轨迹。如果规划失败先检查起始状态是不是在关节限位内再检查目标位姿是不是可达。KR16的臂展大概是1.6米左右目标位姿如果超出这个范围规划肯定失败。6. 那些让我返工三次的坑与排查思路6.1 导出后模型散架link之间的相对位置全乱这个坑我踩过两次表现是RViz里机械臂的各个臂分家了飘在不同位置。根本原因是SolidWorks装配体里零件的配合关系没有被插件正确识别成joint的origin。插件判断joint origin的方式是看两个零件之间的配合面或者配合轴如果配合是“重合”而不是“同轴”插件可能算不出正确的旋转轴。解决办法是在SolidWorks里把每个关节处的配合改成同轴配合并且确保两个零件的坐标系原点在同轴线上。如果改配合太麻烦还有一个取巧的办法在URDF里手动改joint的origin标签把xyz和rpy调对。但这需要你对每个关节的相对位置有精确的数值一般不如回SolidWorks改配合来得快。6.2 夹爪抓不住东西碰撞体和摩擦系数夹爪在Gazebo里能张开闭合但抓不住物体物体一碰就滑掉。这个问题通常出在两个地方一是手指的碰撞体太小和物体的接触面积不够二是摩擦系数没设。Gazebo默认的摩擦系数是1.0但对于光滑的物体1.0可能不够。你可以在URDF的gazebo标签里给手指的碰撞体加摩擦系数gazebo referencefinger_left mu110.0/mu1 mu210.0/mu2 kp1000000.0/kp kd1.0/kd /gazebomu1和mu2是两个方向的摩擦系数调大能增加抓取的稳定性。kp和kd是接触刚度调大能让接触更“硬”但太大会导致仿真不稳定。我一般从mu10开始试不行再往上加。6.3 MoveIt!规划报“Unable to sample any valid states”这个报错的意思是规划器找不到有效的起始状态通常是因为起始状态本身就在碰撞中或者关节限位设置得太紧。排查步骤是先在RViz里看当前状态机械臂是不是和自身或者环境碰撞了然后检查URDF里的joint limit确认起始角度在限位范围内最后检查MoveIt!的规划组配置看有没有把不该加进去的link加进去了。我遇到过一次是因为夹爪的手指在初始状态下就是闭合的而闭合状态下两个手指的碰撞体互相重叠导致规划器认为起始状态就是碰撞的。解决办法是把初始状态设成手指张开或者在自碰撞矩阵里把两个手指之间设成“从不碰撞”。6.4 SolidWorks导出时崩溃的预防前面提过零件多的时候插件容易崩。除了压缩不相关的零件还有一个办法是分步导出先导出KR16本体确认没问题之后再单独导出夹爪最后手动把两段URDF拼起来。拼的时候注意joint的parent和child要接对夹爪的parent是KR16的link_6child是gripper_base。分步导出的另一个好处是夹爪的URDF可以复用。如果你以后换了别的机械臂只要法兰接口一样夹爪的URDF直接拿过来改一下parent link的名字就行。7. 从仿真到实际的几点经验仿真里跑通了不代表实际机械臂就能用。KR16是工业级的臂实际控制的时候有几个和仿真不一样的地方。第一实际机械臂的关节有减速比和编码器分辨率URDF里的joint limit是理论值实际能到的角度可能略小规划的时候留一点余量。第二夹爪的实际夹持力取决于气源压力或者电机电流仿真里的effort值只是个参考实际调试的时候要从低往高慢慢加。第三实际机械臂的基座坐标系和仿真里的base_link可能差一个安装偏置这个偏置要在实际标定的时候测出来然后更新到URDF或者launch文件里。我个人在实际操作中的体会是URDF的精度决定了后面所有环节的上限。坐标系、质量、惯性这些参数在仿真里差一点可能只是抖动在实际里就是安全问题。所以导出之后花时间把URDF里的数值和SolidWorks里的质量属性对一遍比后面在Gazebo里反复调参要省事得多。最后再分享一个小技巧如果你用的是ROS2URDF的加载方式和ROS1略有不同robot_state_publisher的用法基本一样但launch文件的写法变了。ROS2里可以用Python写launch文件把URDF的路径用PathJoinSubstitution拼出来比ROS1的XML launch灵活很多。另外ROS2的Gazebo插件gazebo_ros和ROS1的不兼容transmission的配置也有细微差别迁移的时候要注意。
返回列表