天天看點

PhysX3 User Guide 03 - Joint

原文位址:http://www.cnblogs.com/mumuliang/archive/2011/06/02/2068652.html

1 Joint Creation   Joint提供了一種聯系倆Actor的途徑。典型的例子如門上的合頁,人物的肩膀。.

建立Joint的方法: PxRevoluteJointCreate(PxPhysics &  physics,

                      PxRigidActor *  actor0,  const  PxTransform &  localFrame0,

                      PxRigidActor *  actor1,  const  PxTransform &  localFrame1);

必須有一個Actor可以動,是PxRigidDynamic,要不就是PxArticulationLink. 另一個Actor無所謂。

localFrame參數表示Actor的相對PxTransform,包括位置和姿态,position and orientation. 上面的例子是一個revolute joint,localFrame須指定原點和旋轉軸。

PhysX提供了6中Joint:

    1. 固定。不能相對運動。a fixed joint locks the orientations and origins rigidly together 
    2. 距離。Actor之間像栓了繩子。a distance joint keeps the origins within a certain distance range 
    3. 球體。原點重合,姿态自由。a spherical joint (sometimes known as as a ball-and-socket) keeps the origins together, but allows the orientations to vary freely. 
    4. 開阖。門的合頁那樣的。a revolute joint (often referred to as a hinge) keeps the origins and x-axes of the frames together, and allows free rotation around this common axis. 
    5. 截面。移門那樣的。a prismatic joint keeps the orientations identical, but allows the origin of one actor to slide freely along the line defined by the origin and x-axis of the other. This kind of joint models a sliding door. 
    6. D6。高度自定義的一類,可以高度自由也可以高度固定。a D6 joint is a highly configurable joint that allows specification of individual degrees of freedom either to move freely or be locked together. It can be used to implement a wide variety of mechanical and anatomical joints, but is somewhat less intuitive to configure than the other joint types. 

應用程式可以添加向架構添加新的Joint擴充現有類型。

Note: PhysX中的角度是以弧度為機關。

 2 Beyond the Basics  

  Visualization   所有PhysX的标準joints都支援debug visualization.是以..

但 joint本身是不可見的. 為使其可見, 要将設定其constraint flag為visualization,并改變場景的visualization parameters: scene -> setVisualizationParameter(PxVisualizationParameter::eJOINT_FRAMES,  1.0f );

scene -> setVisualizationParameter(PxVisualizationParameter::eJOINT_LIMITS,  1.0f );

...

joint -> setConstraintFlag(PxConstraintFlag::eVISUALIZATION)

  Force Reporting   Jonit連接配接的Actor每幀都要儲存連接配接它倆的force的資訊。通過設定reporting constraint flag啟用該功能,然後就可以用Joint對象的getForce方法獲得force資訊。 joint -> setConstraintFlag(PxConstraintFlag::eREPORTING)

...

scene -> fetchResults(...)

joint -> getForce(force, torque);

The force is resolved at the origin of actor1’s joint frame.

  Breakage   PhysX的标準joint都是可以被掰開的breakable. 可以定義這個臨界force和torgue。 joint被掰開會引發一個simulate event(參看 PxSimulationEventCallback::onJointBreak), 這個joint盡管可能仍然存在與場景中,但也不再參與運算。

但joint預設是不可掰開的。開啟該屬性,方法如下,首先設定一個臨界force和torgue,然後設定breakable constraint flag為true。 joint -> setBreakForce( 100.0f ,  100.0f );

joint -> setConstraintFlag(PxConstraintFlag::eBREAKABLE,  true );

  Projection   Under stressful conditions, PhysX’ dynamics solver may not be able to accurately enforce the constraints specified by the joint. For joints where this is problematic you can enable kinematic projection, which tries to bring violated constraints back into alignment. Projection is not a physical process and doesn’t preserve momentum or respect collision geometry. It should be avoided where practical, but it can be useful in improving simulation quality where joint separation results in unacceptable artifacts.(這段很迷糊)

在突發情況(有外力情況?)下,PhysX 的dynamics slover(dynamic物體的電腦?)可能會沒辦法正确操作joint定義的Actor之間限制關系。這顯然不太妙。你可以啟用kinematic projection(運動投影?),它會嘗試糾正。但Projection并非實體過程,它不會遵守動量守恒也不會管圖形是否碰撞。實際應用中應該避免使用projection,但它在改善什麼什麼效果時很有用。-_-b

projection也是預設不可用的。啟用方法如下,首先設定會引起joint被project的臨界linear tolerance和angular tolerance,然後開啟那啥constraint flag.

joint -> setProjectionLinearTolerance( 0.1f );

joint -> setConstraintFlag(PxConstraintFlag::ePROJECTION,  true );

Very small tolerance values for projection may result in jittering around the joint.

  Limits   joint限制相關的Actor如何旋轉或隻能沿某方向平移,同時可進一步設定這種可旋轉和可移動的範圍。例如revolute joint,合頁關節,預設是繞軸的任意角度的旋轉,如果需要,你可以開啟limit,然後定義個旋轉的最大角度和最小角度。

Limits可以看做collision碰撞的一種。stable limit需要定義最大最小距離,和一個tolerance。blabla..要說的是limit的模拟開銷是很昂貴的。

設定limit要配置limit的geometry,然後設定joint的limit flag為true。 revolute -> setLimit(PxJointLimitPair( - PxPi / 4 , PxPi / 4 ,  0.1f ));  //  upper, lower, tolerance

revolute -> setRevoluteJointFlag(PxRevoluteJointFlag::eLIMIT_ENABLED,  true );

Limit可硬可軟。硬就是讓joint的運動立刻停下來,如果這是limit被設定為non-zero restitution,會被彈回。軟的就是有阻尼效果。預設的limit是不會回彈的hard。

Note: Limits are not projected.

  Actuation   有些joint是被spring和motor驅動的。這種模拟的開銷比簡單用force驅動的要大,它要求有更多的 stable control ,更多細節參看D6和revolute joint的文檔。

Note: The force generated by actuation is not included in the force reported by the solver, nor does it contribute towards exceeding the joint’s breakage force threshold.

  3 Fixed Joint   image:: ../images/fixedJoint.png

The fixed joint has no additional characteristics.

  4 Spherical Joint   image:: ../images/sphericalJoint.png

A spherical joint constrains a point on each actor to be coincident.

The spherical joint supports a cone limit, which constrains the direction of the x-axis of actor1’s constraint frame. The axis of the limit cone is the x-axis of actor0’s constraint frame, and the allowed limit values are the maximum rotation around the the y- and z- axes of that frame. Different values for the y- and z- axes may be specified, in which case the limit takes the form of an elliptical angular cone: joint -> setLimitCone(PxJointLimitCone(PxPi / 2 , PxPi / 6 ,  0.01f );

joint -> setSphericalJointFlag(PxSphericalJointFlag::eLIMIT_ENABLED,  true );

Note that very small or highly elliptical limit cones may result in solver jitter.

Note Visualization of the limit surface can help considerably in understanding its shape.

  5 Revolute Joint   image:: ../images/revoluteJoint.png

A revolute joint removes all but a single rotational degree of freedom from two objects. The axis along which the two bodies may rotate is specified by the common origin of the joint frames and their common x-axis. In theory, all origin points along the axis of rotation are equivalent, but simulation stability is best in practice when the point is near where the bodies are closest.

The joint supports a rotational limit with upper and lower extents. The angle is zero where the y- and z- axes of the joint frames are coincident, and increases moving from the y-axis towards the z-axis: joint -> setLimit(PxJointLimitPair( - PxPi / 4 , PxPi / 4 ,  0.01f );

joint -> setRevoluteJointFlag(PxRevoluteJointFlag::eLIMIT_ENABLED,  true );

The joint also supports a motor which drives the relative angular velocity of the two actors towards a user-specified target velocity. The magnitude of the force applied by the motor may be limited to a specified maximum: joint -> setDriveVelocity( 10.0f );

joint -> setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_ENABLED,  true );

By default, when the angular velocity at the joint exceeds the target velocity the motor acts as a brake; a freespin flag disables this braking behavior

  6 Prismatic Joint   image:: ../images/prismaticJoint.png

A prismatic joint prevents all rotational motion, but allows the origin of actor1’s constraint frame to move freely along the x-axis of actor0’s constraint frame. The primatic joint supports a single limit with upper and lower bounds on the distance between the two constraint frames’ origin points: joint -> setLimit(PxJointLimitPair( - 10.0f ,  20.0f ,  0.01f );

joint -> setPrismaticJointFlag(PxPrismaticJointFlag::eLIMIT_ENABLED,  true );

  7 Distance Joint   image:: ../images/distanceJoint.png

The distance joint keeps the origins of the constraint frames within a certain range of distance. The range may have both upper and lower bounds, which are enabled separately by flags: joint -> setMaxDistance( 10.0f );

joint -> setDistanceJointFlag(eMAX_DISTANCE_ENABLED,  true );

In addition, when the joint reaches the limits of its range motion beyond this distance may either be entirely prevented by the solver, or pushed back towards its range with an implicit spring, for which spring and damping paramters may be specified.

  8 D6 Joint     Locking and Unlocking Axes   D6是最複雜的标準Joint. 它預設表現的像fixed Joint,兩個物體像黏在一起一樣運動。但使用Joint的 setMotion方法,你可以設定允許旋轉和平移。 d6joint -> setMotion(PxD6Axis::eX, PxD6Motion::eFREE);

如果設定了平移自由translational degrees of freedom,即允許actor1的原點沿着actor0的constraint frame定義的軸移動。

旋轉自由Rotational degrees of freedom分為兩種:扭twist (around the x-axis of actor0’s constraint frame);和擺 swing (around the y- and z- axes.) 通過控制twist和swing參數的開關,可以得到很多效果:

  1. if just a single degree of angular freedom is unlocked, the result is always equivalent to a revolute joint. It is recommended that if just one angular freedom is unlocked, it should be the twist degree, because the joint has various configuration options and optimizations that are designed for this case. 
  2. if both swing degrees of freedom are unlocked but the twist degree remains locked, the result is a zero-twist joint. The x-axis of actor1 swings freely away from the x-axis of actor0 but twists to minimize the rotation required to align the two frames. This creates a kind of isotropic universal joint which avoids the problems of the usual ‘engineering style’ universal joint (see below) that is sometimes used as a kind of twist constraint. There is a nasty singularity at π radians (180 degrees) swing, so a swing limit should be used to avoid the singularity. 
  3. if one swing and one twist degree of freedom are unlocked but the remaining swing is kept locked, a zero-swing joint results (often also called a universal joint.) If for example the SWING1 (y-axis rotation) is unlocked, the x-axis of actor1 is constrained to remain orthogonal to the z-axis of actor0. In character applications, this joint can be used to model an elbow swing joint incorporating the twist freedom of the lower arm or a knee swing joint incorporating the twist freedom of the lower leg. In vehicle applications, these joints can be used as ‘steered wheel’ joints in which the child actor is the wheel, free to rotate about its twist axis, while the free swing axis in the parent acts as the steering axis. Care must be taken with this combination because of anisotropic behavior and singularities (beware the dreaded gimbal lock) at angles of π/2 radians (90 degrees), making the zero-twist joint a better behaved alternative for most use cases. 
  4. if all three angular degrees are unlocked, the result is equivalent to a spherical joint. 

有三種PhysX2的joint在physX3已經木有了,但你可以醬來實作他們。

  • The cylindrical joint (with axis along the common x-axis of the two constraint frames) is given by the combination:

d6joint -> setMotion(PxD6Axis::eX,     PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);

  • the point-on-plane joint (with plane axis along the x-axis of actor0’s constraint frame) is given by the combination:

d6joint -> setMotion(PxD6Axis::eY,      PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eZ,      PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eTWIST,  PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);

  • the point-on-line joint (with axis along the x-axis of actor0’s constraint frame) is given by the combination:

d6joint -> setMotion(PxD6Axis::eX,      PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eTWIST,  PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);

  Limits   除了可以定義軸是自由還是鎖定( axis is free or locked), 還可以定義其受限範圍limit. D6有三種limit,并且可以組合使用。

A single linear limit with only an upper bound is used to constrain any of the translational degrees of freedom. The limit constrains the distance between the origins of the constraint frames when projected onto these axes. For example, the combination: d6joint -> setMotion(PxD6Axis::eX, PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eY, PxD6Motion::eLIMITED);

d6joint -> setMotion(PxD6Axis::eZ, PxD6Motion::eLIMITED);

d6joint -> setLinearLimit(PxJointLimit( 1.0f ,  0.1f ));

constrains the y- and z- coordinates of actor1’s constraint frame to lie within the unit disc. Since the x-axis is unconstrained, the effect is to constrain the origin of actor1’s constraint frame to lie within a cylinder of radius 1 extending along the x-axis of actor0’s constraint frame.

The twist degree of freedom is limited by a pair limit with upper and lower bounds, identical to the limit of the revolute joint.

If both swing degrees of freedom are limited, a limit cone is generated, identical to the limit of the spherical joint. As with the spherical joint, very small or highly elliptical limit cones may result in solver jitter.

If only one swing degree of freedom is limited, the corresponding angle from the cone limit is used to limit rotation. If the other swing degree is locked, the maximum value of the limit is π radians (180 degrees). If the other swing degree is free, the maximum value of the limit is π/2 radians (90 degrees.)

  Drives   D6有1個linear drive model, 和2個angular drive models. The drive is a proportional derivative drive, which applies a force as follows:

force  =  spring  *  (targetPosition  -  position)  +  damping  *  (targetVelocity  -  velocity)

The drive model 也可以代替force用來引起加速。Acceleration drive 調整比force drive要容易些。

linear drive model 有如下參數: 

  • 目标位置,在actor0的constraint frame中定義。target position, specified in actor0’s constraint frame 
  • 目标速度,也定義在actor0的constraint frame中。target velocity, specified in actor0’s constraint frame 
  • 彈性?spring 
  • 阻尼。damping 
  • 能提供的最大力。forceLimit - the maximum force the drive can apply 
  • 加速标志。acceleration drive flag 

它會以設定的阻尼和倔強系數stiffness?往目标位置運動。A physical lag due to the inertia of the driven body acting through the drive spring will occur; therefore, sudden step changes will result over a number of time steps. Physical lag can be reduced by stiffening the spring or supplying a velocity target.

如果位置固定目标速度為0, a position drive will spring about that drive position with the specified springing/damping characteristics:

PhysX3 User Guide 03 - Joint

//  set all translational degrees free

d6joint -> setMotion(PxD6Axis::eX, PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eY, PxD6Motion::eFREE);

d6joint -> setMotion(PxD6Axis::eZ, PxD6Motion::eFREE);

//  set all translation degrees driven:

PxD6Drive drive( 10.0f ,  - 20.0f , PX_MAX_F32,  true );

d6joint -> setDrive(PxD6JointDrive::eX, drive);

d6joint -> setDrive(PxD6JointDrive::eY, drive);

d6joint -> setDrive(PxD6JointDrive::eZ, drive);

// Drive the joint to the local(actor[0]) origin - since no angular dofs are free, the angular part of the transform is ignored

d6joint -> setDrivePosition(PxTransform::createIdentity());

d6joint -> setDriveVelocity(PxVec3::createZero());

PhysX3 User Guide 03 - Joint

Angular drive和linear drive完全不同,angular drive木有一種簡單直接的方式用以描述它相對于奇點(singularities)是怎麼自由運動的, 是以D6 joint提供了兩種angular drive models——扭擺 和 球面插值SLERP (Spherical Linear Interpolation).

這倆angular drive model最大的差別在于他們使用四元數的方式。SLERP中直接使用四元數,扭擺模型裡面會吧四元數分解成blabla. 扭擺模型多數情況下的行為都是比較一緻的,但要注意180度的擺動,這時候actor并不會沿着兩個角度之間的最短弧線運動(球體表面的最短路徑). SLERP模型總是會讓actor沿着最短對角弧運動。

隻有有任何一個方向的角度不能改變, SLERP drive 參數就會被忽略。當所有方向上都是角度自由,and parameters are set for multiple angular drives, the SLERP parameters will be used.

The angular drive model has the following parameters:

  • 角速度,定義在actor0的constraint frame。An angular velocity target specified relative to actor0’s constraint frame 
  • 目标姿态。定義在同上。An orientation target specified relative to actor0’s constraint frame 
  • SLERP或扭擺drive的配置。drive specifications for SLERP (slerpDrive), swing (swingDrive) and twist (twistDrive): 
    • 彈性。spring - amount of torque needed to move the joint to its target orientation proportional to the angle from the target (not used for a velocity drive). 
    • 阻尼。damping - applied to the drive spring (used to smooth out oscillations about the drive target). 
    • 那啥。forceLimit - maximum torque applied when driving towards a velocity target (not used for an orientation drive) 
    • 那啥。acceleration drive flag 

Best results will be achieved when the drive target inputs are consistent with the joint freedom and limit constraints.

繼續閱讀