pydrake.systems.analysis
Bindings for the analysis portion of the Systems framework.
- pydrake.systems.analysis.ApplySimulatorConfig(*args, **kwargs)
Overloaded function.
ApplySimulatorConfig(config: pydrake.systems.analysis.SimulatorConfig, simulator: pydrake.systems.analysis.Simulator) -> None
Modifies the
simulator
based on the givenconfig
. (Always replaces the Integrator with a new one; be careful not to keep old references around.)- Parameter
config
: Configuration to be used. Contains values for both the integrator and the simulator.
- Parameter
simulator
: On input, a valid pointer to a Simulator. On output the integrator for
simulator
is reset according to the givenconfig
.
ApplySimulatorConfig(config: pydrake.systems.analysis.SimulatorConfig, simulator: pydrake.systems.analysis.Simulator_[AutoDiffXd]) -> None
Modifies the
simulator
based on the givenconfig
. (Always replaces the Integrator with a new one; be careful not to keep old references around.)- Parameter
config
: Configuration to be used. Contains values for both the integrator and the simulator.
- Parameter
simulator
: On input, a valid pointer to a Simulator. On output the integrator for
simulator
is reset according to the givenconfig
.
- pydrake.systems.analysis.BatchEvalTimeDerivatives(*args, **kwargs)
Overloaded function.
BatchEvalTimeDerivatives(system: pydrake.systems.framework.System, context: pydrake.systems.framework.Context, times: numpy.ndarray[numpy.float64[1, n]], states: numpy.ndarray[numpy.float64[m, n], flags.f_contiguous], inputs: numpy.ndarray[numpy.float64[m, n], flags.f_contiguous], input_port_index: Union[pydrake.systems.framework.InputPortSelection, pydrake.systems.framework.InputPortIndex] = <InputPortSelection.kUseFirstInputIfItExists: -2>, parallelize: pydrake.common.Parallelism = Parallelism(num_threads=16)) -> numpy.ndarray[numpy.float64[m, n]]
Evaluates the time derivatives of a
system
at many times, states, and inputs.Each column of
times
, states, andinputs
will be associated with a single evaluation of the dynamics. The return value will a matrix with the corresponding time derivatives in each column. Any discrete variables incontext
will be held constant across all evaluations.- Template parameter
T
: The scalar type of the system.
- Parameter
system
: The system to evaluate.
- Parameter
context
: A context associated with
system
, which can be used to pass system parameters and discrete/abstract state.- Parameter
times
: A 1 x N vector of times at which to evaluate the dynamics.
- Parameter
states
: A system.num_continuous_states() x N matrix of continuous states at which to evaluate the dynamics.
- Parameter
inputs
: A num_inputs x N matrix of inputs at which to evaluate the dynamics, where num_inputs must match the size of the input port selected. If input_port_index is set to InputPortSelection::kNoInput, then the inputs argument will be ignored.
- Parameter
input_port_index
: The input port index to use for evaluating the dynamics. The default is to use the first input if there is one. A specific port index or kNoInput can be specified instead. The input port must be vector-valued and have the same size as the number of rows in
inputs
.- Parameter
parallelize
: The parallelism to use for evaluating the dynamics.
- Returns
A matrix with each column corresponding to the time derivatives.
- Raises
RuntimeError if matrix shapes are inconsistent, with inputs –
required only if an input port is provided. –
BatchEvalTimeDerivatives(system: pydrake.systems.framework.System_[AutoDiffXd], context: pydrake.systems.framework.Context_[AutoDiffXd], times: numpy.ndarray[object[1, n]], states: numpy.ndarray[object[m, n], flags.f_contiguous], inputs: numpy.ndarray[object[m, n], flags.f_contiguous], input_port_index: Union[pydrake.systems.framework.InputPortSelection, pydrake.systems.framework.InputPortIndex] = <InputPortSelection.kUseFirstInputIfItExists: -2>, parallelize: pydrake.common.Parallelism = Parallelism(num_threads=16)) -> numpy.ndarray[object[m, n]]
Evaluates the time derivatives of a
system
at many times, states, and inputs.Each column of
times
, states, andinputs
will be associated with a single evaluation of the dynamics. The return value will a matrix with the corresponding time derivatives in each column. Any discrete variables incontext
will be held constant across all evaluations.- Template parameter
T
: The scalar type of the system.
- Parameter
system
: The system to evaluate.
- Parameter
context
: A context associated with
system
, which can be used to pass system parameters and discrete/abstract state.- Parameter
times
: A 1 x N vector of times at which to evaluate the dynamics.
- Parameter
states
: A system.num_continuous_states() x N matrix of continuous states at which to evaluate the dynamics.
- Parameter
inputs
: A num_inputs x N matrix of inputs at which to evaluate the dynamics, where num_inputs must match the size of the input port selected. If input_port_index is set to InputPortSelection::kNoInput, then the inputs argument will be ignored.
- Parameter
input_port_index
: The input port index to use for evaluating the dynamics. The default is to use the first input if there is one. A specific port index or kNoInput can be specified instead. The input port must be vector-valued and have the same size as the number of rows in
inputs
.- Parameter
parallelize
: The parallelism to use for evaluating the dynamics.
- Returns
A matrix with each column corresponding to the time derivatives.
- Raises
RuntimeError if matrix shapes are inconsistent, with inputs –
required only if an input port is provided. –
BatchEvalTimeDerivatives(system: pydrake.systems.framework.System_[Expression], context: pydrake.systems.framework.Context_[Expression], times: numpy.ndarray[object[1, n]], states: numpy.ndarray[object[m, n], flags.f_contiguous], inputs: numpy.ndarray[object[m, n], flags.f_contiguous], input_port_index: Union[pydrake.systems.framework.InputPortSelection, pydrake.systems.framework.InputPortIndex] = <InputPortSelection.kUseFirstInputIfItExists: -2>, parallelize: pydrake.common.Parallelism = Parallelism(num_threads=16)) -> numpy.ndarray[object[m, n]]
Evaluates the time derivatives of a
system
at many times, states, and inputs.Each column of
times
, states, andinputs
will be associated with a single evaluation of the dynamics. The return value will a matrix with the corresponding time derivatives in each column. Any discrete variables incontext
will be held constant across all evaluations.- Template parameter
T
: The scalar type of the system.
- Parameter
system
: The system to evaluate.
- Parameter
context
: A context associated with
system
, which can be used to pass system parameters and discrete/abstract state.- Parameter
times
: A 1 x N vector of times at which to evaluate the dynamics.
- Parameter
states
: A system.num_continuous_states() x N matrix of continuous states at which to evaluate the dynamics.
- Parameter
inputs
: A num_inputs x N matrix of inputs at which to evaluate the dynamics, where num_inputs must match the size of the input port selected. If input_port_index is set to InputPortSelection::kNoInput, then the inputs argument will be ignored.
- Parameter
input_port_index
: The input port index to use for evaluating the dynamics. The default is to use the first input if there is one. A specific port index or kNoInput can be specified instead. The input port must be vector-valued and have the same size as the number of rows in
inputs
.- Parameter
parallelize
: The parallelism to use for evaluating the dynamics.
- Returns
A matrix with each column corresponding to the time derivatives.
- Raises
RuntimeError if matrix shapes are inconsistent, with inputs –
required only if an input port is provided. –
- pydrake.systems.analysis.BatchEvalUniquePeriodicDiscreteUpdate(*args, **kwargs)
Overloaded function.
BatchEvalUniquePeriodicDiscreteUpdate(system: pydrake.systems.framework.System, context: pydrake.systems.framework.Context, times: numpy.ndarray[numpy.float64[1, n]], states: numpy.ndarray[numpy.float64[m, n], flags.f_contiguous], inputs: numpy.ndarray[numpy.float64[m, n], flags.f_contiguous], num_time_steps: int = 1, input_port_index: Union[pydrake.systems.framework.InputPortSelection, pydrake.systems.framework.InputPortIndex] = <InputPortSelection.kUseFirstInputIfItExists: -2>, parallelize: pydrake.common.Parallelism = Parallelism(num_threads=16)) -> numpy.ndarray[numpy.float64[m, n]]
Evaluates the dynamics of a difference equation
system
at many times, states, and inputs. See System<T>::EvalUniquePeriodicDiscreteUpdate().Each column of
times
, states, andinputs
will be associated with a single evaluation of the dynamics. The return value will be a matrix with each column corresponding to the next state of the system evaluatednum_time_steps * time_step
seconds after the provided time, using thetime_step
that is reported by System<T>::IsDifferenceEquationSystem().- Template parameter
T
: The scalar type of the system.
- Parameter
system
: The system to evaluate.
- Parameter
context
: A context associated with
system
, which can be used to pass system parameters.- Parameter
times
: A 1 x N vector of times at which to evaluate the dynamics.
- Parameter
states
: A num_states x N matrix of states at which to evaluate the dynamics.
- Parameter
inputs
: A num_inputs x N matrix of inputs at which to evaluate the dynamics, where num_inputs must match the size of the input port selected. If input_port_index is set to InputPortSelection::kNoInput, then the inputs argument will be ignored.
- Parameter
num_time_steps
: The returned value will be the state at
time + time_step*num_time_steps
.- Parameter
input_port_index
: The input port index to use for evaluating the dynamics. The default is to use the first input if there is one. A specific port index or kNoInput can be specified instead. The input port must be vector-valued and have the same size as the number of rows in
inputs
.- Parameter
parallelize
: The parallelism to use for evaluating the dynamics.
- Returns
A matrix with each column corresponding to the next state at
time + num_time_steps * time_step
.- Raises
RuntimeError if system.IsDifferenceEquationSystem() is not –
true. –
RuntimeError if matrix shapes are inconsistent, with inputs –
required only if an input port is provided. –
BatchEvalUniquePeriodicDiscreteUpdate(system: pydrake.systems.framework.System_[AutoDiffXd], context: pydrake.systems.framework.Context_[AutoDiffXd], times: numpy.ndarray[object[1, n]], states: numpy.ndarray[object[m, n], flags.f_contiguous], inputs: numpy.ndarray[object[m, n], flags.f_contiguous], num_time_steps: int = 1, input_port_index: Union[pydrake.systems.framework.InputPortSelection, pydrake.systems.framework.InputPortIndex] = <InputPortSelection.kUseFirstInputIfItExists: -2>, parallelize: pydrake.common.Parallelism = Parallelism(num_threads=16)) -> numpy.ndarray[object[m, n]]
Evaluates the dynamics of a difference equation
system
at many times, states, and inputs. See System<T>::EvalUniquePeriodicDiscreteUpdate().Each column of
times
, states, andinputs
will be associated with a single evaluation of the dynamics. The return value will be a matrix with each column corresponding to the next state of the system evaluatednum_time_steps * time_step
seconds after the provided time, using thetime_step
that is reported by System<T>::IsDifferenceEquationSystem().- Template parameter
T
: The scalar type of the system.
- Parameter
system
: The system to evaluate.
- Parameter
context
: A context associated with
system
, which can be used to pass system parameters.- Parameter
times
: A 1 x N vector of times at which to evaluate the dynamics.
- Parameter
states
: A num_states x N matrix of states at which to evaluate the dynamics.
- Parameter
inputs
: A num_inputs x N matrix of inputs at which to evaluate the dynamics, where num_inputs must match the size of the input port selected. If input_port_index is set to InputPortSelection::kNoInput, then the inputs argument will be ignored.
- Parameter
num_time_steps
: The returned value will be the state at
time + time_step*num_time_steps
.- Parameter
input_port_index
: The input port index to use for evaluating the dynamics. The default is to use the first input if there is one. A specific port index or kNoInput can be specified instead. The input port must be vector-valued and have the same size as the number of rows in
inputs
.- Parameter
parallelize
: The parallelism to use for evaluating the dynamics.
- Returns
A matrix with each column corresponding to the next state at
time + num_time_steps * time_step
.- Raises
RuntimeError if system.IsDifferenceEquationSystem() is not –
true. –
RuntimeError if matrix shapes are inconsistent, with inputs –
required only if an input port is provided. –
BatchEvalUniquePeriodicDiscreteUpdate(system: pydrake.systems.framework.System_[Expression], context: pydrake.systems.framework.Context_[Expression], times: numpy.ndarray[object[1, n]], states: numpy.ndarray[object[m, n], flags.f_contiguous], inputs: numpy.ndarray[object[m, n], flags.f_contiguous], num_time_steps: int = 1, input_port_index: Union[pydrake.systems.framework.InputPortSelection, pydrake.systems.framework.InputPortIndex] = <InputPortSelection.kUseFirstInputIfItExists: -2>, parallelize: pydrake.common.Parallelism = Parallelism(num_threads=16)) -> numpy.ndarray[object[m, n]]
Evaluates the dynamics of a difference equation
system
at many times, states, and inputs. See System<T>::EvalUniquePeriodicDiscreteUpdate().Each column of
times
, states, andinputs
will be associated with a single evaluation of the dynamics. The return value will be a matrix with each column corresponding to the next state of the system evaluatednum_time_steps * time_step
seconds after the provided time, using thetime_step
that is reported by System<T>::IsDifferenceEquationSystem().- Template parameter
T
: The scalar type of the system.
- Parameter
system
: The system to evaluate.
- Parameter
context
: A context associated with
system
, which can be used to pass system parameters.- Parameter
times
: A 1 x N vector of times at which to evaluate the dynamics.
- Parameter
states
: A num_states x N matrix of states at which to evaluate the dynamics.
- Parameter
inputs
: A num_inputs x N matrix of inputs at which to evaluate the dynamics, where num_inputs must match the size of the input port selected. If input_port_index is set to InputPortSelection::kNoInput, then the inputs argument will be ignored.
- Parameter
num_time_steps
: The returned value will be the state at
time + time_step*num_time_steps
.- Parameter
input_port_index
: The input port index to use for evaluating the dynamics. The default is to use the first input if there is one. A specific port index or kNoInput can be specified instead. The input port must be vector-valued and have the same size as the number of rows in
inputs
.- Parameter
parallelize
: The parallelism to use for evaluating the dynamics.
- Returns
A matrix with each column corresponding to the next state at
time + num_time_steps * time_step
.- Raises
RuntimeError if system.IsDifferenceEquationSystem() is not –
true. –
RuntimeError if matrix shapes are inconsistent, with inputs –
required only if an input port is provided. –
- pydrake.systems.analysis.ExtractSimulatorConfig(*args, **kwargs)
Overloaded function.
ExtractSimulatorConfig(simulator: pydrake.systems.analysis.Simulator) -> pydrake.systems.analysis.SimulatorConfig
Reports the simulator’s current configuration, including the configuration of the integrator.
- Parameter
simulator
: The Simulator to extract the configuration from. $Note:
For non-double T (T=AutoDiffXd), doing ExtractSimulatorConfig will discard the integrator’s scalar type’s extra information such as gradients.
ExtractSimulatorConfig(simulator: pydrake.systems.analysis.Simulator_[AutoDiffXd]) -> pydrake.systems.analysis.SimulatorConfig
Reports the simulator’s current configuration, including the configuration of the integrator.
- Parameter
simulator
: The Simulator to extract the configuration from. $Note:
For non-double T (T=AutoDiffXd), doing ExtractSimulatorConfig will discard the integrator’s scalar type’s extra information such as gradients.
- pydrake.systems.analysis.GetIntegrationSchemes() list[str]
Returns the allowed string values for the
scheme
parameter in ResetIntegratorFromFlags() and SimulatorConfig::integration_scheme.
- class pydrake.systems.analysis.InitializeParams
Parameters for fine control of simulator initialization.
See also
Simulator<T>::Initialize().
- __init__(self: pydrake.systems.analysis.InitializeParams, **kwargs) None
- property suppress_initialization_events
Whether to trigger initialization events. Events are triggered by default; it may be useful to suppress them when reusing a simulator.
- class pydrake.systems.analysis.IntegratorBase
An abstract class for an integrator for ODEs and DAEs as represented by a Drake System. Integrators solve initial value problems of the form:
Click to expand C++ code...
ẋ(t) = f(t, x(t)) with f : ℝ × ℝⁿ → ℝⁿ
(i.e.,
f()
is an ordinary differential equation) given initial conditions (t₀, x₀). Thus, integrators advance the continuous state of a dynamical system forward in time.Drake’s subclasses of IntegratorBase<T> should follow the naming pattern
FooIntegrator<T>
by convention.Note
This class is templated; see
IntegratorBase_
for the list of instantiations.- __init__(*args, **kwargs)
- get_actual_initial_step_size_taken(self: pydrake.systems.analysis.IntegratorBase) float
The actual size of the successful first step.
- get_context(self: pydrake.systems.analysis.IntegratorBase) pydrake.systems.framework.Context
Returns a const reference to the internally-maintained Context holding the most recent state in the trajectory. This is suitable for publishing or extracting information about this trajectory step.
- get_dense_output(self: pydrake.systems.analysis.IntegratorBase) pydrake.trajectories.PiecewisePolynomial
Returns a const pointer to the integrator’s current PiecewisePolynomial instance, holding a representation of the continuous state trajectory since the last StartDenseIntegration() call. This is suitable to query the integrator’s current dense output, if any (may be nullptr).
- get_fixed_step_mode(self: pydrake.systems.analysis.IntegratorBase) bool
Gets whether an integrator is running in fixed step mode. If the integrator does not support error estimation, this function will always return
True
.See also
set_fixed_step_mode()
- get_initial_step_size_target(self: pydrake.systems.analysis.IntegratorBase) float
Gets the target size of the first integration step. You can find out what step size was actually used for the first integration step with
get_actual_initial_step_size_taken()
.See also
request_initial_step_size_target()
- get_largest_step_size_taken(self: pydrake.systems.analysis.IntegratorBase) float
The size of the largest step taken since the last Initialize() or ResetStatistics() call.
- get_maximum_step_size(self: pydrake.systems.analysis.IntegratorBase) float
Gets the maximum step size that may be taken by this integrator. This is a soft maximum: the integrator may stretch it by as much as 1% to hit a discrete event.
See also
set_requested_minimum_step_size()
- get_mutable_context(self: pydrake.systems.analysis.IntegratorBase) pydrake.systems.framework.Context
Returns a mutable pointer to the internally-maintained Context holding the most recent state in the trajectory.
- get_num_derivative_evaluations(self: pydrake.systems.analysis.IntegratorBase) int
Returns the number of ODE function evaluations (calls to CalcTimeDerivatives()) since the last call to ResetStatistics() or Initialize(). This count includes all such calls including (1) those necessary to compute Jacobian matrices; (2) those used in rejected integrated steps (for, e.g., purposes of error control); (3) those used strictly for integrator error estimation; and (4) calls that exhibit little cost (due to results being cached).
- get_num_step_shrinkages_from_error_control(self: pydrake.systems.analysis.IntegratorBase) int
Gets the number of step size shrinkages due to failure to meet targeted error tolerances, since the last call to ResetStatistics or Initialize().
- get_num_step_shrinkages_from_substep_failures(self: pydrake.systems.analysis.IntegratorBase) int
Gets the number of step size shrinkages due to sub-step failures (e.g., integrator convergence failures) since the last call to ResetStatistics() or Initialize().
- get_num_steps_taken(self: pydrake.systems.analysis.IntegratorBase) int
The number of integration steps taken since the last Initialize() or ResetStatistics() call.
- get_num_substep_failures(self: pydrake.systems.analysis.IntegratorBase) int
Gets the number of failed sub-steps (implying one or more step size reductions was required to permit solving the necessary nonlinear system of equations).
- get_requested_minimum_step_size(self: pydrake.systems.analysis.IntegratorBase) float
Gets the requested minimum step size
h_min
for this integrator.See also
set_requested_minimum_step_size()
See also
get_working_minimum_step_size(T)
- get_smallest_adapted_step_size_taken(self: pydrake.systems.analysis.IntegratorBase) float
The size of the smallest step taken as the result of a controlled integration step adjustment since the last Initialize() or ResetStatistics() call. This value will be NaN for integrators without error estimation.
- get_target_accuracy(self: pydrake.systems.analysis.IntegratorBase) float
Gets the target accuracy.
See also
get_accuracy_in_use()
- get_throw_on_minimum_step_size_violation(self: pydrake.systems.analysis.IntegratorBase) bool
Reports the current setting of the throw_on_minimum_step_size_violation flag.
See also
set_throw_on_minimum_step_size_violation().
- Initialize(self: pydrake.systems.analysis.IntegratorBase) None
An integrator must be initialized before being used. The pointer to the context must be set before Initialize() is called (or an RuntimeError will be thrown). If Initialize() is not called, an exception will be thrown when attempting to call IntegrateNoFurtherThanTime(). To reinitialize the integrator, Reset() should be called followed by Initialize().
- Raises
RuntimeError If the context has not been set or a user-set –
parameter has been set illogically (i.e., one of the weighting –
matrix coefficients is set to a negative value- this check is only –
performed for integrators that support error estimation; the –
maximum step size is smaller than the minimum step size; the –
requested initial step size is outside of the interval [minimum –
step size, maximum step size]) –
See also
Reset()
- request_initial_step_size_target(self: pydrake.systems.analysis.IntegratorBase, step_size: float) None
Request that the first attempted integration step have a particular size. If no request is made, the integrator will estimate a suitable size for the initial step attempt. If the integrator does not support error control, this method will throw a RuntimeError (call supports_error_estimation() to verify before calling this method). For variable-step integration, the initial target will be treated as a maximum step size subject to accuracy requirements and event occurrences. You can find out what size actually worked with
get_actual_initial_step_size_taken()
.- Raises
RuntimeError If the integrator does not support error estimation. –
- Reset(self: pydrake.systems.analysis.IntegratorBase) None
Resets the integrator to initial values, i.e., default construction values.
- reset_context(self: pydrake.systems.analysis.IntegratorBase, context: pydrake.systems.framework.Context) None
Replace the pointer to the internally-maintained Context with a different one. This is useful for supplying a new set of initial conditions or wiping out the current context (by passing in a null pointer). You should invoke Initialize() after replacing the Context unless the context is null.
- Parameter
context
: The pointer to the new context or nullptr to wipe out the current context without replacing it with another.
- Parameter
- ResetStatistics(self: pydrake.systems.analysis.IntegratorBase) None
@name Integrator statistics methods These methods allow the caller to manipulate and query integrator statistics. Generally speaking, the larger the integration step taken, the faster a simulation will run. These methods allow querying (and resetting) the integrator statistics as one means of determining how to make a simulation run faster.
Forget accumulated statistics. These are reset to the values they have post construction or immediately after
Initialize()
.
- set_fixed_step_mode(self: pydrake.systems.analysis.IntegratorBase, flag: bool) None
Sets an integrator with error control to fixed step mode. If the integrator runs in fixed step mode, it will always take the maximum step size directed (which may be that determined by get_maximum_step_size(), or may be smaller, as directed by, e.g., Simulator for event handling purposes).
Warning
The error estimation process will still be active (so get_error_estimate() will still return a correct result), meaning that the additional (typically, but not necessarily small) computation required for error estimation will still be performed.
- Raises
RuntimeError if integrator does not support error estimation and –
flag` is set to False –
- set_maximum_step_size(self: pydrake.systems.analysis.IntegratorBase, max_step_size: float) None
@anchor integrator-maxstep @name Methods related to maximum integration step size
Sets the nominal maximum step size- the actual maximum step size taken may be slightly larger (see set_maximum_step_size() and get_stretch_factor())- that an integrator will take. Each integrator has a default maximum step size, which might be infinite. Sets the maximum step size that may be taken by this integrator. This setting should be used if you know the maximum time scale of your problem. The integrator may stretch the maximum step size by as much as 1% to reach a discrete event. For fixed step integrators, all steps will be taken at the maximum step size unless an event would be missed.
Warning
See integrator-initial-step-size “Initial step size selection”
- set_requested_minimum_step_size(self: pydrake.systems.analysis.IntegratorBase, min_step_size: float) None
Sets the requested minimum step size
h_min
that may be taken by this integrator. No step smaller than this will be taken except under circumstances as described integrator-minstep “above”. This setting will be ignored if it is smaller than the absolute minimumh_floor
also described above. Default value is zero.- Parameter
min_step_size
: a non-negative value. Setting this value to zero will cause the integrator to use a reasonable value instead (see get_working_minimum_step_size()).
See also
get_requested_minimum_step_size()
See also
get_working_minimum_step_size()
- Parameter
- set_target_accuracy(self: pydrake.systems.analysis.IntegratorBase, accuracy: float) None
@anchor integrator-accuracy @name Methods for getting and setting integrator accuracy The precise meaning of accuracy is a complicated discussion, but it translates roughly to the number of significant digits you want in the results. By convention it is supplied as
10^-digits
, meaning that an accuracy of 1e-3 provides about three significant digits. For more discussion of accuracy, see accuracy_and_tolerance and ref. [1].Integrators vary in the range of accuracy (loosest to tightest) that they can support, and each integrator will choose a default accuracy to be used that lies somewhere within this range and attempts to balance computation and accuracy. If you request accuracy outside the supported range for the chosen integrator it will be quietly adjusted to be in range. You can find out the accuracy setting actually being used using
get_accuracy_in_use()
.Implicit integrators additionally use the accuracy setting for determining when the underlying Newton-Raphson root finding process has converged. For those integrators, the accuracy setting also limits the allowable iteration error in the Newton-Raphson process. Looser accuracy in that process certainly implies greater error in the ODE solution and might impact the stability of the solution negatively as well.
[1] M. Sherman, A. Seth, S. Delp. Procedia IUTAM 2:241-261 (2011),
Section 3.3. https://dx.doi.org/10.1016/j.piutam.2011.04.023
Request that the integrator attempt to achieve a particular accuracy for the continuous portions of the simulation. Otherwise a default accuracy is chosen for you. This may be ignored for fixed-step integration since accuracy control requires variable step sizes. You should call supports_error_estimation() to ensure that the integrator supports this capability before calling this function; if the integrator does not support it, this method will throw an exception.
- Raises
RuntimeError if integrator does not support error estimation. –
- set_throw_on_minimum_step_size_violation(self: pydrake.systems.analysis.IntegratorBase, throws: bool) None
Sets whether the integrator should throw a RuntimeError when the integrator’s step size selection algorithm determines that it must take a step smaller than the minimum step size (for, e.g., purposes of error control). Default is
True
. IfFalse
, the integrator will advance time and state using the minimum specified step size in such situations. See integrator-minstep “this section” for more detail.
- StartDenseIntegration(self: pydrake.systems.analysis.IntegratorBase) None
Starts dense integration, allocating a new dense output for this integrator to use.
- Precondition:
The integrator has been initialized.
- Precondition:
The system being integrated has continuous state.
- Precondition:
No dense integration is in progress (no dense output is held by the integrator)
- Raises
RuntimeError if any of the preconditions is not met. –
Warning
Dense integration may incur significant overhead.
- StopDenseIntegration(self: pydrake.systems.analysis.IntegratorBase) pydrake.trajectories.PiecewisePolynomial
Stops dense integration, yielding ownership of the current dense output to the caller.
- Remark:
This process is irreversible.
- Returns
A PiecewisePolynomial instance, i.e. a representation of the continuous state trajectory of the system being integrated that can be evaluated at any time within its extension. This representation is defined starting at the context time of the last StartDenseIntegration() call and finishing at the current context time.
- Precondition:
Dense integration is in progress (a dense output is held by this integrator, after a call to StartDenseIntegration()).
- Postcondition:
Previously held dense output is not updated nor referenced by the integrator anymore.
- Raises
RuntimeError if any of the preconditions is not met. –
- template pydrake.systems.analysis.IntegratorBase_
Instantiations:
IntegratorBase_[float]
,IntegratorBase_[AutoDiffXd]
,IntegratorBase_[Expression]
- class pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]
An abstract class for an integrator for ODEs and DAEs as represented by a Drake System. Integrators solve initial value problems of the form:
Click to expand C++ code...
ẋ(t) = f(t, x(t)) with f : ℝ × ℝⁿ → ℝⁿ
(i.e.,
f()
is an ordinary differential equation) given initial conditions (t₀, x₀). Thus, integrators advance the continuous state of a dynamical system forward in time.Drake’s subclasses of IntegratorBase<T> should follow the naming pattern
FooIntegrator<T>
by convention.- __init__(*args, **kwargs)
- get_actual_initial_step_size_taken(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.autodiffutils.AutoDiffXd
The actual size of the successful first step.
- get_context(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.systems.framework.Context_[AutoDiffXd]
Returns a const reference to the internally-maintained Context holding the most recent state in the trajectory. This is suitable for publishing or extracting information about this trajectory step.
- get_dense_output(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.trajectories.PiecewisePolynomial_[AutoDiffXd]
Returns a const pointer to the integrator’s current PiecewisePolynomial instance, holding a representation of the continuous state trajectory since the last StartDenseIntegration() call. This is suitable to query the integrator’s current dense output, if any (may be nullptr).
- get_fixed_step_mode(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) bool
Gets whether an integrator is running in fixed step mode. If the integrator does not support error estimation, this function will always return
True
.See also
set_fixed_step_mode()
- get_initial_step_size_target(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.autodiffutils.AutoDiffXd
Gets the target size of the first integration step. You can find out what step size was actually used for the first integration step with
get_actual_initial_step_size_taken()
.See also
request_initial_step_size_target()
- get_largest_step_size_taken(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.autodiffutils.AutoDiffXd
The size of the largest step taken since the last Initialize() or ResetStatistics() call.
- get_maximum_step_size(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.autodiffutils.AutoDiffXd
Gets the maximum step size that may be taken by this integrator. This is a soft maximum: the integrator may stretch it by as much as 1% to hit a discrete event.
See also
set_requested_minimum_step_size()
- get_mutable_context(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.systems.framework.Context_[AutoDiffXd]
Returns a mutable pointer to the internally-maintained Context holding the most recent state in the trajectory.
- get_num_derivative_evaluations(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) int
Returns the number of ODE function evaluations (calls to CalcTimeDerivatives()) since the last call to ResetStatistics() or Initialize(). This count includes all such calls including (1) those necessary to compute Jacobian matrices; (2) those used in rejected integrated steps (for, e.g., purposes of error control); (3) those used strictly for integrator error estimation; and (4) calls that exhibit little cost (due to results being cached).
- get_num_step_shrinkages_from_error_control(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) int
Gets the number of step size shrinkages due to failure to meet targeted error tolerances, since the last call to ResetStatistics or Initialize().
- get_num_step_shrinkages_from_substep_failures(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) int
Gets the number of step size shrinkages due to sub-step failures (e.g., integrator convergence failures) since the last call to ResetStatistics() or Initialize().
- get_num_steps_taken(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) int
The number of integration steps taken since the last Initialize() or ResetStatistics() call.
- get_num_substep_failures(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) int
Gets the number of failed sub-steps (implying one or more step size reductions was required to permit solving the necessary nonlinear system of equations).
- get_requested_minimum_step_size(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.autodiffutils.AutoDiffXd
Gets the requested minimum step size
h_min
for this integrator.See also
set_requested_minimum_step_size()
See also
get_working_minimum_step_size(T)
- get_smallest_adapted_step_size_taken(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.autodiffutils.AutoDiffXd
The size of the smallest step taken as the result of a controlled integration step adjustment since the last Initialize() or ResetStatistics() call. This value will be NaN for integrators without error estimation.
- get_target_accuracy(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) float
Gets the target accuracy.
See also
get_accuracy_in_use()
- get_throw_on_minimum_step_size_violation(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) bool
Reports the current setting of the throw_on_minimum_step_size_violation flag.
See also
set_throw_on_minimum_step_size_violation().
- Initialize(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) None
An integrator must be initialized before being used. The pointer to the context must be set before Initialize() is called (or an RuntimeError will be thrown). If Initialize() is not called, an exception will be thrown when attempting to call IntegrateNoFurtherThanTime(). To reinitialize the integrator, Reset() should be called followed by Initialize().
- Raises
RuntimeError If the context has not been set or a user-set –
parameter has been set illogically (i.e., one of the weighting –
matrix coefficients is set to a negative value- this check is only –
performed for integrators that support error estimation; the –
maximum step size is smaller than the minimum step size; the –
requested initial step size is outside of the interval [minimum –
step size, maximum step size]) –
See also
Reset()
- request_initial_step_size_target(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd], step_size: pydrake.autodiffutils.AutoDiffXd) None
Request that the first attempted integration step have a particular size. If no request is made, the integrator will estimate a suitable size for the initial step attempt. If the integrator does not support error control, this method will throw a RuntimeError (call supports_error_estimation() to verify before calling this method). For variable-step integration, the initial target will be treated as a maximum step size subject to accuracy requirements and event occurrences. You can find out what size actually worked with
get_actual_initial_step_size_taken()
.- Raises
RuntimeError If the integrator does not support error estimation. –
- Reset(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) None
Resets the integrator to initial values, i.e., default construction values.
- reset_context(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd], context: pydrake.systems.framework.Context_[AutoDiffXd]) None
Replace the pointer to the internally-maintained Context with a different one. This is useful for supplying a new set of initial conditions or wiping out the current context (by passing in a null pointer). You should invoke Initialize() after replacing the Context unless the context is null.
- Parameter
context
: The pointer to the new context or nullptr to wipe out the current context without replacing it with another.
- Parameter
- ResetStatistics(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) None
@name Integrator statistics methods These methods allow the caller to manipulate and query integrator statistics. Generally speaking, the larger the integration step taken, the faster a simulation will run. These methods allow querying (and resetting) the integrator statistics as one means of determining how to make a simulation run faster.
Forget accumulated statistics. These are reset to the values they have post construction or immediately after
Initialize()
.
- set_fixed_step_mode(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd], flag: bool) None
Sets an integrator with error control to fixed step mode. If the integrator runs in fixed step mode, it will always take the maximum step size directed (which may be that determined by get_maximum_step_size(), or may be smaller, as directed by, e.g., Simulator for event handling purposes).
Warning
The error estimation process will still be active (so get_error_estimate() will still return a correct result), meaning that the additional (typically, but not necessarily small) computation required for error estimation will still be performed.
- Raises
RuntimeError if integrator does not support error estimation and –
flag` is set to False –
- set_maximum_step_size(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd], max_step_size: pydrake.autodiffutils.AutoDiffXd) None
@anchor integrator-maxstep @name Methods related to maximum integration step size
Sets the nominal maximum step size- the actual maximum step size taken may be slightly larger (see set_maximum_step_size() and get_stretch_factor())- that an integrator will take. Each integrator has a default maximum step size, which might be infinite. Sets the maximum step size that may be taken by this integrator. This setting should be used if you know the maximum time scale of your problem. The integrator may stretch the maximum step size by as much as 1% to reach a discrete event. For fixed step integrators, all steps will be taken at the maximum step size unless an event would be missed.
Warning
See integrator-initial-step-size “Initial step size selection”
- set_requested_minimum_step_size(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd], min_step_size: pydrake.autodiffutils.AutoDiffXd) None
Sets the requested minimum step size
h_min
that may be taken by this integrator. No step smaller than this will be taken except under circumstances as described integrator-minstep “above”. This setting will be ignored if it is smaller than the absolute minimumh_floor
also described above. Default value is zero.- Parameter
min_step_size
: a non-negative value. Setting this value to zero will cause the integrator to use a reasonable value instead (see get_working_minimum_step_size()).
See also
get_requested_minimum_step_size()
See also
get_working_minimum_step_size()
- Parameter
- set_target_accuracy(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd], accuracy: float) None
@anchor integrator-accuracy @name Methods for getting and setting integrator accuracy The precise meaning of accuracy is a complicated discussion, but it translates roughly to the number of significant digits you want in the results. By convention it is supplied as
10^-digits
, meaning that an accuracy of 1e-3 provides about three significant digits. For more discussion of accuracy, see accuracy_and_tolerance and ref. [1].Integrators vary in the range of accuracy (loosest to tightest) that they can support, and each integrator will choose a default accuracy to be used that lies somewhere within this range and attempts to balance computation and accuracy. If you request accuracy outside the supported range for the chosen integrator it will be quietly adjusted to be in range. You can find out the accuracy setting actually being used using
get_accuracy_in_use()
.Implicit integrators additionally use the accuracy setting for determining when the underlying Newton-Raphson root finding process has converged. For those integrators, the accuracy setting also limits the allowable iteration error in the Newton-Raphson process. Looser accuracy in that process certainly implies greater error in the ODE solution and might impact the stability of the solution negatively as well.
[1] M. Sherman, A. Seth, S. Delp. Procedia IUTAM 2:241-261 (2011),
Section 3.3. https://dx.doi.org/10.1016/j.piutam.2011.04.023
Request that the integrator attempt to achieve a particular accuracy for the continuous portions of the simulation. Otherwise a default accuracy is chosen for you. This may be ignored for fixed-step integration since accuracy control requires variable step sizes. You should call supports_error_estimation() to ensure that the integrator supports this capability before calling this function; if the integrator does not support it, this method will throw an exception.
- Raises
RuntimeError if integrator does not support error estimation. –
- set_throw_on_minimum_step_size_violation(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd], throws: bool) None
Sets whether the integrator should throw a RuntimeError when the integrator’s step size selection algorithm determines that it must take a step smaller than the minimum step size (for, e.g., purposes of error control). Default is
True
. IfFalse
, the integrator will advance time and state using the minimum specified step size in such situations. See integrator-minstep “this section” for more detail.
- StartDenseIntegration(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) None
Starts dense integration, allocating a new dense output for this integrator to use.
- Precondition:
The integrator has been initialized.
- Precondition:
The system being integrated has continuous state.
- Precondition:
No dense integration is in progress (no dense output is held by the integrator)
- Raises
RuntimeError if any of the preconditions is not met. –
Warning
Dense integration may incur significant overhead.
- StopDenseIntegration(self: pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]) pydrake.trajectories.PiecewisePolynomial_[AutoDiffXd]
Stops dense integration, yielding ownership of the current dense output to the caller.
- Remark:
This process is irreversible.
- Returns
A PiecewisePolynomial instance, i.e. a representation of the continuous state trajectory of the system being integrated that can be evaluated at any time within its extension. This representation is defined starting at the context time of the last StartDenseIntegration() call and finishing at the current context time.
- Precondition:
Dense integration is in progress (a dense output is held by this integrator, after a call to StartDenseIntegration()).
- Postcondition:
Previously held dense output is not updated nor referenced by the integrator anymore.
- Raises
RuntimeError if any of the preconditions is not met. –
- class pydrake.systems.analysis.IntegratorBase_[Expression]
An abstract class for an integrator for ODEs and DAEs as represented by a Drake System. Integrators solve initial value problems of the form:
Click to expand C++ code...
ẋ(t) = f(t, x(t)) with f : ℝ × ℝⁿ → ℝⁿ
(i.e.,
f()
is an ordinary differential equation) given initial conditions (t₀, x₀). Thus, integrators advance the continuous state of a dynamical system forward in time.Drake’s subclasses of IntegratorBase<T> should follow the naming pattern
FooIntegrator<T>
by convention.- __init__(*args, **kwargs)
- get_actual_initial_step_size_taken(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.symbolic.Expression
The actual size of the successful first step.
- get_context(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.systems.framework.Context_[Expression]
Returns a const reference to the internally-maintained Context holding the most recent state in the trajectory. This is suitable for publishing or extracting information about this trajectory step.
- get_dense_output(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.trajectories.PiecewisePolynomial_[Expression]
Returns a const pointer to the integrator’s current PiecewisePolynomial instance, holding a representation of the continuous state trajectory since the last StartDenseIntegration() call. This is suitable to query the integrator’s current dense output, if any (may be nullptr).
- get_fixed_step_mode(self: pydrake.systems.analysis.IntegratorBase_[Expression]) bool
Gets whether an integrator is running in fixed step mode. If the integrator does not support error estimation, this function will always return
True
.See also
set_fixed_step_mode()
- get_initial_step_size_target(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.symbolic.Expression
Gets the target size of the first integration step. You can find out what step size was actually used for the first integration step with
get_actual_initial_step_size_taken()
.See also
request_initial_step_size_target()
- get_largest_step_size_taken(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.symbolic.Expression
The size of the largest step taken since the last Initialize() or ResetStatistics() call.
- get_maximum_step_size(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.symbolic.Expression
Gets the maximum step size that may be taken by this integrator. This is a soft maximum: the integrator may stretch it by as much as 1% to hit a discrete event.
See also
set_requested_minimum_step_size()
- get_mutable_context(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.systems.framework.Context_[Expression]
Returns a mutable pointer to the internally-maintained Context holding the most recent state in the trajectory.
- get_num_derivative_evaluations(self: pydrake.systems.analysis.IntegratorBase_[Expression]) int
Returns the number of ODE function evaluations (calls to CalcTimeDerivatives()) since the last call to ResetStatistics() or Initialize(). This count includes all such calls including (1) those necessary to compute Jacobian matrices; (2) those used in rejected integrated steps (for, e.g., purposes of error control); (3) those used strictly for integrator error estimation; and (4) calls that exhibit little cost (due to results being cached).
- get_num_step_shrinkages_from_error_control(self: pydrake.systems.analysis.IntegratorBase_[Expression]) int
Gets the number of step size shrinkages due to failure to meet targeted error tolerances, since the last call to ResetStatistics or Initialize().
- get_num_step_shrinkages_from_substep_failures(self: pydrake.systems.analysis.IntegratorBase_[Expression]) int
Gets the number of step size shrinkages due to sub-step failures (e.g., integrator convergence failures) since the last call to ResetStatistics() or Initialize().
- get_num_steps_taken(self: pydrake.systems.analysis.IntegratorBase_[Expression]) int
The number of integration steps taken since the last Initialize() or ResetStatistics() call.
- get_num_substep_failures(self: pydrake.systems.analysis.IntegratorBase_[Expression]) int
Gets the number of failed sub-steps (implying one or more step size reductions was required to permit solving the necessary nonlinear system of equations).
- get_requested_minimum_step_size(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.symbolic.Expression
Gets the requested minimum step size
h_min
for this integrator.See also
set_requested_minimum_step_size()
See also
get_working_minimum_step_size(T)
- get_smallest_adapted_step_size_taken(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.symbolic.Expression
The size of the smallest step taken as the result of a controlled integration step adjustment since the last Initialize() or ResetStatistics() call. This value will be NaN for integrators without error estimation.
- get_target_accuracy(self: pydrake.systems.analysis.IntegratorBase_[Expression]) float
Gets the target accuracy.
See also
get_accuracy_in_use()
- get_throw_on_minimum_step_size_violation(self: pydrake.systems.analysis.IntegratorBase_[Expression]) bool
Reports the current setting of the throw_on_minimum_step_size_violation flag.
See also
set_throw_on_minimum_step_size_violation().
- Initialize(self: pydrake.systems.analysis.IntegratorBase_[Expression]) None
An integrator must be initialized before being used. The pointer to the context must be set before Initialize() is called (or an RuntimeError will be thrown). If Initialize() is not called, an exception will be thrown when attempting to call IntegrateNoFurtherThanTime(). To reinitialize the integrator, Reset() should be called followed by Initialize().
- Raises
RuntimeError If the context has not been set or a user-set –
parameter has been set illogically (i.e., one of the weighting –
matrix coefficients is set to a negative value- this check is only –
performed for integrators that support error estimation; the –
maximum step size is smaller than the minimum step size; the –
requested initial step size is outside of the interval [minimum –
step size, maximum step size]) –
See also
Reset()
- request_initial_step_size_target(self: pydrake.systems.analysis.IntegratorBase_[Expression], step_size: pydrake.symbolic.Expression) None
Request that the first attempted integration step have a particular size. If no request is made, the integrator will estimate a suitable size for the initial step attempt. If the integrator does not support error control, this method will throw a RuntimeError (call supports_error_estimation() to verify before calling this method). For variable-step integration, the initial target will be treated as a maximum step size subject to accuracy requirements and event occurrences. You can find out what size actually worked with
get_actual_initial_step_size_taken()
.- Raises
RuntimeError If the integrator does not support error estimation. –
- Reset(self: pydrake.systems.analysis.IntegratorBase_[Expression]) None
Resets the integrator to initial values, i.e., default construction values.
- reset_context(self: pydrake.systems.analysis.IntegratorBase_[Expression], context: pydrake.systems.framework.Context_[Expression]) None
Replace the pointer to the internally-maintained Context with a different one. This is useful for supplying a new set of initial conditions or wiping out the current context (by passing in a null pointer). You should invoke Initialize() after replacing the Context unless the context is null.
- Parameter
context
: The pointer to the new context or nullptr to wipe out the current context without replacing it with another.
- Parameter
- ResetStatistics(self: pydrake.systems.analysis.IntegratorBase_[Expression]) None
@name Integrator statistics methods These methods allow the caller to manipulate and query integrator statistics. Generally speaking, the larger the integration step taken, the faster a simulation will run. These methods allow querying (and resetting) the integrator statistics as one means of determining how to make a simulation run faster.
Forget accumulated statistics. These are reset to the values they have post construction or immediately after
Initialize()
.
- set_fixed_step_mode(self: pydrake.systems.analysis.IntegratorBase_[Expression], flag: bool) None
Sets an integrator with error control to fixed step mode. If the integrator runs in fixed step mode, it will always take the maximum step size directed (which may be that determined by get_maximum_step_size(), or may be smaller, as directed by, e.g., Simulator for event handling purposes).
Warning
The error estimation process will still be active (so get_error_estimate() will still return a correct result), meaning that the additional (typically, but not necessarily small) computation required for error estimation will still be performed.
- Raises
RuntimeError if integrator does not support error estimation and –
flag` is set to False –
- set_maximum_step_size(self: pydrake.systems.analysis.IntegratorBase_[Expression], max_step_size: pydrake.symbolic.Expression) None
@anchor integrator-maxstep @name Methods related to maximum integration step size
Sets the nominal maximum step size- the actual maximum step size taken may be slightly larger (see set_maximum_step_size() and get_stretch_factor())- that an integrator will take. Each integrator has a default maximum step size, which might be infinite. Sets the maximum step size that may be taken by this integrator. This setting should be used if you know the maximum time scale of your problem. The integrator may stretch the maximum step size by as much as 1% to reach a discrete event. For fixed step integrators, all steps will be taken at the maximum step size unless an event would be missed.
Warning
See integrator-initial-step-size “Initial step size selection”
- set_requested_minimum_step_size(self: pydrake.systems.analysis.IntegratorBase_[Expression], min_step_size: pydrake.symbolic.Expression) None
Sets the requested minimum step size
h_min
that may be taken by this integrator. No step smaller than this will be taken except under circumstances as described integrator-minstep “above”. This setting will be ignored if it is smaller than the absolute minimumh_floor
also described above. Default value is zero.- Parameter
min_step_size
: a non-negative value. Setting this value to zero will cause the integrator to use a reasonable value instead (see get_working_minimum_step_size()).
See also
get_requested_minimum_step_size()
See also
get_working_minimum_step_size()
- Parameter
- set_target_accuracy(self: pydrake.systems.analysis.IntegratorBase_[Expression], accuracy: float) None
@anchor integrator-accuracy @name Methods for getting and setting integrator accuracy The precise meaning of accuracy is a complicated discussion, but it translates roughly to the number of significant digits you want in the results. By convention it is supplied as
10^-digits
, meaning that an accuracy of 1e-3 provides about three significant digits. For more discussion of accuracy, see accuracy_and_tolerance and ref. [1].Integrators vary in the range of accuracy (loosest to tightest) that they can support, and each integrator will choose a default accuracy to be used that lies somewhere within this range and attempts to balance computation and accuracy. If you request accuracy outside the supported range for the chosen integrator it will be quietly adjusted to be in range. You can find out the accuracy setting actually being used using
get_accuracy_in_use()
.Implicit integrators additionally use the accuracy setting for determining when the underlying Newton-Raphson root finding process has converged. For those integrators, the accuracy setting also limits the allowable iteration error in the Newton-Raphson process. Looser accuracy in that process certainly implies greater error in the ODE solution and might impact the stability of the solution negatively as well.
[1] M. Sherman, A. Seth, S. Delp. Procedia IUTAM 2:241-261 (2011),
Section 3.3. https://dx.doi.org/10.1016/j.piutam.2011.04.023
Request that the integrator attempt to achieve a particular accuracy for the continuous portions of the simulation. Otherwise a default accuracy is chosen for you. This may be ignored for fixed-step integration since accuracy control requires variable step sizes. You should call supports_error_estimation() to ensure that the integrator supports this capability before calling this function; if the integrator does not support it, this method will throw an exception.
- Raises
RuntimeError if integrator does not support error estimation. –
- set_throw_on_minimum_step_size_violation(self: pydrake.systems.analysis.IntegratorBase_[Expression], throws: bool) None
Sets whether the integrator should throw a RuntimeError when the integrator’s step size selection algorithm determines that it must take a step smaller than the minimum step size (for, e.g., purposes of error control). Default is
True
. IfFalse
, the integrator will advance time and state using the minimum specified step size in such situations. See integrator-minstep “this section” for more detail.
- StartDenseIntegration(self: pydrake.systems.analysis.IntegratorBase_[Expression]) None
Starts dense integration, allocating a new dense output for this integrator to use.
- Precondition:
The integrator has been initialized.
- Precondition:
The system being integrated has continuous state.
- Precondition:
No dense integration is in progress (no dense output is held by the integrator)
- Raises
RuntimeError if any of the preconditions is not met. –
Warning
Dense integration may incur significant overhead.
- StopDenseIntegration(self: pydrake.systems.analysis.IntegratorBase_[Expression]) pydrake.trajectories.PiecewisePolynomial_[Expression]
Stops dense integration, yielding ownership of the current dense output to the caller.
- Remark:
This process is irreversible.
- Returns
A PiecewisePolynomial instance, i.e. a representation of the continuous state trajectory of the system being integrated that can be evaluated at any time within its extension. This representation is defined starting at the context time of the last StartDenseIntegration() call and finishing at the current context time.
- Precondition:
Dense integration is in progress (a dense output is held by this integrator, after a call to StartDenseIntegration()).
- Postcondition:
Previously held dense output is not updated nor referenced by the integrator anymore.
- Raises
RuntimeError if any of the preconditions is not met. –
- pydrake.systems.analysis.MonteCarloSimulation(make_simulator: Callable[[pydrake.common.RandomGenerator], pydrake.systems.analysis.Simulator], output: Callable[[pydrake.systems.framework.System, pydrake.systems.framework.Context], float], final_time: float, num_samples: int, generator: pydrake.common.RandomGenerator) list[pydrake.systems.analysis.RandomSimulationResult]
Generates samples of a scalar random variable output by running many random simulations drawn from independent samples of the distributions governing the stochastic simulation.
In pseudo-code, this algorithm implements:
Click to expand C++ code...
for i=1:num_samples const generator_snapshot = deepcopy(generator) output = RandomSimulation(..., generator) data(i) = std::pair(generator_snapshot, output) return data
See also
RandomSimulation() for details about
make_simulator
,output
, andfinal_time
.- Parameter
num_samples
: Number of independent samples to draw from the distribution (and equivalently, the number of simulations to run).
- Parameter
generator
: Random number generator to be used to generate the random samples. If null, then a new RandomGenerator will be allocated and used internally (and repeated calls to this method will return identical results). To produce statistically “independent” samples on a future call to MonteCarloSimulation, you should make repeated uses of the same RandomGenerator object.
- Parameter
parallelism
: Specify number of parallel executions to use while performing
num_samples
simulations. The default value (false) specifies that simulations should be executed in serial. To use the concurrency available on your hardware, specify eitherParallellism::Max()
or its terse abbreviationTrue
.
- Returns
a list of RandomSimulationResult’s.
Thread safety when parallel execution is specified: -
make_simulator
andgenerator
are only accessed from the main thread.Each simulator created by
make_simulator
and its context are only accessed from within a single worker thread; however, any resource shared between these simulators must be safe for concurrent use.output
is called from within worker threads performing simulation with the simulator and context belonging to each worker thread. It must be safe to make concurrent calls tooutput
(i.e. any mutable state inside the function must be safe for concurrent use).
- Parameter
- pydrake.systems.analysis.PrintSimulatorStatistics(*args, **kwargs)
Overloaded function.
PrintSimulatorStatistics(arg0: pydrake.systems.analysis.Simulator) -> None
This method outputs to stdout relevant simulation statistics for a simulator that advanced the state of a system forward in time.
- Parameter
simulator
: The simulator to output statistics for.
PrintSimulatorStatistics(arg0: pydrake.systems.analysis.Simulator_[AutoDiffXd]) -> None
This method outputs to stdout relevant simulation statistics for a simulator that advanced the state of a system forward in time.
- Parameter
simulator
: The simulator to output statistics for.
- pydrake.systems.analysis.RandomSimulation(make_simulator: Callable[[pydrake.common.RandomGenerator], pydrake.systems.analysis.Simulator], output: Callable[[pydrake.systems.framework.System, pydrake.systems.framework.Context], float], final_time: float, generator: pydrake.common.RandomGenerator) float
Run a deterministic simulation of a (stochastic) System using the
generator
to instantiate all “random” quantities.In pseudo-code, this algorithm implements:
Click to expand C++ code...
simulator = make_simulator(generator) simulator.get_system().SetRandomContext(generator) simulator.AdvanceTo(final_time) return output(simulator.get_context())
- Parameter
make_simulator
: Callers to this method define a stochastic simulation by providing the
make_simulator
factory method to return a Simulator using the supplied RandomGenerator as the only source of randomness. This interface was designed to support cases where the System/Diagram is random (not only the Context), e.g. in the case where are variable number of objects are added to a multibody simulation.- Parameter
output
: The scalar random variable output, denoted
output
, is defined as a function of the Simulator’s System’s Context, evaluated at thefinal_time
. Monte-Carlo investigations that studying the details of an entire trajectory can still use this interface, e.g. by including a “runtime monitor” System that latches the worst-case deviation of a specification into it’s Context to be queried at the final time.- Parameter
final_time
: The time that each instance of the Simulator is stepped to. In many cases, this will be equivalent to the duration of the simulation, but it need not be because SetRandomContext() could initialize the time to a non-zero value, or an event could trigger premature termination of the simulation (see #4447).
- Parameter
generator
: Random number generator to be used to generate the random samples.
- Returns
the
output
evaluated from the Context atfinal_time
.
- Parameter
- class pydrake.systems.analysis.RandomSimulationResult
A snapshot of the generator used to produce the random simulation. Use, e.g.,
Click to expand C++ code...
RandomGenerator generator(result.generator_snapshot) RandomSimulation(make_simulator, output, final_time, &generator)
for a deterministic playback of the sampled simulation. RandomNumberEngine concept</a>, if you wish to serialize the results. Note that performing any non-const operations on generator_snapshot may advance the state of the generator and make it no longer capable of reproducing the simulation.
- __init__(*args, **kwargs)
- property generator_snapshot
- property output
- pydrake.systems.analysis.RegionOfAttraction(system: pydrake.systems.framework.System, context: pydrake.systems.framework.Context, options: pydrake.systems.analysis.RegionOfAttractionOptions = RegionOfAttractionOptions(lyapunov_candidate=<Expression "0">, state_variables=array([], dtype=object), use_implicit_dynamics=False, solver_id=None, solver_options=None)) pydrake.symbolic.Expression
Estimates the region of attraction of the time-invariant
system
at the fixed point defined bycontext
.This implementation only searches for the largest level set of the
lyapunov_candidate
function fromoptions
(or a candidate obtained from solving the Lyapunov equation on the linearization).- Parameter
system
: a time-invariant continuous-time System that supports scalar-type conversion to symbolic::Expression. The dynamics of the system must be polynomial.
- Parameter
context
: a Context that defines the parameters of the system and the fixed-point about which we are analyzing the regional stability.
- Parameter
options
: provides a variety of configuration options.
See also
RegionOfAttractionOptions.
- Returns
a symbolic::Expression representing a Lyapunov function using the symbolic Variables named x0, x1…, where the order matches the continuous state vector in the
context
, or the vector state_variables passed in through the options structure (if it is non-empty). The level set {x | V(x)<=1} containing the fixed-point incontext
represents the region of attraction.
- Precondition:
For the given
system
andcontext
, any required input ports onsystem
must be “defined”, i.e., connected to other systems in a larger diagram or holding fixed values; see System::FixInputPortsFrom for possible caveats. Analyzing a closed-loop system would typically be accomplished by having both the plant and the controller in a diagram (which then has no input ports), and passing the diagram into this method assystem
.
Note: There are more numerical recipes for region of attraction analysis that could extend the current implementation. Do report an issue if you discover a system for which this code does not perform well.
- Parameter
- class pydrake.systems.analysis.RegionOfAttractionOptions
Consolidates the many possible options to be passed to the region of attraction algorithm.
- __init__(self: pydrake.systems.analysis.RegionOfAttractionOptions) None
- property lyapunov_candidate
A candidate Lyapunov function using the symbolic Variables named x0, x1, …, where the order matches the continuous state vector of the system being evaluated (or the vector state_variables).
- property solver_id
If not std::nullopt, then we will solve the optimization problem using the specified solver; otherwise Drake will choose a solver.
- property solver_options
The solver options used in the optimization problem.
- property state_variables
If non-empty, a list of Variable that associates the variable name with the elements of the System’s continuous state vector. Must be empty or have size equal to the number of continuous state variables in the system.
- property use_implicit_dynamics
If true, the system dynamics will be evaluated using CalcImplicitTimeDerivativesResidual instead of CalcTimeDerivatives to obtain g(x,ẋ) = 0 (instead of ẋ = f(x)). The Lyapunov conditions will also be evaluated in the implicit form. This is more expensive than analysis in the explicit form, as it requires more indeterminates, but it enables analysis of systems with rational polynomial dynamics.
See https://underactuated.csail.mit.edu/lyapunov.html#ex:implicit for more details.
- pydrake.systems.analysis.ResetIntegratorFromFlags(*args, **kwargs)
Overloaded function.
ResetIntegratorFromFlags(simulator: pydrake.systems.analysis.Simulator, scheme: str, max_step_size: float) -> pydrake.systems.analysis.IntegratorBase
Resets the integrator used to advanced the continuous time dynamics of the system associated with
simulator
according to the given arguments.- Parameter
simulator
: On input, a valid pointer to a Simulator. On output the integrator for
simulator
is reset according to the given arguments.- Parameter
scheme
: Integration scheme to be used, e.g., “runge_kutta2”. See GetIntegrationSchemes() for a the list of valid options.
- Parameter
max_step_size
: The IntegratorBase::set_maximum_step_size() value.
- Returns
A reference to the newly created integrator owned by
simulator
.
ResetIntegratorFromFlags(simulator: pydrake.systems.analysis.Simulator_[AutoDiffXd], scheme: str, max_step_size: pydrake.autodiffutils.AutoDiffXd) -> pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]
Resets the integrator used to advanced the continuous time dynamics of the system associated with
simulator
according to the given arguments.- Parameter
simulator
: On input, a valid pointer to a Simulator. On output the integrator for
simulator
is reset according to the given arguments.- Parameter
scheme
: Integration scheme to be used, e.g., “runge_kutta2”. See GetIntegrationSchemes() for a the list of valid options.
- Parameter
max_step_size
: The IntegratorBase::set_maximum_step_size() value.
- Returns
A reference to the newly created integrator owned by
simulator
.
- class pydrake.systems.analysis.RungeKutta2Integrator
Bases:
pydrake.systems.analysis.IntegratorBase
A second-order, explicit Runge Kutta integrator.
Note
This class is templated; see
RungeKutta2Integrator_
for the list of instantiations.- __init__(self: pydrake.systems.analysis.RungeKutta2Integrator, system: pydrake.systems.framework.System, max_step_size: float, context: pydrake.systems.framework.Context = None) None
Constructs fixed-step integrator for a given system using the given context for initial conditions.
- Parameter
system
: A reference to the system to be simulated
- Parameter
max_step_size
: The maximum (fixed) step size; the integrator will not take larger step sizes than this.
- Parameter
context
: pointer to the context (nullptr is ok, but the caller must set a non-null context before Initialize()-ing the integrator).
See also
Initialize()
- Parameter
- template pydrake.systems.analysis.RungeKutta2Integrator_
Instantiations:
RungeKutta2Integrator_[float]
,RungeKutta2Integrator_[AutoDiffXd]
,RungeKutta2Integrator_[Expression]
- class pydrake.systems.analysis.RungeKutta2Integrator_[AutoDiffXd]
Bases:
pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]
A second-order, explicit Runge Kutta integrator.
- __init__(self: pydrake.systems.analysis.RungeKutta2Integrator_[AutoDiffXd], system: pydrake.systems.framework.System_[AutoDiffXd], max_step_size: pydrake.autodiffutils.AutoDiffXd, context: pydrake.systems.framework.Context_[AutoDiffXd] = None) None
Constructs fixed-step integrator for a given system using the given context for initial conditions.
- Parameter
system
: A reference to the system to be simulated
- Parameter
max_step_size
: The maximum (fixed) step size; the integrator will not take larger step sizes than this.
- Parameter
context
: pointer to the context (nullptr is ok, but the caller must set a non-null context before Initialize()-ing the integrator).
See also
Initialize()
- Parameter
- class pydrake.systems.analysis.RungeKutta2Integrator_[Expression]
Bases:
pydrake.systems.analysis.IntegratorBase_[Expression]
A second-order, explicit Runge Kutta integrator.
- __init__(self: pydrake.systems.analysis.RungeKutta2Integrator_[Expression], system: pydrake.systems.framework.System_[Expression], max_step_size: pydrake.symbolic.Expression, context: pydrake.systems.framework.Context_[Expression] = None) None
Constructs fixed-step integrator for a given system using the given context for initial conditions.
- Parameter
system
: A reference to the system to be simulated
- Parameter
max_step_size
: The maximum (fixed) step size; the integrator will not take larger step sizes than this.
- Parameter
context
: pointer to the context (nullptr is ok, but the caller must set a non-null context before Initialize()-ing the integrator).
See also
Initialize()
- Parameter
- class pydrake.systems.analysis.RungeKutta3Integrator
Bases:
pydrake.systems.analysis.IntegratorBase
A third-order Runge Kutta integrator with a third order error estimate.
For a discussion of this Runge-Kutta method, see [Butcher, 1987]. The embedded error estimate was derived using the method mentioned in [Hairer, 1993].
The Butcher tableau for this integrator follows:
Click to expand C++ code...
| 0 | 1/2 | 1/2 1 | -1 2 --------------------------------------------------------------------------- 1/6 2/3 1/6 0 1 0
where the second to last row is the 3rd-order propagated solution and the last row is the 2nd-order midpoint used for the error estimate.
The following documentation is pulled from Simbody’s implementation of this integrator: “This is a 3-stage, first-same-as-last (FSAL) 3rd order method which gives us an embedded 2nd order method as well, so we can extract a 3rd-order error estimate for the 2nd-order result, which error estimate can then be used for step size control, since it will behave as h^3. We then propagate the 3rd order result (whose error is unknown), which Hairer calls ‘local extrapolation’. We call the initial state (t0,y0) and want (t0+h,y1). We are given the initial derivative f0=f(t0,y0), which most likely is left over from an evaluation at the end of the last step.”
[Butcher, 1987] J. C. Butcher. The Numerical Analysis of Ordinary Differential Equations. John Wiley & Sons, 1987. p. 325.
[Hairer, 1993] E. Hairer, S. Noersett, and G. Wanner. Solving ODEs I. 2nd rev. ed. Springer, 1993. p. 166.
Note
This class is templated; see
RungeKutta3Integrator_
for the list of instantiations.- __init__(self: pydrake.systems.analysis.RungeKutta3Integrator, system: pydrake.systems.framework.System, context: pydrake.systems.framework.Context = None) None
- template pydrake.systems.analysis.RungeKutta3Integrator_
Instantiations:
RungeKutta3Integrator_[float]
,RungeKutta3Integrator_[AutoDiffXd]
- class pydrake.systems.analysis.RungeKutta3Integrator_[AutoDiffXd]
Bases:
pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]
A third-order Runge Kutta integrator with a third order error estimate.
For a discussion of this Runge-Kutta method, see [Butcher, 1987]. The embedded error estimate was derived using the method mentioned in [Hairer, 1993].
The Butcher tableau for this integrator follows:
Click to expand C++ code...
| 0 | 1/2 | 1/2 1 | -1 2 --------------------------------------------------------------------------- 1/6 2/3 1/6 0 1 0
where the second to last row is the 3rd-order propagated solution and the last row is the 2nd-order midpoint used for the error estimate.
The following documentation is pulled from Simbody’s implementation of this integrator: “This is a 3-stage, first-same-as-last (FSAL) 3rd order method which gives us an embedded 2nd order method as well, so we can extract a 3rd-order error estimate for the 2nd-order result, which error estimate can then be used for step size control, since it will behave as h^3. We then propagate the 3rd order result (whose error is unknown), which Hairer calls ‘local extrapolation’. We call the initial state (t0,y0) and want (t0+h,y1). We are given the initial derivative f0=f(t0,y0), which most likely is left over from an evaluation at the end of the last step.”
[Butcher, 1987] J. C. Butcher. The Numerical Analysis of Ordinary Differential Equations. John Wiley & Sons, 1987. p. 325.
[Hairer, 1993] E. Hairer, S. Noersett, and G. Wanner. Solving ODEs I. 2nd rev. ed. Springer, 1993. p. 166.
- __init__(self: pydrake.systems.analysis.RungeKutta3Integrator_[AutoDiffXd], system: pydrake.systems.framework.System_[AutoDiffXd], context: pydrake.systems.framework.Context_[AutoDiffXd] = None) None
- class pydrake.systems.analysis.Simulator
A class for advancing the state of hybrid dynamic systems, represented by
System<T>
objects, forward in time. Starting with an initial Context for a given System, Simulator advances time and produces a series of Context values that forms a trajectory satisfying the system’s dynamic equations to a specified accuracy. Only the Context is modified by a Simulator; the System is const.A Drake System is a continuous/discrete/hybrid dynamic system where the continuous part is a DAE, that is, it is expected to consist of a set of differential equations and bilateral algebraic constraints. The set of active constraints may change as a result of particular events, such as contact.
Given a current Context, we expect a System to provide us with - derivatives for the continuous differential equations that already satisfy the differentiated form of the constraints (typically, acceleration constraints), - a projection method for least-squares correction of violated higher-level constraints (position and velocity level), - a time-of-next-update method that can be used to adjust the integrator step size in preparation for a discrete update, - methods that can update discrete variables when their update time is reached, - witness (guard) functions for event isolation, - event handlers (reset functions) for making appropriate changes to state and mode variables when an event has been isolated.
The continuous parts of the trajectory are advanced using a numerical integrator. Different integrators have different properties; you can choose the one that is most appropriate for your application or use the default which is adequate for most systems.
<h3>How the simulation is stepped: simulation mechanics for authors of discrete and hybrid systems</h3>
This section is targeted toward users who have created a LeafSystem implementing a discrete or hybrid system. For authors of such systems, it can be useful to understand the simulation details in order to attain the desired state behavior over time. This behavior is dependent on the ordering in which discrete events and continuous updates are processed. (By “discrete events” we mean to include any of Drake’s event handlers.) The basic issues and terminology are introduced in the discrete_systems module; please look there first before proceeding.
As pictured in discrete_systems, when a continuous-time system has discrete events, the state x can have two significant values at the event time t. These are - x⁻(t), the value of x before the discrete update occurs (○ markers), and - x⁺(t), the value of x after the discrete update occurs (● markers).
Thus the value of the Context, which contains both time and state, advances from {t, x⁻(t)} to {t, x⁺(t)} as a result of the update. While those Context values are user-visible, the details of stepping here require an intermediate value which we’ll denote {t, x*(t)}.
Recall that Drake’s state x is partitioned into continuous, discrete, and abstract partitions xc, xd, and xa, so
x = { xc, xd, xa }
. Within a single step, these are updated in three stages: -Unrestricted update (can change x) -
Discrete update (can change only xd) -
Continuous update (changes t and xc)
Where needed, we extend the above notation to xc⁻, xa⁺, etc. to indicate the value of an individual partition at a particular stage of the stepping algorithm.
The following pseudocode uses the above notation to describe the algorithm “Step()” that the Simulator uses to incrementally advance the system trajectory (time t and state x). The Simulator’s AdvanceTo() method will be defined in terms of Step below. In general, the length of a step is not known a priori and is determined by the Step() algorithm. Each step consists of zero or more unrestricted updates, followed by zero or more discrete updates, followed by (possibly zero-length) continuous time and state advancement, followed by zero or more publishes, and then a call to the monitor() function if one has been defined.
Updates, publishes, and the monitor can report errors or detect a termination condition; that is not shown in the pseudocode below. We follow this policy: - If any unrestricted update event fails, we leave the state unchanged and report failure. We leave unspecified whether the handlers for other simultaneous unrestricted update events are executed or skipped in this case. (That could affect behavior if they have side effects but in any case the state will not be modified.) - Next, if any discrete update event fails, we report failure. In this case the state may have been partially updated; don’t assume it has been left unchanged. We leave unspecified whether the handlers for other simultaneous discrete events are executed. - Next, if any publish event fails, we continue executing the handlers for all simultaneous publish events, and report failure after they have all been executed. The state is returned as updated since publish events can have external consequences based on that updated state. - A “reached termination” status from any event handler permits continued processing of simultaneous events, but doesn’t permit time to advance any further.
The pseudocode will clarify the effects on time and state of each of the update stages above. This algorithm is given a starting Context value
{tₛ, x⁻(tₛ)}
and returns an end Context value{tₑ, x⁻(tₑ)}
, where tₑ is no later than a given tₘₐₓ.Click to expand C++ code...
// Advance the trajectory (time and state) from start value {tₛ, x⁻(tₛ)} to an // end value {tₑ, x⁻(tₑ)}, where tₛ ≤ tₑ ≤ tₘₐₓ. procedure Step(tₛ, x⁻(tₛ), tₘₐₓ) // Update any variables (no restrictions). x*(tₛ) ← DoAnyUnrestrictedUpdates(tₛ, x⁻(tₛ)) // ---------------------------------- // Time and state are at {tₛ, x*(tₛ)} // ---------------------------------- // Update discrete variables. xd⁺(tₛ) ← DoAnyDiscreteUpdates(tₛ, x*(tₛ)) xc⁺(tₛ) ← xc*(tₛ) // These values carry over from x*(tₛ). xa⁺(tₛ) ← xa*(tₛ) // ---------------------------------- // Time and state are at {tₛ, x⁺(tₛ)} // ---------------------------------- // See how far it is safe to integrate without missing any events. tₑᵥₑₙₜ ← CalcNextEventTime(tₛ, x⁺(tₛ)) // Integrate continuous variables forward in time. Integration may terminate // before reaching tₛₜₒₚ due to witnessed events. tₛₜₒₚ ← min(tₑᵥₑₙₜ, tₘₐₓ) tₑ, xc⁻(tₑ) ← Integrate(tₛ, x⁺(tₛ), tₛₜₒₚ) xd⁻(tₑ) ← xd⁺(tₛ) // Discrete values are held from x⁺(tₛ). xa⁻(tₑ) ← xa⁺(tₛ) // ---------------------------------- // Time and state are at {tₑ, x⁻(tₑ)} // ---------------------------------- DoAnyPublishes(tₑ, x⁻(tₑ)) CallMonitor(tₑ, x⁻(tₑ)) return {tₑ, x⁻(tₑ)}
We can use the notation and pseudocode to flesh out the AdvanceTo(), AdvancePendingEvents(), and Initialize() functions. Termination and error conditions detected by event handlers or the monitor are reported as status returns from these methods.
Click to expand C++ code...
// Advance the simulation until time tₘₐₓ. procedure AdvanceTo(tₘₐₓ) → status t ← current_time while t < tₘₐₓ {tₑ, x⁻(tₑ)} ← Step(t, x⁻(t), tₘₐₓ) {t, x⁻(t)} ← {tₑ, x⁻(tₑ)} endwhile // AdvancePendingEvents() is an advanced method, not commonly used. // Perform just the start-of-step update to advance from x⁻(t) to x⁺(t). procedure AdvancePendingEvents() → status t ≜ current_time, x⁻(t) ≜ current_state x⁺(t) ← DoAnyPendingUpdates(t, x⁻(t)) as in Step() x(t) ← x⁺(t) // No continuous update needed. DoAnyPublishes(t, x(t)) CallMonitor(t, x(t)) // Update time and state to {t₀, x⁻(t₀)}, which is the starting value of the // trajectory, and thus the value the Context should contain at the start of the // first simulation step. procedure Initialize(t₀, x₀) → status // Initialization events can be optionally suppressed. x⁺(t₀) ← DoAnyInitializationUpdates as in Step() x⁻(t₀) ← x⁺(t₀) // No continuous update needed. // ---------------------------------- // Time and state are at {t₀, x⁻(t₀)} // ---------------------------------- DoAnyPublishes(t₀, x⁻(t₀)) CallMonitor(t₀, x⁻(t₀))
Initialize() can be viewed as a “0ᵗʰ step” that occurs before the first Step() call as described above. Like Step(), Initialize() first performs pending updates (in this case only initialization events can be “pending”, and even those may be optionally suppressed). Time doesn’t advance so there is no continuous update phase and witnesses cannot trigger. Finally, again like Step(), the initial trajectory point
{t₀, x⁻(t₀)}
is provided to the handlers for any triggered publish events. That includes initialization publish events (if not suppressed), per-step publish events, and periodic or timed publish events that trigger at t₀, followed by a call to the monitor() function if one has been defined (a monitor is semantically identical to a per-step publish).Optionally, initialization events can be suppressed. This can be useful when reusing the simulator over the same system and time span.
Note
This class is templated; see
Simulator_
for the list of instantiations.- __init__(self: pydrake.systems.analysis.Simulator, system: pydrake.systems.framework.System, context: pydrake.systems.framework.Context = None) None
Create a Simulator that can advance a given System through time to produce a trajectory consisting of a sequence of Context values. The System must not have unresolved input ports if the values of those ports are necessary for computations performed during simulation (see class documentation).
The Simulator holds an internal, non-owned reference to the System object so you must ensure that
system
has a longer lifetime than the Simulator. It also owns a compatible Context internally that takes on each of the trajectory values. You may optionally provide a Context that will be used as the initial condition for the simulation; otherwise the Simulator will obtain a default Context fromsystem
.
- AdvancePendingEvents(self: pydrake.systems.analysis.Simulator) pydrake.systems.analysis.SimulatorStatus
(Advanced) Handles discrete and abstract state update events that are pending from the previous AdvanceTo() call, without advancing time. See the Simulator class description for details about how Simulator advances time and handles events. In the terminology used there, this method advances the internal Context from
{t, x⁻(t)}
to{t, x⁺(t)}
.Normally, these update events would be handled at the start of the next AdvanceTo() call, so this method is rarely needed. It can be useful at the end of a simulation or to get intermediate results when you are specifically interested in the
x⁺(t)
result.This method is equivalent to
AdvanceTo(current_time)
, wherecurrent_time=simulator.get_context().get_time())
. If there are no pending events, nothing happens except possibly a final per-step publish call (if enabled) followed by a call to the monitor() function (if one has been provided).- Raises
RuntimeError if any handled event reports failure. –
- Returns
status
: A SimulatorStatus object indicating success, termination, or an error condition as reported by event handlers or the monitor function.
See also
AdvanceTo(), Initialize(), SimulatorStatus
- AdvanceTo(self: pydrake.systems.analysis.Simulator, boundary_time: float, interruptible: bool = True) pydrake.systems.analysis.SimulatorStatus
Advances the System’s trajectory until
boundary_time
is reached in the Context or some other termination condition occurs.We recommend that you call Initialize() prior to making the first call to AdvanceTo(). However, if you don’t it will be called for you the first time that you attempt a step, possibly resulting in unexpected error conditions. See documentation for
Initialize()
for the error conditions it might produce.Warning
You should consider calling Initialize() if you alter the the Context or Simulator options between successive AdvanceTo() calls. See Initialize() for more information.
Note
You can track simulation progress to terminate on arbitrary conditions using a monitor function; see set_monitor().
- Raises
RuntimeError if any handled event reports failure. Other error –
conditions are possible from the System and integrator in use. –
- Parameter
boundary_time
: The maximum time to which the trajectory will be advanced by this call to AdvanceTo(). The method may return earlier if an event or the monitor function requests termination or reports an error condition.
- Parameter
interruptible
: When True, the simulator will check for
KeyboardInterrupt
signals (Ctrl-C) during the call to AdvanceTo(). When False, the AdvanceTo() may or may not be interruptible, depending on what systems and/or monitors have been added to the simulator. The check has a very minor runtime performance cost, so can be disabled by passingFalse
. This is a Python-only parameter (not available in the C++ API).- Returns
status
: A SimulatorStatus object indicating success, termination, or an error condition as reported by event handlers or the monitor function. The time in the context will be set either to the boundary_time or the time a termination or error was first detected.
- Precondition:
The internal Context satisfies all System constraints or will after pending Context updates are performed.
See also
Initialize(), AdvancePendingEvents(), SimulatorStatus, set_monitor()
- clear_monitor(self: pydrake.systems.analysis.Simulator) None
Removes the monitoring function if there is one.
See also
set_monitor()
- get_actual_realtime_rate(self: pydrake.systems.analysis.Simulator) float
Return the rate that simulated time has progressed relative to real time. A return of 1 means the simulation just matched real time, 2 means the simulation was twice as fast as real time, 0.5 means it was running in 2X slow motion, etc.
The value returned here is calculated as follows:
Click to expand C++ code...
simulated_time_now - initial_simulated_time rate = ------------------------------------------- realtime_now - initial_realtime
The
initial
times are recorded when Initialize() or ResetStatistics() is called. The returned rate is undefined if Initialize() has not yet been called.- Returns
The rate achieved since the last Initialize() or ResetStatistics() call.
See also
set_target_realtime_rate()
- get_context(self: pydrake.systems.analysis.Simulator) pydrake.systems.framework.Context
Returns a const reference to the internally-maintained Context holding the most recent step in the trajectory. This is suitable for publishing or extracting information about this trajectory step. Do not call this method if there is no Context.
- get_integrator(self: pydrake.systems.analysis.Simulator) pydrake.systems.analysis.IntegratorBase
Gets a reference to the integrator used to advance the continuous aspects of the system.
- get_monitor(self: pydrake.systems.analysis.Simulator) Callable[[pydrake.systems.framework.Context], pydrake.systems.framework.EventStatus]
Obtains a reference to the monitoring function, which may be empty.
See also
set_monitor()
- get_mutable_context(self: pydrake.systems.analysis.Simulator) pydrake.systems.framework.Context
Returns a mutable reference to the internally-maintained Context holding the most recent step in the trajectory. This is suitable for use in updates, sampling operations, event handlers, and constraint projection. You can also modify this prior to calling Initialize() to set initial conditions. Do not call this method if there is no Context.
- get_mutable_integrator(self: pydrake.systems.analysis.Simulator) pydrake.systems.analysis.IntegratorBase
Gets a reference to the mutable integrator used to advance the continuous state of the system.
- get_num_discrete_updates(self: pydrake.systems.analysis.Simulator) int
Gets the number of effective discrete variable update dispatcher calls since the last Initialize() or ResetStatistics() call. A dispatch is ineffective (not counted) if any of the discrete update events fails or all the discrete update events return “did nothing”. A single dispatcher call may handle multiple discrete update events.
- get_num_publishes(self: pydrake.systems.analysis.Simulator) int
Gets the number of effective publish dispatcher calls made since the last Initialize() or ResetStatistics() call. A dispatch is ineffective (not counted) if any of the publish events fails or all the publish events return “did nothing”. A single dispatcher call may handle multiple publish events.
- get_num_steps_taken(self: pydrake.systems.analysis.Simulator) int
Gets the number of steps since the last Initialize() or ResetStatistics() call. (We’re not counting the Initialize() 0-length “step”.) Note that every AdvanceTo() call can potentially take many steps.
- get_num_unrestricted_updates(self: pydrake.systems.analysis.Simulator) int
Gets the number of effective unrestricted update dispatcher calls since the last Initialize() or ResetStatistics() call. A dispatch is ineffective (not counted) if any of the unrestricted update events fails or all the unrestricted update events return “did nothing”. A single dispatcher call may handle multiple unrestricted update events.
- get_system(self: pydrake.systems.analysis.Simulator) pydrake.systems.framework.System
Gets a constant reference to the system.
Note
a mutable reference is not available.
- get_target_realtime_rate(self: pydrake.systems.analysis.Simulator) float
Return the real time rate target currently in effect. The default is zero, meaning the Simulator runs as fast as possible. You can change the target with set_target_realtime_rate().
- has_context(self: pydrake.systems.analysis.Simulator) bool
Returns
True
if this Simulator has an internally-maintained Context. This is always true unlessreset_context()
has been called.
- Initialize(self: pydrake.systems.analysis.Simulator, params: pydrake.systems.analysis.InitializeParams = InitializeParams(suppress_initialization_events=False)) pydrake.systems.analysis.SimulatorStatus
Prepares the Simulator for a simulation. In order, the sequence of actions taken here is: - The active integrator’s Initialize() method is invoked. - Statistics are reset. - By default, initialization update events are triggered and handled to produce the initial trajectory value
{t₀, x(t₀)}
. If initialization events are suppressed, it is the caller’s responsibility to ensure the desired initial state. - Then that initial value is provided to the handlers for any publish events that have triggered, including initialization events if any, and per-step publish events, periodic or other time-triggered publish events that are scheduled for the initial time t₀, and finally a call to the monitor() function if one has been defined.See the class documentation for more information. We recommend calling Initialize() explicitly prior to beginning a simulation so that error conditions will be discovered early. However, Initialize() will be called automatically by the first AdvanceTo() call if it hasn’t already been called.
Note
If you make a change to the Context or to Simulator options between AdvanceTo() calls you should consider whether to call Initialize() before resuming; AdvanceTo() will not do that automatically for you. Whether to do so depends on whether you want the above initialization operations performed.
Note
In particular, if you changed the time you must call Initialize(). The time-triggered events must be recalculated in case one is due at the new starting time. The AdvanceTo() call will throw an exception if the Initialize() call is missing.
Note
The only way to suppress initialization events is by calling Initialize() explicitly with the
suppress_initialization_events
parameter set. The most common scenario for this is when reusing a Simulator object. In this case, the caller is responsible for ensuring the correctness of the initial state.Warning
Initialize() does not automatically attempt to satisfy System constraints – it is up to you to make sure that constraints are satisfied by the initial conditions.
- Raises
RuntimeError if the combination of options doesn't make sense or –
if any handled event reports failure. Other error conditions are –
possible from the System and integrator in use. –
- Parameter
params
: (optional) a parameter structure (
See also
InitializeParams).
- Returns
status
: A SimulatorStatus object indicating success, termination, or an error condition as reported by event handlers or the monitor function.
See also
AdvanceTo(), AdvancePendingEvents(), SimulatorStatus
- reset_context(self: pydrake.systems.analysis.Simulator, context: pydrake.systems.framework.Context) None
Replace the internally-maintained Context with a different one. The current Context is deleted. This is useful for supplying a new set of initial conditions. You should invoke Initialize() after replacing the Context.
- Parameter
context
: The new context, which may be null. If the context is null, a new context must be set before attempting to step the system forward.
- Parameter
- ResetStatistics(self: pydrake.systems.analysis.Simulator) None
Forget accumulated statistics. Statistics are reset to the values they have post construction or immediately after
Initialize()
.
- set_monitor(self: pydrake.systems.analysis.Simulator, monitor: Callable[[pydrake.systems.framework.Context], Optional[pydrake.systems.framework.EventStatus]]) None
Provides a monitoring function that will be invoked at the end of every step. (See the Simulator class documentation for a precise definition of “step”.) A monitor() function can be used to capture the trajectory, to terminate the simulation, or to detect error conditions. The monitor() function is invoked by the Simulator with a Context whose value is a point along the simulated trajectory. The monitor can be any functor and should capture any System references it needs to operate correctly.
A monitor() function behaves the same as would a per-step Publish event handler included in the top-level System or Diagram being simulated. As in the case of Publish(), the monitor is called at the end of every step taken internally by AdvanceTo(), and also at the end of Initialize() and AdvancePendingEvents(). (See the Simulator class documentation for more detail about what happens when in these methods.) The monitor receives the top-level (root) Context, from which any sub-Context can be obtained using
subsystem.GetMyContextFromRoot()
, provided the necessary subsystem reference has been captured for use in the monitor.** Examples Output time and continuous states whenever the trajectory is advanced:
Click to expand C++ code...
simulator.set_monitor([](const Context<T>& root_context) { std::cout << root_context.get_time() << " " << root_context.get_continuous_state_vector() << std::endl; return EventStatus::Succeeded(); });
Terminate early but successfully on a condition in a subsystem of the System diagram being simulated:
Click to expand C++ code...
simulator.set_monitor([&my_subsystem](const Context<T>& root_context) { const Context<T>& subcontext = my_subsystem.GetMyContextFromRoot(root_context); if (my_subsystem.GoalReached(subcontext)) { return EventStatus::ReachedTermination(my_subsystem, "Simulation achieved the desired goal."); } return EventStatus::Succeeded(); });
In the above case, the Simulator’s AdvanceTo() method will return early when the subsystem reports that it has reached its goal. The returned status will indicate the termination reason, and a human-readable termination message containing the message provided by the monitor can be obtained with status.FormatMessage().
Failure due to plant center of mass falling below a threshold:
Click to expand C++ code...
simulator.set_monitor([&plant](const Context<T>& root_context) { const Context<T>& plant_context = plant.GetMyContextFromRoot(root_context); const Vector3<T> com = plant.CalcCenterOfMassPositionInWorld(plant_context); if (com[2] < 0.1) { // Check z height of com. return EventStatus::Failed(plant, "System fell over."); } return EventStatus::Succeeded(); });
In the above case the Simulator’s AdvanceTo() method will throw an RuntimeError containing a human-readable message including the text provided in the monitor.
Note
monitor() is called every time the trajectory is advanced by a step, which can mean it is called many times during a single AdvanceTo() call.
Note
The presence of a monitor has no effect on the step sizes taken, so a termination or error condition will be discovered only when first observed after a step is complete; it will not be further localized. Use witness-triggered events instead if you need precise isolation.
- set_publish_at_initialization(self: pydrake.systems.analysis.Simulator, publish: bool) None
(To be deprecated) Prefer using initialization or per-step publish events instead.
Sets whether the simulation should trigger a forced-Publish at the end of Initialize(). See set_publish_every_time_step() documentation for more information.
See also
LeafSystem::DeclareInitializationPublishEvent()
See also
LeafSystem::DeclarePerStepPublishEvent()
See also
LeafSystem::DeclareForcedPublishEvent()
- set_publish_every_time_step(self: pydrake.systems.analysis.Simulator, publish: bool) None
(To be deprecated) Prefer using per-step publish events instead.
Sets whether the simulation should trigger a forced-Publish event on the System under simulation at the end of every trajectory-advancing step. Specifically, that means the System::Publish() event dispatcher will be invoked on each subsystem of the System and passed the current Context and a forced-publish Event. If a subsystem has declared a forced-publish event handler, that will be called. Otherwise, nothing will happen.
Enabling this option does not cause a forced-publish to be triggered at initialization; if you want that you should also call
set_publish_at_initialization(true)
. If you want a forced-publish at the end of every step, you will usually also want one at the end of initialization, requiring both options to be enabled.See also
LeafSystem::DeclarePerStepPublishEvent()
See also
LeafSystem::DeclareForcedPublishEvent()
- set_target_realtime_rate(self: pydrake.systems.analysis.Simulator, realtime_rate: float) None
Slow the simulation down to approximately synchronize with real time when it would otherwise run too fast. Normally the Simulator takes steps as quickly as it can. You can request that it slow down to synchronize with real time by providing a realtime rate greater than zero here.
Warning
No guarantees can be made about how accurately the simulation can be made to track real time, even if computation is fast enough. That’s because the system utilities used to implement this do not themselves provide such guarantees. So this is likely to work nicely for visualization purposes where human perception is the only concern. For any other uses you should consider whether approximate real time is adequate for your purposes.
Note
If the full-speed simulation is already slower than real time you can’t speed it up with this call! Instead consider requesting less integration accuracy, using a faster integration method or fixed time step, or using a simpler model.
- Parameter
realtime_rate
: Desired rate relative to real time. Set to 1 to track real time, 2 to run twice as fast as real time, 0.5 for half speed, etc. Zero or negative restores the rate to its default of 0, meaning the simulation will proceed as fast as possible.
- Parameter
- template pydrake.systems.analysis.Simulator_
Instantiations:
Simulator_[float]
,Simulator_[AutoDiffXd]
- class pydrake.systems.analysis.Simulator_[AutoDiffXd]
A class for advancing the state of hybrid dynamic systems, represented by
System<T>
objects, forward in time. Starting with an initial Context for a given System, Simulator advances time and produces a series of Context values that forms a trajectory satisfying the system’s dynamic equations to a specified accuracy. Only the Context is modified by a Simulator; the System is const.A Drake System is a continuous/discrete/hybrid dynamic system where the continuous part is a DAE, that is, it is expected to consist of a set of differential equations and bilateral algebraic constraints. The set of active constraints may change as a result of particular events, such as contact.
Given a current Context, we expect a System to provide us with - derivatives for the continuous differential equations that already satisfy the differentiated form of the constraints (typically, acceleration constraints), - a projection method for least-squares correction of violated higher-level constraints (position and velocity level), - a time-of-next-update method that can be used to adjust the integrator step size in preparation for a discrete update, - methods that can update discrete variables when their update time is reached, - witness (guard) functions for event isolation, - event handlers (reset functions) for making appropriate changes to state and mode variables when an event has been isolated.
The continuous parts of the trajectory are advanced using a numerical integrator. Different integrators have different properties; you can choose the one that is most appropriate for your application or use the default which is adequate for most systems.
<h3>How the simulation is stepped: simulation mechanics for authors of discrete and hybrid systems</h3>
This section is targeted toward users who have created a LeafSystem implementing a discrete or hybrid system. For authors of such systems, it can be useful to understand the simulation details in order to attain the desired state behavior over time. This behavior is dependent on the ordering in which discrete events and continuous updates are processed. (By “discrete events” we mean to include any of Drake’s event handlers.) The basic issues and terminology are introduced in the discrete_systems module; please look there first before proceeding.
As pictured in discrete_systems, when a continuous-time system has discrete events, the state x can have two significant values at the event time t. These are - x⁻(t), the value of x before the discrete update occurs (○ markers), and - x⁺(t), the value of x after the discrete update occurs (● markers).
Thus the value of the Context, which contains both time and state, advances from {t, x⁻(t)} to {t, x⁺(t)} as a result of the update. While those Context values are user-visible, the details of stepping here require an intermediate value which we’ll denote {t, x*(t)}.
Recall that Drake’s state x is partitioned into continuous, discrete, and abstract partitions xc, xd, and xa, so
x = { xc, xd, xa }
. Within a single step, these are updated in three stages: -Unrestricted update (can change x) -
Discrete update (can change only xd) -
Continuous update (changes t and xc)
Where needed, we extend the above notation to xc⁻, xa⁺, etc. to indicate the value of an individual partition at a particular stage of the stepping algorithm.
The following pseudocode uses the above notation to describe the algorithm “Step()” that the Simulator uses to incrementally advance the system trajectory (time t and state x). The Simulator’s AdvanceTo() method will be defined in terms of Step below. In general, the length of a step is not known a priori and is determined by the Step() algorithm. Each step consists of zero or more unrestricted updates, followed by zero or more discrete updates, followed by (possibly zero-length) continuous time and state advancement, followed by zero or more publishes, and then a call to the monitor() function if one has been defined.
Updates, publishes, and the monitor can report errors or detect a termination condition; that is not shown in the pseudocode below. We follow this policy: - If any unrestricted update event fails, we leave the state unchanged and report failure. We leave unspecified whether the handlers for other simultaneous unrestricted update events are executed or skipped in this case. (That could affect behavior if they have side effects but in any case the state will not be modified.) - Next, if any discrete update event fails, we report failure. In this case the state may have been partially updated; don’t assume it has been left unchanged. We leave unspecified whether the handlers for other simultaneous discrete events are executed. - Next, if any publish event fails, we continue executing the handlers for all simultaneous publish events, and report failure after they have all been executed. The state is returned as updated since publish events can have external consequences based on that updated state. - A “reached termination” status from any event handler permits continued processing of simultaneous events, but doesn’t permit time to advance any further.
The pseudocode will clarify the effects on time and state of each of the update stages above. This algorithm is given a starting Context value
{tₛ, x⁻(tₛ)}
and returns an end Context value{tₑ, x⁻(tₑ)}
, where tₑ is no later than a given tₘₐₓ.Click to expand C++ code...
// Advance the trajectory (time and state) from start value {tₛ, x⁻(tₛ)} to an // end value {tₑ, x⁻(tₑ)}, where tₛ ≤ tₑ ≤ tₘₐₓ. procedure Step(tₛ, x⁻(tₛ), tₘₐₓ) // Update any variables (no restrictions). x*(tₛ) ← DoAnyUnrestrictedUpdates(tₛ, x⁻(tₛ)) // ---------------------------------- // Time and state are at {tₛ, x*(tₛ)} // ---------------------------------- // Update discrete variables. xd⁺(tₛ) ← DoAnyDiscreteUpdates(tₛ, x*(tₛ)) xc⁺(tₛ) ← xc*(tₛ) // These values carry over from x*(tₛ). xa⁺(tₛ) ← xa*(tₛ) // ---------------------------------- // Time and state are at {tₛ, x⁺(tₛ)} // ---------------------------------- // See how far it is safe to integrate without missing any events. tₑᵥₑₙₜ ← CalcNextEventTime(tₛ, x⁺(tₛ)) // Integrate continuous variables forward in time. Integration may terminate // before reaching tₛₜₒₚ due to witnessed events. tₛₜₒₚ ← min(tₑᵥₑₙₜ, tₘₐₓ) tₑ, xc⁻(tₑ) ← Integrate(tₛ, x⁺(tₛ), tₛₜₒₚ) xd⁻(tₑ) ← xd⁺(tₛ) // Discrete values are held from x⁺(tₛ). xa⁻(tₑ) ← xa⁺(tₛ) // ---------------------------------- // Time and state are at {tₑ, x⁻(tₑ)} // ---------------------------------- DoAnyPublishes(tₑ, x⁻(tₑ)) CallMonitor(tₑ, x⁻(tₑ)) return {tₑ, x⁻(tₑ)}
We can use the notation and pseudocode to flesh out the AdvanceTo(), AdvancePendingEvents(), and Initialize() functions. Termination and error conditions detected by event handlers or the monitor are reported as status returns from these methods.
Click to expand C++ code...
// Advance the simulation until time tₘₐₓ. procedure AdvanceTo(tₘₐₓ) → status t ← current_time while t < tₘₐₓ {tₑ, x⁻(tₑ)} ← Step(t, x⁻(t), tₘₐₓ) {t, x⁻(t)} ← {tₑ, x⁻(tₑ)} endwhile // AdvancePendingEvents() is an advanced method, not commonly used. // Perform just the start-of-step update to advance from x⁻(t) to x⁺(t). procedure AdvancePendingEvents() → status t ≜ current_time, x⁻(t) ≜ current_state x⁺(t) ← DoAnyPendingUpdates(t, x⁻(t)) as in Step() x(t) ← x⁺(t) // No continuous update needed. DoAnyPublishes(t, x(t)) CallMonitor(t, x(t)) // Update time and state to {t₀, x⁻(t₀)}, which is the starting value of the // trajectory, and thus the value the Context should contain at the start of the // first simulation step. procedure Initialize(t₀, x₀) → status // Initialization events can be optionally suppressed. x⁺(t₀) ← DoAnyInitializationUpdates as in Step() x⁻(t₀) ← x⁺(t₀) // No continuous update needed. // ---------------------------------- // Time and state are at {t₀, x⁻(t₀)} // ---------------------------------- DoAnyPublishes(t₀, x⁻(t₀)) CallMonitor(t₀, x⁻(t₀))
Initialize() can be viewed as a “0ᵗʰ step” that occurs before the first Step() call as described above. Like Step(), Initialize() first performs pending updates (in this case only initialization events can be “pending”, and even those may be optionally suppressed). Time doesn’t advance so there is no continuous update phase and witnesses cannot trigger. Finally, again like Step(), the initial trajectory point
{t₀, x⁻(t₀)}
is provided to the handlers for any triggered publish events. That includes initialization publish events (if not suppressed), per-step publish events, and periodic or timed publish events that trigger at t₀, followed by a call to the monitor() function if one has been defined (a monitor is semantically identical to a per-step publish).Optionally, initialization events can be suppressed. This can be useful when reusing the simulator over the same system and time span.
- __init__(self: pydrake.systems.analysis.Simulator_[AutoDiffXd], system: pydrake.systems.framework.System_[AutoDiffXd], context: pydrake.systems.framework.Context_[AutoDiffXd] = None) None
Create a Simulator that can advance a given System through time to produce a trajectory consisting of a sequence of Context values. The System must not have unresolved input ports if the values of those ports are necessary for computations performed during simulation (see class documentation).
The Simulator holds an internal, non-owned reference to the System object so you must ensure that
system
has a longer lifetime than the Simulator. It also owns a compatible Context internally that takes on each of the trajectory values. You may optionally provide a Context that will be used as the initial condition for the simulation; otherwise the Simulator will obtain a default Context fromsystem
.
- AdvancePendingEvents(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) pydrake.systems.analysis.SimulatorStatus
(Advanced) Handles discrete and abstract state update events that are pending from the previous AdvanceTo() call, without advancing time. See the Simulator class description for details about how Simulator advances time and handles events. In the terminology used there, this method advances the internal Context from
{t, x⁻(t)}
to{t, x⁺(t)}
.Normally, these update events would be handled at the start of the next AdvanceTo() call, so this method is rarely needed. It can be useful at the end of a simulation or to get intermediate results when you are specifically interested in the
x⁺(t)
result.This method is equivalent to
AdvanceTo(current_time)
, wherecurrent_time=simulator.get_context().get_time())
. If there are no pending events, nothing happens except possibly a final per-step publish call (if enabled) followed by a call to the monitor() function (if one has been provided).- Raises
RuntimeError if any handled event reports failure. –
- Returns
status
: A SimulatorStatus object indicating success, termination, or an error condition as reported by event handlers or the monitor function.
See also
AdvanceTo(), Initialize(), SimulatorStatus
- AdvanceTo(self: pydrake.systems.analysis.Simulator_[AutoDiffXd], boundary_time: pydrake.autodiffutils.AutoDiffXd, interruptible: bool = True) pydrake.systems.analysis.SimulatorStatus
Advances the System’s trajectory until
boundary_time
is reached in the Context or some other termination condition occurs.We recommend that you call Initialize() prior to making the first call to AdvanceTo(). However, if you don’t it will be called for you the first time that you attempt a step, possibly resulting in unexpected error conditions. See documentation for
Initialize()
for the error conditions it might produce.Warning
You should consider calling Initialize() if you alter the the Context or Simulator options between successive AdvanceTo() calls. See Initialize() for more information.
Note
You can track simulation progress to terminate on arbitrary conditions using a monitor function; see set_monitor().
- Raises
RuntimeError if any handled event reports failure. Other error –
conditions are possible from the System and integrator in use. –
- Parameter
boundary_time
: The maximum time to which the trajectory will be advanced by this call to AdvanceTo(). The method may return earlier if an event or the monitor function requests termination or reports an error condition.
- Parameter
interruptible
: When True, the simulator will check for
KeyboardInterrupt
signals (Ctrl-C) during the call to AdvanceTo(). When False, the AdvanceTo() may or may not be interruptible, depending on what systems and/or monitors have been added to the simulator. The check has a very minor runtime performance cost, so can be disabled by passingFalse
. This is a Python-only parameter (not available in the C++ API).- Returns
status
: A SimulatorStatus object indicating success, termination, or an error condition as reported by event handlers or the monitor function. The time in the context will be set either to the boundary_time or the time a termination or error was first detected.
- Precondition:
The internal Context satisfies all System constraints or will after pending Context updates are performed.
See also
Initialize(), AdvancePendingEvents(), SimulatorStatus, set_monitor()
- clear_monitor(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) None
Removes the monitoring function if there is one.
See also
set_monitor()
- get_actual_realtime_rate(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) float
Return the rate that simulated time has progressed relative to real time. A return of 1 means the simulation just matched real time, 2 means the simulation was twice as fast as real time, 0.5 means it was running in 2X slow motion, etc.
The value returned here is calculated as follows:
Click to expand C++ code...
simulated_time_now - initial_simulated_time rate = ------------------------------------------- realtime_now - initial_realtime
The
initial
times are recorded when Initialize() or ResetStatistics() is called. The returned rate is undefined if Initialize() has not yet been called.- Returns
The rate achieved since the last Initialize() or ResetStatistics() call.
See also
set_target_realtime_rate()
- get_context(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) pydrake.systems.framework.Context_[AutoDiffXd]
Returns a const reference to the internally-maintained Context holding the most recent step in the trajectory. This is suitable for publishing or extracting information about this trajectory step. Do not call this method if there is no Context.
- get_integrator(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]
Gets a reference to the integrator used to advance the continuous aspects of the system.
- get_monitor(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) Callable[[pydrake.systems.framework.Context_[AutoDiffXd]], pydrake.systems.framework.EventStatus]
Obtains a reference to the monitoring function, which may be empty.
See also
set_monitor()
- get_mutable_context(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) pydrake.systems.framework.Context_[AutoDiffXd]
Returns a mutable reference to the internally-maintained Context holding the most recent step in the trajectory. This is suitable for use in updates, sampling operations, event handlers, and constraint projection. You can also modify this prior to calling Initialize() to set initial conditions. Do not call this method if there is no Context.
- get_mutable_integrator(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) pydrake.systems.analysis.IntegratorBase_[AutoDiffXd]
Gets a reference to the mutable integrator used to advance the continuous state of the system.
- get_num_discrete_updates(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) int
Gets the number of effective discrete variable update dispatcher calls since the last Initialize() or ResetStatistics() call. A dispatch is ineffective (not counted) if any of the discrete update events fails or all the discrete update events return “did nothing”. A single dispatcher call may handle multiple discrete update events.
- get_num_publishes(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) int
Gets the number of effective publish dispatcher calls made since the last Initialize() or ResetStatistics() call. A dispatch is ineffective (not counted) if any of the publish events fails or all the publish events return “did nothing”. A single dispatcher call may handle multiple publish events.
- get_num_steps_taken(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) int
Gets the number of steps since the last Initialize() or ResetStatistics() call. (We’re not counting the Initialize() 0-length “step”.) Note that every AdvanceTo() call can potentially take many steps.
- get_num_unrestricted_updates(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) int
Gets the number of effective unrestricted update dispatcher calls since the last Initialize() or ResetStatistics() call. A dispatch is ineffective (not counted) if any of the unrestricted update events fails or all the unrestricted update events return “did nothing”. A single dispatcher call may handle multiple unrestricted update events.
- get_system(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) pydrake.systems.framework.System_[AutoDiffXd]
Gets a constant reference to the system.
Note
a mutable reference is not available.
- get_target_realtime_rate(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) float
Return the real time rate target currently in effect. The default is zero, meaning the Simulator runs as fast as possible. You can change the target with set_target_realtime_rate().
- has_context(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) bool
Returns
True
if this Simulator has an internally-maintained Context. This is always true unlessreset_context()
has been called.
- Initialize(self: pydrake.systems.analysis.Simulator_[AutoDiffXd], params: pydrake.systems.analysis.InitializeParams = InitializeParams(suppress_initialization_events=False)) pydrake.systems.analysis.SimulatorStatus
Prepares the Simulator for a simulation. In order, the sequence of actions taken here is: - The active integrator’s Initialize() method is invoked. - Statistics are reset. - By default, initialization update events are triggered and handled to produce the initial trajectory value
{t₀, x(t₀)}
. If initialization events are suppressed, it is the caller’s responsibility to ensure the desired initial state. - Then that initial value is provided to the handlers for any publish events that have triggered, including initialization events if any, and per-step publish events, periodic or other time-triggered publish events that are scheduled for the initial time t₀, and finally a call to the monitor() function if one has been defined.See the class documentation for more information. We recommend calling Initialize() explicitly prior to beginning a simulation so that error conditions will be discovered early. However, Initialize() will be called automatically by the first AdvanceTo() call if it hasn’t already been called.
Note
If you make a change to the Context or to Simulator options between AdvanceTo() calls you should consider whether to call Initialize() before resuming; AdvanceTo() will not do that automatically for you. Whether to do so depends on whether you want the above initialization operations performed.
Note
In particular, if you changed the time you must call Initialize(). The time-triggered events must be recalculated in case one is due at the new starting time. The AdvanceTo() call will throw an exception if the Initialize() call is missing.
Note
The only way to suppress initialization events is by calling Initialize() explicitly with the
suppress_initialization_events
parameter set. The most common scenario for this is when reusing a Simulator object. In this case, the caller is responsible for ensuring the correctness of the initial state.Warning
Initialize() does not automatically attempt to satisfy System constraints – it is up to you to make sure that constraints are satisfied by the initial conditions.
- Raises
RuntimeError if the combination of options doesn't make sense or –
if any handled event reports failure. Other error conditions are –
possible from the System and integrator in use. –
- Parameter
params
: (optional) a parameter structure (
See also
InitializeParams).
- Returns
status
: A SimulatorStatus object indicating success, termination, or an error condition as reported by event handlers or the monitor function.
See also
AdvanceTo(), AdvancePendingEvents(), SimulatorStatus
- reset_context(self: pydrake.systems.analysis.Simulator_[AutoDiffXd], context: pydrake.systems.framework.Context_[AutoDiffXd]) None
Replace the internally-maintained Context with a different one. The current Context is deleted. This is useful for supplying a new set of initial conditions. You should invoke Initialize() after replacing the Context.
- Parameter
context
: The new context, which may be null. If the context is null, a new context must be set before attempting to step the system forward.
- Parameter
- ResetStatistics(self: pydrake.systems.analysis.Simulator_[AutoDiffXd]) None
Forget accumulated statistics. Statistics are reset to the values they have post construction or immediately after
Initialize()
.
- set_monitor(self: pydrake.systems.analysis.Simulator_[AutoDiffXd], monitor: Callable[[pydrake.systems.framework.Context_[AutoDiffXd]], Optional[pydrake.systems.framework.EventStatus]]) None
Provides a monitoring function that will be invoked at the end of every step. (See the Simulator class documentation for a precise definition of “step”.) A monitor() function can be used to capture the trajectory, to terminate the simulation, or to detect error conditions. The monitor() function is invoked by the Simulator with a Context whose value is a point along the simulated trajectory. The monitor can be any functor and should capture any System references it needs to operate correctly.
A monitor() function behaves the same as would a per-step Publish event handler included in the top-level System or Diagram being simulated. As in the case of Publish(), the monitor is called at the end of every step taken internally by AdvanceTo(), and also at the end of Initialize() and AdvancePendingEvents(). (See the Simulator class documentation for more detail about what happens when in these methods.) The monitor receives the top-level (root) Context, from which any sub-Context can be obtained using
subsystem.GetMyContextFromRoot()
, provided the necessary subsystem reference has been captured for use in the monitor.** Examples Output time and continuous states whenever the trajectory is advanced:
Click to expand C++ code...
simulator.set_monitor([](const Context<T>& root_context) { std::cout << root_context.get_time() << " " << root_context.get_continuous_state_vector() << std::endl; return EventStatus::Succeeded(); });
Terminate early but successfully on a condition in a subsystem of the System diagram being simulated:
Click to expand C++ code...
simulator.set_monitor([&my_subsystem](const Context<T>& root_context) { const Context<T>& subcontext = my_subsystem.GetMyContextFromRoot(root_context); if (my_subsystem.GoalReached(subcontext)) { return EventStatus::ReachedTermination(my_subsystem, "Simulation achieved the desired goal."); } return EventStatus::Succeeded(); });
In the above case, the Simulator’s AdvanceTo() method will return early when the subsystem reports that it has reached its goal. The returned status will indicate the termination reason, and a human-readable termination message containing the message provided by the monitor can be obtained with status.FormatMessage().
Failure due to plant center of mass falling below a threshold:
Click to expand C++ code...
simulator.set_monitor([&plant](const Context<T>& root_context) { const Context<T>& plant_context = plant.GetMyContextFromRoot(root_context); const Vector3<T> com = plant.CalcCenterOfMassPositionInWorld(plant_context); if (com[2] < 0.1) { // Check z height of com. return EventStatus::Failed(plant, "System fell over."); } return EventStatus::Succeeded(); });
In the above case the Simulator’s AdvanceTo() method will throw an RuntimeError containing a human-readable message including the text provided in the monitor.
Note
monitor() is called every time the trajectory is advanced by a step, which can mean it is called many times during a single AdvanceTo() call.
Note
The presence of a monitor has no effect on the step sizes taken, so a termination or error condition will be discovered only when first observed after a step is complete; it will not be further localized. Use witness-triggered events instead if you need precise isolation.
- set_publish_at_initialization(self: pydrake.systems.analysis.Simulator_[AutoDiffXd], publish: bool) None
(To be deprecated) Prefer using initialization or per-step publish events instead.
Sets whether the simulation should trigger a forced-Publish at the end of Initialize(). See set_publish_every_time_step() documentation for more information.
See also
LeafSystem::DeclareInitializationPublishEvent()
See also
LeafSystem::DeclarePerStepPublishEvent()
See also
LeafSystem::DeclareForcedPublishEvent()
- set_publish_every_time_step(self: pydrake.systems.analysis.Simulator_[AutoDiffXd], publish: bool) None
(To be deprecated) Prefer using per-step publish events instead.
Sets whether the simulation should trigger a forced-Publish event on the System under simulation at the end of every trajectory-advancing step. Specifically, that means the System::Publish() event dispatcher will be invoked on each subsystem of the System and passed the current Context and a forced-publish Event. If a subsystem has declared a forced-publish event handler, that will be called. Otherwise, nothing will happen.
Enabling this option does not cause a forced-publish to be triggered at initialization; if you want that you should also call
set_publish_at_initialization(true)
. If you want a forced-publish at the end of every step, you will usually also want one at the end of initialization, requiring both options to be enabled.See also
LeafSystem::DeclarePerStepPublishEvent()
See also
LeafSystem::DeclareForcedPublishEvent()
- set_target_realtime_rate(self: pydrake.systems.analysis.Simulator_[AutoDiffXd], realtime_rate: float) None
Slow the simulation down to approximately synchronize with real time when it would otherwise run too fast. Normally the Simulator takes steps as quickly as it can. You can request that it slow down to synchronize with real time by providing a realtime rate greater than zero here.
Warning
No guarantees can be made about how accurately the simulation can be made to track real time, even if computation is fast enough. That’s because the system utilities used to implement this do not themselves provide such guarantees. So this is likely to work nicely for visualization purposes where human perception is the only concern. For any other uses you should consider whether approximate real time is adequate for your purposes.
Note
If the full-speed simulation is already slower than real time you can’t speed it up with this call! Instead consider requesting less integration accuracy, using a faster integration method or fixed time step, or using a simpler model.
- Parameter
realtime_rate
: Desired rate relative to real time. Set to 1 to track real time, 2 to run twice as fast as real time, 0.5 for half speed, etc. Zero or negative restores the rate to its default of 0, meaning the simulation will proceed as fast as possible.
- Parameter
- class pydrake.systems.analysis.SimulatorConfig
The set of all configurable properties on a Simulator and IntegratorBase.
- __init__(self: pydrake.systems.analysis.SimulatorConfig, **kwargs) None
- property accuracy
- property integration_scheme
- property max_step_size
- property publish_every_time_step
Sets Simulator::set_publish_at_initialization() in addition to Simulator::set_publish_every_time_step() when applied by ApplySimulatorConfig().
- property target_realtime_rate
- property use_error_control
- class pydrake.systems.analysis.SimulatorStatus
Holds the status return value from a call to Simulator::AdvanceTo() and related methods. The argument t to AdvanceTo(t) is called the boundary time, and represents the maximum time to which the simulation trajectory will be advanced by a call to AdvanceTo(). (For methods that don’t advance time, the current time is considered to be the boundary time.) A normal, successful return means that simulated time advanced successfully to the boundary time, without encountering a termination condition or error condition. AdvanceTo() may return earlier than the boundary time if one of those conditions is encountered. In that case the return object holds a reference to the subsystem that detected the condition and a human-friendly message from that subsystem that hopefully explains what happened.
- __init__(*args, **kwargs)
- boundary_time(self: pydrake.systems.analysis.SimulatorStatus) float
Returns the maximum time we could have reached with this call; whether we actually got there depends on the status. This is the time supplied in an AdvanceTo() call or the current time for methods that don’t advance time, that is, Initialize() and AdvancePendingEvents().
- FormatMessage(self: pydrake.systems.analysis.SimulatorStatus) str
Returns a human-readable message explaining the return result.
- IsIdenticalStatus(self: pydrake.systems.analysis.SimulatorStatus, other: pydrake.systems.analysis.SimulatorStatus) bool
Returns true if the
other
status contains exactly the same information asthis
status. This is likely only useful for unit testing of SimulatorStatus.
- message(self: pydrake.systems.analysis.SimulatorStatus) str
For termination or error conditions, returns a human-readable message explaining what happened. This is the message from the subsystem that detected the condition. FormatMessage() returns additional information and also includes this message.
- reason(self: pydrake.systems.analysis.SimulatorStatus) pydrake.systems.analysis.SimulatorStatus.ReturnReason
Returns the reason that a Simulator call returned.
- return_time(self: pydrake.systems.analysis.SimulatorStatus) float
Returns the time that was actually reached. This will be boundary_time() if succeeded() returns true. Otherwise it is the time at which a termination or error condition was detected and may be earlier than boundary_time().
- class ReturnReason
Members:
kReachedBoundaryTime : This is the normal return: no termination or error condition was
encountered before reaching the boundary time. There is no message and no saved System.
kReachedTerminationCondition : An event handler or monitor function returned with a “reached
termination condition” EventStatus (has message with details). For AdvanceTo() the return time may be earlier than the boundary time.
kEventHandlerFailed : An event handler or monitor function returned with a “failed”
EventStatus (has message with details). For AdvanceTo() the return time may be earlier than the boundary time.
- __init__(self: pydrake.systems.analysis.SimulatorStatus.ReturnReason, value: int) None
- kEventHandlerFailed = <ReturnReason.kEventHandlerFailed: 2>
- kReachedBoundaryTime = <ReturnReason.kReachedBoundaryTime: 0>
- kReachedTerminationCondition = <ReturnReason.kReachedTerminationCondition: 1>
- property name
- property value
- succeeded(self: pydrake.systems.analysis.SimulatorStatus) bool
Returns true if we reached the boundary time with no surprises.
- system(self: pydrake.systems.analysis.SimulatorStatus) pydrake.systems.framework.SystemBase
Optionally, returns the subsystem to which the status and contained message should be attributed. May be nullptr in which case the status should be attributed to the System as a whole.