多传感器融合定位GNSS、IMU、Lidar、Camera

概述

0.坐标系

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
为了求解速度分量,相当于local
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
自动驾驶如何应用这些坐标系:
在这里插入图片描述

坐标系直接的转换公式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述航向角:
北东地,北偏东某某度
在这里插入图片描述

1.纯激光雷达点云定位
2.融合GNSS的点云定位
3.融合IMU的点云定位

IMU介绍
在这里插入图片描述

在这里插入图片描述
https://blog.csdn.net/hbsyaaa/article/details/108186892
IMU,即惯性测量单元,一般包含三轴陀螺仪与三轴加速度计。
1:通过其内部的DMP处理单元直接得到姿态解算的四元数结果。
2:通过软件解算的方式,利用欧拉角与旋转矩阵来对陀螺仪与加速度计的原始数据进行姿态求解,并将两种姿态进行互补融合,最终得到IMU的实时姿态
在这里插入图片描述

在这里插入图片描述我们使用IMU器件最终想要获取的是位姿数据,包含位置和姿态,而实际IMU直接测量的数据是加速度和角速度,需要对角速度进行一次积分计算角度,也就是姿态;对加速度进行二次积分获取距离,也就是位置。由于种种原因,所有的传感器测量数据,都有测量误差,而IMU是通过积分实现间接测量值,且其参考数据是上时刻数据,这就造成其误差也会随着时间传递下去,时间越久,其误差越大,这一特性成为数据漂移,所以IMU一般需要与其它传感器配合使用。

某些IMU只有线加速度和角加速度,没有四元素;
那么如何求解

在这里插入图片描述
在这里插入图片描述
根据加速度计解算姿态角,会有误差,因为靠重力加速度
在这里插入图片描述
方式二还可以利用重力分离求解roll pitch,但是yaw无法求解

// 订阅IMU
void imuHandler(const sensor_msgs::Imu::ConstPtr& imuIn)
{
    #ifdef INITIAL_BY_IMU
    if(!initialImu)
    {
        // float imupitch_ = atan2(-imuIn->linear_acceleration.x, 
        //                   sqrt(imuIn->linear_acceleration.z*imuIn->linear_acceleration.z + 
        //                   imuIn->linear_acceleration.y*imuIn->linear_acceleration.y));
        int signAccZ;
        if(imuIn->linear_acceleration.z >= 0) signAccZ = 1;
        else signAccZ = -1;
        float imupitch_ = -signAccZ * asin(imuIn->linear_acceleration.x);
        float imuroll_ = signAccZ * asin(imuIn->linear_acceleration.y);
        // float imuroll_ = atan2(imuIn->linear_acceleration.y, imuIn->linear_acceleration.z);
        Eigen::AngleAxisf imuPitch = Eigen::AngleAxisf(imupitch_, Eigen::Vector3f::UnitY());
        Eigen::AngleAxisf imuRoll = Eigen::AngleAxisf(imuroll_, Eigen::Vector3f::UnitX());
        Ext_Livox.rotate(imuRoll * imuPitch);
        // Ext_Livox.pretranslate();
        initialImu = true;
    }
    #endif
}

IMU预积分

https://maimai.cn/article/detail?fid=1658970578&efid=XAH0JEgstI0sq0-pwwnJUg
在这里插入图片描述

预积分问题引入

这种融合模型的核心问题在于,IMU的约束是通过惯性积分得到的,而惯性积分是以它前一时刻的位姿为初始值得到的,但是位姿每次优化后会发生变化,这导致其后的IMU惯性积分就要重新进行,显然运算量过大。

这个问题的解决思路就是直接计算两帧之间的相对位姿,而不依赖初始值影响,即所谓的预积分。本篇文章剩余的篇幅就几乎全在讨论预积分的问题。

  1. 使用思路
    在这里插入图片描述
  2. 残差设计
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    类似于kalman滤波

IMU与GPS

在自动驾驶定位算法中,IMU+GPS被称为黄金搭档,其主要原因是这两种器件互补性比较好,其数据有以下特征:

① 频率互补,GPS频率一般为10Hz,IMU频率一般为100Hz。
② 数据干扰互补,GPS数据易受环境影响,例如高楼、隧道等;IMU不易受外界干扰。
③ 数据误差互补,如上述第六点所述,IMU存在数据漂移,GPS每次测量都是独立的,即与上次测量无关,所以不存在误差累计。
④ IMU测量的是相对位置,GPS测量的是绝对位置。


    // add imu msg
    sensor_msgs::ImuConstPtr imu_msg = m.instantiate<sensor_msgs::Imu>();
    if (imu_msg) {
      ImuData data;
      data.acc = Eigen::Vector3d(imu_msg->linear_acceleration.x, //表示线加速度
                                 imu_msg->linear_acceleration.y,
                                 imu_msg->linear_acceleration.z);
      data.gyr = Eigen::Vector3d(imu_msg->angular_velocity.x, //角速度
                                 imu_msg->angular_velocity.y,
                                 imu_msg->angular_velocity.z);
      // orientation是由linear_acceleration和angular_velocity计算而得
      data.rot =
          Eigen::Quaterniond(imu_msg->orientation.w, //姿态,使用四元数表示
                             imu_msg->orientation.x, imu_msg->orientation.y,
                             imu_msg->orientation.z);
      data.stamp = imu_msg->header.stamp.toSec();

4.融合GNSS、IMU的点云定位
5.融合Camera的点云定位

参考AutoWare 或者 Apollo

AutoWare:
https://github.com/autowarefoundation/autoware_ai_perception
Apollo:
https://github.com/ApolloAuto/apollo/tree/master/modules/localization

在这里插入图片描述

1.纯激光雷达点云定位

LOAM系列算法配置及建图测试:LIO-SAM、LeGO、A-LOAM、LIO-mapping

2.融合GNSS的点云定位

3.融合IMU的点云定位

4.融合GNSS、IMU的点云定位

5.融合Camera的点云定位

遗传蚁群算法是一种基于生物进化和蚁群行为的启发式优化算法,常用于解决组合优化问题。在Python中,可以使用遗传算法和蚁群算法的思想来实现遗传蚁群控制变量法。 以下是一个简单的示例代码,展示了如何使用Python实现遗传蚁群控制变量法: ```python import numpy as np # 初始化种群 def init_population(population_size, variable_size): population = np.random.randint(low=0, high=2, size=(population_size, variable_size)) return population # 计算适应度值 def calculate_fitness(population): fitness = np.sum(population, axis=1) return fitness # 选择操作 def selection(population, fitness): select_idx = np.argmax(fitness) select_individual = population[select_idx] return select_individual # 交叉操作 def crossover(parent1, parent2): crossover_point = np.random.randint(low=0, high=len(parent1)) child = np.concatenate((parent1[:crossover_point], parent2[crossover_point:])) return child # 变异操作 def mutation(child, mutation_rate): for i in range(len(child)): if np.random.rand() < mutation_rate: child[i] = 1 - child[i] return child # 遗传蚁群控制变量法 def genetic_ant_colony_control_variable(population_size, variable_size, num_generations, mutation_rate): population = init_population(population_size, variable_size) for generation in range(num_generations): fitness = calculate_fitness(population) select_individual = selection(population, fitness) child = crossover(select_individual, select_individual) child = mutation(child, mutation_rate) population = np.concatenate((population, child.reshape(1, -1))) best_individual = selection(population, calculate_fitness(population)) return best_individual # 示例运行 population_size = 50 variable_size = 10 num_generations = 100 mutation_rate = 0.01 best_individual = genetic_ant_colony_control_variable(population_size, variable_size, num_generations, mutation_rate) print("Best individual:", best_individual) ``` 在这个示例代码中,我们首先定义了几个基本操作,包括初始化种群、计算适应度值、选择操作、交叉操作和变异操作。然后,我们使用这些操作来实现遗传蚁群控制变量法。 在主函数`genetic_ant_colony_control_variable`中,我们通过循环迭代生成新的个体,并更新种群。每一代中,我们选择适应度值最高的个体作为父代,进行交叉和变异操作,生成子代。最后,我们选择适应度值最高的个体作为最优解。 这只是一个简单的示例代码,实际应用中可能需要根据具体问题进行适当的改进和调整。希望能对你有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值