首页 > 其他分享 >无人机以mid360+光流实现无GPS定位

无人机以mid360+光流实现无GPS定位

时间:2024-10-24 17:47:37浏览次数:3  
标签:mid360 Eigen orientation pose msg init 光流 vision GPS

参考链接PX4|基于FAST-LIO mid360的无人机室内自主定位及定点悬停

使用硬件

pixhawk6c飞控,livox-mid360雷达,MTF-01_Micolink光流测距一体传感器,香橙派5B开发板。

连线

开发板-飞控:usb-ttl,接飞控tele2

光流-飞控:tele3

原理:将来自mid360雷达的位姿信息(odometry)和来自 PX4 飞控系统的位姿信息进行融合和转换。然后将的位置信息在初始偏航角(光流获取,也可以通过其他方式)确定后转换到 ENU(East-North-Up)坐标系下,并发布转换后的位姿消息。

详细过程


基于mid360复现fast-lio

光流使用:

MTF-01光流测距一体传感器-用户手册

微空助手下载和使用说明

当在QGC地面站-analyze tools-MAVLink检测中看见DISTANCE_SENSOR和LOCAL_POSITION_NED就代表配置成功了。

直接上源码:

#include <ros/ros.h>
#include <geometry_msgs/PoseStamped.h>
#include <nav_msgs/Odometry.h>
#include <Eigen/Eigen>
#include <cmath>
#include <queue>

// 三维向量,用于存储激光雷达在机体坐标系下的位置
Eigen::Vector3d p_lidar_body, p_enu;
// 四元数,用于存储从 VINS 得到的姿态信息
Eigen::Quaterniond q_mav;
// 四元数,用于存储从 PX4 里程计得到的姿态信息
Eigen::Quaterniond q_px4_odom;

class SlidingWindowAverage {
public:
    // 构造函数,接收窗口大小作为参数
    SlidingWindowAverage(int windowSize) : windowSize(windowSize), windowSum(0.0) {}

    // 添加数据的方法
    double addData(double newData) {
        bool needReset = false;
        // 如果队列不为空且新数据与队尾数据差值大于 0.01,则需要重置队列
        if (!dataQueue.empty() && std::fabs(newData - dataQueue.back()) > 0.01) {
            needReset = true;
        }

        dataQueue.push(newData);
        windowSum += newData;

        // 如果队列大小超过窗口大小,弹出队首元素并更新总和
        if (dataQueue.size() > windowSize) {
            windowSum -= dataQueue.front();
            dataQueue.pop();
        }

        // 如果需要重置或者队列大小小于窗口大小,直接将平均值设为新数据
        if (needReset || dataQueue.size() < windowSize) {
            windowAvg = newData;
        } else {
            // 否则计算并更新平均值
            windowAvg = windowSum / dataQueue.size();
        }

        return windowAvg;
    }

    // 获取队列大小的方法
    int get_size() {
        return dataQueue.size();
    }

    // 获取平均值的方法
    double get_avg() {
        return windowAvg;
    }

private:
    int windowSize;
    double windowSum;
    double windowAvg;
    std::queue<double> dataQueue;
};

// 从四元数计算偏航角的函数
double fromQuaternion2yaw(const Eigen::Quaterniond& q) {
    double yaw = std::atan2(2 * (q.x()*q.y() + q.w()*q.z()), q.w()*q.w() + q.x()*q.x() - q.y()*q.y() - q.z()*q.z());
    return yaw;
}

int main(int argc, char **argv) {
    ros::init(argc, argv, "vins_to_mavros");
    ros::NodeHandle nh("~");

    // 订阅 VINS 的里程计消息
    ros::Subscriber slam_sub = nh.subscribe<nav_msgs::Odometry>("/Odometry", 100, [&](const nav_msgs::Odometry::ConstPtr& msg) {
        // 将消息中的位置信息存储到向量中
        p_lidar_body = Eigen::Vector3d(msg->pose.pose.position.x, msg->pose.pose.position.y, msg->pose.pose.position.z);
        // 将消息中的姿态信息存储到四元数中
        q_mav = Eigen::Quaterniond(msg->pose.pose.orientation.w, msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z);
    });
    // 订阅 PX4 的里程计消息
    ros::Subscriber px4_odom_sub = nh.subscribe<nav_msgs::Odometry>("/mavros/local_position/odom", 5, [&](const nav_msgs::Odometry::ConstPtr& msg) {
        // 将消息中的姿态信息存储到四元数中
        q_px4_odom = Eigen::Quaterniond(msg->pose.pose.orientation.w, msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z);
        // 将 PX4 里程计的偏航角添加到滑动平均类中
        swa.addData(fromQuaternion2yaw(q_px4_odom));
    });

    // 发布转换后的位姿消息
    ros::Publisher vision_pub = nh.advertise<geometry_msgs::PoseStamped>("/mavros/vision_pose/pose", 10);

    // 设置发布频率
    ros::Rate rate(20.0);

    int windowSize = 8;
    SlidingWindowAverage swa(windowSize);
    float init_yaw = 0.0;
    bool init_flag = false;
    Eigen::Quaterniond init_q;
    while (ros::ok()) {
        // 如果滑动平均队列大小达到窗口大小且未初始化,则进行初始化
        if (swa.get_size() == windowSize &&!init_flag) {
            init_yaw = swa.get_avg();
            init_flag = true;
            // 根据初始偏航角创建初始四元数
            init_q = Eigen::AngleAxisd(init_yaw, Eigen::Vector3d::UnitZ())
                      * Eigen::AngleAxisd(0.0, Eigen::Vector3d::UnitY())
                      * Eigen::AngleAxisd(0.0, Eigen::Vector3d::UnitX());
        }

        if (init_flag) {
            geometry_msgs::PoseStamped vision;
            // 根据初始四元数将激光雷达在机体坐标系下的位置转换到 ENU 坐标系下
            p_enu = init_q * p_lidar_body;

            vision.pose.position.x = p_enu[0];
            vision.pose.position.y = p_enu[1];
            vision.pose.position.z = p_enu[2];

            vision.pose.orientation.x = q_mav.x();
            vision.pose.orientation.y = q_mav.y();
            vision.pose.orientation.z = q_mav.z();
            vision.pose.orientation.w = q_mav.w();

            vision.header.stamp = ros::Time::now();
            vision_pub.publish(vision);

            ROS_INFO("\nposition in enu:\n   x: %.18f\n   y: %.18f\n   z: %.18f\norientation of lidar:\n   x: %.18f\n   y: %.18f\n   z: %.18f\n   w: %.18f",
                     p_enu[0], p_enu[1], p_enu[2], q_mav.x(), q_mav.y(), q_mav.z(), q_mav.w());
        }

        ros::spinOnce();
        rate.sleep();
    }

    return 0;
}

依次运行:

启动雷达

roslaunch livox_ros_driver2 msg_MID360.launch

 启动fast-lio

roslaunch fast_lio mapping_mid360.launch

 启动mavros

roslaunch mavros px4.launch

 启动上述雷达定位节点

rosrun mid2px4_pkg mid2px4_node

 启动offboard

rosrun offboard_run offboard_run_node

就可以实现真机飞行了

标签:mid360,Eigen,orientation,pose,msg,init,光流,vision,GPS
From: https://blog.csdn.net/weixin_67505885/article/details/143215008

相关文章

  • 基于单片机GPS跌倒和心电老人防护监测仪系统
    **文章目录前言概要设计思路软件设计效果图程序文章目录前言......
  • 具有GPS功能的监控设备接入as-v1000视频监控平台后,上层应用软件通过as-v1000视频监控
    目录一、什么是设备GPS轨迹二、设备GPS轨迹的应用场景        1、车辆追踪        2、个人定位        3、物流运输        4、资产安全        5、数据分析三、查询设备GPS轨迹的作用        1、实时监控与追踪 ......
  • 京准电钟:GPS卫星时钟服务器应用部署方案
    京准电钟:GPS卫星时钟服务器应用部署方案京准电钟:GPS卫星时钟服务器应用部署方案京准电子科技官微——ahjzsz项目概述1.1应用背景根据人民银行第2012年第8期《金融业信息安全风险提示》建议大力推广采用能够接收GPS和北斗时钟源信号的国产时钟同步服务器产品,减少现有GPS产品对......
  • 京准电钟:GPS北斗卫星时钟服务器应用政务系统方案
    京准电钟:GPS北斗卫星时钟服务器应用政务系统方案京准电钟:GPS北斗卫星时钟服务器应用政务系统方案京准电子官微——ahjzsz摘要:随着电子政务的不断发展,许多省份都建立了自己的政务网络,使用的网络设备和服务器日益增多,这些设备都有自己的时钟,是可以调节的,因此网络中的所有设备和主......
  • C语言计算GPS卫星位置
    1概述在用GPS信号进行导航定位以与制订观测计划时,都必须已知GPS卫星在空间的瞬间位置。卫星位置的计算是根据卫星电文所提供的轨道参数按一定的公式计算的。本节专门讲解观测瞬间GPS卫星在地固坐标系中坐标的计算方法。2卫星位置的计算1.计算卫星运行的平均角速度n根据......
  • 组合定位-GPS-IMU-Odom
    组合定位GPS遵守NMEA0184GPS每次测量都是独立的,即与上次测量无关,所以不存在误差累计不同IMU器件,其驱动是不同的IMU存在数据漂移,测量相对位置GPS/INS组合制导INS是惯性导航系统(InertialNavigationSystem)的GPS/DR组合定位系统的组成:GPS传感器;odom:novatel/odom-pos......
  • GPS定位和测量原理
    GPS定位和测量原理主要涉及卫星信号的接收、计算和校正过程,以下是对这一原理的详细阐述:一、GPS定位原理卫星信号发射:GPS系统由一定数量的卫星(通常为24颗,其中21颗为工作卫星,3颗为备用卫星)组成,这些卫星以非常准确的时间间隔向地面发射无线电信号。卫星的位置可以根据星载......
  • gnss信号转发器 北斗卫星转发器 gps信号转发器
    在现代社会的工作中,我们都会使用到卫星信号。但存在一个现象,那就是卫星信号不能够穿透建筑物,生产车间、实验室等室内环境下的测试工作就会遇到困难。SYN2309型GNSS信号转发器是由西安同步电子科技有限公司精心设计、自行研发生产的一款增益可调的GNSS全频段卫星信号转发系统,主要功......
  • gps卫星转发器 导航信号转发器 北斗转发器
    在现代社会的工作中,我们都会使用到卫星信号。但存在一个现象,那就是卫星信号不能够穿透建筑物,生产车间、实验室等室内环境下的测试工作就会遇到困难。SYN2309型GNSS信号转发器是由西安同步电子科技有限公司精心设计、自行研发生产的一款增益可调的GNSS全频段卫星信号转发系统,主要功......
  • gps信号转发机 北斗信号转发器 gps北斗信号转发器
    随着科技的不断进步,人们可以使用卫星信号的领域也越来越多,但现目前存在的问题是卫星信号不能够穿透建筑物,生产车间、实验室等室内环境,对相应的测试工作造成困难。SYN2309型GNSS信号转发器可实现将卫星信号从室外转发到室内,产品特点a) 信号稳定、成本低廉、安装简单、操作简单、设......