ARTICLE DETAIL

资讯详情

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

复合机器人ROS二次开发实战:myAGV与mechArm联动从建图到抓取

复合机器人ROS二次开发实战:myAGV与mechArm联动从建图到抓取 复合机器人这几年其实一直不温不火但真正上手玩过的人都知道它才是“机器人能干实事”的最短路径。单独一台机械臂只能固定在工位上给它一片固定工作区单独一台AGV只能把东西送来送去送到之后还得人接手。把移动平台和机械臂组合成一套复合机器人才算打通了“走到哪、看到哪、抓到哪”的闭环。我最近在大象机器人的myAGV移动底盘和mechArm六轴机械臂上做了一轮完整的二次开发从ROS环境搭建到建图导航再到机械臂联动抓取整个过程踩了不少坑也积累了不少经验这篇就把这套开源方案从选型到落地的完整实践整理出来。这套组合特别适合三类人一是刚接触ROS想要一套能吃透的完整机器人平台的在校学生二是做巡检、仓储、实验室自动化相关预研的工程师三是想低成本验证“移动操作”方案的创业者。因为myAGV和mechArm都是开源硬件加开源软件栈文档和社区资料比较全整套调试下来能同时把激光雷达建图、导航避障、机械臂运动规划、视觉抓取这一整条技术栈摸一遍性价比相当高。1. 复合机器人核心价值与方案选型思路1.1 移动操作补上“最后一米”的自动化缺口先说清楚复合机器人解决的根本问题。传统工业机械臂安装在固定基座上工作范围就是臂展画出的那个球体想让它换工位只能重新安装底座。而AGV虽然能到处跑但本质上是个搬运工具没有操作能力。复合机器人的价值就是把两者的能力叠加底盘负责大范围移动机械臂负责局部精细操作中间靠传感器融合和坐标变换把两套系统联系到一起。这个逻辑放在真实场景里很直观。比如一个实验室里要定时抓取培养皿送到不同设备或者一个仓储环境里要从货架不同高度取放物料又或者一个配电房里要按巡检任务操作面板按钮——这些工作都需要机器人先走一段路再执行一个精细动作。复合机器人恰好能把这两个步骤串成一个完整流程。1.2 为什么选myAGVmechArm这套组合选型的时候其实对比过好几套方案。早期市面上做复合机器人的多是工业集成商一套下来十几万起步用的是ABB、KUKA这类工业臂配合顶升式AGV软硬件都封闭学生和中小团队根本碰不到底层。另一类是纯DIY方案自己买底盘、买机械臂、自己写驱动问题是两套系统的时间同步、坐标系标定、协议对接全都要自己造轮子调试周期非常长。大象机器人的这套组合卡在一个很理想的位置myAGV是麦克纳姆轮全向移动底盘自带激光雷达、深度相机、IMU主控支持树莓派和Jetson Nano双版本mechArm是六轴机械臂270mm臂展250g负载自带摄像头同样有树莓派版本。两套硬件都做了ROS驱动封装意味着不用从零开始写串口协议和底层控制可以把精力集中在导航、规划、联动这些真正有意思的问题上。1.3 开源生态决定了你的调试效率我特别看重开源这一点因为它直接影响踩坑时的救援速度。myAGV的ROS驱动包、mechArm的MoveIt配置、官方示例代码全部挂在GitHub上社区里关于Navigation Stack的调参经验、MoveIt规划失败的报错处理、TF坐标偏移的问题都有现成讨论。对于学习者和二次开发者来说能搜到别人踩过的坑比任何宣传材料都重要。另外大象机器人对ROS 1和ROS 2都有适配官方给了我Ubuntu 18.04 ROS Melodic和Ubuntu 20.04 ROS Noetic的两套镜像方案。这意味着你既可以在老版本稳定环境里跑通全流程也能在ROS 2里验证新版Nav2和MoveIt 2的迁移路径学习价值很完整。2. 硬件平台逐项拆解与关键参数解析2.1 myAGV底盘全向移动的核心是麦克纳姆轮myAGV的底盘设计是这套系统里第一个值得研究的地方。它用了四个麦克纳姆轮每个轮子外侧有一圈45度倾斜的辊子通过对四个轮子不同方向和转速的组合可以实现前后平移、左右横移、原地旋转和斜向运动。简单讲普通差速底盘只能前后走和转圈麦克纳姆轮底盘可以像螃蟹一样横着走这在空间狭窄的实验室巡检、仓储货架间穿行场景里优势非常明显。底盘的核心传感器配置是这样的顶部装了一颗激光雷达用于SLAM建图和导航避障前方一颗深度相机用于视觉识别和避障底盘内部有IMU惯性测量单元用于姿态估计轮子上带编码器用于里程计计算。这套传感器组合覆盖了“我在哪、周围有什么、我要去哪”三个导航基本问题。底盘的ROS驱动提供了两种工作模式。一种是订阅/cmd_vel速度指令驱动层把线速度和角速度解算成四个轮子的独立转速这种模式适合用teleop_twist_keyboard手动控制也适合直接接Navigation Stack的move_base输出。另一种是直接发轮速指令进行底层控制适合做里程计标定和运动学测试。日常开发绝大多数时间用的是第一种因为导航框架本身就是基于/cmd_vel设计的接口天然匹配。2.2 mechArm六轴机械臂270mm臂展里的完整运动学mechArm是典型的六自由度串联机械臂六个关节从基座到末端分别是腰关节、肩关节、肘关节和三个腕关节结构上紧凑但覆盖了一个完整的球型工作空间。270mm的臂展听起来不大但在桌面上完成抓取、分拣、码放这类操作绰绰有余250g的末端负载配合一个机械爪或者吸泵能处理大部分学习和轻量工业预研任务。这里我要特别提一下机械臂控制的两个层次这也是很多新手容易绕晕的地方。底层控制是直接操作六个舵机的角度你发一组PWM或者串口指令机械臂摆出一个固定姿态上层控制则是通过运动学求解你要的是末端执行器移动到某个三维坐标控制器反向解算出六个关节应该转到的角度。mechArm的ROS驱动里封装了正运动学和逆运动学求解配合MoveIt可以直接在RViz里拖拽目标点机器人会自动规划出关节轨迹完全不用自己碰求解器细节。2.3 两套系统的供电、通信与物理连接把底盘和机械臂装到一台机器人上看似只是拧螺丝的事实际上要考虑供电和通信两件事。myAGV底盘自带锂电池和稳压模块上面预留了给传感器和上层设备的供电接口mechArm也有独立的电源输入。我的做法是让机械臂用独立电源避免机械臂启动瞬间的大电流把底盘的IMU读数拉偏。这个问题在调试时遇到过一次——机械臂一启动底盘里程计的漂移突然变大排查了很久才意识到是共地电源干扰后来把两者的电源彻底分开问题就消失了。通信方面底盘的主控和机械臂的主控都接入同一个局域网。通过一个轻量级路由器两块开发板用ROS的分布式通信机制互相收发话题。简单说底盘发布里程计和激光数据机械臂订阅目标点指令两边的状态通过同一套ROS时钟同步。分布式通信是ROS最方便的特性之一不用在物理上接一根线网络通了就能协作。3. 软件架构与开发环境搭建实录3.1 系统准备和ROS版本选择我的开发环境是Ubuntu 20.04 ROS Noetic这是目前ROS 1里最稳定的搭配官方对myAGV和mechArm的驱动包也都做了Noetic适配。如果你手上有老版本树莓派的镜像可能是Ubuntu 18.04 Melodic用起来也没问题但Noetic的社区资料更多踩坑时更容易搜到答案。安装ROS本体这一步就不展开了搜官方安装教程即可。重要的是把myAGV和mechArm的驱动源码拉下来本地编译。建议新建一个工作空间专门给复合机器人用避免和系统自带的包冲突。创建完工作空间后把两个仓库的源码放到src目录然后用catkin_make编译。编译过程中如果出现依赖缺失按报错提示逐一把依赖包装上就行这个环节比较耗时但没什么技术难度。3.2 驱动层逐项验证驱动层验证是整个开发过程里最枯燥也最关键的一步。先启动底盘驱动roslaunch myagv_odometry myagv_odometry.launch这条命令会启动底盘的串口通信节点、里程计节点同时把激光雷达驱动也拉起来。启动后可以用rqt_graph看一下话题图正常情况应该能看到/odom、/scan、/cmd_vel这几个核心话题。然后跑teleop键盘控制rosrun teleop_twist_keyboard teleop_twist_keyboard.py按键盘上的按键确认底盘能前后左右横移和原地旋转同时观察RViz里激光数据是否跟着底盘转动而变化。这一步的核心目的有两个一是确认底层驱动没问题二是顺便检查里程计方向是否和实际运动方向一致。我遇到过里程计方向反了的情况现象是RViz里底盘模型往左走实际车往右走最后在驱动配置里把编码器方向参数取反才解决。机械臂部分先启动驱动节点roslaunch mecharm_bringup mecharm_bringup.launch再启动MoveIt配置roslaunch mecharm_moveit_config demo.launch在RViz里用拖拽工具随便拖一个目标点点击Plan机械臂模型会在虚拟空间里规划出一条轨迹再用Execute下发。这里我建议先做虚拟规划确认关节规划正常后再把真实机械臂接入。真实执行时把bringup节点里的virtual参数设为false直接让MoveIt把规划结果发给舵机执行。3.3 TF坐标变换复合机器人的灵魂如果只玩单独的底盘或单独的机械臂都不需要关心坐标变换的问题。但一旦把两者组合起来TF就成了整个系统里最容易出错也最核心的环节。我先把TF的基本概念讲明白。机器人系统里每个部件都有自己的坐标系底盘的激光雷达有一个坐标系IMU有一个坐标系机械臂基座有一个坐标系机械臂末端执行器有一个坐标系。导航的时候move_base要计算的是“目标点在map坐标系下的位置怎么映射到底盘base_link坐标系下”抓取的时候视觉识别得到的目标点是在摄像头坐标系下的要让机械臂末端过去抓必须先把目标点转换到机械臂基座坐标系下这个转换过程靠的就是TF树。myAGV和mechArm联动时标准做法是把机械臂基座坐标系挂载到底盘坐标系下因为机械臂是固定在底盘上的两者之间是一个固定的相对位置关系。在项目里我们定义了一个新的坐标系叫arm_base_link通过静态坐标变换发布节点把arm_base_link和base_link关联起来。这样导航时底盘带着整个“身体”移动机械臂只需要在arm_base_link坐标系下做运动规划两套系统互不干扰又协同工作。TF树查看用这个命令rosrun rqt_tf_tree rqt_tf_tree如果看到哪两个坐标系断连或者某个变换没有发布者联动十有八九会出问题。这块值得花时间仔细排查因为很多“机械臂抓不到东西”的诡异问题最后查到最后都是坐标系对不上。4. 实战全流程从建图导航到机械臂联动抓取4.1 第一步用激光SLAM把工作环境地图建出来复合机器人要干活第一件事是让底盘知道工作环境长什么样这就是建图。myAGV上用Gmapping算法配合激光雷达建二维栅格地图在空旷环境下效果很好对计算资源要求也低树莓派也能流畅跑。建图的启动命令大致是roslaunch myagv_navigation myagv_navigation.launch roslaunch myagv_navigation gmapping.launch然后用键盘控制底盘在环境里缓慢移动。这里有个很重要的技巧建图时速度一定要慢特别是转弯时转太快会导致激光帧匹配错乱地图里出现重影或者墙壁扭曲。我慢慢推着底盘在实验室里绕了两圈大概五分钟建出一张20平方米左右的地图墙体和桌椅轮廓都清晰可辨。地图建好后用map_saver保存rosrun map_server map_saver -f ~/map/my_room保存下来的是一张PGM图片加一个YAML描述文件以后每次启动导航直接加载这张图就行不用重新建。4.2 第二步配置导航参数并让底盘自主移动有地图之后下一步是让底盘能从A点自动走到B点。Navigation Stack的核心是move_base节点它接收目标点融合全局代价地图和局部代价地图信息规划路径并下发速度指令。导航启动roslaunch myagv_navigation navigation.launch然后在RViz里用“2D Nav Goal”工具指定目标点底盘就会自动规划路径并移动过去。这个过程涉及很多参数全局规划器用的A*还是Dijkstra、局部规划器用DWA还是Teb、机器人的膨胀半径设多少、加速度限制是多少。每个参数都会影响导航表现我最初用默认参数时底盘经常在墙角前犹豫不决后来把膨胀半径缩小了2厘米并且把局部规划器从DWA换成了Teb绕行和过窄道的表现明显改善。这一步有一个隐藏的坑值得提前讲myAGV的麦克纳姆轮运动模型和多差速底盘的模型不同Navigation Stack默认的运动模型配置不一定匹配。好在move_base支持通过配置设置全向运动正确的配置下底盘可以一边横移一边调整姿态这比普通底盘只能一边转向一边前进要灵活得多。如果你发现底盘导航时非要原地转向后才肯直行多半是全向运动标志没有打开。4.3 第三步用MoveIt规划机械臂抓取动作底盘能到位之后机械臂的抓取动作是下一个节点。先用MoveIt做运动规划核心流程是定义目标位姿求解逆运动学得到关节角做碰撞检测避开障碍生成平滑的关节轨迹下发执行。在RViz里操作时把机械臂的模型加载进来拖拽末端的交互标记到目标位置点Plan看轨迹是否可行没问题再Execute。MoveIt背后做的是笛卡尔空间的规划它会把末端位姿要求转换到关节空间再在关节空间里插值产生轨迹。如果你要在代码里完成这个动作核心代码逻辑长这样import rospy from moveit_python import MoveGroupInterface move_group MoveGroupInterface(arm_group, base_link) move_group.moveToPose(pose_stamped, gripper_link)这块学的其实是机器人学里正逆运动学和轨迹规划那套东西。MoveIt帮我们省掉了自己写DH建模和IK求解的工作但要知道它生成的轨迹只是经过位置点能不能真的执行成功取决于机械臂的控制精度和响应速度。mechArm用的是数字舵机控制精度在几百微秒级别做慢速精确定位没问题但别指望它像工业伺服电机那样高速高精度。4.4 第四步复合联动让底盘和机械臂配合起来前面每一步单独跑通之后最后就是联动逻辑了。这里有两种实现方式我分享一套简单实用的方案用有限状态机把整个任务串起来状态依次是IDLE待机、NAVIGATING导航中、ARRIVED已到位、GRASPING抓取中、DONE完成。代码逻辑大致是系统初始状态是NAVIGATINGmove_base发布导航目标等到底盘反馈到达目标点后状态切换到GRASPING触发机械臂执行抓取动作序列。机械臂完成抓取后通知主控底盘再规划下一个任务点整个过程自动衔接。这套方案的核心是事件驱动的状态切换而事件来源就是ROSTopic。底盘是否到位可以通过订阅move_base的反馈话题来判断机械臂是否完成动作可以通过监听动作服务器的状态来获得。把这两个消息源接进状态机联动逻辑就通了。我把整个过程写成一张处理流程图描述阶段触发事件执行动作监听话题待机收到任务指令加载地图等待导航目标/initialpose导航中收到导航目标move_base规划并移动/move_base/feedback到位反馈到达目标发布机械臂抓取指令/move_base/status抓取中收到抓取指令MoveIt规划执行抓取/arm_action/status完成机械臂返回初始姿态通知主控进入下一任务/arm_done联动调试的时候我遇到一个很典型的时序问题底盘反馈的“到达目标点”其实是一个模糊信号move_base判定到达后底盘往往还有一个小的减速和稳定过程如果此时立即启动机械臂底盘微小的抖动会被放大到机械臂末端导致抓取位置偏差好几毫米。解决方案是在状态切换时加一个1到2秒的延时或者监听底盘的实时速度话题等速度归零再触发机械臂动作。5. 实际开发中遇到的典型问题与避坑心得5.1 常见问题排查速查表这一节我把开发过程中遇到的高频问题按“现象-原因-解法”的方式整理出来方便读者直接对照排查。现象疑点排查思路与解法底盘建图时地图重影或墙体扭曲建图速度过快或激光帧匹配失败放慢移动速度转弯时尤其要慢检查激光雷达安装面是否松动清空地图重新建导航时底盘频繁急停或绕路代价地图膨胀半径过大或局部规划器参数不当适当缩小inflation_radius把局部规划器切换为Teb调大最大速度限制底盘里程计漂移越来越大编码器方向反了或轮子打滑检查驱动配置里的编码器方向参数确认麦克纳姆轮辊子安装方向一致重做里程计标定机械臂规划出的轨迹走不过去工作空间奇异点或碰撞检测误判调整目标位姿避开奇异点检查MoveIt碰撞矩阵配置尝试给机械臂一个初始偏移姿态机械臂实际位置和RViz模型不一致舵机零点偏移重新校准机械臂每个关节的零点角度必要时在驱动配置里做偏移补偿底盘和机械臂联动时抓取位置偏移底盘未完全停止或TF坐标系偏差到位后延时1-2秒再触发机械臂用rqt_tf_tree检查TF树重新标定arm_base_link相对base_link的偏移量机械臂启动瞬间底盘传感器数据异常供电干扰底盘和机械臂分开供电避免共地大电流干扰5.2 几个特别值得展开的教训先讲定位精度的事。复合机器人最容易让人误判的就是“导航到位了机械臂就能准确抓取”。实际上单纯靠AMCL在二维栅格地图里的定位精度大概在正负3到5厘米这还不算底盘停止时的微小滑移。真实抓取时如果目标物只有厘米级尺寸这点误差足以让机械臂抓空。我尝试过三种改善办法。最简单的办法是在底盘上加一个视觉引导回流先用深度相机识别目标物的实际位置把识别结果作为补偿量叠加到机械臂目标点。第二个办法是加强定位精度在AMCL定位后再用视觉标记物做一次精细校正。第三个办法是机械臂加到点后做一次视觉伺服根据末端相机图像实时调整位置。对于入门开发第一种方案性价比最高改动量小效果又明显。再讲供电的坑。前面提到机械臂和底盘分开供电之后传感器干扰问题消失这件事其实值得展开。复合机器人功耗是两套系统的总和机械臂六个舵机同时大扭矩动作时瞬间电流很可观如果供电模块没有足够的余量电压跌落会导致底盘上的IMU采样漂移、激光雷达数据异常甚至主控重启。评估供电方案时务必要给峰值电流留出至少30%的余量并且把模拟传感器和数字控制器的电源地做好去耦隔离。还有一个关于调试策略的心得。复合机器人系统复杂度高线上问题往往跨模块耦合新手最容易犯的错误是一出问题就到处怀疑到处改参数最后越改越乱。我的习惯是严格遵循“单模块验证再联调”的顺序先确保底盘能遥控、能建图、能导航再确保机械臂能独立规划执行最后才去做复合联动。每个阶段用日志和RViz画面记录当前状态一旦联调出问题先回到上一阶段复现缩小问题范围而不是直接在新问题里乱撞。我个人在实际操作中的体会是这套myAGVmechArm组合最大的价值不在于它能完成多么复杂的任务而在于它在合理的成本范围内把复合机器人涉及的每一个关键知识点——轮式运动学、SLAM建图、导航避障、机械臂运动规划、坐标变换、状态机设计——全部开放出来让你亲手拆解和调试一遍。把这些内容跑通一遍之后你再去看工业级复合机器人系统的设计文档会发现底层逻辑完全一致无非是换成了更高精度的传感器、更稳定的工业总线和更复杂的调度软件。当然如果你打算在这个平台上做更深入的控制算法研究还可以尝试把底盘换成差速模型对比麦克纳姆轮的规划差异或者把机械臂从position控制升级到力控制模式做柔顺操作实验。这套开源平台的边界远不止一篇博文能写完的真正有趣的部分都在你动手之后才会冒出来。
返回列表