使用WTGAHRS2(JY-GPSIMU)在ROS中读取数据并发布话题

2023-11-13

IMU简介

在这里插入图片描述

 十轴惯性导航传感器WTGAHRS2传感器集成高精度的陀螺仪、加速度计、地磁场传感器、GPS 模块,采用高性能的微处理器和先进的动力学解算与卡尔曼动态滤波算法,能够快速求解出模块当前的实时运动姿态。
 采用先进的数字滤波技术,能有效降低测量噪声,提高测量精度。传感器内部集成了姿态解算器,配合动态卡尔曼滤波算法,能够在动态环境下准确输出模块的当前姿态,姿态测量精度静态 0.05 度,动态 0.1 度,稳定性极高,性能甚至优于某些专业的倾角仪!
内部自带电压稳定电路,工作电压 3.3v~5v,引脚电平兼容 3.3V/5V 的嵌入式系
统,连接方便。支持串口 TTL/232,方便用户选择最佳的连接方式。串口速率 2400bps~921600bps
可调。GPS 信息、姿态传感器信息同步输出。最高 200Hz 数据输出速率。输入内容可以任意选择,输出速率 0.1~200HZ 可调节。
资料下载:https://pan.baidu.com/s/1kUxka08OW2x1Ej-7jvEgWw
验证码:0eug
官网:http://wit-motion.cn/guandaodaohang/26.html

驱动程序

在ROS中的驱动是以驱动文件的形式存在的,需要我们自己编写驱动程序。在这里我们参考https://blog.csdn.net/qqliuzhitong/article/details/114384297文章编写自己的驱动程序。

IMU串口通信协议

IMU使用的是JY901芯片,在官方说明文档里可以找到串口通信协议
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

程序

关于自定义话题及ros话题发布接受机制请参考:https://blog.csdn.net/qq_43569735/article/details/108065179
串口程序+话题发布

//Created by ljm
#include <ros/ros.h>
#include <serial/serial.h>
#include <iostream>
#include "agv_imu/imu_data.h"
int main(int argc, char** argv)
{
    ros::init(argc, argv, "agv_imu");
    ros::NodeHandle n;
    //创建imu数据话题发布
    ros::Publisher pub_imu_data;
    pub_imu_data = n.advertise<agv_imu::imu_data>("AGV/imu",50);

    //创建一个serial对象
    serial::Serial sp;
    //创建timeout
    serial::Timeout to = serial::Timeout::simpleTimeout(100);
    //设置要打开的串口名称
    sp.setPort("/dev/ttyUSB0");
    //设置串口通信的波特率
    sp.setBaudrate(9600);
    //串口设置timeout
    sp.setTimeout(to);

    double ax,ay,az;
    double wx,wy,wz;
    double angle_roll,angle_pitch,angle_yaw;
    
    agv_imu::imu_data msg;
    
    try
    {
        //打开串口
        sp.open();
    }
    catch(serial::IOException& e)
    {
        ROS_ERROR_STREAM("Unable to open port.");
        return -1;
    }

    //判断串口是否打开成功
    if(sp.isOpen())
    {
        ROS_INFO_STREAM("/dev/ttyUSB0 is opened.");
    }
    else
    {
        return -1;
    }

    ros::Rate loop_rate(100);
    while(ros::ok())
    {
        //获取缓冲区内的字节数
        size_t n = sp.available();
        if(n!=0)
        {
            uint8_t buffer[1024];
            //读出数据
            n = sp.read(buffer, n);

            for(int i=0; i<n; i++)
            {
                if(buffer[i]==0X55)            //IMU地址
                {
                        if(buffer[i+1]==0x51) //加速度帧
                        {
                            signed short int temp;
                            temp=buffer[i+3];
                            temp=temp<<8;
                            temp=(temp|buffer[i+2]);
                            ax=(temp/32768.0)*16*9.8051;
                            temp=buffer[i+5];         //加速度八位
                            temp=temp<<8;
                            temp=(temp|buffer[i+4]);  //加速度高八位
                            ay=(temp/32768.0)*16*9.8051;
                            temp=buffer[i+7];         //加速度低八位
                            temp=temp<<8;
                            temp=(temp|buffer[i+6]);  //加速度高八位
                            az=(temp/32768.0)*16*9.8051;
                            std::cout<<"ax:"<<ax<<std::endl;
                            std::cout<<"ay:"<<ay<<std::endl;
                            std::cout<<"az:"<<az<<std::endl;
                            i+=11;
                        }
                        if(buffer[i+1]==0x52) //角速度帧
                        {
                            signed short int temp;
                            temp=buffer[i+3];
                            temp=temp<<8;
                            temp=(temp|buffer[i+2]);
                            wx=(temp/32768.0)*2000;
                            temp=buffer[i+5];         //角速度低八位
                            temp=temp<<8;
                            temp=(temp|buffer[i+4]);  //角速度高八位
                            wy=(temp/32768.0)*2000;
                            temp=buffer[i+7];         //角速度低八位
                            temp=temp<<8;
                            temp=(temp|buffer[i+6]);  //角速度高八位
                            wz=(temp/32768.0)*2000;
                            std::cout<<"wx:"<<wx<<std::endl;
                            std::cout<<"wy:"<<wy<<std::endl;
                            std::cout<<"wz:"<<wz<<std::endl;
                            i+=11;
                        }
                     if(buffer[i+1]==0x53) //角度帧
                    {
                        unsigned short int temp;
                        temp=buffer[i+3];         //角度低八位
                        temp=temp<<8;
                        temp=(temp|buffer[i+2]);  //角度高八位
                        angle_roll=(temp/32768.0)*180;
                        temp=buffer[i+5];         //角度低八位
                        temp=temp<<8;
                        temp=(temp|buffer[i+4]);  //角度高八位
                        angle_pitch=(temp/32768.0)*180;
                        temp=buffer[i+7];         //角度低八位
                        temp=temp<<8;
                        temp=(temp|buffer[i+6]);  //角度高八位
                        angle_yaw=(temp/32768.0)*180;
                        std::cout<<"angle_roll:"<<angle_roll<<std::endl;
                        std::cout<<"angle_pitch:"<<angle_pitch<<std::endl;
                        std::cout<<"angle_yaw:"<<angle_yaw<<std::endl;
                        i+=11;
                    }
                     msg.angx=angle_roll;
                     msg.angy=angle_pitch;
                     msg.angz=angle_yaw;
                     msg.ax=ax;
                     msg.ay=ay;
                     msg.az=az;
                     msg.wx=wx;
                     msg.wy=wy;
                     msg.wz=wz;
                     pub_imu_data.publish(msg);
                }
            }
            std::cout << std::endl;
            //sp.write(buffer, n);
        }
        loop_rate.sleep();
    }

    //关闭串口
    sp.close();

    return 0;
}

自定义消息话题:imu_data.msg

float64 ax
float64 ay
float64 az
float64 wx
float64 wy
float64 wz
float64 angx
float64 angy
float64 angz

效果

在这里插入图片描述

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

使用WTGAHRS2(JY-GPSIMU)在ROS中读取数据并发布话题 的相关文章

  • 谁能建议我一种在 C++ 中分割名称的简单方法

    我一直在尝试将名称分为名字和姓氏 但我确信我的实现就简单性而言并不是最好的 string name John Smith string first string last name name find getting lastname fo
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • EF Core 通过完全替换断开集合导航属性的更新

    使用 EF Core 5 0 我有一个 SPA 页面 可以加载Group实体及其集合Employee来自 API 的实体 var groupToUpdate await context Groups Include g gt g Emplo
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • ASP.Net Core 内容配置附件/内联

    我正在从 WebAPI 控制器返回一个文件 Content Disposition 标头值自动设置为 附件 例如 处置 附件 文件名 30956 pdf 文件名 UTF 8 30956 pdf 当它设置为附件时 浏览器将要求保存文件而不是打
  • vs2008 c#:Facebook.rest.api如何使用它来获取好友列表?

    如何在此基础上取得进一步的进步 获取好友列表的下一步是什么 string APIKey ConfigurationManager AppSettings API Key string APISecret ConfigurationManag
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • 从 WebBrowser 控件 C# 获取滚动值

    我试图在 WebBrowser 控件中获取网页的 Y 滚动索引 但无法访问内置滚动条的值 有任何想法吗 对于标准模式下的 IE 使用文档类型 正如你所说 scrollTop是的财产元素 而不是 HtmlDocument htmlDoc th
  • 如何在标准 WPF ListView 中启用 UI 虚拟化

    我正在使用 NET 4 5 VS2012 并且我有一个 ListView 看起来像这样
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • 如何通过 JsonConvert.DeserializeObject 在动态 JSON 中使用 null 条件运算符

    我正在使用 Newtonsoft 反序列化已知的 JSON 对象并从中检索一些值 如果存在 关键在于对象结构可能会不断变化 因此我使用动态来遍历结构并检索值 由于对象结构不断变化 我使用 null 条件运算符来遍历 JSON 代码看起来像这
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 您是否将信息添加到每个 .hpp/.cpp 文件的顶部? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 创建新的 C 头文件 源文件时 您会在顶部添加哪些信息 例如 您是否添加日期 您的姓名 文件描述等 您是否使用结构化格式来存储此信息 e g F
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959

随机推荐

  • FreeRTOS的学习(二)——队列的介绍和操作

    目录 队列的简介 任务对队列的操作 读取队列中的消息 向队列中发送消息 队列结构体 队列创建 1 函数 xQueueCreate 动态创建队列 函数原型 参数 返回值 2 函数 xQueueCreateStatic 静态创建队列 函数原型
  • C++ cout << “\n“与 cout << endl的一个区别

    一句话概括 n 不会终止setw的计算 endl会 实际场景 代码1 include
  • MySQL必知必会 学习笔记 第十八章 全文本搜索

    并非所有引擎都支持全文本搜索 MyISAM支持 更新 1 MySQL 5 6 以前的版本 只有 MyISAM 存储引擎支持全文索引 2 MySQL 5 6 及以后的版本 MyISAM 和 InnoDB 存储引擎均支持全文索引 3 只有字段的
  • idea自定义注释模板方法名、参数、返回类型为空的问题

    重点的地方 在你的方法上输入 然后加上模板的名称 param和retrun才不会为空 如果你直接模板的名称 按键就会为空 https blog csdn net weixin 39591795 article details 7884442
  • 如何给Winform 的Panel控件添加滚动条

    真是太笨了 刚想起来 Panel控件还有一个AutoScoll属性 直接修改为true即可 添加Panel控件的如下两个事件即可 当然 只是添加的竖向滚动条 横向滚动条只需把VerticalScroll改为HorizontalScroll即
  • linux进阶-运维自动化工具之ansible

    文章目录 云计算运维工程师核心职能 ansible特性 ansible架构 ansible组成部分 ansible命令执行来源 ansible使用注意事项 ansible安装和入门 epel源的rpm包安装 编译安装 git方式 pip安装
  • ConvertException: Unsupported source type: class java.lang.String

    项目上遇到 文件异步上传时会把不符合标准的数据放入redis 然后隔几秒去请求redis里面的数据 但是时不时会出现ConvertException Unsupported source type class java lang Strin
  • tensorflow报错总结

    项目场景 tensorflow 版本 不兼容产生的报错 问题描述 1 AttributeError module tensorflow has no attribute random uniform 解决办法 tf2 0中用tf rando
  • 使用rancher在k8s上完成第一个CI/CD的项目_.NET篇

    隔了几天没写了 一是忙的不行 二是遇到一个问题一直没解决 我们自己搭建的harbor仓库是没有域名的 也没做nginx转发 所以都是http请求的 构建项目时会在两个地方遇到关于docker访问http仓库不通的问题 第一个 构建成功pus
  • Hadoop集群——shell自动采集文件到HDFS

    1 配置环境变量 在 export data logs目录下 目录不存在 则先提前创建该目录 使用vi命令创建 upload2HDFS sh脚本文件 在编写Shell脚本时 需要设置Java环境变量 即使当前虚拟 机节点已经配置了Java环
  • windows10下navicat 无限使用小技巧

    windows10下navicat 无限次使用小技巧 1 首先win R 输入regedit 2 找到HKEY CURRENT USER gt Software gt Classes gt CLSID gt 下面文件夹中有info的删除掉
  • 如何从巨潮资讯爬取股票公告

    z如何做一个难以被反制的爬虫 Selenium Python爬取新股材料实例 之前我写了上面这篇文章来说明如何从深交所或者上交所的网站爬取文件 但是这个爬虫是有点不稳定的 因为网速的原因 偶然间我发现巨潮资讯已经整合了所需要的公告 因此又写
  • tomcat常见报错

    1 Web页面乱码 解决方案 1 可以采用英文输出 只需要配置启动参数即可 2 确认项目编码都设置为UTF 8后 在StringManager java 134行后 增加一行代码 str new String str getBytes St
  • PAT 乙级 1057 数零壹 python

    题目 思路 先判断是否为字母 再求和 通过迭代取余 计算0 1的数目 代码 alpha a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17
  • 蓝桥杯题库 历届试题部分(C++、Java)代码实现(16-30)

    文章目录 五 历届试题 PREV 16 农场阳光 PREV 17 约数倍数选卡片 PREV 18 车轮轴迹 PREV 19 九宫重排 PREV 20 公式求值 PREV 21 回文数字 PREV 22 国王的烦恼 PREV 23 数字游戏
  • flutter toast插件 OKToast的介绍

    OKToast 是一款 在 flutter 上 使用的 toast 插件 使用简单 可定制性强 纯 flutter 调用不用 context 文章目录 安装 使用 在代码中定义 OKToast 组件 调用 文本 toast 自定义 widg
  • Centos7安装redis(详细步骤)

    一 安装redis 1 yum安装redis yum install redis 2 启动redis 启动redis service redis start 停止redis service redis stop 查看redis运行状态 se
  • c++栈详解(附代码)

    1 栈 Stack 是一种线性存储结构 它具有如下特点 1 栈中的数据元素遵守 先进后出 First In Last Out 的原则 简称FILO结构 后进先出的叫法 也是可以的 2 限定只能在栈顶进行插入和删除操作 2 栈的相关概念 1
  • CNN中feature map、卷积核、卷积核个数、filter、channel的概念解释,以及CNN 学习过程中卷积核更新的理解

    feature map 卷积核 卷积核个数 filter channel的概念解释 feather map的理解 在cnn的每个卷积层 数据都是以三维形式存在的 你可以把它看成许多个二维图片叠在一起 像豆腐皮一样 其中每一个称为一个feat
  • 使用WTGAHRS2(JY-GPSIMU)在ROS中读取数据并发布话题

    目录 IMU简介 驱动程序 IMU串口通信协议 程序 效果 IMU简介 十轴惯性导航传感器WTGAHRS2传感器集成高精度的陀螺仪 加速度计 地磁场传感器 GPS 模块 采用高性能的微处理器和先进的动力学解算与卡尔曼动态滤波算法 能够快速求