hbtmwangjin

为了便于调试,特意写了一个通过键盘控制机械臂舵机的代码,来调试舵机,代码是基于teleop_twist_keyboard修改的。在arduino_node.py中已经声明了舵机读和写的ROS Service:

        # A service to position a PWM servo
        rospy.Service(\'~servo_write\', ServoWrite, self.ServoWriteHandler)

        # A service to read the position of a PWM servo
        rospy.Service(\'~servo_read\', ServoRead, self.ServoReadHandler)
  • 1
  • 2
  • 3
  • 4
  • 5

配合上一篇微博中arduino端的舵机驱动,我们只需要实现这两个ROS Service的client就可以控制舵机了,具体原理请看代码中的注释代码如下:

#!/usr/bin/env python
import roslib; roslib.load_manifest(\'teleop_twist_keyboard\')
import rospy

from geometry_msgs.msg import Twist
from ros_arduino_msgs.srv import *
from math import pi as PI
import sys, select, termios, tty

msg = """
Reading from the keyboard  and Publishing to Twist, Servo or sensor!
---------------------------
Moving around:
   u    i    o
   j    k    l

, : up (+z)
. : down (-z)
m : stop

----------------------------
Left arm servo control:控制机器人左臂,每次调整0.09弧度
+   1   2   3   4   5   6
-   q   w   e   r   t   y  
----------------------------
Right arm servo control:控制机器人右臂,每次调整0.09弧度
+   a   s   d   f   g   h
-   z   x   c   v   b   n 

p : init the servo 初始化舵机

CTRL-C to quit
"""

moveBindings = {
        \'i\':(1,0,0,0),
        \'o\':(1,0,0,1),
        \'j\':(-1,0,0,-1),
        \'l\':(-1,0,0,1),
        \'u\':(1,0,0,-1),
        \'k\':(-1,0,0,0),
        \',\':(0,0,1,0),
        \'.\':(0,0,-1,0),
           }

#右臂舵机的控制数组,1表示增加0.09弧度,0表示减少0.09弧度
rightArmServo={
                \'1\':(0,1),
            \'2\':(1,1),
            \'3\':(2,1),
            \'4\':(3,1),
            \'5\':(4,1),
            \'6\':(5,1),
            \'q\':(0,0),
            \'w\':(1,0),
            \'e\':(2,0),
            \'r\':(3,0),
            \'t\':(4,0),
            \'y\':(5,0),
          }

#左臂舵机的控制数组,1表示增加0.09弧度,0表示减少0.09弧度
leftArmServo={
            \'a\':(6,1),
            \'s\':(7,1),
            \'d\':(8,1),
            \'f\':(9,1),
            \'g\':(10,1),
            \'h\':(11,1),
            \'z\':(6,0),
            \'x\':(7,0),
            \'c\':(8,0),
            \'v\':(9,0),
            \'b\':(10,0),
            \'n\':(11,0),
          }

#手臂臂舵机的控制命令数组         
armCmd={
    \'[\':(0,1),#左臂初始化
    \']\':(1,1),#右臂初始化
       }

def getradians(angle):
    return PI*angle/180


def getKey():
    tty.setraw(sys.stdin.fileno())
    select.select([sys.stdin], [], [], 0)
    key = sys.stdin.read(1)
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
    return key

#舵机当前位置读取,调用servo_read service
def servoRead(servoNum):
    rospy.wait_for_service(\'/arduino/servo_read\')
    try:
        readServo=rospy.ServiceProxy(\'/arduino/servo_read\',ServoRead)
        return readServo(servoNum)
        except rospy.ServiceException, e:
            print "Service call failed: %s"%e

#舵机位置写,根据舵机标号设置舵机的位置0~π,注意这里的value对应的是弧度        
def servoWrite(servoNum, value):
        rospy.wait_for_service(\'/arduino/servo_write\')
    try:
        servo_write=rospy.ServiceProxy(\'/arduino/servo_write\',ServoWrite)
        servo_write(servoNum,value)
        print servoNum
            print value
        except rospy.ServiceException, e:
            print "Service call failed: %s"%e

#初始化右臂舵机角度,要根据实际情况调整舵机角度     
def initRightArm():
    servoWrite(0,getradians(60)) 
    servoWrite(1,getradians(80))
    servoWrite(2,getradians(90))
    servoWrite(3,getradians(90))
    servoWrite(4,getradians(90))
    servoWrite(5,getradians(90))

#初始化左臂舵机角度,要根据实际情况调整舵机角度    
def initLeftArm():  
    servoWrite(6,getradians(90))
    servoWrite(7,getradians(90))
    servoWrite(8,getradians(90))
    servoWrite(9,getradians(90))
    servoWrite(10,getradians(90))
    servoWrite(11,getradians(90))    

def vels(speed,turn):
    return "currently:\tspeed %s\tturn %s " % (speed,turn)

if __name__=="__main__":
        settings = termios.tcgetattr(sys.stdin)

    pub = rospy.Publisher(\'cmd_vel\', Twist, queue_size = 1)
    rospy.init_node(\'teleop_twist_keyboard\')

    speed = rospy.get_param("~speed", 0.5)
    turn = rospy.get_param("~turn", 1.0)
    x = 0
    y = 0
    z = 0
    th = 0
    status = 0

    try:
        print msg
        print vels(speed,turn)
        while(1):
            key = getKey()
            print key
            if key in moveBindings.keys():
                x = moveBindings[key][0]
                y = moveBindings[key][1]
                z = moveBindings[key][2]
                th = moveBindings[key][3]
            elif key in leftArmServo.keys():#左臂舵机控制
                value=servoRead(leftArmServo[key][1]).value             
                if(leftArmServo[key][1]==0):
                    value=value-getradians(5)
                    

分类:

技术点:

相关文章: