RobotArm using PxJoint - PhysX 3.2

I create robot arm using dynamic actors and mainly PxRevoluteJoint. Now I’d like to control every single joint through set angle. Here’s my sample code:

PxRevoluteJoint *j; // my joint
// if angle is less than current degree
while(degrees >= angle)
{
j->setDriveVelocity(0.25);

			actor0->getGlobalPose().q.toRadiansAndUnitAxis(angleq,axisq); // ACTOR2 on picture
			instance->onRenderCallback(); // render and simulate()
			degrees = angleq * 180/PI;
		}

j->setDriveVelocity(0.0);
setAllKinematicJoints(pPhx->joints, true); // set up all joints to kinematic because I dont’t wont to // move them

My problem is that sometimes everythings works fine but often the ‘degrees’ variable is 180 and axisq changes. I want to rotate my actor0 (actor2 on picture) only in X axis and get always current angle. How I can do that?

Hi.

… You didnt limit your joints dont you?

Look at my answer here to limit a PxD6Joint - its similiar for other joints.

https://devtalk.nvidia.com/default/topic/523431/physx-and-physics-modeling/the-equivalent-of-nx_bf_frozen_rot-in-physx-3-2-2/

In short:

Create a joint and connect them with your actors:
(This code will add a joint to only one actor - thus the actor rotation / movement itself can be locked or limited)

Joints are by default locked.

PxD6Joint* mJoint = PxD6JointCreate(*mPhysic->getSDK(), mActor, PxTransform::createIdentity(), nullptr, mActor->getGlobalPose());

mJoint->setMotion(PxD6Axis::eX,PxD6Motion::eLIMITED); // Limited on X allowed
//Limit rotations:
mJoint->setSwingLimit(PxJointLimitCone(...)); 
mJoint->setTwistLimit(PxJointLimitPair(...));

Look into the Bridge sample - the bridge use different type of joints and rotation limits.
Also look into the PhysXGuide for more information.
Its also usefull to read the comments for the desired method.
(In VS 2012: Click the mouse on the methode name and push F12 to go to the definition / declaration)

Ok I try it but I tought that when I use RevoluteJoint then one axis is free(or limited) and other two are locked. I always set PxJointLimitPair.

createRevoluteJoint(PxRigidActor &actor0, PxRigidActor &actor1, PxJointLimitPair &limitPair, bool limit,
PxReal driveVelocity, bool velocity, PxTransform &mtransf0, PxTransform &mtransf1, char name)
{
PxRevoluteJoint
joint;
joint = PxRevoluteJointCreate(*gPhysicsSDK, &actor0, mtransf0, &actor1, mtransf1);
joint->setRevoluteJointFlag(PxRevoluteJointFlag::eLIMIT_ENABLED, limit);
joint->setLimit(limitPair);

  joint->setDriveVelocity(driveVelocity);
  joint->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_ENABLED, velocity);
  joint->setName(name);

  joint->setProjectionLinearTolerance(0.1);
  joint->setProjectionAngularTolerance(0.1);

}

I checked D6Joint and it works the same as RevoluteJoint. Sometimes everythings ok but sometimes there’s error. It is because in line:
actor0->getGlobalPose().q.toRadiansAndUnitAxis(angleq,axisq); // ACTOR2 on picture

variable ‘angleq’ is 180 degrees instead of true current angle in X axis. Maybe this is cause all joints aren’t fit properly and there some jittering. Is there other way to get this angle?

Hi,

sry for the delay.

Take a look into the PhysXGuide - it shows you the differences between the joints and their usage.

I dont know what do you want to achieve but maybe you can get your rotations directly
from your joint using this snippet:

PxTransform pos = mJoint->getLocalPose(PxJointActorIndex::eACTOR0);

Or you calculate the angle between a fixed axis - sample code:
PxTransform pos;
PxReal angle = pos.q.getBasisVector0().dot(PxVec3(0,1,0)); //Just change the values you to your needs

Or calculate it via the cross product (inner product) combined with the outer product.

Maybe you get a new point to solve it with that.