ROS实现串口GPS数据的解析与通信

2023-05-16

1. 配置串口

配置串口时,利用ROS自带的serial功能包进行串口数据的读取,具体来说就是创建一个串口对象,用成员函数read进行读取,需要注意的是其中Timeout的设置以及read在调用一次后就会清空缓存中的串口数据。

参考:
ROS之串口编程学习笔记 https://blog.csdn.net/u014695839/article/details/81209082
ROS系统的串口数据读取和解析 https://blog.csdn.net/Tansir94/article/details/81357612

2. 数据截取

从串口助手cutecom可以看到,GPS的数据为以下形式(GGA协议):
$GNGGA,131547.30,3908.17889767,N,11715.45111804,E,1,14,1.7,18.282,M,-8.614,M, ,*54

字段0:$GNGGA,语句ID,表明该语句为Global Positioning System Fix Data(GGA)GPS定位信息
字段1:UTC 时间,hhmmss.sss,时分秒格式
字段2:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
字段3:纬度N(北纬)或S(南纬)
字段4:经度dddmm.mmmm,度分格式(前导位数不足则补0)
字段5:经度E(东经)或W(西经)
字段6:GPS状态,0=未定位,1=非差分定位,2=差分定位,3=无效PPS,6=正在估算
字段7:正在使用的卫星数量(前导位数不足则补0)
字段8:HDOP水平精度因子(0.5 - 99.9)
字段9:海拔高度(-9999.9 - 99999.9)
字段10:地球椭球面相对大地水准面的高度
字段11:差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
字段12:差分站ID号0000 - 1023(前导位数不足则补0,如果不是差分定位将为空)
字段13:校验值
由于在串口读取过程中,有可能每次不能完全读取到完整的信息,所以根据上述GGA协议的数据格式及含义,可用以下代码截取出一段符合协议要求的数据。

C++代码片段:

//GPS起始标志
std::string gstart = "$GN";
//GPS终止标志
std::string gend = "\r\n";
int i = 0, start = -1, end = -1;
while ( i < strRece.length() )//strRece为从串口读取的待截取的字符串
{
    //找起始标志
    start = strRece.find(gstart);
    //如果没找到,丢弃这部分数据,但要留下最后2位,避免遗漏掉起始标志
    if ( start == -1)
    {
        if (strRece.length() > 2)   
        strRece = strRece.substr(strRece.length()-3);
        break;
    }
    //如果找到了起始标志,开始找终止标志
    else
    {
        //找终止标志
        end = strRece.find(gend);
        //如果没找到,把起始标志开始的数据留下,前面的数据丢弃,然后跳出循环
        if (end == -1)
        {
            strRece = strRece.substr(start);
            break;
        }
        //如果找到了终止标志,把这段有效的数据剪切给解析的函数,剩下的继续开始寻找
        else
        {
            i = end;
            //把有效的数据给解析的函数以获取经纬度
            double lat, lon;
            RecePro(strRece.substr(start,end+2-start),lat,lon);
            std::cout << std::setiosflags(std::ios::fixed)<<std::setprecision(7)<< "纬度:" << lat << " 经度:"<< lon << "\n";
            //发布消息到话题
            serialPort::GPS GPS_data;
            GPS_data.lat = lat;
            GPS_data.lon = lon;
            GPS_pub.publish(GPS_data);
            //如果剩下的字符大于等于4,则继续循环寻找有效数据,如果所剩字符小于等于3则跳出循环
            if ( i+5 < strRece.length())
            strRece = strRece.substr(end+2);
            else
            {   strRece = strRece.substr(end+2);
                break;
            }
        }
    }
}

3. 数据解析

由于C++中没有字符串分割函数,用find和push_back实现字符串的分割,并用atof实现字符串的转换,得到了解析后的经纬度。

C++代码片段:

void RecePro(std::string s , double& lat , double& lon )
{
    //分割有效数据,存入vector中
    std::vector<std::string> v;
    std::string::size_type pos1, pos2;
    pos2 = s.find(",");
    pos1 = 0;
    while ( std::string::npos !=pos2 )
    {
        v.push_back( s.substr( pos1, pos2-pos1 ) );
        pos1 = pos2 + 1;
        pos2 = s.find(",",pos1);
    }
    if ( pos1 != s.length() )
        v.push_back( s.substr( pos1 ));
    //解析出经纬度
    if (v.max_size() >= 6 && (v[6] == "1" || v[6] == "2" || v[6] == "3" || v[6] == "4" || v[6] == "5" || v[6] == "6" || v[6] == "8" || v[6] == "9"))
    {
        //纬度
        if (v[2] != "") lat = std::atof(v[2].c_str()) / 100;
        int ilat = (int)floor(lat) % 100;
        lat = ilat + (lat - ilat) * 100 / 60;
        //经度
        if (v[4] != "") lon = std::atof(v[4].c_str()) / 100;
        int ilon = (int)floor(lon) % 1000;
        lon = ilon + (lon - ilon) * 100 / 60;

    }
}

4. 自定义GPS消息

自定义GPS消息类型,先暂时包含lat(纬度)和lon(经度)两个数据,其实就类似于结构体的定义,在配置CmakeList.txt时,要注意其中函数定义的先后顺序不能任意更改。
参考:
ROS之msg文件定义以及自定义发布主题消息类型 https://blog.csdn.net/myhalan/article/details/64126584
ROS 自定义消息类型、使用方法以及常见错误解决方案 https://blog.csdn.net/qq_16775293/article/details/80449203

5. 完成发布器的编写

有了以上的基础之后,即可完成消息发布器的编写,完整的C++代码(serialPort.cpp)如下:

#include <ros/ros.h> 
#include <serial/serial.h>  //ROS已经内置了的串口包 
#include <std_msgs/String.h>
#include <std_msgs/Empty.h> 
#include <string>
#include <vector>
#include <sstream>
#include <cmath>
#include <cstdlib>//string转化为double
#include <iomanip>//保留有效小数
#include "serialPort/GPS.h"
serial::Serial ser; //声明串口对象

//解析GPS
void RecePro(std::string s , double& lat , double& lon )
{
    //分割有效数据,存入vector中
    std::vector<std::string> v;
    std::string::size_type pos1, pos2;
    pos2 = s.find(",");
    pos1 = 0;
    while ( std::string::npos !=pos2 )
    {
        v.push_back( s.substr( pos1, pos2-pos1 ) );
        pos1 = pos2 + 1;
        pos2 = s.find(",",pos1);
    }
    if ( pos1 != s.length() )
        v.push_back( s.substr( pos1 ));
    //解析出经纬度
    if (v.max_size() >= 6 && (v[6] == "1" || v[6] == "2" || v[6] == "3" || v[6] == "4" || v[6] == "5" || v[6] == "6" || v[6] == "8" || v[6] == "9"))
    {
        //纬度
        if (v[2] != "") lat = std::atof(v[2].c_str()) / 100;
        int ilat = (int)floor(lat) % 100;
        lat = ilat + (lat - ilat) * 100 / 60;
        //经度
        if (v[4] != "") lon = std::atof(v[4].c_str()) / 100;
        int ilon = (int)floor(lon) % 1000;
        lon = ilon + (lon - ilon) * 100 / 60;

    }
}
int main(int argc, char** argv)
{
    //初始化节点
    ros::init(argc, argv, "serial_node");
    //声明节点句柄
    ros::NodeHandle nh;
    //注册Publisher到话题GPS
    ros::Publisher GPS_pub = nh.advertise<serialPort::GPS>("GPS",1000);
    try
    {
      //串口设置
      ser.setPort("/dev/ttyUSB0");
      ser.setBaudrate(115200);
      serial::Timeout to = serial::Timeout::simpleTimeout(1000);
      ser.setTimeout(to);
      ser.open();
    }
    catch (serial::IOException& e)
    {
        ROS_ERROR_STREAM("Unable to open Serial Port !");
        return -1;
    }
    if (ser.isOpen())
    {
        ROS_INFO_STREAM("Serial Port initialized");
    }
    else
    {
        return -1;
    }

    ros::Rate loop_rate(50);

    std::string strRece;
    while (ros::ok())
    {

        if (ser.available())
        {
            //1.读取串口信息:
            ROS_INFO_STREAM("Reading from serial port\n");
            //通过ROS串口对象读取串口信息
            //std::cout << ser.available();
            //std::cout << ser.read(ser.available());
            strRece += ser.read(ser.available());
            //std::cout <<"strRece:" << strRece << "\n" ;
            //strRece = "$GNGGA,122020.70,3908.17943107,N,11715.45190423,E,1,17,1.5,19.497,M,-8.620,M,,*54\r\n";
            //2.截取数据、解析数据:
            //GPS起始标志
            std::string gstart = "$GN";
            //GPS终止标志
            std::string gend = "\r\n";
            int i = 0, start = -1, end = -1;
            while ( i < strRece.length() )
            {
                //找起始标志

                start = strRece.find(gstart);
                //如果没找到,丢弃这部分数据,但要留下最后2位,避免遗漏掉起始标志
                if ( start == -1)
                {
                    if (strRece.length() > 2)   
                        strRece = strRece.substr(strRece.length()-3);
                        break;

                }
                //如果找到了起始标志,开始找终止标志
                else
                {
                    //找终止标志
                    end = strRece.find(gend);
                    //如果没找到,把起始标志开始的数据留下,前面的数据丢弃,然后跳出循环
                    if (end == -1)
                    {
                        if (end != 0)
                        strRece = strRece.substr(start);
                        break;
                    }
                    //如果找到了终止标志,把这段有效的数据剪切给解析的函数,剩下的继续开始寻找
                    else
                    {
                        i = end;

                        //把有效的数据给解析的函数以获取经纬度
                        double lat, lon;
                        RecePro(strRece.substr(start,end+2-start),lat,lon);
                        std::cout << std::setiosflags(std::ios::fixed)<<std::setprecision(7)<< "纬度:" << lat << " 经度:"<< lon << "\n";
                        //发布消息到话题
                        serialPort::GPS GPS_data;
                        GPS_data.lat = lat;
                        GPS_data.lon = lon;
                        GPS_pub.publish(GPS_data);
                        //如果剩下的字符大于等于4,则继续循环寻找有效数据,如果所剩字符小于等于3则跳出循环
                        if ( i+5 < strRece.length())
                            strRece = strRece.substr(end+2);
                        else
                        {   strRece = strRece.substr(end+2);
                            break;
                        }
                    }
                }
            }
        }
    ros::spinOnce();
    loop_rate.sleep();
    }
}

6. 完成订阅器的编写

参考:
ROS消息发布器和订阅器的编写 https://blog.csdn.net/weixin_43795921/article/details/85055679
C++代码(listener.cpp):

#include "ros/ros.h"
#include "std_msgs/String.h"
#include "serialPort/GPS.h"
#include <iomanip>
void chatterCallback(const serialPort::GPSConstPtr& msg)
{
    std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(7) << "纬度:" << msg->lat << " 经度:" << msg->lon << "\n";
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("GPS", 1000, chatterCallback);
    ros::spin();
    return 0;
}

7. 编译配置

CmakeLists.txt:

cmake_minimum_required(VERSION 2.8.3)
project(serialPort)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  serial
  std_msgs
  message_generation
)


add_message_files(
   FILES
   GPS.msg
 )
generate_messages(DEPENDENCIES
  std_msgs
)

catkin_package(

  CATKIN_DEPENDS message_runtime

)

include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)


add_executable(serialPort src/serialPort.cpp)
target_link_libraries(serialPort ${catkin_LIBRARIES})
add_dependencies(serialPort ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

package.xml:

<?xml version="1.0"?>
<package format="2">
  <name>serialPort</name>
  <version>0.0.0</version>
  <description>The serialPort package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="bingo@todo.todo">bingo</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>


  <!-- Url tags are optional, but multiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/serialPort</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, but could be -->
  <!-- Example: -->
  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->


  <!-- The *depend tags are used to specify dependencies -->
  <!-- Dependencies can be catkin packages or system dependencies -->
  <!-- Examples: -->
  <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
  <!--   <depend>roscpp</depend> -->
  <!--   Note that this is equivalent to the following: -->
  <!--   <build_depend>roscpp</build_depend> -->
  <!--   <exec_depend>roscpp</exec_depend> -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use build_export_depend for packages you need in order to build against this package: -->
  <!--   <build_export_depend>message_generation</build_export_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use exec_depend for packages you need at runtime: -->
  <!--   <exec_depend>message_runtime</exec_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <!-- Use doc_depend for packages you need only for building documentation: -->
  <!--   <doc_depend>doxygen</doc_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>serial</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>message_generation</build_depend>

  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>serial</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>serial</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>message_runtime</exec_depend>

  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

8. 运行测试

roscore后,分别在两个终端中运行serialPort和listener两个节点:
ROS实现串口GPS数据的解析与通信

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS实现串口GPS数据的解析与通信 的相关文章

  • 图文教学读懂can报文

    can报文协议是汽车工程最基础的知识点 DBC协议 can有两种定义 Intel格式与Motorola格式 xff0c 主要的区别是能不能跨字节 xff0c 我们用主流的摩托摩拉格式 以一个报文ID 0x121为例 xff0c 他的解析如下
  • 四旋翼无人机数学模型推导

    本周开始进行四旋翼无人机的学习工作 xff0c 首先来进行四旋翼无人机的数学模型推导工作 四旋翼动力学数学模型 坐标变换 介绍四旋翼数学模型之前 xff0c 首先引入坐标变换的概念 xff0c 定义两个坐标系惯性坐标系 E xff0c 以及
  • NVIDIA Jetson Xavier NX 计算GPIO编号

    NVIDIA Jetson Xavier NX 计算GPIO编号 前言准备工作计算步骤计算示例注意 xff1a 附件 xff1a tegra gpio h参考链接 前言 公司产品使用了自主设计的载板 xff0c 需要使用指定的GPIO引脚
  • 深度学习人脸表情识别中,需要比较数据集中的文件名和train_list.txt中的文件名是否相一致的java代码实现

    如下图所示 xff0c 现有一个人脸表情数据集RAF DB xff0c 其train文件中的每一个图片的文件名称为 train 00001 aligned jpg 另外 xff0c 有train list txt文件标记了上图文件夹每一张数
  • git拉取后,代码被覆盖怎么办?

    1 File gt Local History gt Show History 2 右击 xff0c Revert找回本地历史版本
  • 【面试】C/C++面试宝典一

    1 const 修饰变量 xff0c 说明该变量不可以被改变 xff1b 修饰指针 xff0c 分为指向常量的指针 xff08 pointer to const xff09 和自身是常量的指针 xff08 常量指针 xff0c const
  • Docker安装Xfce桌面环境(轻量可视化操作系统)

    0 Xfce是什么 xff1f Xfce是一个适用于类UNIX操作系统的轻量级桌面环境 它的目标是快速而低廉的系统资源 xff0c 同时仍然具有视觉吸引力和用户友好性 具体参考官网 https www xfce org 项目地址 xff1a
  • Linux系统常用快捷键及VNC基本使用命令

    Linux系统常用快捷键及VNC基本使用命令 文章目录 Linux系统常用快捷键及VNC基本使用命令Linux系统的特点Linux树型目录结构Linux系统常用命令VNC常用命令 Linux系统的特点 多任务系统 在linux系统中可以同时
  • 【docker】docker学习(3)——Dockerfile的常用语法和编写实战

    大家好 xff0c 我是好学的小师弟 xff0c 今天和大家分享下Dockerfile的常用语法和编写实战 插曲 xff1a 在学习Dockerfile之前 xff0c 我们先讲解下docker save 和docker load 这两个命
  • 1.2 安装 docker 容器并配置镜像加速器

    1 2 1 实验环境准备 实验环境 xff1a CENTOS7 9 64 位 主机名 xff1a hou 主机 ip 10 0 8 120 xff08 这个 ip 大家可以根据自己所在环境去配置 xff0c 配置成静态 IP xff09 4
  • 弯管参数计算及编程实现

    船舶软件建立三维管道模型后 xff0c 需要自动生成管子加工信息 xff0c 这样就提高了设计效率 其中弯管参数主要是下料长度 xff0c 弯角和转角 下料长度是由各管段实长 xff0c 即管子中心线长度 xff0c 减去弯管部分切线长再加
  • 完整版数据库系统概论(第五版)-课后答案-免费网盘自提

    包含全部的课后答案与复习笔记 xff01 大家伙不挂科不被刷 xff0c 一起冲 xff01 虽然这个我也是找的别人的 xff0c 但是真的好用 xff01 百度网盘 https pan baidu com s 1Ux07PWvPb k3l
  • 踩坑笔记:安装Gazebo11

    安装环境 xff1a ubuntu18 04 在我上一篇博客中 xff0c 我们安装了ROS Melodic amp amp Ros2 Dashing 在我想要安装Gazebo11时候出现了错误 一 依赖错误 安装Gazebo11 xff1
  • 在keil5中调试串口遇到的问题

    1 问题 在keil5中调试stm32串口实验时 xff0c 向单片机的串口1发送数据 xff0c 观察串口1的寄存器 xff0c 此时串口1的中断服务函数会遇到无法进入下图if 的情况 xff0c 此时观察串口1寄存器 RXEN 的值 由
  • 树莓派在上电后一直重启进入不了系统桌面

    问题描述 树莓派在上电后一直重启进入不了系统桌面 xff0c 在检查了各种接口没问题后解决办法 原因分析与解决方案 xff1a 用了键盘 鼠标 显示器后5v 1A的插头不行 xff0c 换了ipad用的5V 2A的充电器后就可以开启了 xf
  • 树莓派连接“手机热点“或“WiFi“ 后无法上网,以及连接“手机热点“或“WiFi“时VNC连接失败问题

    问题描述 之前一直在开热点 xff0c 通过电脑端VNC控制树莓派拍摄照片 xff0c 今天突然发现树莓派上不去网 xff0c 所以就试着尝试解决了一下 xff0c 心路历程如下 xff1a 要么就是树莓派连不上网 xff0c 要么就是连上
  • 相机标定和双目相机标定标定原理推导及效果展示

    文章目录 前言一 相机标定1 相机的四个坐标系2 相机的畸变 二 张正友标定法1 求解内参矩阵与外参矩阵的积2 求解内参矩阵3 求解外参矩阵4 标定相机的畸变参数5 双目标定6 极线矫正 xff08 立体校正 xff09 三 视差图与深度图
  • keras:tensor从全连接层输出到卷积层

    一 tensor从卷积层输出到全连接层 用过keras的都知道 xff0c 想从卷积层输出tensor到全连接层 xff0c 只需加一层 xff1a model add Flatten shape就不会出现错误 二 但是如果从全连接层输出t
  • 保研面试复习之数据结构篇

    数据项 数据元素和数据结构的概念 数据项是组成数据元素的 xff0c 有独立含义的 xff0c 不可分割的最小单位 数据元素是数据的基本单位 数据结构是带结构的数据元素的集合 数据结构包括逻辑结构和存储结构两个层次 数据结构的三要素是逻辑结
  • 视觉里程计的重定位问题1——SVO的重定位部分

    SVO的重定位部分代码解析与分析 SVO的重定位功能体现在 xff1a 运动跟踪丢失后通过与上一关键帧匹配以及地图点投影 xff0c 找回当前相机位姿 由于没有后端和回环 xff0c SVO的重定位并不是回环校正后的重定位 代码部分被放在运

随机推荐

  • 组合导航(一):定位技术分类与介绍

    组合导航 xff08 一 xff09 xff1a 导航定位技术分类与介绍 一 定位技术分类1 1 基于相对测量的定位 xff08 航位推算 xff09 1 2 基于绝对测量的定位1 3 组合定位 一 定位技术分类 1 1 基于相对测量的定位
  • git bash可以正常commit,但是 VSCode 里不能正常commit使用的解决方法

    问题描述 同一路径下的源码 xff0c 使用git bash可以正常commit xff0c 但是使用vscode提交commit就会一直卡住 xff0c 转圈圈 参考方案链接 xff1a VS CODE GIT 500 问题处理 pudn
  • 组合导航(四):惯性导航系统

    1 惯性导航系统的物理平台2 惯性测量单元IMU3 惯性传感器的测量值3 1静止状态下的加速度测量3 2静止与运动状态下的角速度测量 4 惯性传感器误差4 1 系统误差 xff08 可通过实验进行校正 xff09 4 2 随机误差4 3 惯
  • 组合导航(七):卡尔曼滤波

    Kalman滤波1 离散卡尔曼滤波2 卡尔曼滤波的流程2 1 预测与时间更新2 2 测量更新与校正 3 卡尔曼滤波 算法步骤4 非线性卡尔曼滤波4 1 线性化kalman滤波4 2 扩展kalman滤波 5 卡尔曼滤波发散控制5 1 KF过
  • 组合导航(八):INS/GPS组合导航

    INS GPS组合导航1 误差反馈1 1 开环INS GPS架构1 2 闭环INS GPS架构 2 组合导航的类型2 1 松耦合 的INS GPS组合导航2 2 紧耦合 的INS GPS组合导航2 3 深度耦合的 INS GPS组合导航 3
  • 组合导航(九):三维简化的INS/GPS组合导航系统

    简化INS与GPS组合系统在三维路面上的导航1 MEMS级IMU的三维定位的性能分析2 解决MEMS级IMU在路面导航中存在的问题3 三维简化的惯性传感器系统3 1 3D RISS概述3 2 xff08 轮式车辆 xff09 采用3D RI
  • PX4安装与编译

    第一步 xff1a 下载源码 下载方式一 xff1a git clone https github com PX4 Firmware git recursive 默认下载版本为master 下载时间比较长 xff0c 包含各种包以及依赖工具
  • PX4:【系统架构】

    PX4系统架构 由两个层组成 xff1a 一是飞行控制栈 xff08 flight stack xff09 二是中间件 xff08 middleware xff09 flight stack xff1a 集成了各种自主无人机的制导 导航以及
  • PX4:【uORB通讯机制】

    uORB xff1a Micro Object Request Broker PX4进程间的通讯机制 xff1a 多对多的信息发布与订阅方式 发布消息 xff1a 1 公告 advertise xff1a 相当于初始化 xff0c 在发布消
  • PX4:【传感器校准】

    sensor的校准校准步骤 xff1a 文件目录 xff1a 代码入口 xff1a 求解模型计算公式 sensor的校准 校准步骤 xff1a 首先通过地面站QGC进行校准 xff0c QGC将校准参数设置到sh文件中 此后再基于QGC的校
  • PX4:【sensor_combined】

    功能介绍消息内容sensor combined 产生机制 amp 代码流程 功能介绍 sensor combined 是一个冗余传感器集合的消息 xff0c 通过订阅多个传感器的数据 xff0c 将冗余的数据经过VoteSensorsUpd
  • PX4:【地面站传感器数据校准】

    上电 gt rsC 运行 sensor start commander start 入口函数 xff1a 位于commander文件夹中 Commader cpp Commander run xff08 xff09 commander lo
  • Windows和Linux双系统安装教程

    最近刚刚完成了Windows和Linux双系统 xff08 这里以Ubuntu安装为例 xff09 的安装 xff0c 应某奔同学要求 xff0c 这里简单记录下安装过程 系统启动盘准备Windows系统安装分出给Linux系统的磁盘空间安
  • MSCKF系列论文阅读与代码流程

    MSCKF原理与代码总结 算法原理前端理论 xff08 图像的特征提取与跟踪 xff09 后端理论 xff08 误差状态卡尔曼滤波模型 xff09 1 IMU状态预测1 1 IMU状态传播 xff08 p v q 4阶Runge Kutta
  • open_vins(二):rosbag精度测试

    一 xff0e ros读取与轨迹保存二 xff0e euroc数据集测试三 结论 一 xff0e ros读取与轨迹保存 运行open vins launch 读取ros数据包 xff1a roslaunch pgeneva ros eth
  • open_vins(三):imu静止初始化

    一 xff0e 静止初始化原理二 xff0e 理论公式三 xff0e 相关代码四 xff0e 小结 xff1a 初始化是指在系统启动阶段 xff0c 需要估计重力方向 gravity direction 加速度计以及陀螺仪biases ac
  • ros数据集录制:rosbag record

    1 查看话题 查看topic列表 xff1a rostopic list 打印topic内容 xff1a rostopic echo topic xff12 话题录制rosbag record 用于在ros系统中录取系统中其他ros节点发出
  • git pull的时候:您对下列文件的本地修改将被合并操作覆盖,请在合并前提交或贮藏您的修改。 正在终止

    使用git pull的时候报错 xff1a 更新 span class token number 008728 span e span class token punctuation span span class token number
  • 使用webpack-dev-server自动打包并实现debug调试

    webpack dev server 是一个开发服务器 xff0c 它的功能就是可以实现热加载 xff0c 并且自动刷新浏览器 准备工作 xff1a 创建一个程序目录test xff0c 将html页面拷贝进来 xff0c 在目录下新建sr
  • ROS实现串口GPS数据的解析与通信

    1 配置串口 配置串口时 xff0c 利用ROS自带的serial功能包进行串口数据的读取 xff0c 具体来说就是创建一个串口对象 xff0c 用成员函数read进行读取 xff0c 需要注意的是其中Timeout的设置以及read在调用