基于反光柱特征的激光定位算法思路

1. 识别反光柱

反光柱是特殊材料制成,根据激光雷达对反光材料扫描得到的反射值来提取特征。反光柱是圆柱形,我们提取的特征就是反光柱圆心在当前帧下对应激光扫描线束的dist以及angle。提取方法如下:
在这里插入图片描述
大体思路是,根据激光雷达扫描到反光材料的反射值来确定扫到反光柱开始和结束的两条线束,计算两者之间的夹角,根据三角关系就能算出反光柱圆心到激光雷达的dist和angle。

2. 数据关联

2.1 基于几何形状寻找匹配

在这里插入图片描述
这里用到了一个寻找匹配的技巧。
我们在构建右边完整的多边形图的时候将边长的单位由米转换成了像素。比如我们设定右边多边形图的一个像素代表0.1米,则lidar扫描到的点之间的距离如果是3.132m,在右边图中就是31个像素(int)3.132/0.1。这个像素值作为多边形图中map数据结构的key,在根据真实的边长寻找匹配时,可以快速定位要寻找边的范围,比如3.132m的边在key为[31,32]范围内寻找匹配。在这里插入图片描述
上一步可以认为是粗匹配,接着根据激光雷达的观测精度设置一个精匹配阈值来寻找最接近的边长。(这里反光柱布置较分散时也没有啥影响。)

2.2 暴力寻找匹配

在这里插入图片描述

3. 位姿估计(最小二乘求解)

在这里插入图片描述
定位结果展示:

在这里插入图片描述
运动轨迹展示:
在这里插入图片描述
在这里插入图片描述

4. 问题

4.1 精度问题

反光柱识别算法精度较差,静止agv,将识别到的反光柱坐标可视化,同一个反光柱,位置应该重合在一处。
在这里插入图片描述

agv静止不动识别反光柱的重复精度在厘米级,这个提取精度会传导到定位上去。从轨迹放大来看在厘米级,可接受。
在这里插入图片描述

4.2 快速旋转时定位较差

在这里插入图片描述
直线行驶较好:
在这里插入图片描述

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个基于ROS下2D激光雷达提取光柱坐标的示例代码及注释,希望能对您有所帮助: ```python #!/usr/bin/env python # -*- coding: utf-8 -*- import rospy import math import numpy as np from sensor_msgs.msg import LaserScan from geometry_msgs.msg import PointStamped class ReflectivePillarDetection: def __init__(self): # 初始化ROS节点 rospy.init_node('reflective_pillar_detection', anonymous=True) # 订阅激光雷达数据 self.laser_sub = rospy.Subscriber('/scan', LaserScan, self.laser_callback) # 发布光柱坐标 self.pillar_pub = rospy.Publisher('/reflective_pillar', PointStamped, queue_size=10) # 光柱的最小距离,单位:米 self.pillar_min_distance = 0.2 # 光柱的最大距离,单位:米 self.pillar_max_distance = 2.0 # 激光雷达数据中的最小角度,单位:弧度 self.angle_min = -math.pi / 2 # 激光雷达数据中的最大角度,单位:弧度 self.angle_max = math.pi / 2 def laser_callback(self, msg): # 获取激光雷达数据 ranges = msg.ranges # 获取激光雷达数据中的角度间隔 angle_increment = msg.angle_increment # 获取激光雷达数据中的起始角度 angle_start = msg.angle_min # 获取激光雷达数据中的结束角度 angle_end = msg.angle_max # 计算激光雷达数据中的角度值 angles = np.arange(angle_start, angle_end + angle_increment, angle_increment) # 初始光柱坐标值 pillar_x = 0 pillar_y = 0 # 统计光柱个数 pillar_count = 0 # 遍历激光雷达数据 for i in range(len(ranges)): # 获取当前激光雷达数据点的距离值 range_i = ranges[i] # 获取当前激光雷达数据点的角度值 angle_i = angles[i] # 如果当前激光雷达数据点距离小于最小距离或大于最大距离,则跳过该点 if range_i < self.pillar_min_distance or range_i > self.pillar_max_distance: continue # 如果当前激光雷达数据点的角度值不在最小角度和最大角度之间,则跳过该点 if angle_i < self.angle_min or angle_i > self.angle_max: continue # 计算当前激光雷达数据点的坐标值 x = range_i * math.cos(angle_i) y = range_i * math.sin(angle_i) # 如果当前激光雷达数据点的y值小于0,则跳过该点 if y < 0: continue # 更新光柱坐标值 pillar_x += x pillar_y += y # 增加光柱个数 pillar_count += 1 # 如果没有检测到光柱,则不发布光柱坐标 if pillar_count == 0: return # 计算光柱坐标平均值 pillar_x /= pillar_count pillar_y /= pillar_count # 发布光柱坐标 pillar_msg = PointStamped() pillar_msg.header.stamp = rospy.Time.now() pillar_msg.header.frame_id = 'laser' pillar_msg.point.x = pillar_x pillar_msg.point.y = pillar_y pillar_msg.point.z = 0 self.pillar_pub.publish(pillar_msg) if __name__ == '__main__': ReflectivePillarDetection() rospy.spin() ``` 注释中已经对代码进行了详细的解释,代码实现的主要思路是遍历激光雷达数据,依次计算每个数据点的坐标值,并更新光柱坐标值。最后计算光柱坐标平均值并发布。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宛如新生

转发即鼓励,打赏价更高!哈哈。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值