PyBullet快速上手教程(二)

(译自PyBullet官方英文文档

控制一个机器人

  1. 在第一章的内容里面我们已经介绍了如何初始化PyBullet环境并载入一些对象。我们以ROS教程里面的"r2d2.urdf"为例介绍如何控制R2D2机器人移动,查看环境和控制末端操作器。当然首先我们需要知道驱动关节电机。

基座,关节和节点(实际上就是零件(个体/对象),感觉节点会好听一点)

基座、关节和节点的关系

  1. 一般来说,使用URDF文件描述的机器人至少会有一个基座,还可以有一些使用关节连接的节点。每个关节连接一个父节点和一个子节点。整个装配体的根节点(最开始的那个父节点)一般称作基座。基座可以是完全固定的,也可以有任意个自由度。由于这里每个节点都是通过一个关节连接到父节点的,因此实际上关节数量等同于节点的数量(不计基座在内)。每个节点都有一个节点索引(从0到getNumJoints())。基座我们一般用-1表示零件索引。跟其他很多程序差不多,这里的关节的表示是相对于父节点的质心表示的,参考系是惯性系。
  • 在PyBullet中由getJointInfo()函数用于获取关节信息,实际上y已经包含了节点的信息,因此其实没有getLinkInfo()这样的函数,节点的索引与关节的索引完全一致,可以通过getJointInfo()函数得到节点的名称和对应的索引

getNumJoints

  1. 加载了机器人之后可以通过getNumJointsAPI接口获取关节的数量信息。r2d2.urdf文件会返回15。
  2. getNumJoints包含以下输入参数:
required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
optional physicsClientId int 有些模式下可以建立多个仿真平台,就需要仿真平台的ID了

getJointInfo

  1. 对于每一个关节都可以查询其详细信息,包括关节的名字和类型
  2. getJointInfo输入的参数如下:
required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required jointIndex int 范围在[0,getNumJoints(bodyUniqueId)]
optional physicsClientId int 有些模式下可以建立多个仿真平台,就需要仿真平台的ID了
  1. getJointInfo返回如下信息
jointIndex int 和上面的输入参数一致
jointName string 关节名称,在URDF或者SDF等文件里面指定
jointType int 关节的类型,也表示了位置和速度变量的数目。包括JOINT_REVOLUTE, JOINT_PRISMATIC, JOINT_SPHERICAL, JOINT_PLANAR, JOINT_FIXED,更多可以参考Base, Joint, and Links的部分
qIndex int 机器人第一个位置变量索引
uIndex int 机器人第一个速度变量索引
flags int 保留参数
jointDamping float 关节的阻尼大小,在URDF等文件里指定
jointFriction float 关节的摩擦参数,在URDF等文件里指定
jointLowerLimit float 针对slider和revolute(hinge)类型的限位:位移的最小值(负数表示了反方向)
jointUpperLimit float 针对slider和revolute(hinge)类型的限位:位移的最大值(负数表示了反方向)。如果upperlimit小于lowerlimit的话则该值将被忽略
jointMaxForce float 关节驱动力的最大值,在URDF等文件中指定。需要指出的是该值不会自动使用?。开发人员可以在setJointMotorControl2中添加最大的驱动力
jointMaxVelocity float 关节的最大速度,在URDF等文件中指定。目前该值不会再实际的电机控制命令中使用
linkName string 节点的名称,在URDF等文件中指定
jointAxis vec3 local frame中的关节轴系(JOINT_FIXED类型的将会忽略此值)
parentFramePos vec3 父节点frame的关节位置
parentFrameOn vec3 父节点frame的关节方向
parentIndex int 父节点的索引,如果是基座的话会返回-1

setJointMotorControl2/Array

  • 老版本中的setJointMotorControl已经不再使用了,全部被setJointMotorControl2或者setJointMotorControlArray代替
  1. 通过设定控制模式我们可以控制一个机器人的多个关节。在stepSimulation过程中PyBullet物理引擎会自动计算关节可以到达的目标位置(考虑最大驱动力和其它约束的条件下)
  • 需要注意的是:默认情况下,revolute和prismatic类型的关节式速度控制方式。如果想改成力控制方式,可以通过设定最大力为0的方式关闭这种速度控制方式。另外还可以设定为一个小的非零力来模拟关节摩擦。举个例子:
maxForce = 0
mode = p.VELOCITY_CONTROL
p.setJointMotorControl2(objUid, JointIndex, controlMode=mode, force=maxForce)
  1. 以下给出一个轮子保持恒定转速的示例:
maxForce = 500
p.setJointMotorControl2(bodyUniqueId=objUid, jointIndex=0, controlMode=p.VELOCITY_CONTROL, targetVelocity=targetVel, force=maxForce)
  1. setJointMotorControl2的输入参数包括:
required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required jointIndex int 节点索引范围是[0,getNumJoints(bodyUniqueId)(节点的索引实际上与关节的索引相等)]
required controlMode int POSITION_CONTROL(实际上是CONTROL_MODE_POSITION_VELOCITY_PD(笔者觉得这应该是旧版本中的输入参数)), VELOCITY_CONTROL, TORQUE_CONTROL 和PD_CONTROL
optional targetPostion float 在POSITION_CONTROL中targetPostion是关节的期望位置
optional targetVelocity float 在VELOCITY_CONTROL和POSITION_CONTROL中targetVelocity是关节的期望速度,其它信息请见后面中的文档说明(implementation note)。注意:targetVelocity并不是关节的最大速度,在PD_CONTROL和POSITION_CONTROL/CONTROL_MODE_POSITION_VELOCITY_PD中,最终的目标速度通过下述公式计算:kp*(erp*(desiredPostion-currentPosition)/dt)+currentVelocity+kd*(m_desiredVelocity-currentVelocity).详见examples/pybullet/examples/pdControl.py文件
optional force float 在POSITION_CONTROL和VELOCITY_CONTROL中指定了最大的关机驱动力。在TORQUE_CONTROL中制定了关节实际驱动力
optional positionGain float 详见文档说明
optional velocityGain float 详见文档说明
optional maxVelocity float 在POSITION_CONTROL中限制了速度的最大值
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了
  • 注意:关节电机控制器实际上就是施加位置或者速度约束(对于POSITION_CONTROL和VELOCITY_CONTROL)或者施加外力约束(对于TORQUE_CONTROL)
控制模式 实现方式 实现内容 进行最小化的约束的误差
POSITION_CONTROL 约束 速度和位置约束 error=position_gain*(desired_position-actual_position)+velocity_gain*(deired_velocity-actual_velocity)
VELOCITY_CONTROL 约束 纯速度约束 error=desired_velocity-actual_velocity
TORQUE_CONTROL 外力
  1. 一般来讲,速度或者位置控制会比力控制方便的多。对于力控制而言,在仿真中,真实的力还依赖于精确的URDF/SDF中指定的机器人参数(包括质量关节摩擦等等)和文件参数

setJointMotorControlArray

  1. 这个实际上是setJointMotorControl2的加强版,可以用来同时控制多个关节,输入参数也与后者几乎一样,只是把单个的数值变成了列表(list)。这里就不介绍了。

getJointState(s), resetJointState

  1. 我们可以通过getJointState获取多个关节的状态信息,比如关节的位置、速度、关节反力和关节驱动力
    该API的输入参数如下:
required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required jointIndex int 节点的索引,范围在[0,getNumJoints(bodyUniqueId)]
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

该API的输出参数如下:

jointPosition float 关节的位置参数
jointVelocity float 关节的速度参数
jointReactionForces list of 6 floats 如果打开了关节力传感器,则会返回关节反力[Fx, Fy, Fz, Mx,My, Mz]。如果关节力传感器处于关闭状态,则是[0, 0, 0, 0, 0, 0]
appliedJointMotorTorque float 最后一步stepSimulation中关节的驱动力。在VELOCITY_CONTROL和POSITION_CONTROL中这个才有用,在TORQUE_CONTROL中其实没啥用,因为就是开发者施加的关节驱动力
  1. getJointStates就是getJointState的阵列版本,可以获取多个关节的状态信息。
  2. 对于球绞关节比较特殊,使用getJointStateMultiDof获取状态信息

resetJointState

  1. 这个API是用来重置关节状态的。一般在最开始的时候用这个函数来复位关节。目前官方没有像获取关节信息一样可以一次设置多个关节,这里一次只能设置一个关节,sliding关节或者revolute关节。输入参数如下:
required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required jointIndex int 关节索引,范围在[0,getNumJoints(bodyUniqueId)]
required targetValue float 关节位置,如果是关节角度,单位是弧度
optional targetVelocity float 关节的(角)速度
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了
  1. 对于spherical关节来说请使用 resetJointStateMultiDofAPI。详见humaniodMotionCapture。

enableJointForceTorqueSensor

  1. 我们可以使用这个函数来打开或者关闭关节力/力矩传感器。打开之后,在每一步的stepSimulation中,getJointState会返回关节固定自由度所受到的反力(比如对于一个完全固定的关节,就会返回6个自由度方向的关节力/力矩)。关节实际的自由度方向上施加的力会存在getJointState里面的appliedJointMotorTorque
    该API的输入参数如下:
required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required jointIndex int 关节索引,范围在[0,getNumJoints(bodyUniqueId)]
optional enable int 1/True:打开; 0/False:关闭;
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

getLinkState

  1. 我们可以通过getLinkState获取每个节点的质心的笛卡尔坐标和方位。该函数还会返回质心的局部惯性系给URDF 的link frame, 以便计算graphics/visualization frame

该函数的输入参数:

required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required linkIndex int 节点索引(不支持基座即-1的信息获取,使用第一章里面的getBasePositionAndOrientation获取基座的信息)
optional computeLinkVelocity int 设置为1:计算并返回笛卡尔坐标系下的速度值
optional computeForwardKinematics int 设置为1/True:使用正运动学重新计算笛卡尔坐标系下的坐标和方位?
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

该函数返回以下参数:

linkWorldPosition vec3, list of 3 floats 节点质心的笛卡尔坐标
linkWorldOrientation vec3, list of 4 floats 质心的方向,以[x,y,z,w]四元数的形式返回
localInertialFramePosition vec3, list of 3 floats URDF link frame中传递的质心惯性系的局部坐标偏移量
localInertialFrameOrientation vec3, list of 4 floats URDF link frame中传递的质心惯性系的局部方向偏移量
worldLinkFramePosition vec3, list of 3 floats URDF link frame中的世界坐标系中的位置
worldLinkFrameOrientation vec3, list of 4 floats URDF link frame中的世界坐标系中的方向
worldLinkLinearVelocity vec3, list of 3 floats 笛卡尔坐标系下的速度。只有在输入参数computeLinkVelocity非0时会生效
worldLinkAngularVelocity vec3, list of 3 floats 笛卡尔坐标系下的角速度。只有在输入参数computeLinkVelocity非0时会生效
  1. URDF link frame和质心框架的关系如下图所示。urdfLinkFrame=comLinkFrame*localInertialFrame.inverse().详见ROS的URDF教程
    URDF link Frame和质心框架的关系
  • 官方源程序的Bullet/examples/pybullet/examples文件夹下提供了多种API的应用示例

getBaseVelocity, resetBaseVelocity

  1. 该API函数提供了获取基座的线速度和角速度的功能。
    输入参数如下:
required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了
  1. 返回值是两个三维向量的列表,包括笛卡尔空间坐标系下的线速度[x,y,z]和角速度[wx,wy,wz]

  2. resetBaseVelocity提供了复位基座线速度/角速度的功能
    输入参数如下:

required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
optional linearVelocity vec3, list of 3 floats 笛卡尔空间坐标系下的线速度[x,y,z]
optional angularVelocity vec3, list of 3 floats 笛卡尔空间坐标系下的角速度[wx,wy,wz]
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

applyExternalForce/Torque

  1. 该函数提供了给机器人施加外力的功能。需要注意的是,这个只在单步仿真中才会起作用(也就是使用stepSimulation函数进行单步仿真,另外设置setRealTimeSimulation(0))。在单步的仿真后,外力都会清零。当设置setRealTimeSimulation(1)的时候,这个函数会起一些奇怪的作用(比如施加0,1或者多次力)

输入参数为:

required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required linkIndex int 基座的节点索引为-1
required forceObj vec3, list of 3 floats 要施加的外力[x,y,z]。详见坐标系统(coordinate system)中的标志(flags)
required posObj vec3, list of 3 floats 要施加的外力的位置。只用于applyExternalForce函数。详见坐标系统(coordinate system)中的标志(flags)
required flags int 确定上述力和位置的坐标系统(也就是参考坐标系):笛卡尔坐标系下的WORLD_FRAME或者局部坐标系下的LINK_FRAME
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

getNumBodies, getBodyInfo, getBodyUniqueId, removeBody

  1. getNumBodies会返回当前服务器个体的数目,然后还可以使用getBodyUniqueId查询个体的唯一ID。提醒:这些API都会返回个体的唯一ID,所以在这种情况下,其实并不需要使用getBodyUniqueId

  2. getBodyInfo: 返回基座的名称(在URDF等文件中指定)

  3. removeBody: 根据个体的唯一ID移除某个个体

createConstraint, removeConstraint

  1. 实际上,URDF等文件中以树状结构确立了一种铰接式的个体(不能形成环路的那种)。createConstraint可以帮助我们连接一些特定的节点,形成环路,跟实际的物理物体更加相符。Bullet/examples/pybullet/examples/quadruped.py文件中提供了一种连接四足动物五连杆的腿的示例。另外,还可以在物体之间、物体与某一坐标系之间添加任意约束。Bullet/examples/pybullet/examples/constraint.py提供了一些更多的应用。它还可以用来控制物体的运动,通过动画框架来驱动,比如VR控制器。实际上因为这里的约束可以放在其它动力学约束里面一起求解,所以使用这种办法比单纯的添加位置和速度限制更好一点。

输入参数如下:

required parentBodyUniqueId int 参考个体(父个体?)的唯一ID
required parentLinkIndex int 父节点的索引,基座为-1
required childBodyUniqueId int 目标个体(子个体?)的唯一ID,如果没有的话用输入为-1(specify a non-dynamic child frame in world coordinates)
required childLinkIndex int 子节点的索引,-1表示基座
required jointType int 关节类型:JOINT_PRISMATIC, JOINT_FIXED, JOINT_POINT2POINT, JOINT_GEAR(这里面应该指定两个个体之间的约束类型)
required jointAxis vec3, list of 3 floats 子节点的关节轴系
required parentFramePosition vec3, list of 3 floats 关节框架相对于参考个体质心框架的位置
required childFramePosition vec3, list of 3 floats 关节框架相对于给定的目标个体质心框架的位置(如果没有指定目标个体则为世界原点)
optional parentFrameOrientation vec4, list of 4 floats 关节框架相对于参考个体质心坐标系的方向
optional childFrameOrientation vec4, list of 4 floats 关节框架相对于目标个体质心坐标系的方向(如果没有指定目标个体,则为世界原点)
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了
  1. 该函数会返回一个integer类型的ID,可以用于移除添加的约束。examples/pybullet/examples/mimicJointConstraint.py给出了一个JOINT_GEAR的示例, examples/pybullet/examples/minitaur.py——JOINT_POINT2POINT, examples/pybullet/examples/constraint.py——JOINT_FIXED.

changeConstraint

  1. 该函数允许修改已经添加的约束
    输入的参数如下:
required userConstraintUniqueId int 也就是createContraint函数的返回值
optional jointChildPivot vec3, list of 3 floats 用于更新目标个体的轴系(应该是createConstraint里面的*jointAxis)
optional jointChildFrameOrientation vec4, list of 4 floats 更新目标个体的框架方向,四元数的形式
optional maxForce float 约束可以施加的最大力
optional gearRadio float 一对旋转齿轮的传动比
optional gearAuxLink int 有些情况下,比如差分传动,会用到一个辅助节点作为参考姿势。详见racecar differential.py
optional relativePositionTarget float 一对齿轮的相对位置目标偏移量
optional erp float 约束误差减小参数?
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了
  • 关于该API的更多信息详见Bullet/examples/pybullet/examples/constraint.py
  1. removeConstraint函数提供了根据ID移除约束的功能,输入参数为:
required userConstraintUniqueId int 函数createConstraint返回的约束的ID
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

getNumConstraint, getConstraintUniqueId

  1. 用于查询添加的约束的数量和ID,注意可能返回来的ID并不连续,因为可能开发人员中间会移除某些约束

getConstraintInfo/State

  1. 我们可以通过约束的ID查询约束的相关信息。
    输入参数为:
required constraintUniqueId int 函数createConstraint返回的约束的ID
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

返回参数为:

parentBodyUniqueId int
parentJointIndex int
childBodyUniqueId int
childLinkIndex int
constraintType int
jointAxis int
jointPivotInParent int
jointPivotInChild int
jointFrameOrientationParent int
jointFrameOrientationChild int
maxAppliedForce int

关于这些参数的详细说明参见createConstraint部分内容

getConstraintState

  1. 通过约束的唯一ID可以查询最近仿真步中的施加的约束力。输入参数只有约束的ID,输出是约束力组成的向量,维数与约束所限制的的自由度数目相等(比如一个完全固定的约束对应的数量为6)

getDynamicsInfo/changeDynamics

  1. 我们可以通过这个API获取基座和节点的一些动力学相关的参数:比如质量,质心位置,摩擦参数等等
    输入参数为:
required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required linkIndex int 节点或者关节的索引,基座的索引为-1
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

返回的参数为:

mass double 质量为kg
lateral_friction double 摩擦系数
local inertial diagnoal vec3, list of 3 floats 局部惯性对角线?注意:节点和基座以质心为中心,并于惯性主轴对齐
local inertial pos vec3 关节框架的局部坐标系下的惯性框架位置
local inertial orn vec4 关节框架的局部坐标系下的惯性框架的方向
restitution double 恢复系数
rolling friction double 滚动摩擦系数
spining friction double 滑动摩擦系数
contact damping double 阻尼系数,-1表示没有此项
contact stiffness double 刚度系数,-1表示没有此项

changeDynamics

  1. 这个API用于改变个体的物理性质包括质量、摩擦等等

输入参数包括:

required bodyUniqueId int 机器人的唯一ID,就是使用loadURDF...时返回的数值
required linkIndex int -1表示基座
optional mass double 改变节点的质量
optional lateralFriction double 横向接触摩擦
optional spiningFriction double 滑动摩擦
optional rollingFriction double 滚动摩擦
optional restitution double 恢复系数,小于1
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了
optional linearDamping double 节点的滑动阻尼(默认是0.04)
optional angularDamping double 节点的转动阻尼(默认是0.04)
optional contactStiffness double 接触约束的刚度系数,一般和contactDamping一起使用
optional contactDamping double 接触约束的接触阻尼。若设定此值会覆写URDF文件contact部分中设定的值
optional frictionAnchor int 打开或关闭friction anchor:位置摩擦矫正?(默认关闭,除非在URDFcontact部分中设定打开)
optional localInertialDiagnoal vec3 惯性张量的对角线元素。注意:由于基座和节点以质心为中心并与惯性主轴对齐,因此其惯性张量中没有非对角线元素
optional jointDamping double 每个关节的阻尼系数,在URDF文件中已经设定好了这个参数。一般这个参数非常接近于0。joint damping force = -damping_coefficient*joint_velocity

setTimeStep

注意:默认值为240Hz,大部分情况下不要动这个参数,因为实际上仿真器中有一些参数是根据这个参数调整的(牵一发而动全身)。一旦改了这个,其它参数也需要进行相应修改,比如求解器迭代的次数、接触误差减小参数(erp),摩擦和非接触关节等等

  1. 我们可以使用这个API设定物理仿真的单步时间(单步的物理仿真通过stepSimulation函数实现)。一般由于上述原因尽可能不要使用这个函数,但如果要用的话也要在仿真最开始的时候用,在仿真进行的时候不要轻易使用这个函数。另外setPhysicsEngineParameter函数也可以设定单步仿真的时间。

该函数的输入参数为:

required timeStep float 每一次调用stepSimulation的时候都会调用这个参数
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了

setPhysicsEngineParameter

  1. 这个函数可以用来设定物理引擎的一些参数,包括如下输入参数:
optional fixedTimeStep float setTimeStep的功能一样,不要轻易修改这个参数
optional numSolverIterations int 选择约束求解器迭代的最大次数。不过如果先达到solverResidualThreshold,求解器会在达到numSolverIterations之前就终止计算
optional useSplitImpulse int 仅当使用最大的坐标系时:将位置约束求解和速度约束求解分成两个独立的求解过程,以防止巨大的恢复力矩
optional splitImpulsePenetrationThreshold float 与上个参数useSplitImpulse相关:如果特定的接触约束穿透值没有达到这个设定阈值,则此接触不会进行分割计算
optional numSubSteps int 奖物理引擎仿真的单步进一步划分成numSubSteps个子步,这个参数允许开发者在精确度和性能之间权衡
optional collisionFilterMode int 默认的碰撞过滤值为0,表示:(groupA&maskB)AND(groupB&maskA).该值为1时则切换到OR碰撞过滤器:(groupA&maskB) OR (groupB&maskA)
optional contactBreakingThreshold float 超过此距离阈值的接触点将不会被LCP求解器触力。另外,这个值还扩展了AABBs(?)。在Bullet2.x版本中这个值是0.02
optional maxNumCmdPer1ms int 目前还在测试的参数:如果执行的命令的数目超过了这个阈值,则添加1ms的睡眠(笔者认为应该是考虑到实际机器人的嵌入式设备的实时计算时间)
optional enableFileCaching int 该值为0时禁用文件缓存,比如.obj波前文件加载(?)
optional restitutionVelocityThreshold float 如果相对速度低于这个阈值,则恢复将被设置为0
optional rep float 约束误差减小参数(无摩擦、无接触)
optional contactERP float 接触误差减小参数
optional frictionERP float 摩擦误差减小参数(仅当位置摩擦角功能被打开时有效)
optional enableConeFriction
int 该值为0时:禁用隐式锥体摩擦,使用金字塔式进行近似(默认椎体摩擦有效)
optional deterministicOverlappingPairs int 该值为1为启用。为0时为禁用:禁用重叠对的排序(向后兼容性设置)(?)
optional solveResidualThreshold double 速度阈值,如果哪个约束的最大速度误差低于该阈值,则求解器会终止求解(除非求解器碰到numSolverIteration)。默认值是1e-7
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了
  1. setDefaultContactERP函数用来设置默认的接触参数设置,该函数会加入到setPhysicsEngineParameter函数中

getPhysicsEngineParameters

  1. 我们可以使用这个函数查询当前物理引擎的一些参数,输入是physicsClientID参数。该函数返回一些带有名称的参数

resetSimulation

  1. 该函数会移除当前环境中的所有对象并复位当前环境。该函数有一个optional 的输入:the physics client Id。在有多个仿真平台时,可以通过这个参数指定需要复位的平台

startStateLogging/stopStateLogging

  1. 我们可以通过状态记录的功能来记录仿真的一些状态,包括不同对象在每一步仿真后的状态。我们可以通过这种方式记录对象的运动轨迹。我们还可以选择是否记录每个对象中的基座、关节的信息比如位置、力等等
  2. 所有产生的日志文件都可以被C++或者Python脚本。关于python的使用方法详见quadruped_playback.py和kuka_with_cube_playback.py文件,关于C++的使用方法可以使用bullet3/examples/Utils/RobotLoggingUtil.cpp/h来读入日志文件
  3. 我们还能通过STATE_LOGGING_VIDEO_MP4选项来录制MP4格式的视频。以后还将支持其它状态的记录,包括VR控制器的状态
  4. 我们做了一个minitaur机器人记录的示例,Pybullet仿真的日志文件和真正的Minitaur四足机器人的日志文件相同。详见Bullet/examples/pybullet/examples/logMinitaur.py for an example.
    ==注意:==不同的日志记录器有着自己的记录时间(开始的时候设置为0)。所以我们最好同时开启所有记录器以保持同步,并且最好在开启实时仿真之前启用记录器
    该函数有以下输入参数:
required loggingType int 该参数有多个值可供选择:1.STATE_LOGGING_MINITAUR: (官方做的特例),该值主要在载入使用quadruped/quadruped.urdf模型的时候使用(对象ID是该四足机器人的ID)。该值能记录下时间戳、IMU的三个角度、8个腿电机的位置、8个腿电机的转矩和躯干的前进速度以及模式(仿真中未使用) 2.STATE_LOGGING_GENERIC_ROBOT:此值会记录所有的或者指定的(如果给定了objectUniqueID的话)机器人的状态数据 3.STATE_LOGGING_VIDEO_MP4: 此值会创建一个MP4文件,并记录OPenGL_3D视觉像素流。该值使用ffmpeg管道方法,因此需要安装好ffmpeg。我们也可以使用Ubuntu中默认的avconv来创建一个符号连接以便ffmpeg指向avconv。windows平台在某些情况下会出现一些导致撕裂/颜色瑕疵的问题。 4.STATE_LOGGING_CONTACT_POINTS 5.STATE_LOGGING_VR_CONTROLLERS 6.STATE_LOGGING_PROFILE_TIMINGS: 该值可以转储JSON格式的计时文件,该文件可以使用google Chrome打开://tracing LOAD
required fileName string 用于存储数据的文件名称(含路径,绝对或者相对路径)
optional objectUniqueIds list of int 指定了需要记录状态的对象,如果为空,则记录所有的对象
optional maxLogDof int 可以记录的机器人的关节自由度的最大数目(除了基座的自由度)。仅对第一个参数的STATE_LOGGING_GENERIC_ROBOT_DATA参数有效。默认值是12。如果机器人超过了这个阈值,则该机器人的状态将不会被记录
optional bodyUniqueIdA int 仅对STATE_LOGGING_CONTACT_POINTS有效。如果提供了A的ID,则只会记录涉及到对象A的接触点
optional bodyUniqueIdB int 仅对STATE_LOGGING_CONTACT_POINTS有效。如果提供了B的ID,则只会记录涉及到对象B的接触点
optional linkIndexA int 仅对STATE_LOGGING_CONTACT_POINTS有效。如果提供了该ID,则对于只会记录涉及到对象A中索引为A的节点的接触点
optional linkIndexA int 仅对STATE_LOGGING_CONTACT_POINTS有效。如果提供了该ID,则对于只会记录涉及到对象A中索引为B的节点的接触点
optional deviceTypeFilter int 我们可以使用该值记录所需要记录的VR设备的状态。可以使用VR_DEVICE_CONTROLLER, VR_DEVICE_HMD ,VR_DEVICE_GENERIC_TRACKER的任意参数或者参数组合,仅对STATE_LOGGING_VR_CONTROLLERS有效。默认值是VR_DEVICE_CONTROLLER
optional logFlags int (Pybullet1.3.1中新增选项)。该值可以为STATE_LOG_JOINT_TORQUES用于记录关节电机产生的关节转矩
optional physicsClientId int 有些模式下可以建立多个仿真平台,就可以选择某一个仿真平台的ID了
  1. 该命令正常情况下会返回一个非负值,可以用于停止状态记录。

Todo: 记下为每种日志记录类型记录的数据(有点绕口)。目前只能使用日志查看工具来查找,详见 C++ source code of the logging 或者 Python dumpLog.py 脚本

stopStateLogging

  1. 该函数可以用来停止日志记录程序。输入是startStateLogging的返回值(即loggingUniqueId)。
submitProfileTiming
  1. PyBullet和Bullet测试过很多种功能,目前我们可以看到时间都花在哪些地方。我们可以转储这些时间到一个文件里面然后用Google Chrome来看://tracing window using the LOAD feature。在GUI界面中,我们可以使用’p’命令来开始或者停止文件转储,以便于有些时候我们希望计量某些时间。我们还能使用Pybulet提交一些定时存下来的文件

猜你喜欢

转载自blog.csdn.net/yingyue20141003/article/details/89509173