基于ROS的串口底层写法
serial_device.cpp
#include "serial_device.h"
namespace roborts_sdk {
SerialDevice::SerialDevice(std::string port_name,
int baudrate) :
port_name_(port_name),
baudrate_(baudrate),
data_bits_(8),
parity_bits_('N'),
stop_bits_(1) {}
SerialDevice::~SerialDevice() {
CloseDevice();
}
bool SerialDevice::Init() {
DLOG_INFO << "Attempting to open device " << port_name_ << " with baudrate " << baudrate_;
if (port_name_.c_str() == nullptr) {
port_name_ = "/dev/ttyUSB0";
}
if (OpenDevice() && ConfigDevice()) {
FD_ZERO(&serial_fd_set_);
FD_SET(serial_fd_, &serial_fd_set_);
DLOG_INFO << "...Serial started successfully.";
return true;
} else {
DLOG_ERROR << "...Failed to start serial "<<port_name_;
CloseDevice();
return false;
}
}
bool SerialDevice::OpenDevice() {
serial_fd_ = open(port_name_.c_str(), O_RDWR | O_NOCTTY);
if (serial_fd_ < 0) {
DLOG_ERROR << "cannot open device " << serial_fd_ << " " << port_name_;
return false;
}
return true;
}
bool SerialDevice::CloseDevice() {
close(serial_fd_);
serial_fd_ = -1;
return true;
}
bool SerialDevice::ConfigDevice() {
int st_baud[] = {B4800, B9600, B19200, B38400,
B57600, B115200, B230400, B921600};
int std_rate[] = {4800, 9600, 19200, 38400, 57600, 115200,
230400, 921600, 1000000, 1152000, 3000000};
int i, j;
/* save current port parameter */
if (tcgetattr(serial_fd_, &old_termios_) != 0) {
DLOG_ERROR << "fail to save current port";
return false;
}
memset(&new_termios_, 0, sizeof(new_termios_));
/* config the size of char */
new_termios_.c_cflag |= CLOCAL | CREAD;
new_termios_.c_cflag &= ~CSIZE;
/* config data bit */
switch (data_bits_) {
case 7:new_termios_.c_cflag |= CS7;
break;
case 8:new_termios_.c_cflag |= CS8;
break;
default:new_termios_.c_cflag |= CS8;
break; //8N1 default config
}
/* config the parity bit */
switch (parity_bits_) {
/* odd */
case 'O':
case 'o':new_termios_.c_cflag |= PARENB;
new_termios_.c_cflag |= PARODD;
break;
/* even */
case 'E':
case 'e':new_termios_.c_cflag |= PARENB;
new_termios_.c_cflag &= ~PARODD;
break;
/* none */
case 'N':
case 'n':new_termios_.c_cflag &= ~PARENB;
break;
default:new_termios_.c_cflag &= ~PARENB;
break; //8N1 default config
}
/* config baudrate */
j = sizeof(std_rate) / 4;
for (i = 0; i < j; ++i) {
if (std_rate[i] == baudrate_) {
/* set standard baudrate */
cfsetispeed(&new_termios_, st_baud[i]);
cfsetospeed(&new_termios_, st_baud[i]);
break;
}
}
/* config stop bit */
if (stop_bits_ == 1)
new_termios_.c_cflag &= ~CSTOPB;
else if (stop_bits_ == 2)
new_termios_.c_cflag |= CSTOPB;
else
new_termios_.c_cflag &= ~CSTOPB; //8N1 default config
/* config waiting time & min number of char */
new_termios_.c_cc[VTIME] = 1;
new_termios_.c_cc[VMIN] = 18;
/* using the raw data mode */
new_termios_.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
new_termios_.c_oflag &= ~OPOST;
/* flush the hardware fifo */
tcflush(serial_fd_, TCIFLUSH);
/* activite the configuration */
if ((tcsetattr(serial_fd_, TCSANOW, &new_termios_)) != 0) {
DLOG_ERROR << "failed to activate serial configuration";
return false;
}
return true;
}
int SerialDevice::Read(uint8_t *buf, int len) {
int ret = -1;
if (NULL == buf) {
return -1;
} else {
ret = read(serial_fd_, buf, len);
DLOG_INFO<<"Read once length: "<<ret;
while (ret == 0) {
LOG_ERROR << "Connection closed, try to reconnect.";
while (!Init()) {
usleep(500000);
}
LOG_INFO << "Reconnect Success.";
ret = read(serial_fd_, buf, len);
}
return ret;
}
}
int SerialDevice::Write(const uint8_t *buf, int len) {
return write(serial_fd_, buf, len);
}
}
serial_device.h
#ifndef ROBORTS_SDK_SERIAL_DEVICE_H
#define ROBORTS_SDK_SERIAL_DEVICE_H
#include <string>
#include <cstring>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include "../utilities/log.h"
#include "hardware_interface.h"
namespace roborts_sdk {
/**
* @brief serial device class inherited from hardware interface
*/
class SerialDevice: public HardwareInterface {
public:
/**
* @brief Constructor of serial device
* @param port_name port name, i.e. /dev/ttyUSB0
* @param baudrate serial baudrate
*/
SerialDevice(std::string port_name, int baudrate);
/**
* @brief Destructor of serial device to close the device
*/
~SerialDevice();
/**
* @brief Initialization of serial device to config and open the device
* @return True if success
*/
virtual bool Init() override ;
/**
* @brief Serial device read function
* @param buf Given buffer to be updated by reading
* @param len Read data length
* @return -1 if failed, else the read length
*/
virtual int Read(uint8_t *buf, int len) override ;
/**
* @brief Write the buffer data into device to send the data
* @param buf Given buffer to be sent
* @param len Send data length
* @return < 0 if failed, else the send length
*/
virtual int Write(const uint8_t *buf, int len) override ;
private:
/**
* @brief Open the serial device
* @return True if open successfully
*/
bool OpenDevice();
/**
* @brief Close the serial device
* @return True if close successfully
*/
bool CloseDevice();
/**
* @brief Configure the device
* @return True if configure successfully
*/
bool ConfigDevice();
//! port name of the serial device
std::string port_name_;
//! baudrate of the serial device
int baudrate_;
//! stop bits of the serial device, as default
int stop_bits_;
//! data bits of the serial device, as default
int data_bits_;
//! parity bits of the serial device, as default
char parity_bits_;
//! serial handler
int serial_fd_;
//! set flag of serial handler
fd_set serial_fd_set_;
//! termios config for serial handler
struct termios new_termios_, old_termios_;
};
}
#endif //ROBORTS_SDK_SERIAL_DEVICE_H
//简单初始化
device_ = std::make_shared<SerialDevice>("/dev/ttyUSB0", 921600);
device_ ->Init();
基于ROS的串口底层写法的更多相关文章
- 基于STM32F10x的串口(USART)输入输出编程
1 前言 STM32有强大的固件库,绝大部分函数都可以有库里面的函数组合编写.固件库可以到ST官网(www.st.com)上下载,也可以搜索“STM32 固件库 v3.5”下载到固件库.本文章就是基于 ...
- 基于ROS的分布式机器人远程控制平台
基于ROS的分布式机器人远程控制平台 1 结构说明 HiBot架构主要使用C/S架构,其中HibotServer为服务器,Muqutte为消息服务器中间件,HiBotClient为运行在机器人上的 ...
- ROS 设置串口USB软连接
原创:未经同意,请勿转载 我们在windows 通过USB连接串口,在设备串口中可以观测到COM0或者COMx.当我们插入不同的USB口时会显示不同的COM. 在UBUNTU下,ROS下接收串口信息时 ...
- Ubuntu16.04 + ROS下串口通讯
本文参考https://blog.csdn.net/weifengdq/article/details/84374690 由于工程需要,需要Ubuntu16.04 + ROS与STM32通讯,主要有两 ...
- 基于ROS和beaglebone的串口通信方式,使用键盘控制移动机器人
一.所需工具包 1.ROS键盘包:teleop_twist_keyboard 2.ROS串口通讯包:serial $ cd ~/catkin_ws/src $ git clone https://g ...
- [转]基于ROS平台的移动机器人-4-通过ROS利用键盘控制小车移动
原文出处: https://blog.csdn.net/Forrest_Z/article/details/55002484 准备工作 1.下载串口通信的ROS包 (1)cd ~/catkin_ws/ ...
- 基于ROS和python,通过TCP通信协议,完成键盘无线控制移动机器人运动
一.所需工具包 1.ROS键盘包:teleop_twist_keyboard 2.TCP通讯包:socket $ cd ~/catkin_ws/src $ git clone https://gith ...
- 【Delphi】基于状态机的串口通信
通信协议 串行通信接口(如RS232.RS485等)作为计算机与单片机交互数据的主要接口,广泛用于各类仪器仪表.工业监测及自动控制领域中. 通信协议是需要通信的双方所达成的一种约定,它对包括数据格式. ...
- 基于Android的串口聊天室 (基于tiny4412) 一
一.平台介绍 硬件平台: tiny4412ADK + S700 4GB Flash Android版本:Android-5.0.2 Linux版本: Linux-3.0.86 Bootloader:S ...
- 基于433MHz无线串口,多发一收解决方案
一.无线发展背景 随着科学技术的飞速发展,智能家居.智慧农业.智慧城市如雨后春笋.而这些行业的发展离不开无线的应用. 传统的有线连接不仅仅是成本高,包括布线安装.维护等也是成本巨大.并且机动性也很差, ...
随机推荐
- ThinkPHP6.0在phpstorm添加查询构造器和模型的代码提示
ThinkPHP6.0升级后 使用查询构造器和模型都没有了提示 原因是tp6源码中没有添加注释 找到Model.php * @method Query where(mixed $field, stri ...
- mac连接mysql出现Access denied for user ‘root‘@‘localhost‘
处理方法:1.关闭mysql的服务,点击最左上的苹果图标在系统偏好设置中,找到mysql,点击,stop 确认关闭后进入终端 输入(cd /usr/local/mysql/bin/)回车 输入(sud ...
- 《HTTP权威指南》– 3.HTTP方法和状态码
常见HTTP方法: 常用HTTP方法 描述 是否包含主体 GET 从服务器获取一份文档 否 HEAD 只从服务器获取文档的首部 否 POST 向服务器发送需要处理的数据 是 PUT 将请求的主体部分存 ...
- SQLMap入门——获取表中的字段名
查询表名之后,查询表中的字段名 python sqlmap.py -u http://localhost/sqli-labs-master/Less-1/?id=1 -D xssplatform -T ...
- python循环结构之for循环
在python中,for循环是应用非常广的循环语句,遍历字典.遍历列表等等... # for语句结构 for 遍历 in 序列: 执行语句 遍历字典 lipsticks = {"Chanel ...
- JavaScript:原型(prototype)
面向对象有一个特征是继承,即重用某个已有类的代码,在其基础上建立新的类,而无需重新编写对应的属性和方法,继承之后拿来即用: 在其他的面向对象编程语言比如Java中,通常是指,子类继承父类的属性和方法: ...
- .net core-利用PdfSharpCore 操作PDF实例
前序 使用PdfSharpCore请注意使用XGraphics基类,与System.Drawing 的Graphics类似,XGraphics 提供XColor(颜色).XPen(画笔).XBrush ...
- vue3 递归组件 树形组件
递归组件 第一种方式,直接自己调用自己 Tree.vue <template> <div class="tree"> <div v-for=" ...
- APICloud平台使用融云模块实现音视频通话实践经验总结分享
需求概要:实现视频拨打.接听.挂断.视频界面大小窗口.点击小窗口实现大小窗口互换. 实现思路:一方拨打后,另一方要能收到相应事件,然后接听.接通后,渲染对方视频画面.那么己方视频画面什么时候渲染呢?对 ...
- 再聊一下那 SQLSERVER 行不能跨页的事
一:背景 1. 讲故事 上一篇写完了之后,马上就有朋友留言对记录行的 8060byte 限制的疑惑,因为他的表记录存储了大量的文章,存储文章的字段类型用的是 nvarchar(max),长度很显然是超 ...