An introduction to vehicle physics

A physics vehicle is a collision object used to simulate a vehicle driving on (or gliding over) a smooth surface.

Bullet’s physics vehicle makes many simplifying assumptions:

  • A rigid chassis, supported by wheels.

  • Acceleration, steering, and braking forces are applied to the chassis, not the wheels.

  • The wheels have no momentum, and as long as they touch the ground, they don’t lose traction or "drift". Tire friction is calculated using a basic anisotropic friction model.

  • Engine power is unlimited. There is no transmission and no gearing.

The chassis is simulated by a dynamic rigid body, with all the features thereof. During each simulation step, the vehicle controller casts physics rays to calculate the height of each wheel’s axis above the ground. Those heights are used to calculate the forces exerted on the chassis by the suspension.

Instead of applying forces or directly updating the vehicle’s velocities, an app using a physics vehicle should specify when and how the vehicle accelerates, steers, and brakes.

Direct creation

You can create a vehicle without wheels by directly invoking the PhysicsVehicle constructor. This allows you to specify the shape and mass of the chassis. Before adding it to a physics space, you should add wheels to it. For stability, a vehicle needs at least 3 wheels, and the chassis center of mass should be located between the wheels, roughly speaking.

HelloVehicle is a simple application that demonstrates the direct creation of a vehicle, followed by automated steering and acceleration. Things to notice while running the app:

  1. The vehicle has a wedge-shaped chassis.

  2. The vehicle has 4 wheels, arranged in a rectangle.

  3. The vehicle circles to the left, accelerating steadily until it "wipes out" and flips over.

VehicleControl

To associate a vehicle with a Spatial, there’s VehicleControl, a physics control that extends PhysicsVehicle.

As with RigidBodyControl, the physics control and the collision object are the same object.

The Jme3Examples subproject contains 4 demo apps that showcase physics vehicles:

  1. The TestPhysicsCar app demonstrates a VehicleControl with keyboard-controlled motion and debug visualization.

  2. The TestFancyCar app demonstrates a VehicleControl with keyboard-controlled motion. A textured model is used to visualize the chassis and wheels.

  3. The TestAttachDriver app demonstrates attaching a rigid body to vehicle by means of a physics joint. This demo uses VehicleControl and debug visualization.

  4. The TestHoveringTank app simulates a hovercraft traveling over rough terrain. In this demo, the "wheels" are invisible, and braking is disabled. This demo uses the PhysicsHoverControl custom vehicle control.

The first 3 demo apps share the following keyboard controls:

  • U to accelerate the vehicle,

  • H/K to steer left/right,

  • J to apply the brake, and

  • W/A/S/D to dolly the camera forward/left/back/right.

TestHoveringTank uses a different set of keyboard controls:

  • W to accelerate the vehicle,

  • A/D to rotate the vehicle left/right,

  • S to apply the brake, and

  • Space bar to fire the gun.

Most of the remaining keyboard controls are standardized:

  • Return restarts the simulation,

  • F5 toggles visibility of the render-statistics overlay,

  • C dumps the camera’s position to the console,

  • M prints memory statistics to the console, and

  • Esc ends the application.

Configuration and tuning

Bullet’s vehicle model includes many details that can affect stability and/or realism. The complexity of the model is often an obstacle to achieving the desired behavior. Kester Maddock has published a 16-page document on this subject.

Chassis shape

Because the chassis is a dynamic rigid body, it requires a suitable collision shape. In particular:

  • it should be 3-dimensional, and

  • its center and local axes should be plausible.

A symmetrical collision shape will place the center of gravity rather high, resulting in a vehicle prone to tipping. To avoid this pitfall,

  • use an asymmetrical shape such as a HullCollisionShape or compound shape and

  • make sure its center is low.

By default, the local axes of the chassis are assigned as follows:

  • +X points left,

  • +Y points up, and

  • +Z points forward.

However, the local-axis assignments can be customized to match any 3-D model. For instance:

vehicle.setPhysicsSpace(physicsSpace);
VehicleController controller = vehicle.getController();
Vector3f right = new Vector3f(0f, -1f, 0f);
Vector3f up = new Vector3f(0f, 0f, -1f);
Vector3f forward = new Vector3f(-1f, 0f, 0f);
controller.setCoordinateSystem(right, up, forward);

Continuous collision detection

If a vehicle moves rapidly, it may pass through a thin obstacle without any collision being detected. To prevent this, enable continuous collision detection (CCD) on the chassis:

vehicleControl.setCcdMotionThreshold(distancePerTimeStep);

For more information on CCD, see the rigid-body tutorial.

Maximum suspension force

A vehicle’s suspension connects its wheels to its chassis and supports the weight of the chassis. If the maximum suspension force is set too low, the suspension will collapse, causing the chassis to scrape the ground.

The default maximum suspension force is 6000 per wheel. For a vehicle with 4 wheels and a mass of 3000, the default is inadequate for a gravitational acceleration of 8 or more, even if the weight of the chassis is distributed evenly among the wheels.

If the weight is distributed unevenly, some of the maxima might need to be increased even more.

Suspension rest length

Rest length is the length of a spring when no force is applied to it. If the suspension’s rest lengths are too large, the chassis will seem to be jacked up on stilts and the vehicle will be prone to tipping, even when not moving.

Suspension stiffness

Stiffness is the force exerted by a spring divided by its change in length. If the suspension is too stiff, a small bump could cause the vehicle to bounce violently. If it isn’t stiff enough, a large bump could cause the chassis to "bottom out".

Suspension damping

Each wheel has 2 suspension damping parameters, one for expansion and one for compression. The range of plausible values depends on the suspension stiffness, according to the formula in the javadoc:

damping = 2f * k * FastMath.sqrt(stiffness);

where k is the suspension’s damping ratio:

  • k = 0: undamped and bouncy.

  • k = 1: critically damped.

Good values of k are between 0.1 and 0.3.

The default damping parameters of 0.83 and 0.88 are suitable for a chassis with the default stiffness of 5.88 (k=0.171 and 0.181, respectively). If you override the default stiffness, you should override the damping parameters as well.

Friction slip

The friction slip parameter quantifies how much traction a tire has. Its effect is most noticeable when the vehicle is braking.

Too much traction could cause a vehicle to flip over if it braked hard. Too little traction would make braking ineffective, as if the tires were bald or the supporting surface were icy.

The default value for friction slip is 10.5 . The PhysicsHoverControl custom control used in TestHoveringTank sets the friction slip to 0.001, making its brakes useless.

Roll influence

The roll-influence factor reduces (or magnifies) torques that tend to cause vehicles to roll over.

The default value of 1.0 yields realistic behavior. Reducing this parameter will improve stability, but it’s a bit of a hack; use it only as a last resort.

Advanced vehicles

For further inspiration, look at the More Advanced Vehicles demo which includes:

  • a Pacejka model for tire friction,

  • multiple gears including reverse,

  • sound effects,

  • a speedometer display,

  • a tachometer display,

  • tire smoke, and

  • skid marks.

Summary

  • A physics vehicle simulates a vehicle accelerating, steering, and braking on a smooth surface.

  • To associate a vehicle with a spatial, use a VehicleControl.

  • The vehicle model is simplified, yet its complexity can be an obstacle to achieving the desired behavior.