RobotLocomotion / drake

Model-based design and verification for robotics.
https://drake.mit.edu
Other
3.17k stars 1.24k forks source link

[framework] Sugar to force a full update #21659

Closed jwnimmer-tri closed 1 day ago

jwnimmer-tri commented 2 days ago

Is your feature request related to a problem? Please describe.

As part of #20545, we are planning to change certain MbP output ports to be "sampled" -- their values will only change during a time step update event.

With those new semantics, and when not using a Simulator, some users might want to force a step in order to see new output port values. Currently they can call 2-3 functions in sequence to force a step, but it would be most clear if there was exactly 1 function they could call to accomplish the goal directly.

Describe the solution you'd like

A new System function something like this (but with better docs):

// Calls CalcForcedDiscreteVariableUpdate and writes back into context.
// Calls CalcForcedUnrestrictedUpdate and writes back into context:
EventStatus CalcForcedUpdates(Context<T>* context);

Describe alternatives you've considered

Users can call existing System functions, but they need to know which order to do it, and how to write the answers back into the Context.

Or, we may also offer "unsampled" mode for MbP with direct-feedthrough ports, but possibly some users would not able to use this mode (e.g., in case they want both simulator and non-simulator users on the same MbP).

Additional context

N/A.

sherm1 commented 2 days ago

Currently we have System::ExecuteInitializationEvents(Context*) that knows how to properly sequence unrestricted, discrete, and publish events with initialization triggers.

I propose to add System::ExecuteForcedEvents(Context*) that does the same thing for Forced events.

Does that seem adequate for the purpose at hand?

jwnimmer-tri commented 2 days ago

Possibly. I worry that users will hate the extra publish, though. They might just want to step their motion planning algorithm, without actually visualizing it. We might want to have a publish=(true|false) as an optional argument.

sherm1 commented 2 days ago

To get an extra publish, the subsystem author would have to have explicitly provided a ForcedPublish event in addition to ForcedDiscrete and/or ForcedUnrestricted. MbP for example declares only a PeriodicDiscreteUpdateEvent and a ForcedDiscreteUpdateEvent. I'm not seeing yet why a subsystem would declare multiple Forced events but not want them all triggered. So my inclination would be to defer adding options until we get a complaint.

jwnimmer-tri commented 2 days ago

If they have MeshcatVisualizer in their Diagram (which they would, by default), it declares a forced publish event.

jwnimmer-tri commented 2 days ago

(The whole purpose of this issue is getting out in front of speculative complaints, so I think if we're going to do it, we should try to cover all of the bases.)

sherm1 commented 2 days ago

OK, I see that makes sense for a Diagram. We could also perform a discrete update of MbP only by invoking MultibodyPlant::ExecuteForcedEvents(mbp_subcontext*). I'll include the option.