ROS串⼝通信(2)以⼗六进制指令读取IMU数据
ROS串⼝通信(2)以⼗六进制指令读取IMU数据
引⾔
20200527更新:最近发现阅读量还蛮⾼,应该⽐较实⽤吧,刚刚把之前的代码贴到github上了,如果有帮助到您,希望帮我博客或github点个赞啊,助我⼯作⼀臂之⼒!谢谢了.
.
前期准备参考
1、下载安装ROS的serial软件包
sudo apt-get install ros-kinetic-serial #ros为Kinect版本
进⼊下载的软件包的位置
roscd serial
安装成功:
opt/ros/kinetic/share/serial
这个路径也是ROS的其他库⽂件路径,很重要,经常会⽤到。相关头⽂件路径在opt/ros/kinetic/include⾥⾯,相关源⽂件在opt/ros/kinetic/share⾥⾯。⽐如要查看imu.msg,则源⽂件路径为/opt/ros/kinetic/include/sensor_msgs。
头⽂件或者说是消息格式路径在/opt/ros/kinetic/share/sensor_msgs/msg下⾯。
# This is a message to hold data from an IMU (Inertial Measurement Unit)
#
# Accelerations should be in m/s^2 (not in g's), and rotational velocity should be in rad/sec
#
# If the covariance of the measurement is known, it should be filled in (if all you know is the
# variance of each measurement, e.g. from the datasheet, just put those along the diagonal)
# A covariance matrix of all zeros will be interpreted as "covariance unknown", and to use the
# data a covariance will have to be assumed or gotten from some other source
#
# If you have no estimate for one of the data elements (e.g. your IMU doesn't produce an orientation # estimate), please set element 0 of the associated covariance matrix to -1
# If you are interpreting this message, please check for a value of -1 in the first element of each
# covariance matrix, and disregard the associated estimate.
Header header
geometry_msgs/Quaternion orientation
float64[9] orientation_covariance # Row major about x, y, z axes
geometry_msgs/Vector3 angular_velocity
float64[9] angular_velocity_covariance # Row major about x, y, z axes
geometry_msgs/Vector3 linear_acceleration
float64[9] linear_acceleration_covariance # Row major x, y z
2、通⽤serial通信代码
#include <ros/ros.h>
#include <serial/serial.h> //ROS已经内置了的串⼝包
#include <std_msgs/String.h>
#include <std_msgs/Empty.h>
serial::Serial ser; //声明串⼝对象
//回调函数
void write_callback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO_STREAM("Writing to serial port" <<msg->data);
ser.write(msg->data); //发送串⼝数据
}
int main (int argc, char** argv)
{
//初始化节点
ros::init(argc, argv, "serial_example_node");
/
/声明节点句柄
ros::NodeHandle nh;
//订阅主题,并配置回调函数
ros::Subscriber write_sub = nh.subscribe("write", 1000, write_callback); //发布主题
ros::Publisher read_pub = nh.advertise<std_msgs::String>("read", 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 port ");
return -1;
}
//检测串⼝是否已经打开,并给出提⽰信息
if(ser.isOpen())
{
ROS_INFO_STREAM("Serial Port initialized");
}
else
{
return -1;
}
//指定循环的频率
ros::Rate loop_rate(50);
while(ros::ok())
{
if(ser.available())
{
ROS_INFO_STREAM("Reading from serial port\n");
std_msgs::String result;
result.data = ad(ser.available());
ROS_INFO_STREAM("Read: " << result.data);
read_pub.publish(result);
}
//处理ROS的信息,⽐如订阅消息,并调⽤回调函数
ros::spinOnce();
loop_rate.sleep();
}
}
此部分主要参考.该⽂章主要实现的功能:
3、使⽤ROS serial包实现IMU⼗六进制指令发送及数据读取编解码保存。
在⼀开始,ROS serial不⽀持直接发送⼗六进制指令尝试了⼀下更改,⽹上⼤多数资料都是直接通过串⼝进⾏数据读取,没有指令发送的环节即是很少有实现通过serial.write()函数进⾏指令发送,⼤多的应⽤环境只需要接收数据即可。后来参考,此⽂虽然实现了⼗六进制的通信,但是实现过程是⾃⼰定义了⼀个消息类型通过topic转换还是怎么的过后就能够使⽤serial.write()函数进⾏指令发送,然后我在这上⾯浪费了些时间,后来查到资料说将指令转换为Unicode编码可以使⽤serial.write()函数进⾏发送,Unicode编码相当于是⼀个底层的通信格式,也进⾏了尝试,实现了Unicode的转换但是依然不能发送,原因可能是我⽤的C++,⽽资料⾥⾯是使⽤的python,后来也就放弃了该⽅法。回归到最初进⾏思考,发现⾃⼰真的很傻,根本不需要如此⿇烦,也不需要像参考博客那样进⾏⾃定义消息类型然后进⾏发送,虽然我是在复现了他的机制后才醒悟的,果断改了。⾄于是怎样实现的直接上代码吧。
ImuCommand.h
/************************************************************************************************************
* Copyright Notice
* Copyright (c) 2018,冯****
*
* @File : ImuCommand.h
* @Brief : IMu指令
*
* @Version : V1.0
* @Date : 2018/11/23
* @History :
python怎么读取串口数据
* Author : 冯****
* Descrip: 命令字节,由外部控制器发送⾄GY953,帧头0xa5,指令格式:帧头+指令+校验和
*************************************************************************************************************/
#ifndef IMUCOMMAND_H
#define IMUCOMMAND_H
#include <iostream>
#include "serial/serial.h"
#include <ros/ros.h>
#include <std_msgs/String.h>
#include <std_msgs/Empty.h>
#include "serial_msgs/serial.h"
#define READ_BUFFERSIZE 13 //读取数据数组长度
#define cmd_num 3 //指令数组长度
#define DATA_LENGTH 3 //解码后数组长度
#define Q4DATA_LENGTH 4 //解码后四元数数组长度
#define mulitCmd_num 9 //复合指令数组长度
#define EULAR_MEASURE 100.0 //欧拉⾓度量,原始数据除以之
#define Q4_MEASURE 1000.0 //四元数度量,原始数据除以之
//判断本帧数据类型
#define DATA_FrameHead (unsigned char)(90) //接收数据的帧头
#define DATA_TYPE_ACC (unsigned char)(21) //该帧输出数据为加速度类型
#define DATA_TYPE_GRY (unsigned char)(37) //该帧输出数据为陀螺仪类型
#define DATA_TYPE_MAG (unsigned char)(53) //该帧输出数据为磁⼒计类型
#define DATA_TYPE_EULAR (unsigned char)(69) //该帧输出数据为欧拉⾓类型
#define DATA_TYPE_STOP (unsigned char)(85) //该帧输出数据为保留不⽤类型
#define DATA_TYPE_Q4 (unsigned char)(101) //该帧输出数据为四元数类型
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论