基于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 年代,当时 ...
随机推荐
- ubuntu16.04 在/etc/network/interfaces设置static ip无效
双网卡使用无线网卡上互联网,使用以太网卡连局域网,在/etc/network/interfaces里对以太网卡设置static ip无效,使用ifconfig临时设置也仅能工作一会,设置的ip马上就消 ...
- Spring data jpa JavassistLazyInitializer 不仅是Json序列化问题.以及解决办法
最近偷点时间更新一下框架,使用SpringBoot2.0 整套一起更新一下,发现些小问题 Spring data jpa getOne 返回的是代理对象,延迟加载的,ResponseBody成Json ...
- linux下的ssh和rynsc
在ubuntu下有ssh的目录,但是没有使用 ps -e | grep ssh时没有任何输出,说明没有安装ssh或者是1.x版本,可以打开etc/ssh目录,看是否有文件,下装系统再看看吧.还有ryn ...
- linux搭建mysql集群
一.公共配置 请在三个虚拟机上分别配置此处的配置项. 1. 安装虚拟机 虚拟机操作系统安装CentOS 6.5的x86_64版本. 2. 拷贝mysql cluster 下载以下版本的MySQL-Cl ...
- 26、jQuery
一. jQuery简介 (一) jQuery是什么: 是一个javascript代码仓库 是一个快速的简洁的javascript框架,可以简化查询DOM对象.处理事件.制作动画.处理Ajax交互过程. ...
- 时时监控的rtsp流视频显示在前端与一些css;
不过试了下只兼容IE. <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- String字面量
public class assa{ static String ee = "aa";//ee指向常量池中的aa static String ff = new String(&qu ...
- pytorch入门与实践-2.2
Tensor 1--本质上可以理解为具有不同维度的数组 2--支持的基本运算 |---创建Tensor: x=t.tensor(x,y) x,y 表示数组的大小 , x=t.rand(x,y), x ...
- Luogu 1093 - 奖学金 - [排序水题]
题目链接:https://www.luogu.org/problemnew/show/P1093 题目描述某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金.期末,每个学生 ...
- 智能门锁测试程序和PCB板线路通断检测程序经验总结
这次去WZ出差,还是很累的,之前一年多没有搞嵌入式了,更重要的是之前没有接触太深刻GPIO的用法等等原因,导致很心累. 必须掌握的技能: (1)SPI和IIC总线,模拟和专用外设两种方式,他们的重要性 ...