Ammo.js Hinge Constraint Motor Targets and Impulses

This article explains how to define and configure motor targets and maximum motor impulses for a hinge constraint in the ammo.js physics engine. You will learn how the angular motor uses target velocity, target angles, and impulse limits to control joint rotation, enabling precise physical simulations of hinges, wheels, and robotic joints.

Understanding the Ammo.js Hinge Motor

In ammo.js (the JavaScript port of the Bullet Physics engine), a btHingeConstraint restricts the movement of two rigid bodies to a single rotational axis. To make the hinge move automatically rather than just reacting to external forces, you must enable and configure its internal angular motor.

The motor operates by trying to reach a specified target (either a velocity or a specific angle) while being constrained by a maximum motor impulse, which acts as the strength or torque limit of the motor.

Defining the Motor Target

There are two primary ways to define the target for an ammo.js hinge motor depending on whether you want to control the speed of rotation or rotate to a specific angle.

1. Velocity Target (Constant Rotation)

To drive a hinge at a continuous speed (like a wheel or a fan), you define a target angular velocity using the enableAngularMotor method:

hinge.enableAngularMotor(true, targetVelocity, maxMotorImpulse);
  • true: Enables the motor.
  • targetVelocity: The desired rotational speed in radians per second. A positive value rotates the joint clockwise, while a negative value rotates it counter-clockwise.
  • maxMotorImpulse: The maximum force allocated to reach that velocity.

2. Angle Target (Servo/Position Control)

To rotate the hinge to a specific angle (like a robotic arm or a steering joint), you define a target angle using the setMotorTarget method:

hinge.setMotorTarget(targetAngle, deltaTime);
  • targetAngle: The desired angle of the hinge in radians.
  • deltaTime: The time step (usually the physics step delta time, e.g., 1/60) used by the solver to calculate the required acceleration to reach the target angle in time.

Under the hood, setMotorTarget calculates the velocity required to bridge the gap between the current angle and the target angle, then internally applies that velocity target.

Defining the Maximum Motor Impulse

The maximum motor impulse represents the maximum torque the constraint solver can apply in a single physics step to achieve your motor target.

In physics engines, impulses are mathematically equivalent to force multiplied by time (\(I = F \cdot \Delta t\)). In practical terms for ammo.js:

  • High Maximum Impulse: The motor is strong. It will aggressively overcome resistance, friction, and the weight of connected rigid bodies to reach its target velocity or angle almost instantly.
  • Low Maximum Impulse: The motor is weak. If the connected rigid bodies are heavy or blocked by obstacles, the motor will stall or lag, unable to reach the target velocity.
// A weak motor that can easily be stopped by external collisions
hinge.enableAngularMotor(true, 5.0, 0.5);

// A strong motor that will force its way to the target velocity
hinge.enableAngularMotor(true, 5.0, 500.0);

Key Considerations for Implementation

  • Matching Mass to Impulse: The value of your maximum motor impulse must scale with the mass of the rigid bodies attached to the hinge. A maximum impulse of 1.0 might spin a light box weighing 0.1kg instantly, but will fail to budge a massive wheel weighing 100kg.
  • Target Limits: Ensure your motor targets do not fight against the hinge's angular limits. If you set limits using setLimit(low, high) and command the motor to drive past those limits, the solver will experience instability or jittering.