You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ROS下Python2转Python3的URG激光雷达180度滤波失效问题

问题现象

将Python2版本可正常运行的URG激光雷达滤波代码迁移至Python3,目标是将原270度扫描输出裁剪为180度范围。ROS环境下启动launch文件无报错、进程运行正常,但RVIZ中观测到传感器仍输出270度扫描数据,未实现预期裁剪效果。

根因定位
  • RVIZ显示话题配置错误:滤波节点发布的裁剪后数据话题为/scan_filtered,若RVIZ中订阅的是URG驱动原生发布的/scan话题,会一直显示原始270度扫描数据,和滤波节点逻辑无关。
  • launch文件中URG驱动参数配置无效:配置的angle_max=-2.3562、angle_min=2.3562违反ROS LaserScan消息规范(要求angle_min < angle_max),同时start_angle=270、end_angle=40的跨零配置未做正确适配,驱动会直接忽略无效参数,默认输出270度原始扫描数据。
  • 滤波代码硬编码索引适配性差:代码中写死索引偏移ID_0DEG=180、ID_180DEG=900,未根据原始扫描数据的实际角度范围、角度增量动态计算裁剪位置,若原始点云数量、角度分辨率和硬编码预期不匹配,会出现裁剪错位、范围不符合预期的问题。
  • Python3下列表初始化逻辑冗余:原代码用list(range(num_filter))生成整数类型的空列表再循环赋值,虽然不会直接报错,但存在类型隐式转换风险,且循环赋值效率低于原生切片操作。
修复方案
  • 修正RVIZ显示配置
    打开RVIZ的LaserScan插件配置,将订阅的Topic从原始/scan修改为滤波节点输出的/scan_filtered,确认Fixed Frame设置为lrf_link或存在正确TF变换的父坐标系。

  • 修正launch文件URG驱动参数
    删除无效的反角度、跨零角度配置,若需要直接让雷达硬件输出180度数据,可将参数修改为如下内容:

<node pkg="urg_node" name="urg_node" type="urg_node">
  <param name="ip_address" value="192.168.0.10"/>
  <param name="frame_id" value="lrf_link" />
  <!-- 180度扫描对应-90°~+90°,换算为弧度是-1.5708~1.5708 -->
  <param name="angle_min" value="-1.5708" />
  <param name="angle_max" value="1.5708" />
</node>

如果需要保留软件裁剪逻辑、让雷达输出原生270度数据再做滤波,可以注释掉angle_min、angle_max相关配置,使用驱动默认参数即可。

  • 修正滤波代码硬编码逻辑
    替换原代码中固定索引裁剪的逻辑,根据原始激光数据的角度参数动态计算裁剪范围,增加边界保护,用Python原生切片替代循环赋值,修正后的回调函数代码如下:
def call_scan(self, data):
    self.newdata.header = data.header
    # 目标裁剪范围:正前方-90°~+90°
    target_min = -math.pi / 2.0
    target_max = math.pi / 2.0
    self.newdata.angle_min = target_min
    self.newdata.angle_max = target_max
    self.newdata.angle_increment = data.angle_increment
    self.newdata.time_increment = data.time_increment
    self.newdata.scan_time = data.scan_time
    self.newdata.range_min = data.range_min
    self.newdata.range_max = data.range_max

    # 动态计算裁剪索引,替代硬编码
    start_idx = int(round((target_min - data.angle_min) / data.angle_increment))
    end_idx = int(round((target_max - data.angle_min) / data.angle_increment))
    # 索引越界保护
    start_idx = max(0, start_idx)
    end_idx = min(len(data.ranges) - 1, end_idx)

    # 切片直接截取数据,兼容Python3类型要求
    self.newdata.ranges = list(data.ranges[start_idx:end_idx+1])
    self.newdata.intensities = list(data.intensities[start_idx:end_idx+1])
    self.pub_scan.publish(self.newdata)

    # 后续Range消息发布逻辑适配实际数据长度
    for x in range(0, len(self.newdata.ranges), STEP2):
        self.range.field_of_view = int(AREA_ANGLE - x * AREA_ANGLE / len(self.newdata.ranges))
        self.range.range = self.newdata.ranges[x]
        self.pub_range.publish(self.range)
  • 功能验证
    启动launch文件后,依次执行以下操作验证:
    • 执行rostopic list,确认存在/scan和/scan_filtered两个话题
    • 执行rostopic echo /scan_filtered -n1,查看输出的angle_min=-1.57、angle_max=1.57,ranges数组长度为720左右(对应0.25度角分辨率的180度扫描)
    • 回到RVIZ查看点云显示,确认扫描范围为正前方180度。

内容的提问来源于stack exchange,提问作者mattcrouse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:01:11