基于cartographer的优化和功能开发,以及二维码、反光板定位

一、编辑地图功能

后续操作均需以非冻结模式加载地图并且不开启新轨迹。

{
    "op":"call_service",
    "service": "/slam/set_cmd",
    "args":{
        "cmd":7,
        "map_name": "we"
    }
}

1.删除子图(TrimSubmapService)

流程:

  1. 传入 map_name ,返回地图和子图的pose点位;
  2. map_name 为空,传入 submap_point_list ,预览删除后的地图效果;
{
    "op":"call_service",
    "service": "/trim_submap",
    "args":{
        "map_name": "map1",
        "submap_point_list": [
            {
                "trajectory_id": 0,
                "submap_index": 7,
                "keep": false,
                "y": 161.1341552734375,
                "x": 447.395263671875
            },
            {
                "trajectory_id": 0,
                "submap_index": 8,
                "keep": false,
                "y": 238.68544006347656,
                "x": 448.4936218261719
            }
        ]
    }
}
  1. 删除轨迹(DeleteTrajectoryService)
    传入 map_name 和 trajectory_id ,即可删除轨迹:
{
   "op":"call_service",
   "service": "/delete_trajectory",
   "args":{
       "map_name": "map1",
       "trajectory_id": 0,
       "keep": false
       
   }
}

2.匹配地图(手动回环)(AddConstraintService)

{
    "op":"call_service",
    "service": "/add_constraint",
    "args":{
        "map_name": "map",
        "trajectory_id": 0,
        "submap_id": 0,
        "initial_pose":{
            "x":0,
            "y":0,
            "theta":0
        }
    }
}

流程:

  1. if(!req.map_name.empty()),初始化submap点位;
  2. "map_name"为空,initial_pose.x = 0 && initial_pose.y = 0 && initial_pose.theta = 0,返回去除指定子图的mapPicture,单张子图的submapPicture.,和submap左上角坐标;
  3. "map_name"为空,!(initial_pose.x = 0 && initial_pose.y = 0 && initial_pose.theta = 0,传位姿,执行匹配.

3.保存地图

传入 map_name

{
    "op":"call_service",
    "service": "/slam/set_cmd",
    "args":{
        "cmd":0,
        "map_name": "we"
    }
}

二、二维码SLAM(usb_cam,apriltag_ros,apriltag)

  1. 二维码安置:将二维码板垂直于墙贴放,正反两面都贴二维码,可让机器的正前方摄像头识别到。(如要利用二维码的角度,正反应该贴不一样的二维码,建议不用
  2. 精度和探测距离:选定合适的镜头和全局快门(克服动态模糊),在足够的光照条件下,机器在5m内,1.2m/s的速度下,二维码距离精度5-10cm左右,角度精度得在2m内较为稳定。
    影响因素:
    ①相机内参外参精度
    ②光照条件(相机曝光时间越短,亮度越低,动态模糊性能越好;反之,亮度越高,动态模糊性能越差)
    ③镜头与二维码相对角度
    ④机器运动速度
    ⑤摄像头分辨率
    ⑥二维码大小

    ⑦采用二维码组合(组合能提高稳定性,但是有限,并不能提高检测距离),
  3. CPU占用:在640*480分辨率下,帧率5 FPSusb_cam + apriltagi51135 占用率为单核50%。(选用apriltag不用aruco的原因是,apriltag距离更远)
    影响因素:
    ①分辨率
    ②帧率

三、反光板SLAM(reflecter_ekf_slam)

优点:cpu占用率比二维码方案很多,单核10%以下。检测距离远近,取决于雷达分辨率
缺点:超出设置距离后,无法提供回环。
流程图:
请添加图片描述

  1. 雷达前段滤波,计算reflector在位置(laser_reflector):
    ①订阅lidar数据,过滤特定范围内和激光强度大于反光板阈值的点,将连续的高强度点云放入同一reflector集合中。考虑点云中间出现断点,合并距离很近的reflector集合。如果雷达为360°,需将点云头尾的reflector集合合并;
    ②判断reflector半径是否达到实际半径,考虑误差;
    ③计算reflector中心点,将反光板集合输出给后端。

  2. 后端根据机器实时位置,计算reflector在 map 中的位置(reflecter_ekf_slam
    ①订阅tf来实时更新机器实时位姿;
    ②判断 reflector 是否与记录的 reflector 匹配,匹配的话使用 EKF 更新 reflector , 不匹配则录入新 reflector,并将landmark发送给 cartographer;
    ③订阅 cartographer 的 landmark_poses_list ,来保持 cartographer 和 reflecter_ekf_slam 后端 reflector 的一致性。

四、landmark 位姿的增删改查(UpdateLandmarkService)

{
    "op":"call_service",
    "service": "/update_landmark",
    "args":{
        "landmark_id":0,
        "x": "2.56"
        "y": "1.5"
    }
}

①传入 landmark_id ,更新 x, y;

②传入 landmark_id ,x = 0 && y = 0 ,删除 landmark;

③传入新 landmark_id ,增加新 landmark。

五、业务流程优化

  1. 扩展地图前,将地图压缩备份;
  2. 建图时监控工控机的CPU,和内存占用率;

六、优化代码逻辑和性能

  1. 优化扩展地图时CPU占用过高,取消全局约束的生成,只生成局部约束;

七、修复BUG

  1. 修复扩展建图开始时,地图的跳动问题;
  2. 修复雷达时间戳异常导致的 cartographer 崩溃。
1. 优化数据结构 在Cartographer算法中,使用了许多数据结构,如图、位姿、激光数据等。优化这些数据结构可以提高算法的效率。例如,使用紧凑的数据结构来存储激光数据,可以减少内存使用量访问时间。 2. 优化并行处理 Cartographer算法可以通过并行处理来提高效率。例如,可以使用多线程来处理激光数据,同时进行地图构建位姿估计,以减少计算时间。 3. 优化地图更新策略 地图更新策略是Cartographer算法中的重要组成部分。优化地图更新策略可以减少计算时间内存使用量。例如,可以根据激光数据的密度运动状态调整地图更新频率,以避免不必要的计算。 代码示例: 以下是一个优化Cartographer算法的代码示例,用于优化地图更新策略。在这个例子中,我们使用一个自适应地图更新策略,根据激光数据的密度运动状态调整地图更新频率。 ```python def update_map(laser_data, pose_data, map_data): density = calculate_density(laser_data) motion = calculate_motion(pose_data) if density > 0.5 and motion > 0.5: # 高密度高运动状态,更新地图 map_data.update(laser_data, pose_data) elif density > 0.5 and motion <= 0.5: # 高密度低运动状态,降低地图更新频率 map_data.update(laser_data, pose_data, update_rate=0.5) elif density <= 0.5 and motion > 0.5: # 低密度高运动状态,增加地图更新频率 map_data.update(laser_data, pose_data, update_rate=2.0) else: # 低密度低运动状态,不更新地图 pass ``` 在这个代码示例中,我们首先计算激光数据的密度运动状态,然后根据这些因素调整地图更新频率。如果密度运动状态都很高,则更新地图。如果密度很高但是运动状态很低,则降低地图更新频率。如果密度很低但是运动状态很高,则增加地图更新频率。如果密度运动状态都很低,则不更新地图。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值