NAO机器人——运动控制(2)

目录

一、关节控制方法

1.1 控制关节

1.2 定时插值

1.3 反应控制

1.4 读关节角度

一、关节控制方法

关节控制通常要经历多个ALMotion周期(20ms)。为使关节平稳转动,每隔20ms,API需要重新计算电机电流和刚度变化。

控制关节或关节组有两种方式:

(1)插值方法,阻塞调用,类似于动画,在起始位置和终止位置间定时插入若干中间值。

(2)反应式方法,非阻塞调用,通常在反应控制中多次调用。例如在头部跟踪时,NAO可能得到一组相互矛盾的命令序列(如前一个命令是头部左转,后一个命令是右转),调用反应式方法可以保证运动平滑且速度连续。 

方法名

说明

调用方式

angleInterpolation (names, angleLists, timeLists, isAbsolute)

插值运动。names 是关节名称;angleLists是角度、角度列表或二维角度列表,单位为弧度;timeLists是为达到目标角度的时间、时间列表或二维时间列表;isAbsolute为True,代表绝对角度,为False,代表相对角度。

阻塞调用

angleInterpolationWithSpeed(names, targetAngles, maxSpeedFraction)

插值运动(带速度限制)。names是关节名称;targetAngles为弧度表示的角度或角度列表,maxSpeedFraction为最大速度百分比

阻塞调用

angleInterpolationBezier(jointNames, times,controlPoints)

贝塞尔角度插值。jointNames为关节名称列表,times为时间列表,controlPoints为控制点列表

阻塞调用

setAngles(names,angles, fractionMaxSpeed)

设置关节角度。names是关节名称;angles为一个或多个角度;maxSpeedFraction为最大速度百分比

非阻塞调用

changeAngles(names,angles, fractionMaxSpeed)

改变关节角度。names是关节名称;angles为一个或多个角度;maxSpeedFraction为最大速度百分比

非阻塞调用

getAngles(names, useSensors)

获取关节角度。names为关节名;useSensors为True返回关节传感器角度,为False返回执行器角度

closeHand(handName)

合上手掌。handName取值:LHand,RHand

阻塞调用

openHand(handName)

张开手掌。handName取值:LHand,RHand

阻塞调用

1.1 控制关节

需要给出关节名称、以弧度为单位的目标角度和转到目标角度的速度。

almath是NAOqi系统提供的数学函数库,almath.TO_RAD为1度所对应的弧度数,在关节控制方法中,目标角度都以弧度为单位,本例及以后示例中,目标角度都用角度*1度对应弧度数形式表示。 setAngles()方法为非阻塞调用方法,本例中转头动作后面的语句将头部刚度设置为0,因此调用setAngles()方法时需要使用延时。

# 头部关节运动(头部左转30度)
import  time
import  almath
class  MyClass(GeneratedClass):
    def  __init__(self):
         GeneratedClass.__init__(self)
         self.motion=ALProxy("ALMotion")
    def  onLoad(self):
         pass
    def  onUnload(self):
         pass
    def  onInput_onStart(self):
         self.motion.setStiffnesses("Head", 1.0)
         names = "HeadYaw"
         angles = 30.0*almath.TO_RAD
         fractionMaxSpeed = 0.1       # HeadYaw joint at 10% max speed
         self.motion.setAngles(names,angles,fractionMaxSpeed)
         time.sleep(3.0)
         self.motion.setStiffnesses("Head", 0.0)
         pass
    def  onInput_onStop(self):
         self.onUnload()
         self.onStopped() 

1.2 定时插值

如果关节运动的轨迹是已知的,angleInterpolation()[阻塞调用]angleInterpolationWithSpeed()方法可以在每个ALMotion周期中重新计算执行器(电机)参数,控制关节运动速度,使机器人运动平稳。关节插值运动方法可以对一个关节或多个关节指定运动角度,也可以指定角度序列及完成这些动作的时间序列

# 头部插值运动
import  almath
import  time

class  MyClass(GeneratedClass):
    def  __init__(self):
        GeneratedClass.__init__(self)
        self.motion=ALProxy("ALMotion")
    def  onLoad(self):
        pass
    def  onUnload(self):
        pass
    def  onInput_onStart(self):
        self.motion.setStiffnesses("Head", 1.0)
        names = "HeadYaw"
        angleLists = 50.0*almath.TO_RAD
        timeLists  = 1.0
        isAbsolute = True
        self.motion.angleInterpolation(names, angleLists, timeLists, isAbsolute)
        time.sleep(1.0)
        names= "HeadYaw"
        angleLists = [30.0*almath.TO_RAD, 0.0]
        timeLists  = [1.0, 2.0]
        isAbsolute = True
        self.motion.angleInterpolation(names, angleLists, timeLists, isAbsolute)
        time.sleep(1.0)
        names      = ["HeadYaw", "HeadPitch"]
        angleLists = [30.0*almath.TO_RAD, 30.0*almath.TO_RAD]
        timeLists  = [1.0, 1.2]
        isAbsolute = True
        self.motion.angleInterpolation(names, angleLists, timeLists, isAbsolute)
        names  = ["HeadYaw","HeadPitch"]
        angleLists=[[50.0*almath.TO_RAD, 0.0],[-30.0*almath.TO_RAD, 30.0*almath.TO_RAD, 0.0]]
        timeLists=[[1.0, 2.0], [ 1.0, 2.0, 3.0]]
        isAbsolute=True
        self.motion.angleInterpolation(names, angleLists, timeLists, isAbsolute)
        self.motion.setStiffnesses("Head", 0.0)
        pass
    def  onInput_onStop(self):
        self.onUnload() 
        self.onStopped()

1.3 反应控制

setAngles() changeAngles()方法为非阻塞调用方法,经常用于关节反应式控制,在前一个调用未完成前,可以执行下一个调用。

# 反应控制
import  time

class  MyClass(GeneratedClass):
    def  __init__(self):
        GeneratedClass.__init__(self)
        self.motion=ALProxy("ALMotion")
    def  onLoad(self):
        pass
    def  onUnload(self):
        pass
    def  onInput_onStart(self):
        self.motion.setStiffnesses("Head", 1.0)
        names = "HeadYaw"
        angles = 0.3
        fractionMaxSpeed = 0.1
        self.motion.setAngles(names,angles,fractionMaxSpeed)      
        time.sleep(0.5)   # wait  half  a  second       
        angles = 0.0   # change  target
        self.motion.setAngles(names,angles,fractionMaxSpeed)       
        time.sleep(0.5)   # wait  half  a second       
        angles = 0.1   # change  target
        self.motion.setAngles(names,angles,fractionMaxSpeed)
        time.sleep(3.0)
        self.motion.setStiffnesses("Head", 0.0)
        pass
    def  onInput_onStop(self):
        self.onUnload()
        self.onStopped() 

1.4 读关节角度

关节控制是通过调用API方法,将关节控制命令发送给相应的执行器(电机)完成的。命令执行完成后,关节角度应该与发给执行器的命令相一致(实际的机械结构执行过程中可能存在微小误差)。NAO在每个关节上安装了位置传感器测量关节角度。getAngles()方法即可以读取执行器角度,也可以读取传感器角度。

# 获取关节角度
import time
class  MyClass(GeneratedClass):
    def  __init__(self):
        GeneratedClass.__init__(self)
        self.motion=ALProxy("ALMotion")
    def onLoad(self):
        pass
    def  onUnload(self):
        pass
    def  onInput_onStop(self):
        self.onUnload() 
        self.onStopped() 
    def  onInput_onStart(self):
        self.motion.setStiffnesses("Head", 1.0)
        names = "HeadYaw"
        angles = 0.3
        fractionMaxSpeed = 0.8
        self.motion.setAngles(names,angles,fractionMaxSpeed)      
        time.sleep(1.5)   
        names = "Head"                  #包括HeadYaw和HeadPitch
        useSensors = False
        commandAngles = self.motion.getAngles(names, useSensors)   #读取执行器角度
        self.logger.info("Command angles:")
        self.logger.info(str(commandAngles))
        useSensors  = True
        sensorAngles = self.motion.getAngles(names, useSensors)   #读取传感器角度
        self.logger.info("Sensor angles:")
        self.logger.info(str(sensorAngles))
        errors = []
        for  i  in  range(0, len(commandAngles)):
            errors.append(commandAngles[i]-sensorAngles[i])
        self.logger.info("Errors")
        self.logger.info(errors)
        pass

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清园暖歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值