基本思路:

上一篇已经能实现arduino对ROS节点的订阅与发布,所以只要订阅到ROS的移动控制消息,并把它转换为小车的移动命令即可实现ROS对小车的移动驱动。

ROS小车打造(十一)--arduino订阅/发布Topic_leoFY123的博客-CSDN博客

关键点:

1.ROS的小车移动控制消息cmd_vel是什么样的

2.差速小车如何实现控制

3.cmd_vel与控制如何桥接

1. cmd_vel解析

roscore

新终端

 rosrun turtlesim turtle_teleop_key

新终端

rostopic list
rostopic type /turtle1/cmd_vel
rosmsg show geometry_msgs/Twist

以上内容可以看到,机器人的控制有两个大项一个是线速度,一个是角速度

第一项都有一个XYZ,右手坐标系下,车头方向为X+,左为Y+,上为Z+

这里这个坐标系是永远以车为参考对象,不是世界坐标系

那我们就好理解了,如果只有线速度,X+就是正向直线运动,Y+就是左向直线运动,但是可惜小车只能前进后退不能平移,也不能上下,所以只有X有值。

角速度就是绕着某一轴转动,X方向就是打滚,Y方向就是翻跟头 ,Z方向就是转弯,方向同样符合右手定则。我们的小车只能转弯不会翻跟头,所以只有Z向有值。

2.差速小车如何控制

两轮速度一样时,同时为+前进,同时为-后退

左轮比右轮快右转,右轮比左轮快左转。

简单说两轮的共同速度线速度,差值大小反映的是角速度大小

每个轮的快慢由PWM的占空比决定,在这里255(0xFF)是全速,0是停

方向由单独的方向引脚控制

3. 二者如何转换

4.程序编写

arduino端

#include <ros.h>
#include <std_msgs/String.h>
#include <std_msgs/Empty.h>
#include <geometry_msgs/Twist.h>
#define LEFT_EN  A1
#define LEFT_FR  A2
#define LEFT_PG  3
#define LEFT_SV  6#define RIGHT_EN 12
#define RIGHT_FR 8
#define RIGHT_PG 2
#define RIGHT_SV 5
#define ROBOT_WIDTH 300
#define LEFT 0
#define RIGHT 1
unsigned char channel;
unsigned char dir;
unsigned char spd;
unsigned char leftSpd;
unsigned char leftDir;
unsigned char rightSpd;
unsigned char rightDir;
unsigned char recBuf;
double left_vel;
double right_vel;
long lasttim;
long tim;ros::NodeHandle nh;void messageCb(const geometry_msgs::Twist& cmd_vel)
{ lasttim=millis();Serial.println("recevied"); double vel_x=cmd_vel.linear.x;double vel_th=cmd_vel.angular.z;left_vel=vel_x-vel_th*ROBOT_WIDTH/2000;right_vel=vel_x+vel_th*ROBOT_WIDTH/2000;setSpeed(LEFT,left_vel);setSpeed(RIGHT,right_vel);
} void setSpeed(char channel,double vel)
{vel= vel*255;if(vel>255){dir=1;spd=255;}else if(vel>10){dir=1;spd=(unsigned char)vel;}else if(vel>-10){spd=0;}else if(vel>-255){spd=(unsigned char)(-vel);dir=0;}else{dir=0;spd=255;}if(channel== LEFT){digitalWrite(LEFT_FR, dir);analogWrite (LEFT_SV,spd); }else if(channel== RIGHT){digitalWrite(RIGHT_FR, !dir);analogWrite (RIGHT_SV,spd);}}ros::Subscriber<geometry_msgs::Twist> sub("/cmd_vel", messageCb);void setup()
{ pinMode(LED_BUILTIN, OUTPUT);pinMode(LEFT_EN, OUTPUT);pinMode(LEFT_FR, OUTPUT);pinMode(LEFT_SV, OUTPUT);pinMode(RIGHT_EN, OUTPUT);pinMode(RIGHT_FR, OUTPUT);pinMode(RIGHT_SV, OUTPUT);Serial.begin(115200); nh.initNode(); nh.subscribe(sub); leftSpd=0;leftDir=0;rightSpd=0;rightDir=0;digitalWrite(LEFT_EN, LOW); digitalWrite(LEFT_FR, leftDir); digitalWrite(RIGHT_EN, LOW); digitalWrite(RIGHT_FR, rightDir);analogWrite (LEFT_SV,leftSpd);analogWrite (RIGHT_SV,rightSpd);
} void loop()
{
//    Serial.println(sub.data);tim = millis(); if((tim-lasttim)>1000){setSpeed(LEFT,0);setSpeed(RIGHT,0);}nh.spinOnce(); delay(1);
} 

键盘控制发布cmd_vel python代码mbot_teleop.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-import rospy
from geometry_msgs.msg import Twist
import sys, select, termios, ttymsg = """
Control mbot!
---------------------------
Moving around:u    i    oj    k    lm    ,    .q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%
space key, k : force stop
anything else : stop smoothlyCTRL-C to quit
"""moveBindings = {'i':(1,0),'o':(1,-1),'j':(0,1),'l':(0,-1),'u':(1,1),',':(-1,0),'.':(-1,1),'m':(-1,-1),}speedBindings={'q':(1.1,1.1),'z':(.9,.9),'w':(1.1,1),'x':(.9,1),'e':(1,1.1),'c':(1,.9),}def getKey():tty.setraw(sys.stdin.fileno())rlist, _, _ = select.select([sys.stdin], [], [], 0.1)if rlist:key = sys.stdin.read(1)else:key = ''termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)return keyspeed = .2
turn = 1def vels(speed,turn):return "currently:\tspeed %s\tturn %s " % (speed,turn)if __name__=="__main__":settings = termios.tcgetattr(sys.stdin)rospy.init_node('mbot_teleop')pub = rospy.Publisher('/cmd_vel', Twist, queue_size=5)x = 0th = 0status = 0count = 0acc = 0.1target_speed = 0target_turn = 0control_speed = 0control_turn = 0try:print msgprint vels(speed,turn)while(1):key = getKey()# 运动控制方向键(1:正方向,-1负方向)if key in moveBindings.keys():x = moveBindings[key][0]th = moveBindings[key][1]count = 0# 速度修改键elif key in speedBindings.keys():speed = speed * speedBindings[key][0]  # 线速度增加0.1倍turn = turn * speedBindings[key][1]    # 角速度增加0.1倍count = 0print vels(speed,turn)if (status == 14):print msgstatus = (status + 1) % 15# 停止键elif key == ' ' or key == 'k' :x = 0th = 0control_speed = 0control_turn = 0else:count = count + 1if count > 4:x = 0th = 0if (key == '\x03'):break# 目标速度=速度值*方向值target_speed = speed * xtarget_turn = turn * th# 速度限位,防止速度增减过快if target_speed > control_speed:control_speed = min( target_speed, control_speed + 0.02 )elif target_speed < control_speed:control_speed = max( target_speed, control_speed - 0.02 )else:control_speed = target_speedif target_turn > control_turn:control_turn = min( target_turn, control_turn + 0.1 )elif target_turn < control_turn:control_turn = max( target_turn, control_turn - 0.1 )else:control_turn = target_turn# 创建并发布twist消息twist = Twist()twist.linear.x = control_speed; twist.linear.y = 0; twist.linear.z = 0twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = control_turnpub.publish(twist)except:print efinally:twist = Twist()twist.linear.x = 0; twist.linear.y = 0; twist.linear.z = 0twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 0pub.publish(twist)termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)

运行

新终端

roscore

新终端

rosrun rosserial_python serial_node.py /dev/ttyUSB4

新终端

python mbot_teleop.py

ROS小车打造(12)--Arduino订阅cmd_vel实现差速控制相关推荐

  1. ROS小车打造(七)--YOLO运行ROS例子--TX2安装darknet_ros

    Darknet可以对目标对象进行识别,目前可以实现以下80 个目标的识别.也可以训练自己的识别库.目前很多的超市就使用该技术进行称重识别,替代人工选择物品类别.(尝试过连红心柚子与白心柚子都可以分开. ...

  2. 零基础玩转ROS小车

    本文1000字左右,阅读时间大约45分钟,尽可能按照教程自己过一遍,熟练地应用还是需要更多地思考和揣摩. 如有纰漏,请不吝指出,如对读者有一定帮助,某不胜荣幸. 本文作者: AndyJen 联系邮箱( ...

  3. ROS订阅/cmd_vel话题,转化成移动机器人左右轮的转速

    1,理论模型 在使用ROS导航时,move_base发布的时 /cmd_vel 话题,但是为了驱动小车,可能我们的车的底盘并不支持ros系统,因此需要通过串口通信交换数据,因此我们必须自己订阅 /cm ...

  4. 开源!手把手教你搭建Arduino+英伟达Jetson的ROS小车(上)

    1 引言 今年6月,我们应小伙伴儿的需求,写了两篇如何通过购买零件从零搭建一台ROS实体车的推文<开源!手把手教你搭建Arduino+树莓派的ROS小车(上)>.<开源!手把手教你搭 ...

  5. 基于亚博Arduino电机拓展板的ROS小车

    文章目录 前言 一.硬件搭建 二.软件环境搭建 1.在window下安装VMware和Ubuntu 16.04 2.安装ROS-kinetic(各种坑) 3.在Ubuntu下安装Arduino IDE ...

  6. ROS学习笔记-创建订阅cmd_vel话题节点

    创建工作空间 cd ~ mkdir catkin_ws cd catkin_ws mkdir src cd src catkin_init_workspace #初始化工作空间 cd ~/catkin ...

  7. ROS小车——发布与订阅节点(7)【ROS保姆注释教学】

    文章目录 前言 1.编写发布节点 2.修改CmakeLists 3.运行程序 4.编写订阅节点 5.修改CmakeLists 前言 本系列博客参照<ROS机器人编程原理与应用>一书,搭载平 ...

  8. ROS小车——登录和简单控制(1)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.无线连接wifi和ssh登录 二.AP热点和ssh登录 1.ROS小车开机 2.电脑连接ROS小车热点 3.使用p ...

  9. ROS小车实践记录(一)

    小车实践 ROS小车 一.开发环境搭建(Jeston Nano平台) 二.ROS分布式组网(Jeston Nano平台) ROS小车 学习ROS小车相关的ROS基础教程,以及相关进阶课程,本系列文章作 ...

最新文章

  1. 当NLPer爱上CV:后BERT时代生存指南之VL-BERT篇
  2. 文字加减前后缀lisp_华为笔试题---仿LISP算法
  3. 06CRecordView类
  4. java停启was集群_shell脚本实现weblogic 节点启停,应用部署
  5. bzoj 4570: [Scoi2016]妖怪 凸包
  6. json_decode()和json_encode()区别----2015-0929
  7. 多线程条件通行工具——Semaphore
  8. android sim卡分析,Android 判断SIM卡属于哪个移动运营商详解及实例
  9. Linux Curl命令实用参数
  10. poj1270_toposort+回溯
  11. 【摩尔吧今日推荐】我们一定要给自己提出这样的任务:第一,学习,第二是学习,第三还是学习。
  12. Flutter 项目实战 网络请求MD5+时间戳+验证签名 十一
  13. zabbix应用之详细的拓扑图标签--链路流量
  14. 硬盘无法访问设备硬件出现致命错误,导致请求失败数据找到的法子
  15. 矢志不渝,人生会慢慢露出轮廓。
  16. 微信小程序父子组件方法调用方法汇总
  17. 微信二维码活码制作管理系统源码+独立版网站
  18. CES 2018前瞻:家居/音箱/AR/汽车都有什么新玩法 | 关注
  19. 谷歌浏览器扩展工具---eye dropper取色器使用
  20. 承香墨影的行业周报-0x0010

热门文章

  1. python opencv 绘制简单图形
  2. 什么是商业智能 (BI) 仪表板?
  3. 大淘客的index.php,index.php · zenozhengs/大淘客CMS底部菜单修改版 - Gitee.com
  4. 关于下载《Java程序员,上班那点事儿》的电子版
  5. oracle列转行用逗号隔开,Oracle逗号分隔列转行实现方法
  6. 《人月神话》,没有银弹
  7. 如何把浏览器中知乎文章导出成PDF
  8. php爆路径方法收集
  9. 指数基金投资指南读书笔记
  10. 使用PDF编辑器进行PDF合并与PDF页面提取