DiscreteControlLoopSimulator¶
Bases: BaseSimulator
Closed-loop simulator: simulate, observe, filter, and decide controls online.
Unlike DiscreteTimeSimulator, which requires the entire control
trajectory as a pre-supplied ctrl_values array, DiscreteControlLoopSimulator
computes each \(u_k\) online from the current belief via control_policy.
Which control an observation sees is set by the model's
dynamics.observation_control_alignment -- the same field that governs
open-loop simulation.
With convention "previous_transition", the control \(u_k\) is chosen
after seeing the observation \(y_k\) (which uses the previous control). The
policy therefore sees the filtered belief \(\hat p_k\). This is the only
convention the filtered closed loop supports for now, and it is what an
unspecified (None) field resolves to, with a warning.
With convention "same_time", the control \(u_k\) would be chosen before
seeing the observation \(y_k\) it drives, so the policy would see the
predicted belief \(\tilde p_k\). That needs separate prediction and analysis
filter steps, which cuthbert does not expose; an explicit "same_time"
raises NotImplementedError until they are built.
Both loops are written out in full on the Closed-loop control page.
With use_true_state=True the loop skips filtering altogether and hands
the policy the true state \(x_k\). Both conventions run.
The one-step filter update runs on the cuthbert backend
(filter_source="cuthbert"). See the
filters page
for the available filters, and build_cuthbert_filter in
discrete_filter.py
for which of them the online update supports. Plated controlled simulation
is not yet supported; see
Issue #318.
Attributes:
| Name | Type | Description |
|---|---|---|
control_policy |
Control policy \(\pi\); see |
|
filter_config |
Selects the filtering algorithm; any config
|
|
use_true_state |
Give the policy the true state \(x_k\) instead of a
filtered belief, and run no filter at all. Defaults to |
|
n_simulations |
int
|
Currently only |
simulate(dynamics: DynamicalModel, *, rng_key: PRNGKeyArray, ctrl_times: Real[Array, ' ctrl_time'] | None = None, ctrl_values: Real[Array, 'ctrl_time control_dim'] | Real[Array, ' ctrl_time'] | None = None, predict_times: Real[Array, ' predict_time'] | None = None, initial_policy_state: PyTree | None = None, **kwargs: Any) -> ControlledSimulatedResult
¶
Simulate one online controlled trajectory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dynamics
|
DynamicalModel
|
Discrete-time dynamical model. |
required |
rng_key
|
PRNGKeyArray
|
Root key for environment and fallback filter randomness. |
required |
ctrl_times
|
Real[Array, ' ctrl_time'] | None
|
Unsupported because controls are selected online. |
None
|
ctrl_values
|
Real[Array, 'ctrl_time control_dim'] | Real[Array, ' ctrl_time'] | None
|
Unsupported because controls are selected online. |
None
|
predict_times
|
Real[Array, ' predict_time'] | None
|
Strictly increasing simulation times. |
None
|
initial_policy_state
|
PyTree | None
|
Initial state passed to |
None
|
**kwargs
|
Any
|
Additional shared simulator-handler metadata, ignored here. |
{}
|
Returns:
| Type | Description |
|---|---|
ControlledSimulatedResult
|
States, observations, controls, filtered beliefs and policy states |
ControlledSimulatedResult
|
on all |
ControlledSimulatedResult
|
Under the |
ControlledSimulatedResult
|
Under the |
Raises:
| Type | Description |
|---|---|
ValueError
|
If inputs are incompatible with online discrete control. |
NotImplementedError
|
If the requested simulation mode is unsupported,
including an explicit |
Warns:
| Type | Description |
|---|---|
UserWarning
|
If |
ControlledSimulatedResult¶
Bases: SimulatedResult
SimulatedResult extended with the control loop's extra outputs.
Registered as deterministic sites the same generic way as
SimulatedResult's own fields.
Both conventions return \(N+1\) states and \(N\) controls, so the array
lengths alone do not say which one ran: consult obs_times,
which is \([t_0, \dots, t_{N-1}]\) under "same_time" and
\([t_1, \dots, t_N]\) under "previous_transition".
unflatten(layout: LayoutCollection) -> StructuredControlledSimulatedResult
¶
Return a structured copy of this result.
Converts fields as
SimulatedResult.unflatten
does. filtered_states_mean is converted by layout.state, and
policy_states is copied unchanged.
StructuredControlledSimulatedResult¶
Bases: StructuredSimulatedResult
A ControlledSimulatedResult with structured values.
Returned by ControlledSimulatedResult.unflatten. filtered_states_mean
shares the structure of the state fields; policy_states is unchanged.
flatten(layout) converts back to a ControlledSimulatedResult.
flatten(layout: LayoutCollection) -> ControlledSimulatedResult
¶
Return the flat result that unflatten(layout) converted.
layout must be the LayoutCollection passed to unflatten.
Raises ValueError if a structured field has no sublayout.