I’m working on a robot simulation using the PhysX Candy Wrapper (physx system software v 9.11.0621) and am having some serious trouble controlling the joints (RevolutionJoint) with motors.
First, I know that the Candy Wrapper may not be widely used here, and it may even be the source of the problem, but I’m just checking here to see if there are any common mistakes I may be making.
It seems that no matter what kind of signal I send to the joints, they kind of flap about wildly. They stay within the limits I have specified, but their velocity seems to be very unrelated to the velTarget I’m giving to the motor for each joint. I have tried a wide variety of max joint speeds, forces, etc. and can’t seem to figure this out. I have also tried setting the spring and damping constants (in an attempt to add a kind of friction to the joints), and these seem to have absolutely no effect whatsoever. Below is some code samples of how I’m creating and attempting to manipulate the joints. It is a small subset of the overall code. Keep in mind that while this is in C#, much of the task of creating bodies and joints is roughly the same.
Any guidance or tips are greatly appreciated. Thanks in advance.
BodyDesc shoulder1BD = new BodyDesc();
shoulder1BD.SolverIterationCount = SOLVERITERATIONCOUNT;
BoxShapeDesc shoulder1BSD = new BoxShapeDesc(new Vector3(4 * SCALE, 4 * SCALE, 2 * SCALE));
shoulder1BSD.MaterialIndex = bodyMaterial.Index;
shoulder1BSD.SkinWidth = SKINWIDTH;
ActorDesc shoulder1AD = new ActorDesc(shoulder1BSD);
shoulder1AD.Body = shoulder1BD;
shoulder1AD.Density = DENSITY;
shoulder1AD.GlobalPosition = new Vector3(body.GlobalPosition.X - 7, body.GlobalPosition.Y, body.GlobalPosition.Z);
Actor shoulder1 = scene.CreateActor(shoulder1AD);
shoulder1.Name = SHOULDER1NAME;
BodyDesc upperLeg1BD = new BodyDesc(); upperLeg1BD.SolverIterationCount = SOLVERITERATIONCOUNT; BoxShapeDesc upperLeg1BSD = new BoxShapeDesc(new Vector3(10 * SCALE, 2 * SCALE, 2 * SCALE)); upperLeg1BSD.MaterialIndex = bodyMaterial.Index; upperLeg1BSD.SkinWidth = SKINWIDTH; ActorDesc upperLeg1AD = new ActorDesc(upperLeg1BSD); upperLeg1AD.Body = upperLeg1BD; upperLeg1AD.Density = DENSITY; upperLeg1AD.GlobalPosition = new Vector3(body.GlobalPosition.X - 14, body.GlobalPosition.Y, body.GlobalPosition.Z); Actor upperLeg1 = scene.CreateActor(upperLeg1AD); upperLeg1.Name = UPPER1NAME;
RevoluteJointDesc jd1 = new RevoluteJointDesc();
//jd1.MaxForce = MAXJOINTFORCE; // if we speciy no max force, the joint becomes unbreakable, which is what we want
jd1.GlobalAxis = new Vector3(0, 1, 0);
jd1.GlobalAnchor = new Vector3(body.GlobalPosition.X - 5 * SCALE, body.GlobalPosition.Y, body.GlobalPosition.Z);
RevoluteJoint rj1 = (RevoluteJoint)(scene.CreateJoint(jd1));
rj1.Limits.High.Value = (float)(Math.PI / 4);
rj1.Limits.Low.Value = (float)(-Math.PI / 4);
rj1.Flags = RevoluteJointFlags.MotorEnabled | RevoluteJointFlags.LimitEnabled | RevoluteJointFlags.SpringEnabled;
rj1.Spring.Damper = DAMPINGCOEFFICIENT;
rj1.Spring.Spring = SPRINGCOEFFICIENT;
((RevoluteJoint)joints[i + 4]).Motor.VelTarget = (outputs[i] * 2 * MOTORSPEED) - MOTORSPEED;