ARTICLE DETAIL

资讯详情

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

Gazebo仿真中宇树GO2接入Livox Mid360激光雷达完整配置指南

Gazebo仿真中宇树GO2接入Livox Mid360激光雷达完整配置指南 最近在帮团队做宇树机器狗GO2的导航仿真预研坦白说机器狗本体在Gazebo里跑起来并不难真正让我折腾到凌晨的是给GO2外接的那颗Livox Mid360。市面上关于这块的教程要么太零散要么只讲了真机驱动很少把Gazebo仿真里的完整配置链路讲清楚。这篇就把我从零到一把Mid360接入Gazebo的完整流程、参数选择、踩过的坑和最终稳定出点云的配置方式一次性写清楚给准备在仿真阶段就接入Mid360做SLAM和导航验证的朋友一个可以直接抄的作业。这篇文章适合几类人已经有GO2的URDF模型、想在Gazebo里搭一个带激光雷达的仿真环境正在做机器人导航方案预研打算用Mid360做感知传感器或者已经试过一些雷达插件、但点云出不来或形态不对、卡在版本和配置上的人。如果你只是想在真机上跑livox_ros_driver2这篇文章也会有一定参考价值但重点还是在Gazebo仿真链路。1. 先说结论GO2仿真里为什么非要单独接Mid3601.1 GO2自带传感器和Mid360的差距宇树GO2本身是带有深度相机的在Gazebo仿真里直接使用官方URDF通常也能看到深度相机的点云输出。但深度相机的视场角窄、量程短做近距离避障可以想验证大范围建图、回环检测、导航重定位这些算法数据就明显不够用了。Mid360是Livox系列里专门为机器人设计的混合固态激光雷达。它的核心亮点是水平方向360度覆盖垂直视场59度量程最远40米而且是非重复扫描方式。这意味着随着时间累积点云能越来越密地覆盖视场内的物体不是传统机械雷达那种均匀一圈一圈转出来的形态。在实际项目中很多人给GO2外接雷达会优先考虑Mid360因为体积小、重量轻、功耗低在四足机器人这种对载荷敏感的平台上有明显优势。那么在仿真阶段如果直接把传感器换成普通2D激光雷达插件物理特性完全对不上后面算法迁移到真机时就会出问题。所以仿真里不能偷懒要尽可能贴近Mid360的几何参数和扫描特性。1.2 我先定的技术路线我最终采用的路线是从宇树官方开源仓库拿到GO2的URDF描述文件在URDF里手动添加一个Mid360雷达的link和joint把Gazebo传感器插件挂在这个link下配置成接近Mid360参数的ray或gpu_lidar传感器然后启动一个带障碍物的世界在RViz里验证点云输出最后把点云话题送到SLAM算法里去测试。这条路线没有用特别花哨的组件核心就三个字“先跑通”。如果一开始就去研究非重复扫描的精确建模会被细节拖死。我的建议是先用最接近物理参数的通用激光雷达插件把链路打通再评估是否有必要切换到更复杂的仿真方案。1.3 最容易翻车的几个环节提前说我在操作过程中遇到的主要坑集中在四类版本环境错配、坐标系不统一、传感器插件参数不合理、点云数据量太大导致仿真卡死。这四个问题下面都会展开讲。提前有个心理预期后面就不至于被某一个坑卡住半天。2. 环境搭建与仿真方案选型2.1 版本组合是成败的关键这句话我说在前面版本选错了后面所有配置都是白费。很多人在Gazebo里装雷达插件翻车根源不是代码问题是ROS版本和Gazebo版本不匹配。先说我最推荐的一套组合Ubuntu 20.04 ROS Noetic Gazebo 11。这套组合的优点在于ROS Noetic官方支持的就是Gazebo 11gazebo_ros_pkgs插件完整度最高而且GO2官方有对应的ROS1包unitree_ros很多现成模型和配置都是按这个环境写的。网上能搜到的大部分雷达仿真教程也基于这个组合遇到问题容易查到解决方案。如果你因为其他原因必须用ROS2也有可行路径Ubuntu 22.04 ROS2 Humble然后手动安装Gazebo Classic 11也就是gazebo11用ros-humble-gazebo-ros-pkgs。但是要注意Humble默认带的是Gazebo Fortress也就是gz sim那个环境下很多为Gazebo Classic编写的传感器插件无法直接使用。简单说用Humble的时候别去碰默认的Fortress老老实实install gazebo11否则雷达仿真的配置工作量会翻倍。下面做了个版本组合对比方便按自己情况选组合推荐度说明Ubuntu 20.04 Noetic Gazebo 11五颗星插件最全资料最多GO2的ROS1包可用Ubuntu 22.04 Humble Gazebo Classic 11四颗星能用gazebo_ros_pkgs需要手动装gazebo11Ubuntu 22.04 Humble Gazebo Fortress一颗星很多旧插件不可用雷达仿真会很痛苦Ubuntu 18.04 Melodic Gazebo 9两颗星太旧编译新功能包容易踩坑2.2 雷达仿真插件怎么选确定好环境之后下一个选择是雷达仿真方案。我在实践里用过两种各有优缺点。第一种是Gazebo自带的gpu_lidar也就是GPU激光雷达仿真。它把激光雷达的每条射线放到GPU上并行计算性能好配置简单修改一下sensor参数就能近似模拟Mid360的视场角范围。缺点是它模拟的是理想化的机械旋转雷达射线分布是均匀的非重复扫描的形态模拟不出来。但对于大部分SLAM算法验证来说这个近似已经够了。第二种是Livox官方关联的开源仿真包livox_laser_simulation它能在Gazebo里模拟非重复扫描的点云分布形态更贴近真实Mid360的数据特征。缺点是编译和使用麻烦兼容性一般在较新的Gazebo版本上可能出现插件加载失败而且计算开销大点云数量多了之后仿真帧率会明显下降。我的建议是不要一上来就死磕livox_laser_simulation。先用gpu_lidar把整个流程跑到能出点云、能跑SLAM把雷达和算法的链路验证完再去考虑升级到非重复扫描仿真。很多时候算法验证并不需要100%还原真实点云细节均匀扫描的点云反而更容易调试。2.3 依赖安装清单以Ubuntu 20.04 Noetic为例基础的依赖安装如下sudo apt update sudo apt install ros-noetic-gazebo-ros-pkgs ros-noetic-gazebo-ros \ ros-noetic-gazebo-msgs ros-noetic-gazebo-plugins \ ros-noetic-robot-state-publisher ros-noetic-xacro \ ros-noetic-rviz ros-noetic-tf2-tools如果后面要编译livox_laser_simulation需要拉取源码并自行编译cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_laser_simulation.git cd ~/catkin_ws catkin_make这里提醒一句git拉取慢是很常见的情况不用死等可以直接从网页下载压缩包再解压到src目录效果一样。如果编译过程中出现livox相关依赖缺失注意看提示具体缺哪个库手动装上再重新编译。3. 在GO2的URDF里把Mid360挂上去3.1 准备好GO2的模型文件宇树官方在GitHub上有unitree_ros和unitree_ros2仓库里面包含GO2的URDF描述。下载之后把go2_description相关包放到工作空间编译如果没有报错就可以在RViz里看到一个完整的机器狗模型。我用的时候发现直接拿官方URDF来改并不友好因为文件里包含的信息太多腿部关节、传感器、控制器参数混在一起。更好的做法是新建一个自己的xacro文件把官方模型include进来再在xacro里追加雷达的link和joint。这样既不动原始文件又方便以后调整安装位置。这里给一个xacro结构示例具体名称和路径要按你实际拉下来的包来改robot namego2_with_livox xmlns:xacrohttp://www.ros.org/wiki/xacro xacro:include filename$(find go2_description)/urdf/go2.xacro / !-- 雷达link和joint写在这里 -- link namelivox_mid360_link ... /link joint namebase_to_mid360 typefixed ... /joint /robot3.2 给Mid360建立link和固定joint接下来是给雷达建立一个物理描述。Mid360是个圆柱体外形直径大概8.7厘米质量265克左右。在URDF里其实不用把外观做得多精细用一个圆柱体来表示就足够了重点是坐标系和惯性参数要合理。我这里写的link定义可以参考link namelivox_mid360_link visual geometry cylinder radius0.0435 length0.058/ /geometry material nameblack/ /visual collision geometry cylinder radius0.0435 length0.058/ /geometry /collision inertial mass value0.265/ inertia ixx0.0001 iyy0.0001 izz0.0002 ixy0.0 ixz0.0 iyz0.0/ /inertial /link然后需要把这个link固定到GO2的base_link上。这个固定joint就是雷达的安装位置一定要想清楚装在机器狗哪个位置。我实际是把雷达装在GO2头部前上方也就是base_link往前大概0.1米、向上0.2米左右的位置这样水平扫描时不会被身体挡住太多。joint namebase_to_mid360 typefixed parent linkbase_link/ child linklivox_mid360_link/ origin xyz0.1 0 0.2 rpy0 0 0/ /joint需要注意URDF中固定joint的origin是子link坐标系在父link坐标系中的位姿。如果你想让雷达稍微前倾以便前下方地面能被扫到可以把rpy中的pitch设置成一个小角度比如0.02弧度。但是我建议在和真机安装姿态保持一致的前提下做这个调整否则仿真数据迁移到真机时坐标系就对不上了。3.3 配置Gazebo雷达插件这一步是整个配置流程的核心。雷达link建好之后需要在gazebo标签里给它挂一个传感器插件。我常用的是gpu_lidar原因是性能好、配置简单。下面的配置是我在Gazebo 11里验证过的模板gazebo referencelivox_mid360_link sensor typegpu_lidar namemid360_lidar_sensor pose0 0 0 0 0 0/pose visualizetrue/visualize update_rate10/update_rate ray scan horizontal samples720/samples resolution1/resolution min_angle-3.141592/min_angle max_angle3.141592/max_angle /horizontal vertical samples32/samples resolution1/resolution min_angle-0.122173/min_angle max_angle0.907571/max_angle /vertical /scan range min0.1/min max40.0/max resolution0.01/resolution /range /ray plugin namegazebo_ros_lidar_controller filenamelibgazebo_ros_gpu_laser.so topicName/livox/lidar/topicName frameNamelivox_mid360_link/frameName pointCloudName/livox/pointcloud/pointCloudName /plugin /sensor /gazebo这里每个参数我都解释一下知道含义才能调出自己想要的雷达。update_rate是雷达频率Mid360工作频率一般是10Hz所以设10就够。horizontal下面的samples是水平方向一个扫描周期内的射线数量。720表示360度范围分成720条相当于0.5度一条。这个值影响点云密度也直接影响性能。min_angle和max_angle范围设置成-3.141592到3.141592也就是正负180度合成360度覆盖。vertical下面的samples是垂直方向的射线数量min_angle和max_angle对应Mid360的垂直视场。Mid360的垂直视场是59度角度范围是-7度到52度。换算成弧度就是-0.122173到0.907571。这是Mid360一个很关键的参数和常见的2D激光雷达完全不一样如果照搬普通雷达的垂直配置比如正负15度那仿真出来的数据形态就和真机差得远了。range里的min和max对应雷达的量程。Mid360最小0.1米最远40米我这里就按这个来设。插件部分发布的topic是/livox/lidar和/livox/pointcloudframeName必须和URDF里的link名字一致写成livox_mid360_link。这一步很容易出错如果名字对不上RViz里即使能看到模型点云位置也会错乱。3.4 用launch一键启动并在RViz验证传感器配置好后launch文件把世界、GO2模型、RViz一起拉起来。我通常会写一个launch结构大概是launch include file$(find gazebo_ros)/launch/empty_world.launch arg namepaused valuefalse/ arg nameuse_sim_time valuetrue/ arg namegui valuetrue/ /include !-- 发布机器人的URDF和TF -- param namerobot_description command$(find xacro)/xacro $(find go2_with_livox)/urdf/go2_with_livox.xacro/ node namerobot_state_publisher pkgrobot_state_publisher typerobot_state_publisher/ node namespawn_model pkggazebo_ros typespawn_model args-urdf -model go2 -param robot_description -x 0 -y 0 -z 0.2/ node namerviz pkgrviz typerviz/ /launch启动之后先在RViz里把Fixed Frame设置为base_link添加PointCloud2显示话题选/livox/pointcloud。如果一切正常会看到机器狗周围的障碍物点云。在Gazebo窗口里也能看到雷达射线射线撞到物体会形成点云。到这里Mid360的仿真链路就算初步打通了。第一次运行时建议把sensor里的visualize设成true这样可以直观看到射线是否正确。确认无误后再改成false减少UI开销。4. Gazebo仿真实操中的高频坑位4.1 雷达有射线但没有点云数据这个问题我碰到过不止一次表现是Gazebo场景里能看到雷达射线说明ray sensor在正常计算但RViz里就是没有点云。原因通常是ROS插件没有正确加载或者话题名对不上。排查思路是固定的先看插件是否加载成功启动时终端有没有报错找不到libgazebo_ros_gpu_laser.so之类的信息。再看话题名称rostopic list里有没有/livox/pointcloud没有的话用rostopic list | grep livox看一眼实际话题名。最后用rostopic hz /livox/pointcloud查看发布频率如果显示0说明插件内部有问题改检查frameName和topicName是否都配置正确。另一个容易被忽略的点是Gazebo里模型的link和joint必须已经正确加载。如果固定joint写错雷达link没有跟着base_link动传感器姿态会异常点云也可能无法正常显示。4.2 点云旋转、错位、飞到远处点云数据有、但位置不对基本可以锁定是坐标系问题。最常见的两个原因一是TF树里找不到雷达坐标系二是frameName参数和URDF里的link名不一致。解决方法是统一frame。雷达插件的frameName必须和URDF里定义的链名称完全一致包括大小写。RViz里的Fixed Frame最好先设为base_link确认机器狗模型和点云相对位置一致后再切换到livox_mid360_link。另外要注意如果是在launch文件里通过spawn_model加载机器人robot_state_publisher必须正常发布TF。用rosrun tf view_frames生成TF树查看livox_mid360_link是否存在、是否挂在base_link下。TF树里看不到这个坐标系点云就一定对不上。4.3 仿真卡顿严重点云密集到掉帧gpu_lidar虽然用GPU计算但射线数量设置不合理时同样会卡。720乘以32那就是23040条射线每帧输出23040个点10Hz下来每秒23万个点。这个数据量已经不小了如果再开多个传感器或者加载复杂地图Gazebo帧率会明显下降。解决方式有三种。第一降低samples数量水平设360、垂直设16点云密度肉眼看起来也还在。第二在点云出来后加一个体素滤波节点把点云降采样比如VoxelGrid的leaf size设0.05米。第三让RViz的PointCloud2显示使用Decay Time或者降低显示分辨率也能减少渲染压力。实测下来我用水平720、垂直32、10Hz的点云跑Fast-LIO类算法计算负载还能接受只是Gazebo的实时性会掉到0.8左右。如果只是验证算法链路把垂直降到16实时性会好很多。4.4 livox_laser_simulation编译不过或加载不了livox_laser_simulation这个包在Gazebo 9上相对稳定但在Gazebo 11上偶尔会出现插件加载失败的现象。编译时还会遇到各种依赖缺失。我的建议是不要在一个环境里反复折腾先确认Gazebo版本再编译对应的分支。如果实在编译不过还有一个替代思路保留gpu_lidar作为传感器另外写一个节点对点云做时间累积来模拟非重复扫描。这样虽然不够精确但能大体复现“点云越来越密”的效果而且完全可控。这种“伪非重复扫描”方案在算法验证阶段是够用的。4.5 地面扫不到SLAM容易退化Mid360垂直视场向下只有7度向上是52度。这意味着雷达平放时能看到很大范围的上方场景但近距离地面覆盖很少。在Gazebo里如果直接把雷达水平装在GO2头顶机器狗附近的地面点云会很少跑SLAM时特征不够定位容易飘。解决办法和真实机器上的处理方式一样让雷达稍微低头。在joint的origin里把rpy设置成pitch约0.02到0.05弧度也就是前倾1到3度。这样雷达的垂直视场能覆盖到前下方地面SLAM特征会更充足。调整后记得同步修改TF确保雷达坐标系和视觉模型一致。5. 验证完雷达之后还能做什么5.1 把点云接给SLAM算法Mid360的仿真点云话题接好之后最直接的应用就是跑SLAM。比如Fast-LIO系列需要接收PointCloud2格式的点云话题只要把话题名改成/livox/pointcloud坐标系设成livox_mid360_linkIMU话题用GO2仿真里的imu数据就能在Gazebo环境里做激光惯性里程计验证。这个阶段有一个心得仿真的好处是可以制造“理想条件”和“退化条件”两组数据。先用理想环境验证算法框架通顺再逐步往环境里增加障碍物、改变雷达姿态看算法在哪些场景下会退化。真机上不方便做的实验在仿真里可以反复试成本几乎为零。5.2 接入导航和避障框架如果跑完SLAM后还要做导航验证可以把雷达点云或转换后的LaserScan接到move_base或Nav2框架里。需要注意的是Mid360输出的原始数据不应该直接等同于2D LaserScan使用因为它包含多线垂直视场的点云。通常做法是从点云里提取一定高度范围的数据投影成2D代价地图。这个投影和过滤逻辑最好提前在仿真里验证因为后面迁移到真机时这部分代码几乎不用改换的只是数据来源。我习惯把所有过滤参数放到launch文件和yaml参数文件里不要硬编码到节点里。5.3 参数统一管理的小建议做完整套配置后我发现一个很实用的技巧把雷达的frame名、话题名、安装位置、前倾角这些参数集中放到一个yaml文件里再通过launch加载。这样后续无论换仿真环境还是切换算法框架都只需要改一处不会出现改了URDF忘了改算法配置的情况。我自己就是吃了这个亏之后才改的。一开始雷达frame名在URDF里叫livox_mid360_link在SLAM配置里写成了mid360_link结果排查了半天最后发现只是name不一致。集中管理参数之后这类低级错误基本不会再犯。最后再说一个我自己常用的调试方法在Gazebo里把雷达的visualize打开配合RViz一起看一个看射线物理覆盖范围一个看点云输出结果两边对照能很快定位问题出在传感器计算环节还是ROS发布环节。后面做复杂环境测试时也会在场景里放一些不同反射率的物体观察点云形态变化。这个技巧在仿真阶段养成习惯后真机调试会顺畅很多。
返回列表