Search code examples
drake

How to record calculated multibody quantities during a simulation in Drake


The drake multibody plant class has a lot of functions for calculating quantities that I am interested in recording during a simulation (e.g. momentum, center of mass, etc.). What is the best way of recording data like this? I haven't used drake extensively, but I had a few ideas:

  1. Run the simulation in a loop with a defined time step (i.e. simulator.AdvanceTo(current_time + dt)) and use the multibody plant to calculate the quantities directly.
    • Seems a bit limited (i.e. can't use a single call to AdvanceTo() to run the simulation) and may require a very small time step to get the resolution I'm looking for.
  2. Record available quantities from the multibody plant output ports (e.g. body spatial velocities, body poses, etc.) using a VectorLogSink block, and solve for the quantities of interest after the conclusion of the simulation by reconstructing a Context from the values and calling the multibody plant calculation functions
    • Not sure if this is possible; seems like a bit of a roundabout approach; the quantities of interest are not available during the simulation
  3. Create a system block that can connect to a multibody plant to perform these computations at every internal simulation timestep. That block could then connect to a VectorLogSink block to record the data.
    • Not sure if this is possible or where to start

Can anyone provide some guidance on how to record multibody quantities like this?

Porting this question from this issue for continued discussion


Solution

  • Initial response from @jwnimmer-tri

    Your assessment of option (1) is correct. If you already know a reasonable dt step size for your logging that suits your needs, it can work well. If the "interesting" times are not always on a fixed schedule, this way can be difficult.

    Relatedly, there is an option (4) you hadn't found yet. The Simulator::set_monitor() can be used to set a simulation callback. You could use that for the ability to log at every simulation step, no matter how large or small the step was.

    Option (2) should work as well. Assuming that the only state in your simulation is the multibody plant positions and velocities, you could log those during the simulation, and then be able to set the context state to those values offline later, and make any queries on the plant that you need. If you have extra state (e.g., controller state), this approach becomes more difficult.

    Option (3) is also possible, but more complicated to explain.