Articulated Bodies¶
Overview¶
NovaPhy implements the Featherstone articulated body algorithms for efficient simulation of jointed rigid body systems (robots, pendulums, chains, etc.).
Joint Types¶
| Type | DOF | Description |
|---|---|---|
Revolute |
1 | Rotation about a single axis |
Prismatic / Slide |
1 | Translation along a single axis |
Ball |
3 | Spherical joint (3 rotational DOF) |
Fixed |
0 | Rigid attachment |
Free |
6 | Unconstrained (floating base) |
Featherstone Algorithms¶
Forward Kinematics (FK)¶
Computes body transforms from joint coordinates q:
Inverse Dynamics (RNEA)¶
Computes joint torques required for a given motion:
Mass Matrix (CRBA)¶
Computes the joint-space mass matrix:
Forward Dynamics¶
Computes joint accelerations from applied torques:
Creating Articulated Bodies¶
import numpy as np
import novaphy
# Define a revolute joint
joint = novaphy.Joint()
joint.type = novaphy.JointType.Revolute
joint.axis = np.array([0, 0, 1])
joint.parent = -1
# Define the link body
body = novaphy.RigidBody.from_box(1.0, np.array([0.1, 0.5, 0.1]))
joints = [joint]
bodies = [body]
Driving the Featherstone solver¶
For full simulation with collision detection, construct
novaphy.solvers.SolverFeatherstone(model, ...) directly and call its
Newton-aligned step:
builder = novaphy.ModelBuilder()
builder.add_ground_plane(y=0.0)
body_index = builder.add_body(body)
dof = novaphy.JointDofConfig()
dof.axis = np.array([0, 0, 1], dtype=np.float32)
joint_index = builder.add_joint_revolute(parent=-1, child=body_index, axis=dof)
builder.add_articulation([joint_index])
model = builder.finalize()
solver = novaphy.solvers.SolverFeatherstone(
model,
angular_damping=0.05,
update_mass_matrix_interval=1,
)
state = model.state()
control = model.control()
collision_pipeline = novaphy.CollisionPipeline(model)
contacts = collision_pipeline.contacts()
for _ in range(1000):
collision_pipeline.collide(state, contacts)
solver.step(state, state, control, contacts, 1.0 / 120.0)
Spatial Algebra Convention¶
NovaPhy follows the Featherstone convention for 6D spatial vectors:
- Spatial velocity:
[angular_x, angular_y, angular_z, linear_x, linear_y, linear_z] - Spatial force:
[torque_x, torque_y, torque_z, force_x, force_y, force_z]
Free joint generalized coordinates:
- q =
[px, py, pz, qx, qy, qz, qw](7 DOF: position + quaternion) - qd =
[wx, wy, wz, vx, vy, vz](6 DOF: angular + linear velocity)
Flat rigid-body state views use component order instead:
state.body_qd[i] == [vx, vy, vz, wx, wy, wz] and
state.body_f[i] == [fx, fy, fz, tx, ty, tz].
Demos¶
| Demo | Description |
|---|---|
demo_newtons_cradle_pendulum.py |
Newton's cradle with hinge suspension |
demo_rope.py |
15-link chain released from horizontal |
demo_wrecking_ball.py |
Chain pendulum smashing a box tower |
demo_seesaw.py |
Box dropped onto revolute seesaw |
demo_motor_arm.py |
Motor-driven arm sweeping boxes |
demo_100_robots.py |
Quadruped grid via Featherstone / XPBD |