REVOLUTE JOINT

21
Jun
2012



A revolute joint forces two bodies to share a common anchor point, often called a hinge point. The revolute joint has a single degree of freedom: the relative rotation of the two bodies. This is called the joint angle. Let us create a car.

var    b2Vec2 = Box2D.Common.Math.b2Vec2
,      b2BodyDef = Box2D.Dynamics.b2BodyDef
,      b2Body = Box2D.Dynamics.b2Body
,      b2FixtureDef = Box2D.Dynamics.b2FixtureDef
,      b2World = Box2D.Dynamics.b2World
,      b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape
,      b2CircleShape = Box2D.Collision.Shapes.b2CircleShape
,      b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef
,      b2DebugDraw = Box2D.Dynamics.b2DebugDraw
,      b2Fixture = Box2D.Dynamics.b2Fixture
,      b2AABB = Box2D.Collision.b2AABB;

var world = new b2World(new b2Vec2(0,10), true);

var bodyDef = new b2BodyDef;
bodyDef.type = b2Body.b2_dynamicBody;

var fixDef = new b2FixtureDef;
fixDef.density = 30;
fixDef.friction = 10;
fixDef.restitution = 0.1;
fixDef.shape = new b2CircleShape(0.3);

//  wheel1
bodyDef.position.Set(8,10);
var wheel1=world.CreateBody(bodyDef);
wheel1.CreateFixture(fixDef);
//  wheel2
bodyDef.position.Set(12,10);
var wheel2=world.CreateBody(bodyDef);
wheel2.CreateFixture(fixDef);

//  Car body
bodyDef.position.Set(10,8);
//  just change the fixDef.shape and keep other properties
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(4,2);
var car = world.CreateBody(bodyDef);
car.CreateFixture(fixDef);

//  Revolute Joints
var revoluteJointDef1 = new b2RevoluteJointDef();
revoluteJointDef1.Initialize(car, wheel1, wheel1.GetWorldCenter());
//revoluteJointDefB.lowerAngle = -Math.PI/2;  (-90 degrees)
//revoluteJointDefB.upperAngle = Math.PI/4; (45 degrees)
//revoluteJointDefA.enableLimit = true;
revoluteJointDef1.maxMotorTorque = 1100.0;
revoluteJointDef1.motorSpeed = 3.0;
revoluteJointDef1.enableMotor = true;
revoluteJointA = world.CreateJoint(revoluteJointDef1);

var revoluteJointDef2 = new b2RevoluteJointDef();
revoluteJointDef2.Initialize(car, wheel2, wheel2.GetWorldCenter());
revoluteJointDef2.lowerAngle = -Math.PI/2; 
revoluteJointDef2.upperAngle = Math.PI*8;
revoluteJointDef2.enableLimit = true;
revoluteJointDef2.maxMotorTorque = 1100.0;
revoluteJointDef2.motorSpeed = 3.0;
revoluteJointDef2.enableMotor = true;
revoluteJointB = world.CreateJoint(revoluteJointDef2);
First make sure lines 1 to 11 are present in your script. Line 8 most importantly.

The line 29
revoluteJointDef1.Initialize(car, wheel1, wheel1.GetWorldCenter());
takes three arguements Body1, Body2 and an Anchor Point about which the body will rotate. wheel1.GetWorldCenter() gives the coordinates of Center of wheel in world coordinates. If we want any other point as an Anchor point, use the below code:
revoluteJointDef1.Initialize(car, wheel1, new b2Vec2(8,9.8));
NOTE: Remember Box2d assumes body is in the correct position when the joint is made. So be careful. Also it is not necessary that the anchor point should lie on the body.

We can set Maximum Motor Torque and Motor Speed in line 47 and 48 respectively. If line 49 is set to true then "Motor" will be on and will run on its own power.

NOTE: A +ve Motor Speed turns the body in Clockwise direction while a -ve one turns the body in Anti Clockwise direction.

In lines 54 and 55 we can set lower angle and upper angle respectively. If lower angle is say -90 degrees and upper angle is 1440 degrees, then body will turn a maximum of 90 degrees anticlockwise and 1440 degrees clockwise after which it will cease to rotate.

NOTE: Notice the '-' sign before the angle in the lower limit. It should be there.


NOTE: If we want to create a Revolute Joint between a Static Body and a Dynamic Body then in the joint initialization line first body should be Static Body.
revoluteJointDef1.Initialize(staticBody, dynamicBody, new b2Vec2(8,3));

Line 28 to 46 can also be replaced by
var revoluteJointDef = new b2RevoluteJointDef();
revoluteJointDef.Initialize(car, wheel1, wheel1.GetWorldCenter());
revoluteJointDef.maxMotorTorque = 1100.0;
revoluteJointDef.motorSpeed = 3.0;
revoluteJointDef.enableMotor = true;
revoluteJointA = world.CreateJoint(revoluteJointDef);

revoluteJointDef.Initialize(car, wheel2, wheel2.GetWorldCenter());
revoluteJointDef.lowerAngle = -Math.PI/2; 
revoluteJointDef.upperAngle = Math.PI*8;
revoluteJointDef.enableLimit = true;
revoluteJointB = world.CreateJoint(revoluteJointDef);
NOTE: We can use same bodyDef, fixDef and revoluteJointDef throughout by just changing the properties associated between them after creation of particular bodies and fixtures and joints.

Destroying a Joint

Remember this goes for any type of joints (Gear Joint, Prismatic Joint etc.).
world.DestroyJoint(revoluteJointA);
The above code will destroy the joint between bodies car and wheel1.

You can access a revolute joint's angle, speed, and motor torque.
revoluteJointA.GetJointAngle();
revoluteJointA.GetJointSpeed();
revoluteJointA.GetMotorTorque();
You also update the motor parameters each step.
revoluteJointA.SetMotorSpeed(speed);
revoluteJointA.SetMaxMotorTorque(torque);

By administrator at 03:43:25 PM 0 Comment(s)

Comments

There are no comments yet. Be the first one to add a comment!

Add a Comment

Please enter the email address.Invalid format. (Won't be Displayed)
Notify me of followup comments
Enter the displayed Code: captcha