As explained in the manual of ODE a typical simulation will proceed like this:
Here is how it looks like in OCaml with the ODE bindings with the most simple possible example:
open Ode.LowLevel let () = dInitODE (); let wrl = dWorldCreate () in dWorldSetGravity wrl 0. 0. (-0.9); let space = dHashSpaceCreate None in let plane = dCreatePlane (Some space) 0. 0. 1. 0. in let cgrp = dJointGroupCreate () in let (lx,ly,lz) = (1.,1.,1.) in let b = dBodyCreate wrl in dBodySetPosition b 0. 0. 1.; let m = dMassCreate () in dMassSetBox m 2.4 lx ly lz; dMassAdjust m 1.0; dBodySetMass b m; let g = dCreateBox (Some space) lx ly lz in dGeomSetBody g (Some b); let near ga gb = let surf_params = { surf_param_zero with sp_mode = [`dContactBounce]; sp_mu = dInfinity; sp_bounce = 0.7; sp_bounce_vel = 0.1; } in let cnt_arr = dCollide ga gb 5 in ArrayLabels.iter cnt_arr ~f:(fun cnt_geom -> let cnt = { c_surface = surf_params; c_geom = cnt_geom; c_fdir1 = { x=0.; y=0.; z=0.; w=0. } } in let j = dJointCreateContact wrl (Some cgrp) cnt in dJointAttach j (dGeomGetBody ga) (dGeomGetBody gb); ); in Sys.catch_break true; try while true do dSpaceCollide space near; let p = dGeomGetPosition g in Printf.printf " (%6.3f %6.3f %6.3f)\n%!" p.x p.y p.z; dWorldStep wrl 0.1; dJointGroupEmpty cgrp; Unix.sleep 1; done with Sys.Break -> dBodyDestroy b; dGeomDestroy g; dGeomDestroy plane; dSpaceDestroy space; dWorldDestroy wrl; dCloseODE (); ;;