关节
每个关节都可以被分别控制,或是与其它关节一起被同时控制。
链及关节名
Head | LArm | LLeg | RLeg | RArm |
---|---|---|---|---|
HeadYaw | LShoulderPitch | LHipYawPitch1 | RHipYawPitch1 | RShoulderPitch |
HeadPitch | LShoulderRoll | LHipRoll | RHipRoll | RShoulderRoll |
LElbowYaw | LHipPitch | RHipPitch | RElbowYaw | |
LElbowRoll | LKneePitch | RKneePitch | RElbowRoll | |
LWristYaw2 | LAnklePitch | RAnklePitch | RWristYaw2 | |
LHand2 | RAnkleRoll | LAnkleRoll | RHand2 |
1 LHipYawPitch和RHipYawPitch共用一个电机,LHipYawPitch始终优先。
2 RoboCup版本中没有这些关节。
编程访问关节名
可以使用getJointNames方法来获得机器人身上或关节链上的关节名。
# Example showing how to get joint names > print proxy.getJointNames("Body") ['HeadYaw', 'HeadPitch', 'LShoulderPitch', 'LShoulderRoll', 'LElbowYaw', 'LElbowRoll', 'LHipYawPitch', 'LHipRoll', 'LHipPitch', 'LKneePitch', 'LAnklePitch', 'LAnkleRoll', 'RHipYawPitch', 'RHipRoll', 'RHipPitch', 'RKneePitch', 'RAnklePitch', 'RAnkleRoll', 'RShoulderPitch', 'RShoulderRoll', 'RElbowYaw', 'RElbowRoll'] > print proxy.getJointNames("LArm") ['LShoulderPitch', 'LShoulderRoll', 'LElbowYaw', 'LElbowRoll']
控制关节
要控制一个关节时,需要指定关节的名称、以弧度为单位的目标角度以及达到目标角度所需的速度。
# Simple command for the HeadYaw joint at 10% max speed names = "HeadYaw" angles = 0.2 fractionMaxSpeed = 0.1 proxy.setAngles(names,angles,fractionMaxSpeed)
反应控制(Reactive Control)
setAngles和changeAngles这两个命令不会阻塞调用线程,因而非常适用于诸如头部跟踪等反应控制回路。您可以经常使用这些命令,动作模块会保证轨迹位置流畅、速度连贯。
# Example simulating reactive control names = "HeadYaw" angles = 0.3 fractionMaxSpeed = 0.1 proxy.setAngles(names,angles,fractionMaxSpeed) # wait half a second time.sleep(0.5) # change target angles = 0.0 proxy.setAngles(names,angles,fractionMaxSpeed) # wait half a second time.sleep(0.5) # change target angles = 0.1 proxy.setAngles(names,angles,fractionMaxSpeed)
定时插值
在已经确定了要遵循的轨迹时, angleInterpolation和angleInterpolationWithSpeed这两个方法可以用来设定插值。
# Example showing a joint trajectory with a single destination names = "HeadYaw" angleLists = 1.0 times = 1.0 isAbsolute = True proxy.angleInterpolation(names, angleLists, times, isAbsolute)
可以在同一个命令中控制多个关节,只需使用一个时间以及与关节数量相同的目标角度数量。
# Example showing a command for the two joints in the 'Head' alias # 'Head' is expanded to ['HeadYaw','HeadPitch'] names = "Head" angleLists = [-1.0,-1.0] times = 1.0 isAbsolute = True proxy.angleInterpolation(names, angleLists, times, isAbsolute)
同一个命令可以采用带有相应时间的角度列表。
# Shake the head from side to side names = "HeadYaw" angleLists = [1.0, -1.0, 1.0, -1.0, 0.0] times = [1.0, 2.0, 3.0, 4.0, 5.0] isAbsolute = True proxy.angleInterpolation(names, angleLists, times, isAbsolute)
轨迹也同样可以被指定给多个关节。
# Two trajectories in one command. Each trajectory must have a # corresponding number of times names = ["HeadYaw", "HeadPitch"] angleLists = [[1.0, -1.0, 1.0, -1.0], [-1.0]] times = [[1.0, 2.0, 3.0, 4.0], [ 5.0]] isAbsolute = True proxy.angleInterpolation(names, angleLists, times, isAbsolute)
初始姿势(Init Pose)
下面的例子展示如何将NAO置于初始姿势。通过改变kneeAngle、torsoAngle和wideAngle的参数,您可以设计出各种各样稳定的姿势。
# Example showing how to create an init pose import math TO_RAD = math.pi/180 # Feel free to experiment with these values kneeAngle = 40 torsoAngle = 0 wideAngle = 0 #----------------------------- prepare the angles ---------------------------- # Get the Number of Joints NumJoints = len(proxy.getJointNames("Body")) # Define The Initial Position Head = [0, 0] LeftArm = [120, 15, -90, -80] LeftLeg = [0, wideAngle, -kneeAngle/2-torsoAngle, kneeAngle, -kneeAngle/2, -wideAngle] RightLeg = [0, -wideAngle, -kneeAngle/2-torsoAngle, kneeAngle, -kneeAngle/2, wideAngle] RightArm = [120, -15, 90, 80] # If we have hands, we need to add angles for wrist and hand if (NumJoints == 26): LeftArm += [0, 0] RightArm += [0, 0] # Gather the joints together pTargetAngles = Head + LeftArm + LeftLeg + RightLeg + RightArm # Convert to radians pTargetAngles = [ x * TO_RAD for x in pTargetAngles] #------------------------------ send the commands ----------------------------- # Display the starting position print proxy.getSummary() # We use the "Body" name to signify the collection of all joints pNames = "Body" # We set the fraction of max speed pMaxSpeedFraction = 0.2 # Ask motion to do this with a blocking call proxy.angleInterpolationWithSpeed(pNames, pTargetAngles, pMaxSpeedFraction) # Display the end position print proxy.getSummary()