ARTICLE DETAIL

资讯详情

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

diliverycar(三)

diliverycar(三) 一、整体概念今天的主线已经从“装 ROS、打通主从机通信”正式进入了小车代码检查 → 激光雷达验证 → SLAM 建图启动 → TF 树排错目前已经确认ROS 主从通信是通的Ubuntu(car) 能看到小车发布的话题激光雷达/scan也能正常收到数据Gmapping 已经能够启动。现在真正卡住的是Gmapping 收到了激光数据但缺少正确的odom → base_link动态 TF因此一直丢弃激光消息地图还出不来。一些概念1.SLAMsimultaneous localization and mapping同步定位与建图小车第一次进入一个陌生场地一边判断自己在哪一边把周围墙障碍物通道画成图2.Gmapping是一种2D激光SLAM算法odom是里程计odometry的缩写3.TF理解成ROS里的“坐标系关系表”小车身上不只有一个坐标系比如1map整个地图坐标系2odom小车从启动位置累计出来的里程计坐标系3base_link小车车体中心坐标系4base_laser_link激光雷达自己的坐标系上面四个应该串成一条树这样ROS才能算这面墙在整个地图中的哪个位置然后odom-base_link是地面参考系-小车这个是动态TF因为小车会跑而base_link -base_laser_link是小车 -雷达这个是静态TF因为雷达固定安装在车上所以基本不变二、今天先确认了项目工作空间和代码结构在小车 Bitvise 终端里你执行过source ~/robot_ws/devel/setup.bash然后确认rospack find pharmacy_pkg rospack find robot_navigation能找到/home/EPRobot/robot_ws/src/pharmacy_pkg /home/EPRobot/robot_ws/src/robot_navigation说明智慧药房相关 ROS 包已经存在于小车工作空间中而且 ROS 能识别这些包。还查看了ls ~/robot_ws/src/pharmacy_pkg/launch ls ~/robot_ws/src/robot_navigation/launch其中比较重要的 launch 文件包括pharmacy_pkg: detect.launch export.launch smart_pharmacy_demo_init.launch以及robot_navigation: robot_slam_laser.launch robot_lidar.launch robot_navigation.launch robot_race_init.launch move_base.launch ...所以后面的调试不是“随便找一个 Python 跑”而是优先顺着已有的 ROS launch 结构跑。三、思路与流程结合老师讲的比赛流程你们现在单车阶段最合理的顺序是先确认小车能动 ↓ 确认激光雷达 ↓ SLAM 建图 ↓ 保存地图 ↓ 设定坐标点 ↓ 导航到定点 ↓ 再接二维码识别 ↓ 根据二维码选择 A/B/C 坐标 ↓ 语音播报、虚假二维码判断等老师提到的“最优路径”“全局/局部路径规划”“坐标点”“二维码判断”“激光雷达避障”等实际上都依赖前面的地图、定位、导航链路。所以目前的主线任务定成先把 Gmapping 建图跑通再谈定点导航和二维码。四、今天确认了激光雷达确实正常在 Ubuntu(car) 端你先执行rostopic list | grep scan能看到/scan /scan_filtered然后rostopic info /scan返回Type: sensor_msgs/LaserScan Publishers: /lslidar_driver_node Subscribers: /laser_filter说明/lslidar_driver_node正在发布原始雷达数据/laser_filter正在订阅并处理雷达数据。一开始执行rostopic hz /scan出现no new messages后来解决主机名/网络问题后再测已经出现average rate: 9.999也就是大约10 Hz。这说明雷达本身是正常工作的。五、rostopic echo -n 1 /scan看到的东西是什么后来执行rostopic echo -n 1 /scan已经成功返回了一整帧激光数据。其中你看到frame_id: base_laser_link angle_min: 0.0 angle_max: 6.283... angle_increment: ... range_min: 0.1 range_max: 100.0 ranges: [...]这可以理解成雷达围着自己转一圈对不同角度分别测距离。ranges里面的大量数值例如0.62 0.71 1.08 5.2 7.1 inf表示不同方向测到的距离。其中inf表示该方向没有测到有效障碍物或者距离超出有效范围。所以这一阶段可以明确记激光雷达驱动正常ROS 能收到实际 LaserScan 数据。六、今天真正开始启动 SLAM 建图小车端执行source ~/robot_ws/devel/setup.bash roslaunch robot_navigation robot_slam_laser.launch默认配置里原本使用cartographer但是启动时出现ERROR: cannot launch node of type [cartographer_ros/cartographer_node] ERROR: cannot launch node of type [cartographer_ros/cartographer_occupancy_grid_node]说明当前系统没有安装cartographer_ros所以后来改用roslaunch robot_navigation robot_slam_laser.launch slam_methods:gmapping这样成功启动了gmapping (gmapping/slam_gmapping)因此目前用的是Gmapping 建图方案。七、今天发现了重复 ROS 节点问题启动过程中出现过Shutdown request received. Reason given for shutdown: new node registered with same name例如/base_to_laser /robot_state_publisher /lslidar_driver_node /laser_filter /base_control这个提示的意思是ROS Master 发现了两个同名节点。ROS1 中同一个 Master 下不能同时存在完全相同名字的节点后启动的节点可能会把之前那个节点挤掉。今天检查代码后发现robot_navigation这套启动链里确实存在一些重复启动的可能性。特别是base_control有不同实现eprobot_start/art_racecar.py以及huanyu_robot_start/art_racecar.py这是后续需要继续整理的代码结构问题。不过目前还不是最主要的卡点。八、Gmapping 当前最核心的报错虽然 Gmapping 启动成功但一直出现MessageFilter [targetodom]: Dropped 100.00% of messages so far.这句话非常关键。意思不是“激光没有数据”。因为我们已经确认/scan正常 10 Hz。真正的意思是Gmapping 收到了激光数据但是它无法把这帧激光数据转换到odom坐标系所以全部丢掉了。九、今天用 TF 排查发现了“两棵树”你后来执行rosrun tf tf_echo odom base_link返回Could not find a connection between odom and base_link because they are not part of the same tree.然后它列出了很多 frame。可以大致理解成现在 TF 关系是map ↓ odom是一棵树。而base_link ↓ base_laser_link ↓ 其他车体 frame是另一棵树。中间缺了一条odom → base_link所以整个 TF 没连起来。而 Gmapping 真正需要的是map ↓ odom ↓ base_link ↓ base_laser_link只有这条链完整Gmapping 才知道“雷达现在位于地图里的什么位置”。十、为什么odom → base_link不能用静态 TF 随便补这点今天也搞清楚了。像base_link → base_laser_link这种关系是固定的。因为雷达安装在车上的位置不会随着车运动改变。这种可以用static_transform_publisher但是odom → base_link不是固定关系。因为小车一旦移动它会不断变化例如开始 odom → base_link (0, 0) 往前走 1 m odom → base_link (1, 0)所以这必须由小车底盘里程计动态发布。不能用一条静态 TF 硬补否则地图会错误。十一、今天找到了负责发布 odom TF 的代码搜索grep -Rni is_pub_odom_tf ~/robot_ws/src成功找到了eprobot_start/script/art_racecar.py代码里有类似self.is_pub_odom_tf rospy.get_param(~is_pub_odom_tf, false)并且后面会判断if self.is_pub_odom_tf true:也就是说是否发布odom TF是由 ROS 参数~is_pub_odom_tf控制的。如果没传这个参数它默认就是false十二、还发现官方启动文件里本来就会开启它搜索结果里发现EPRobot_test_odom.launch里面是param nameis_pub_odom_tf typestring valuefalse/而EPRobot_start.launch里面明确是param nameis_pub_odom_tf typestring valuetrue/说明官方设计本来就支持发布 odom → base_link TF所以目前问题并不是功能不存在而是我们现在robot_slam_laser.launch这条启动链没有正确把这个参数传给真正运行的base_control节点。十三、今天尝试修改robot_lidar.launch实际小车上的文件是/home/EPRobot/robot_ws/src/robot_navigation/launch/robot_lidar.launch不是 Ubuntu(car) 里面的/home/diliverycart/...这个区分今天也很重要。两台机器提示符记住diliverycartdiliverycart-virtual-machine Ubuntu(car) 虚拟机而EPRobotEPRobot2 真正的小车系统修改项目源码时当前主要是在EPRobotEPRobot2这一边操作。十四、今天加参数后为什么还是 false我们尝试往robot_lidar.launch加param nameis_pub_odom_tf typestring valuetrue/重新启动以后在PARAMETERS中确实出现了/is_pub_odom_tf: true但是底盘节点自己的日志还是is_pub_odom_tf : false这个现象非常关键。因为 Python 读取的是rospy.get_param(~is_pub_odom_tf, ...)这里的~表示节点私有参数。节点名字叫/base_control所以它真正寻找的是/base_control/is_pub_odom_tf而我们当时加出来的是/is_pub_odom_tf这是全局参数。所以节点还是找不到自己的私有参数最后用了默认值false十五、目前真正卡在哪里截至今天结束最准确的状态是ROS 主从通信 ✅ 小车 SSH ✅ robot_ws ✅ ROS 包识别 ✅ /scan 雷达话题 ✅ 雷达频率约 10 Hz ✅ LaserScan 实际数据 ✅ Gmapping 能启动 ✅ odom → base_link TF ❌ 地图 /map ❌核心日志仍然是is_pub_odom_tf : false以及MessageFilter [targetodom]: Dropped 100.00% of messages所以目前还没有进入真正的建图阶段。十六、明天从哪里继续明天不要重新从网络、ROS 安装、雷达开始查。直接从这个问题继续让eprobot_start/art_racecar.py对应的/base_control节点真正拿到/base_control/is_pub_odom_tf true目标启动日志必须变成is_pub_odom_tf : true然后立刻验证rosrun tf tf_echo odom base_link如果成功应不再出现Could not find a connection而是持续输出Translation: [...] Rotation: [...]之后再验证rostopic hz /map如果/map开始正常发布才算Gmapping 建图链路真正打通。十七、学到的几个 ROS 概念今天可以重点记这几个结论rostopic list看有哪些 ROS 话题。rostopic info /scan看这个话题是谁发、谁收。rostopic hz /scan看话题实际发布频率。rostopic echo -n 1 /scan只看一帧数据。rosrun tf tf_echo A B查看 A 到 B 的 TF 是否连通。roslaunch不是单纯运行一个程序而是一次可以启动多个 ROS 节点、加载参数、建立 TF。~paramROS 节点的私有参数例如/base_control/is_pub_odom_tf。/param全局参数与节点私有参数不是一回事。Gmapping 不只需要激光雷达还必须知道机器人运动后的位姿变化。十八、今天工作记录版今天继续进行 EPRobot 智慧药房项目单车调试。首先确认pharmacy_pkg与robot_navigation均能被 ROS 正确识别并检查了项目 launch 文件与 Python 脚本结构。根据比赛任务流程确定当前不直接运行完整智慧药房程序而是优先完成单车 SLAM 建图、保存地图和定点导航为后续二维码识别、坐标决策和避障提供基础。随后对激光雷达进行测试通过rostopic info /scan、rostopic hz /scan和rostopic echo -n 1 /scan确认 LSLIDAR M10 能正常发布 LaserScan 数据频率约为 10 Hz。启动robot_slam_laser.launch时发现默认 Cartographer 缺少相关 ROS 包因此改用 Gmapping成功启动slam_gmapping。Gmapping 启动后持续出现MessageFilter [targetodom]: Dropped 100.00% of messages。通过tf_echo odom base_link排查发现odom与base_link位于不同 TF 树中缺失动态的odom → base_link变换。进一步搜索源码发现eprobot_start/script/art_racecar.py使用is_pub_odom_tf参数控制是否发布里程计 TF官方EPRobot_start.launch中该参数设置为true。但当前robot_slam_laser.launch → robot_lidar.launch启动链中未正确向/base_control节点传入该私有参数。今天尝试在robot_lidar.launch中加入is_pub_odom_tftrue启动参数表中出现/is_pub_odom_tf: true但底盘节点日志仍显示is_pub_odom_tf : false说明该参数目前被作为全局参数加载而art_racecar.py实际读取的是/base_control/is_pub_odom_tf私有参数。下一步需要继续调整该参数在base_control节点中的位置使节点日志真正显示is_pub_odom_tf : true随后重新验证odom → base_linkTF并检查 Gmapping 是否开始发布/map。
返回列表