基于ROS和beaglebone的串口通信方式,使用键盘控制移动机器人
一、所需工具包
1.ROS键盘包:teleop_twist_keyboard
2.ROS串口通讯包:serial
- $ cd ~/catkin_ws/src
- $ git clone https://github.com/Forrest-Z/teleop_twist_keyboard.git
- $ git clone https://github.com/Forrest-Z/serial.git
- $ catkin_make
3.在ubuntu的ros中建立一个ros_car_pkg包:
- $ cd ~/catkin_ws/src
- $ catkin_create_pkg ros_car_pkg roscpp rospy std_msgs
4.新建 base_controller 文件:
- $ cd catkin_ws/src/base_controller
- $ mkdir src
- $ vim src/base_controller.cpp
代码如下:
/******************************************************************
串口通信说明:
1.写入串口
(1)内容:左右轮速度,单位为mm/s
(2)格式:10个字节,[右轮速度4字节][左轮速度4字节][结束符"\n"1个字节]
2.读取串口
(1)内容:小车线速度,角速度,单位依次为:mm/s,rad/s
*******************************************************************/
- #include "ros/ros.h"
- #include <geometry_msgs/Twist.h>
- #include <string>
- #include <iostream>
- #include <cstdio>
- #include <unistd.h>
- #include <math.h>
- #include "serial/serial.h"
- using std::ios;
- using std::string;
- using std::exception;
- using std::cout;
- using std::cerr;
- using std::endl;
- using std::vector;
- float ratio = 1000.0f ; //转速转换比例,执行速度调整比例
- float D = 0.2680859f ; //两轮间距,单位是m
- float linear_temp=0,angular_temp=0;//暂存的线速度和角速度
- unsigned char data_terminal=0x0a; //“/n"字符
- unsigned char speed_data[9]={0}; //要发给串口的数据
- union floatData //union的作用将较大的对象分解成组成这个对象的各个字节
- {
- float d;
- unsigned char data[4];
- }right_speed_data,left_speed_data;
- /************************************************************/
- void callback(const geometry_msgs::Twist& cmd_input)//订阅/cmd_vel主题回调函数
- {
- string port("/dev/ttyUSB0"); //小车串口号
- unsigned long baud = 115200; //小车串口波特率
- serial::Serial my_serial(port, baud, serial::Timeout::simpleTimeout(1000)); //配置串口
- angular_temp = cmd_input.angular.z ;//获取/cmd_vel的角速度,rad/s
- linear_temp = cmd_input.linear.x ;//获取/cmd_vel的线速度.m/s
- //将转换好的小车速度分量为左右轮速度
- left_speed_data.d = linear_temp- 0.5f*angular_temp*D ;
- right_speed_data.d = linear_temp+ 0.5f*angular_temp*D ;
- //存入数据到要发布的左右轮速度消息
- left_speed_data.d*=ratio; //放大1000倍,mm/s
- right_speed_data.d*=ratio;//放大1000倍,mm/s
- cout<<"angular_temp = "<< angular_temp << endl;
- cout<<"linear_temp = "<< linear_temp<<endl;
- cout<<"left_speed_data.d = "<< left_speed_data.d<<endl;
- cout<<"right_speed_data.d = "<< right_speed_data.d << endl;
- for(int i=0;i<4;i++) //将左右轮速度存入数组中发送给串口
- {
- speed_data[i]=right_speed_data.data[i];
- speed_data[i+4]=left_speed_data.data[i];
- }
- //在写入串口的左右轮速度数据后加入”/n“
- speed_data[8]=data_terminal;
- //speed_data[9]=data_terminal1;
- //写入数据到串口
- for(int i=0;i<9;i++){
- cout.setf(ios::hex,ios::basefield);//设置十六进制显示数值
- cout.setf(ios::showbase|ios::uppercase);//设置0x头和大写
- cout<<"s_i = "<<(int)speed_data[i]<<endl;
- }
- my_serial.write(speed_data,10);
- }
- int main(int argc, char **argv)
- {
- ros::init(argc, argv, "base_controller");
- ros::NodeHandle n;
- ros::Subscriber sub = n.subscribe("cmd_vel", 20, callback); //订阅cmd_vel主题
- ros::spin();//周期执行
- return 0;
- }
修改CMakeList.txt:
- cmake_minimum_required(VERSION 2.8.3)
- project(ros_car_pkg)
- find_package(catkin REQUIRED COMPONENTS
- message_generation
- roscpp
- rospy
- std_msgs
- serial
- tf
- nav_msgs
- )
- include_directories(
- # include
- ${catkin_INCLUDE_DIRS}
- ${serial_INCLUDE_DIRS}
- )
- add_message_files(FILES MsgCar.msg)
- generate_messages(DEPENDENCIES std_msgs)
- add_executable(base_controller src/base_controller.cpp)
- target_link_libraries(base_controller ${catkin_LIBRARIES})
- add_dependencies(base_controller ros_car_pkg_generate_messages_cpp)
- catkin_package(CATKIN_DEPENDS roscpp rospy std_msgs)
单独编译ros_car_pkg包:
- $ catkin_make -DCATKIN_WHITELIST_PACKAGES='ros_car_pkg'
二、控制原理:
- 当我们按下键盘时,teleop_twist_keyboard 包会发布 /cmd_vel 发布速度主题
- 在 base_controller 节点订阅这个话题,接收速度数据,转换成字节数据,然后写入串口
- 通过USB转串口线,连接到板子的UART串口,在beaglebone中读取串口数据
- 将串口数据转换成pwm信号,并加载设备树,控制电机运转,从而实现键盘控制小车的移动
1.设置beaglebone串口:
查询手册,选择UART4,其中TXD(发送数据引脚)为P9-13,RXD(接受数据引脚)p9-11
实验室的usb转串口线为:蓝色对应数据接受端,接RXD;白色对应发送数据端,接TXD, 黑色和红色一定要悬空!!!
将串口线的USB端插上电脑,启动板子,在ubuntu中登录板子
$ ssh root@192.168.7.2
测试的时候先手动加载UART4设备树(后面串口配置成功之后,可以通过程序直接启动)
$ cd /sys/devices/bone_capemgr.9/
$ echo BB-UART4 > slots
$ cat slots
如果加载成功,在/dev下会出现ttyO4串口
$ cd /dev
$ ls tty*
先使用screen或者minicom监测该串口
$ sudo screen /dev/ttyO4 115200
设置ubuntu中的ros串口:
如果usb转串口线没坏的话,在/dev下看到ttyUSB0
$ cd /dev
$ ls tty*
$ sudo chmod 666 /dev/ttyUSB0
如果该步骤设置成功的话,通过往ros串口发数据,可以在上述screen监测的串口看到发送的数据
$ echo "Hello HFUT" > /dev/ttyUSB0
至此,串口设置完成
三、建立ros通信:
1.ubuntu中的ros端操作:
- $ roscore
- $ rosrun teleop_twist_keyboard teleop_twist_keyboard.py
- $ rosrun ros_car_pkg base_controller
2.beaglebone终端操作:
运行代码加载设备树并读串口数据用于控制PWM,进而控制小车运动
- #include<stdio.h>
- #include<fcntl.h>
- #include<unistd.h>
- #include<termios.h>
- #define SLOTS "/sys/devices/bone_capemgr.9/slots"
- int main()
- {
- int fd, count_r,count_t,i;
- unsigned char buff[100]; // the reading & writing buffer
- struct termios opt; //uart confige structure
- //加载设备树
- if ((fd = open(SLOTS, O_WRONLY)) < 0)
- {
- perror("SLOTS: Failed to open the file. \n");
- return -1;
- }
- if ((count_t = write(fd, "BB-UART4",8))<0) //8ge zi fu
- {
- perror("SLOTS:Failed to write to the file\nFailed to mount the UART4");
- return -1;
- }
- close(fd);
- //设置串口
- if ((fd = open("/dev/ttyO4", O_RDWR | O_NOCTTY )) < 0)
- {
- perror("UART: Failed to open the UART device:ttyO4.\n");
- return -1;
- }
- tcgetattr(fd, &opt); // get the configuration of the UART
- opt.c_cflag = B115200| CS8 | CREAD | CLOCAL;
- // 115200 baud, 8-bit, enable receiver, no modem control lines
- opt.c_iflag = IGNPAR | ICRNL;
- // ignore partity errors, CR -> newline
- opt.c_iflag &= ~(IXON | IXOFF | IXANY);
- //turn off software stream control
- opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
- tcflush(fd,TCIOFLUSH); // 清理输入输出缓冲区
- tcsetattr(fd, TCSANOW, &opt); // changes occur immmediately
- //读串口
- while(1)
- {
- if ((count_r = read(fd,(void*)buff,100))<0){
- perror("ERR:No data is ready to be read\n");
- return -1;
- }
- if (count_r == 0){
- printf("ERR:No data is ready to be read\n");
- }
- else
- {
- printf("The following was read in [%d]:%X\n",count_r,buff); //具体格式是字节
- }
- //发送PWM
- if (buff != NULL)
- {
- if ((fd = open(SLOTS, O_WRONLY)) < 0)
- {
- perror("SLOTS: Failed to open the file. \n");
- return -1;
- }
- if ((count_t = write(fd, "bone_pwm_P9_22",14))<0) //8ge zi fu
- {
- perror("SLOTS:Failed to write to the file\nFailed to mount the bone_pwm_P9_22");
- return -1;
- }
- if ((count_t = write(fd, "bone_pwm_P9_16",14))<0) //8ge zi fu
- {
- perror("SLOTS:Failed to write to the file\nFailed to mount the bone_pwm_P9_16");
- return -1;
- }
- if ((count_t = write(fd, "am33xx_pwm",10))<0) //8ge zi fu
- {
- perror("SLOTS:Failed to write to the file\nFailed to mount the PWM");
- return -1;
- }
- close(fd);
- if ((fd = open(p922,O_WRONLY))<0)
- {
- perror("p922: Failed to open the file. \n");
- return -1;
- }
- if((count_t= write(fd,"1",1))<0) //8ge zi fu
- {
- perror("p922run:Failed to write to the file\nFailed to mount the p9223");
- return -1;
- }
- close(fd);
- if ((fd = open(p916,O_WRONLY))<0)
- {
- perror("p916: Failed to open the file. \n");
- return -1;
- }
- if((count_t= write(fd,"1",1))<0) //8ge zi fu
- {
- perror("p916run:Failed to write to the file\nFailed to mount the p9223");
- return -1;
- }
- close(fd);
- usleep(50000000);
- }
- return 0;
- }
基于ROS和beaglebone的串口通信方式,使用键盘控制移动机器人的更多相关文章
- [转]基于ROS平台的移动机器人-4-通过ROS利用键盘控制小车移动
原文出处: https://blog.csdn.net/Forrest_Z/article/details/55002484 准备工作 1.下载串口通信的ROS包 (1)cd ~/catkin_ws/ ...
- 自己编写的基于VC++6.0的串口调试软件,并贡献源程序!
自己编写的基于VC++6.0的串口调试软件源程序! 程序下载链接: 点击打开链接
- 基于ROS的分布式机器人远程控制平台
基于ROS的分布式机器人远程控制平台 1 结构说明 HiBot架构主要使用C/S架构,其中HibotServer为服务器,Muqutte为消息服务器中间件,HiBotClient为运行在机器人上的 ...
- 自制单片机之十七……PC与单片机RS-232串口的通讯和控制
这次我们来试着一步步的去掌握PC与单片机通过RS-232进行通讯和控制. 先说说我硬件的情况.我用的PC是个二手的IBM240小本本,十寸屏,赛扬400,机子很老了.但也有它的优点:1.串口,并口,P ...
- 基于TINY4412的Andorid开发-------简单的LED灯控制【转】
本文转载自:http://www.cnblogs.com/pengdonglin137/p/3857724.html 基于TINY4412的Andorid开发-------简单的LED灯控制 阅读 ...
- Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级
1.权限管理 权限管理的基本定义:百度百科. 基于<Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员.后台管理员同时登录>我们做过了登录认证, ...
- 基于spring security 实现前后端分离项目权限控制
前后端分离的项目,前端有菜单(menu),后端有API(backendApi),一个menu对应的页面有N个API接口来支持,本文介绍如何基于spring security实现前后端的同步权限控制. ...
- 基于VHDL利用PS2键盘控制的电子密码锁设计
基于VHDL利用PS2键盘控制的密码锁设计 附件:下载地址 中文摘要 摘 要:现代社会,人们的安全意识正在不断提升.按键密码锁由于其具有方便性.低成本等特征,还是大有用武之地的.但是通常的按键密码锁开 ...
- 基于FPGA的5寸LCD显示屏的显示控制
基于FPGA的5寸LCD显示屏的显示控制 作者:lee神 1,图像处理基础知识 数字图像处理是指将图像信号转换成数字信号并利用计算机对其进行处理的过程.图像处理最早出现于 20 世纪 50 年代,当时 ...
随机推荐
- OpenGL step by step 38 : Skeletal Animation with Assimp
一般骨架模型由两部分组成: Rigging(bone):相当于骨架,可以用来控制模型的动作 Mesh(skin):相当于表面皮肤 骨架模型一般是层级结构的,比如上面 背骨是root,他的孩子包括胳膊. ...
- Linux系统挂载windows共享目录报错mount error(121):remote error I/O error
经查,这是由于NFS(Network File System)即网络文件系统服务器有多个版本,V2.V3.V4.而且各版本同时运行,因此挂载时需要说明版本号 mount -o username='pk ...
- vue.config.js
const path = require('path'); const vConsolePlugin = require('vconsole-webpack-plugin'); // 引入 移动端模拟 ...
- HTTP状态码--含义
以下是HTTP状态码(HTTP Status Code)及其解释 1xx(临时响应) (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. (切换协议) 请 ...
- 类似于Mimikatz的Linux Hash Dump工具
项目主页 https://github.com/huntergregal/mimipenguin 需要root权限 支持 Kali 4.3.0 (rolling) x64 (gdm3) Ubuntu ...
- python全栈开发 * 24 知识点汇总 * 180705
24 模块-------序列化一.什么是模块 模块:py文件就是一个模块.二.模块的分类:(1)内置模块 (登录模块,时间模块,sys模块,os模块)(2)扩展模块 (itchat 微信有关,爬虫,b ...
- java动态加载配置文件(申明:来源于网络)
java动态加载配置文件 地址:http://blog.csdn.net/longvs/article/details/9361449
- Dijkstra模板
Dijkstra struct node { long long x,d; node(); node(long long xx,long long dd){ x = xx; d = dd; } }; ...
- ionic3.x版本开发问题记录---使用Image Resizer打包报错问题
按照官方文档安装和使用,最后在打包的时候报错 /platforms/android/src/info/protonet/imageresizer/ImageResizer.java:12: error ...
- shiro 角色与权限的解读
1.为什么 shiro 有了<角色>后,还要设置<角色权限>呢?(问题) 思考:设置好角色了,那么就代表什么操作都可以执行了吗? 理解:如果上边回答是的话,那么只是<角色 ...