Physics Tutorial 2: Pendulum

In this tutorial, we set up a pendulum simulation in which a rectangle pendulum swings freely from a circular anchor under the force of gravity. The pendulum is attached to the anchor using a pin joint. The pin joint is a type of constraint - something that restricts the motion of the objects it affects.

This tutorial teaches:

Create the Anchor

In the sim/app/physicsTutorial2 directory, create a file called Anchor.java. In this file add:


package sim.app.physicsTutorial2;

import java.awt.*;
import sim.physics2D.physicalObject.*;
import sim.physics2D.util.*;

public class Anchor extends StationaryObject2D 
{
	public double radius;
	public Anchor(Double2D pos, double radius)
	{
		this.setPose(pos, new Angle(0));
		this.setShape(new sim.physics2D.shape.Circle(radius, Color.gray));
		this.setCoefficientOfRestitution(1);
	} 
}

The anchor is simply a stationary object (recall that a StationaryObject has infinite mass, so doesn't move no matter what) in the shape of a circle.

Create the Pendulum

In the sim/app/physicsTutorial2 directory, create a file called Pendulum.java. In this file add:

package sim.app.physicsTutorial2;

import java.awt.*;
import sim.engine.*;
import sim.physics2D.physicalObject.*;
import sim.physics2D.util.*;
import sim.physics2D.forceGenerator.*;

public class Pendulum extends MobileObject2D implements Steppable, ForceGenerator
{
	public Pendulum(Double2D pos, Double2D vel, double width, double height, Paint paint)
	{
		this.setVelocity(vel);
		this.setPose(pos, new Angle(0));

		this.setShape(new sim.physics2D.shape.Rectangle(width, height, paint), width * height);

		this.setCoefficientOfFriction(0);
		this.setCoefficientOfRestitution(1);
	}
 
	public void step(SimState state)
	{
		Double2D position = this.getPosition();
		PhysicsTutorial2 simPhysicsTutorial2 = (PhysicsTutorial2)state;
		simPhysicsTutorial2.fieldEnvironment.setObjectLocation(this, new sim.util.Double2D(position.x, position.y));
	}
	
	public void addForce()
	{
		this.addForce(new Double2D(0, 5));
	}
}

The Pendulum is a rectangular mobile object. The only real difference between the Pendulum and the MobilePoly from physics tutorial 1 is that a force is applied to the pendulum (simulated gravity). Forces can be applied to mobile objects using MobileObject's addForce method. This method takes as a parameter a vector (represented by the physics engine's Double2D) defining the direction and magnitude of the force.

Constant forces (like gravity) need to be applied at every time step throughout the simulation. Experienced MASON users may wonder, therefore, why the gravity force isn't applied to the pendulum in the step method. The reason is that depending on the numerical integrator used, the force may need to be applied more than once per time step. For example, the default integrator provided with the physics engine, the Runge-Kutta integrator, applies forces to objects four times in each time step. The physics engine deals with this issue by requiring anything that applies forces to an object to implement the ForceGenerator interface which exposes one method: addForce (no parameters). In this case, the Pendulum applies a force to itself (to simulate gravity), so it implements the ForceGenerator interface and applies the gravity force within the addForce method.

Create the anchor and pendulum and constrain them together with a pin joint

The file sim/app/physicsTutorial2/PhysicsTutorial2.java already has much of the non-physics related MASON code needed to set up the simulation. The only code to add is in the start method after the "Add physics specific code here" line.

		// Create and schedule the physics engine
		PhysicsEngine2D objPE = new PhysicsEngine2D();
		schedule.scheduleRepeating(objPE);
		
		// Create the anchor that the pendulum swings from
		Anchor anchor = new Anchor(new Double2D(100, 50), 5);
		fieldEnvironment.setObjectLocation(anchor, new sim.util.Double2D(100, 50));
		objPE.register(anchor);
		
		// Create the pendulum
		Pendulum pend = new Pendulum(new Double2D(80, 50), new Double2D(0, 0), 20, 5, Color.red);
		fieldEnvironment.setObjectLocation(pend, new sim.util.Double2D(80, 50));
		schedule.scheduleRepeating(pend);
		objPE.register(pend);
		
		// Connect the pendulum to the anchor with a pin joint
		PinJoint pj = new PinJoint(new Double2D(100, 50), anchor, pend);
		objPE.register(pj);

As in physics tutorial 1, this code creates and schedules the physics engine and the physical objects and registers the physical objects with the physics engine. The last two lines create a pin joint that connects the anchor and the pendulum. The PinJoint constructor takes three parameters - the initial position of the pin joint and the two objects to connect. In this case, we set the pin joint to have the same position as the anchor so the pendulum will swing around the center of the anchor.

Run the simulation

Compile Anchor.java, Pendulum.java, PhysicsTutorial2.java, and PhysicsTutorial2WithUI.java. Then run the program as java sim.app.physicsTutorial2.PhysicsTutorial2WithUI

After pressing play, you should see a red rectangular pendulum swinging from a gray circular anchor.