我是靠谱客的博主 冷艳柚子,最近开发中收集的这篇文章主要介绍ROS学习与分享:循环读取键盘摁下的键,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

唠嗑一下

为了更加快地让我的车车动起来,直接向车车发送多个速度信息显然不实际。循环发送一些简单的字符,对车车实现简单的前进后退、加速减速以及旋转,能够更加方便的进行其他的实验。并且当时由于假期,领导为了安全着想,不允许进入实验室,电控组的小哥哥,无法拿到正常的电机,就用两个不同型号的电机和一个支撑轮做了一个“三角鸡”。

这里参照的是古-月的文章进行改动: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学习与分享:循环读取键盘摁下的键所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部