lego-loam加入imu数据建图,使用自己的数据集建图

配置lego-loam教程:

https://blog.csdn.net/qq_35102059/article/details/122671432?spm=1001.2014.3001.5501

激光雷达与imu的外参标定教程:

https://blog.csdn.net/qq_35102059/article/details/122577644?spm=1001.2014.3001.5501

lego-loam默认可以没有imu信息,但有imu建图效果会更好

配置跑通lego-loam后,进行外参标定,得到标定结果.

开始修改程序参数:

utility.h文件:

确认utility.h文件中imu的话题名称是否正确:

extern const string imuTopic = "/imu/data";

featureAssociation.cpp文件:

1. 私有成员加入3个转换变量:

class FeatureAssociation{

private:
    ...
    ...
    ...
    Eigen::Matrix3d extRot;
    Eigen::Matrix3d extRPY;
    Eigen::Quaterniond extQRPY;
public:
    ...

2.nh("~")函数中加入标定好的外参旋转矩阵:

nh("~")
        {
			// extRot << 1, 0, 0,
			// 					0, -1, 0,
			// 					0, 0, -1;
			// extRPY << 1, 0, 0,
			// 					0, -1, 0,
			// 					0, 0, -1;
            extRot <<     -0.2424,   -0.937885,   -0.248224,
                                -0.44903,   -0.118344,    0.885645, 
                                -0.860008,     0.32614,   -0.392452;
            extRPY <<     -0.2424,   -0.937885,   -0.248224,
                                -0.44903,   -0.118344,    0.885645, 
                                -0.860008,     0.32614,   -0.392452;
			extQRPY = Eigen::Quaterniond(extRPY);

        subLaserCloud = nh.subscribe<sensor_msgs::PointCloud2>("/segmented_cloud", 1, &FeatureAssociation::laserCloudHandler, this);
        subLaserCloudInfo = nh.subscribe<cloud_msgs::cloud_info>("/segmented_cloud_info", 1, &FeatureAssociation::laserCloudInfoHandler, this);
        subOutlierCloud = nh.subscribe<sensor_msgs::PointCloud2>("/outlier_cloud", 1, &FeatureAssociation::outlierCloudHandler, this);
        subImu = nh.subscribe<sensor_msgs::Imu>(imuTopic, 50, &FeatureAssociation::imuHandler, this);

        pubCornerPointsSharp = nh.advertise<sensor_msgs::PointCloud2>("/laser_cloud_sharp", 1);
        pubCornerPointsLessSharp = nh.advertise<sensor_msgs::PointCloud2>("/laser_cloud_less_sharp", 1);
        pubSurfPointsFlat = nh.advertise<sensor_msgs::PointCloud2>("/laser_cloud_flat", 1);
        pubSurfPointsLessFlat = nh.advertise<sensor_msgs::PointCloud2>("/laser_cloud_less_flat", 1);

        pubLaserCloudCornerLast = nh.advertise<sensor_msgs::PointCloud2>("/laser_cloud_corner_last", 2);
        pubLaserCloudSurfLast = nh.advertise<sensor_msgs::PointCloud2>("/laser_cloud_surf_last", 2);
        pubOutlierCloudLast = nh.advertise<sensor_msgs::PointCloud2>("/outlier_cloud_last", 2);
        pubLaserOdometry = nh.advertise<nav_msgs::Odometry> ("/laser_odom_to_init", 5);
        
        initializationValue();
}

3.紧跟着下面写一个外参转换函数:

sensor_msgs::Imu imuConverter(const sensor_msgs::Imu& imu_in)
{
    sensor_msgs::Imu imu_out = imu_in;
    // rotate acceleration
    Eigen::Vector3d acc(imu_in.linear_acceleration.x, imu_in.linear_acceleration.y, imu_in.linear_acceleration.z);
    acc = extRot * acc;
    imu_out.linear_acceleration.x = acc.x();
    imu_out.linear_acceleration.y = acc.y();
    imu_out.linear_acceleration.z = acc.z();
    // rotate gyroscope
    Eigen::Vector3d gyr(imu_in.angular_velocity.x, imu_in.angular_velocity.y, imu_in.angular_velocity.z);
    gyr = extRot * gyr;
    imu_out.angular_velocity.x = gyr.x();
    imu_out.angular_velocity.y = gyr.y();
    imu_out.angular_velocity.z = gyr.z();
    // rotate roll pitch yaw
    Eigen::Quaterniond q_from(imu_in.orientation.w, imu_in.orientation.x, imu_in.orientation.y, imu_in.orientation.z);
    Eigen::Quaterniond q_final = q_from * extQRPY;
    imu_out.orientation.x = q_final.x();
    imu_out.orientation.y = q_final.y();
    imu_out.orientation.z = q_final.z();
    imu_out.orientation.w = q_final.w();

    if (sqrt(q_final.x()*q_final.x() + q_final.y()*q_final.y() + q_final.z()*q_final.z() + q_final.w()*q_final.w()) < 0.1)
    {
        ROS_ERROR("Invalid quaternion, please use a 9-axis IMU!");
        ros::shutdown();
    }

    return imu_out;
}

4.在imu的回调函数第一行加入调用转换函数,完成转换:

void imuHandler(const sensor_msgs::Imu::ConstPtr& imuIn)
{
        sensor_msgs::Imu thisImu = imuConverter(*imuIn);  //就加这1行

    double roll, pitch, yaw;
    tf::Quaternion orientation;
    tf::quaternionMsgToTF(thisImu.orientation, orientation);
    tf::Matrix3x3(orientation).getRPY(roll, pitch, yaw);

注:

1.此外参为imu与激光雷达的标定结果中的旋转矩阵.

2.lego-loam中只考虑了imu到激光雷达的旋转,没有考虑平移(个人理解是,与小车的运动模型有关),故应该尽量将imu安装在激光雷达的正下方.

保存重新catkin_make编译.即可开始运行程序建图:

 

### 回答1: 要将IMU信息添加到LEGO-LOAM中,需要进行以下步骤: 1. 首先,需要在代码中添加IMU数据的读取和处理功能。可以使用ROS中的IMU消息类型来读取IMU数据,并将其转换为适合LEGO-LOAM使用的格式。 2. 接下来,需要将IMU数据与激光雷达数据进行同步。可以使用时间戳来将两者同步,确保它们在同一时刻被处理。 3. 最后,需要将IMU数据与激光雷达数据进行融合,以提高定位和的精度。可以使用卡尔曼滤波或扩展卡尔曼滤波等技术来实现融合。 总之,将IMU信息添加到LEGO-LOAM中需要进行一些代码修改和算法调整,以确保IMU数据能够与激光雷达数据有效地融合。 ### 回答2: LEGO-LOAM是一个基于LEGO Mindstorms EV3硬件平台和三维激光雷达(3D Lidar)的开源SLAM系统。在实际的应用场景中,通常需要加入IMU(惯性测量单元)信息来提高其定位精度和鲁棒性。那么,LEGO-LOAM如何加入IMU信息呢? 在LEGO-LOAM中,IMU信息是通过IMU传感器进行获取的。具体来说,IMU传感器能够测量设备的加速度和角速度信息,通过对这些信息进行积分可以获取设备的位置和姿态信息。因此,将IMU传感器的输出信息与3D Lidar的测量数据进行融合,便可以提高LEGO-LOAM系统的定位精度和鲁棒性。 在LEGO-LOAM中,可以通过以下步骤将IMU信息加入到系统中: 1.将IMU传感器与LEGO Mindstorms EV3设备相连接,通过EV3软件获取IMU传感器的输出数据。可以使用EV3DEV系统配合Python命令行工具对IMU传感器进行操作。 2.利用IMU传感器获取到设备的加速度和角速度信息,并进行积分得到设备的位置和姿态信息。 3.通过将IMU信息与3D Lidar测量数据进行融合,得到更可靠和精准的定位信息。 4.在代码实现中,可以运用卡尔曼滤波等算法进行IMU信息的融合和滤波,进一步提高系统的精度和稳定性。 总之,在LEGO-LOAM系统中加入IMU信息,能够显著提高系统的定位精度和鲁棒性,为实际的应用场景带来更多便利和价值。 ### 回答3: LEGO-LOAM是一种基于激光雷达的无人驾驶系统,它利用点云数据进行和定位。但是,对于具有运动状态的无人车辆而言,仅仅使用激光雷达并不能很好地实现和定位。因此,LEGO-LOAM需要结合IMU(惯性测量单元)的信息。 惯性测量单元(IMU)是一种能够测量物体姿态和运动状态的仪器。它通常包括加速度计和陀螺仪。加速度计可以测量物体的加速度,从而可以得到物体的姿态信息。而陀螺仪可以测量物体的角速度,从而可以得到物体的旋转信息。 在LEGO-LOAM中,可以通过将IMU的信息加入激光雷达数据中,使得无人车辆能够更准确地进行和定位。 具体来讲,首先需要读取IMU数据,并将其转换为IMU坐标系下的加速度和角速度信息。然后,需要将IMU坐标系和激光雷达坐标系之间的关系进行校准,从而得到准确的坐标系转换矩阵。最后,将转换后的IMU信息与激光雷达数据进行融合,从而得到更加准确的点云数据,进而进行和定位。 总的来说,加入IMU信息可以提高LEGO-LOAM的定位精度和效果,使得无人车辆能够更加准确和稳定地进行自主导航和控制。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

和道一文字_

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值