概述
唠嗑一下
为了更加快地让我的车车动起来,直接向车车发送多个速度信息显然不实际。循环发送一些简单的字符,对车车实现简单的前进后退、加速减速以及旋转,能够更加方便的进行其他的实验。并且当时由于假期,领导为了安全着想,不允许进入实验室,电控组的小哥哥,无法拿到正常的电机,就用两个不同型号的电机和一个支撑轮做了一个“三角鸡”。
这里参照的是古-月的文章进行改动:ROS探索总结(八)——键盘控制
摁下键盘,并通过话题广播出去
为了方便,我便将我的控制键设置为数字控制键,所以就有了以下的程序。
teleop.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import sys, select, termios, tty
from std_msgs.msg import String
#操作教程
msg = """
Control mbot!
---------------------------
Moving around:
1
3 0 4
2
5/6 : clockwise/counterclockwise rotation
7/8 : increase/decrease max speeds by 10%
0 : force stopmsgs
anything else : stop smoothly
CTRL-C to quit
"""
def getKey():
tty.setraw(sys.stdin.fileno())
#tty 模块定义了将 tty 放入 cbreak 和 raw 模式的函数。因为他需要termios模块,所以只能在UNIX上运行
#tty 模块定义了以下函数
#tty.setraw(fd, when=termios.TCSAFLUSH)
#将文件描述符 fd 的模式更改为 raw 。如果 when 被省略,则默认为 termios.TCSAFLUSH ,并传递给 termios.tcsetattr() 。
#tty.setcbreak(fd, when=termios.TCSAFLUSH)
#将文件描述符 fd 的模式更改为 cbreak 。如果 when 被省略,则默认为 termios.TCSAFLUSH ,并传递给 termios.tcsetattr() 。
rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
#rlist则是键盘输入的信息列表
#select()方法接收并监控3个通信列表
#第1个是所有的输入的data,就是指外部发过来的数据
#第2个是监控和接收所有要发出去的data(outgoing data)
#第3个监控错误信息
#判断是否接受到数据
if rlist:
key = sys.stdin.read(1)#读取终端上的交互输入
else:
key = '0'
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
#termios.tcsetattr(fd, when, attributes)
#fd获取终端上交互输入的返回列表
#when tcsanow立即更改,tcsadrain在传输所有排队的输出后更改,或tcsaflush在传输所有排队的输出并丢弃所有排队的输入后更改。
return key
if __name__=="__main__":
settings = termios.tcgetattr(sys.stdin)
rospy.init_node('mbot_teleop')
pub = rospy.Publisher('/robot_teleop_key', String, queue_size = 10)
try:
print msg
while(1):
key = getKey()
#print key
pub.publish(key)
if (key == 'x03'):
break
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
emmmm,不过根据调控小哥哥的反馈,这样不方便,最好还是像游戏一样用wasd。所以我又更新了一下。不过这里就不作展示了,大家实验一下还是很快可以做出来的。
到这里,车车就可以动起来了。
车车,我的车车欸嘿嘿…
底板都不知道电控老哥在哪里找的????
[盗图必究]
垃圾堆里面拼出来的东西你还要盗我也是服气。
摁下按键,广播XY线性速度和z转角速度
到了实现雷达导航时,在完全由计算机控制的情况下,一开始肯定有失控的情况,利用这个程序可以取得控制权,将机器回到安全位置。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import sys, select, termios, tty
from geometry_msgs.msg import Twist
from std_msgs.msg import String
#操作教程
msg = """
Control mbot!
---------------------------
Moving around:
q w e
a k d
s
q/e : counterclockwise/clockwise rotation
z/x : increase/decrease max speeds by 10%
space key, k : force stop
anything else : stop smoothly
CTRL-C to quit
"""
#用于改变机器人运动方向的字典
moveBindings = {
'w':(1,0,0),
'e':(0,0,-1),
'a':(0,1,0),
'd':(0,-1,0),
'q':(0,0,1),
's':(-1,0,0),
}
speedBindings={
'z':(.5,.5),
'x':(-.5,-.5),
}
def getKey():
tty.setraw(sys.stdin.fileno())
#tty 模块定义了将 tty 放入 cbreak 和 raw 模式的函数。因为他需要termios模块,所以只能在UNIX上运行
#tty 模块定义了以下函数
#tty.setraw(fd, when=termios.TCSAFLUSH)
#将文件描述符 fd 的模式更改为 raw 。如果 when 被省略,则默认为 termios.TCSAFLUSH ,并传递给 termios.tcsetattr() 。
#tty.setcbreak(fd, when=termios.TCSAFLUSH)
#将文件描述符 fd 的模式更改为 cbreak 。如果 when 被省略,则默认为 termios.TCSAFLUSH ,并传递给 termios.tcsetattr() 。
rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
#rlist则是键盘输入的信息列表
#select()方法接收并监控3个通信列表
#第1个是所有的输入的data,就是指外部发过来的数据
#第2个是监控和接收所有要发出去的data(outgoing data)
#第3个监控错误信息
#判断是否接受到数据
if rlist:
key = sys.stdin.read(1)#读取终端上的交互输入
else:
key = ''
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
#termios.tcsetattr(fd, when, attributes)
#fd获取终端上交互输入的返回列表
#when tcsanow立即更改,tcsadrain在传输所有排队的输出后更改,或tcsaflush在传输所有排队的输出并丢弃所有排队的输入后更改。
return key
speed = .4 #设置初始直行速度
turn = 1 #设置初始角速度
def vels(speed,turn):
return "currently:tspeed %s m/stturn %s rad/s " % (speed,turn)
if __name__=="__main__":
settings = termios.tcgetattr(sys.stdin)
rospy.init_node('robot_teleop')
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
pub_voice = rospy.Publisher('/cmd_voice', String, queue_size = 10)
x = 0
y = 0
th = 0
status = 0
count = 0
acc = 0.1
target_speed_x = 0
target_speed_y = 0
target_turn = 0
control_speed_x = 0
control_speed_y = 0
control_turn = 0
try:
print msg
print vels(speed,turn)
while(1):
key = getKey()
#print key
# 运动控制方向键(1:正方向,-1负方向)
if key in moveBindings.keys():
x = moveBindings[key][0]
y = moveBindings[key][1]
th = moveBindings[key][2]
#print "x = %d" %x
#print "y = %d" %y
#print "th = %d" %th
count = 0
# 速度修改键
elif key in speedBindings.keys():
speed = speed + speedBindings[key][0]/5 # 线速度增加0.1
turn = turn + speedBindings[key][1] # 角速度增加0.5
count = 0
print vels(speed,turn)
# 停止键
elif key == ' ' or key == 'k' :
x = 0
y =0
th = 0
control_speed_x = 0
control_speed_y = 0
control_turn = 0
elif key == '1':
pub_voice.publish(key)
else:
count = count + 1
if count > 4:
x = 0
y = 0
th = 0
if (key == 'x03'):
break
# 目标速度=速度值*方向值
target_speed_x = speed * x
target_speed_y = speed * y
#print "target_speed_y = %f" %target_speed_y
target_turn = turn * th
# 速度限位,防止速度增减过快
#if target_speed_x > control_speed_x:
#control_speed_x = min( target_speed_x, control_speed_x + 0.1 )
#elif target_speed_x < control_speed_x:
#control_speed_x = max( target_speed_x, control_speed_x - 0.1 )
#else:
control_speed_x = target_speed_x
#if target_speed_y > control_speed_y:
#control_speed_y = min( target_speed_y, control_speed_y + 0.1 )
#elif target_speed_y < control_speed_y:
#control_speed_y = max( target_speed_y, control_speed_y - 0.1 )
#else:
control_speed_y = target_speed_y
#if target_turn > control_turn:
#control_turn = min( target_turn, control_turn + 0.5 )
#elif target_turn < control_turn:
#control_turn = max( target_turn, control_turn - 0.5 )
#else:
control_turn = target_turn
# 创建并发布twist消息
twist = Twist()
twist.linear.x = control_speed_x;
twist.linear.y = control_speed_y;
twist.linear.z = 0
twist.angular.x = 0;
twist.angular.y = 0;
twist.angular.z = control_turn
pub.publish(twist)
except:
print e
finally:
twist = Twist()
twist.linear.x = 0; twist.linear.y = 0; twist.linear.z = 0
twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 0
pub.publish(twist)
pub_voice.publish(' ')
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
里面有些内容注释掉了,也忘记是什么原因了。
最后
以上就是冷艳柚子为你收集整理的ROS学习与分享:循环读取键盘摁下的键的全部内容,希望文章能够帮你解决ROS学习与分享:循环读取键盘摁下的键所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复