Skip to content

novaphy.SimulationExporter

Frame-by-frame keyframe / collision / constraint-reaction recorder. Drop capture_frame into the simulation loop to log per-body motion, and write the captured buffers as CSV or an OpenUSD animation layer for offline visualisation and regression. The same class also provides a separate UrdfModelData-to-URDF asset serializer; that method does not serialize the captured frame buffers.

Methods

Method Description
capture_frame(state, contacts, time_seconds) Record body keyframes from a SimState and (optionally) collision events from a Contacts aggregate. Pass contacts=None to skip collision recording.
add_constraint_reaction(reaction) Append a single RecordedConstraintReaction.
write_keyframes_csv(output_path) Serialize the captured keyframes to CSV.
write_collision_log_csv(output_path) Serialize the captured collision events to CSV.
write_constraint_reactions_csv(output_path) Serialize captured constraint reactions to CSV.
write_urdf(model, output_path) Serialize an UrdfModelData asset to URDF.
write_openusd_animation_layer(output_path) Emit captured keyframes as an OpenUSD animation layer (USDA).

Properties

Property Description
keyframes List of RecordedKeyframe entries (read-only).
collision_events List of RecordedCollisionEvent entries.
constraint_reactions List of RecordedConstraintReaction entries.

Example

import novaphy

exporter = novaphy.SimulationExporter()
state    = model.state()
pipeline = novaphy.CollisionPipeline(model)
contacts = pipeline.contacts()
solver   = novaphy.solvers.SolverSemiImplicit(model)

t = 0.0
for _ in range(600):
    pipeline.collide(state, contacts)
    solver.step(state, state, None, contacts, 1 / 240)
    t += 1 / 240
    exporter.capture_frame(state, contacts, t)

exporter.write_keyframes_csv("trajectory.csv")
exporter.write_collision_log_csv("collisions.csv")
exporter.write_openusd_animation_layer("trajectory.usda")

Notes

  • capture_frame records one RecordedKeyframe per body at the given time — not a single aggregate frame. The CSV writer groups them on output.
  • Collision recording appends every active rigid contact; it does not filter zero-penetration rows.
  • capture_frame currently requires CPU-resident state and contact buffers. It indexes their DeviceArray storage directly; perform an explicit host readback/copy before exporting data produced on CUDA.
  • write_urdf accepts UrdfModelData, not a finalized Model. Keep the parsed asset data when a later round trip is required.

See Also