Robustness, Calibration, and Safe Control › Risk-Sensitive and Constrained Planning

Michael BrenndoerferAugust 7, 202613 min read
World Models HandbookAll chapters
Part 12 of 12Reliable World Models
Chapter 68Robustness, Calibration, and Safe Control › Risk-Sensitive and Constrained Planning
Reading section 4 of 8 · Risk-Sensitive and Constrained Planning · 13 minSection 4 of 8 · 13 min

Book contents

Section 4 of 8 · 13 min read

Robustness, Calibration, and Safe Control › Risk-Sensitive and Constrained PlanningOne section · Sections in this chapter4 / 8 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Everything so far has been about the model. Now we change the objective. Minimizing expected cost is risk-neutral with respect to that cost: a certain cost of 10 and an equally likely cost of 0 or 20 have the same expectation. A point prediction does not force risk neutrality; a controller can still use conservative margins, robust constraints, or nonlinear costs. A predictive distribution permits explicit tail objectives, whose suitability depends on the application's losses and requirements.

Two families of alternatives recur in practice:

  • Risk-sensitive objectives use a tail-sensitive functional. For integrable costs, CVaR at level α\alpha averages the worst (1−α)(1-\alpha) probability mass, using fractional boundary mass when necessary. It approaches expected cost as α\alpha decreases to zero; near one it emphasizes increasingly extreme upper-tail costs. Here α=0.75\alpha=0.75 selects the worst quarter.
  • Constrained objectives separate feasibility requirements from performance. A pointwise constraint limits predicted states; a chance constraint such as Pr⁡[∣p∣>pmax⁡]≤δ\Pr[|p|>p_{\max}]\le\delta imposes a hard bound on violation probability, not a promise that every realized state stays inside. The objective can itself be expected cost or a risk-sensitive functional.

The expected-cost objective summarizes average loss; CVaR summarizes a chosen upper tail. These answer different questions. Expected cost can penalize rare failures heavily if their assigned loss is large, and a hard constraint can reject them without CVaR. Conversely, minimizing CVaR can still permit a safety violation if it improves the chosen tail objective. Specify safety requirements separately from performance preferences.

Where the distribution comes from

A risk-sensitive planner needs a distribution of outcomes for a candidate action sequence, not a single rollout. Several sources are available, and they are not equivalent:

  • Ensemble members as samples. Run the candidate sequence through each member. This uses variation between fitted models as an approximation to epistemic uncertainty, i.e., uncertainty about the model fit. Its quality depends on both coverage of plausible dynamics and the weights assigned to members; bootstrap ensembles do not by themselves guarantee calibrated tail probabilities. See Part VIII: Decision-Centric Research Lineages for the lineage.
  • Residual-noise propagation. Add sampled process noise to each member's predicted transition. In this toy plant, position and velocity noise innovations satisfy ϵt(p)=Δt ϵt(v)\epsilon_t^{(p)}=\Delta t\,\epsilon_t^{(v)}, so they must not be sampled independently. This relation concerns the noise contributions, not the full state increments. Combining model fits with this noise defines an approximate rollout distribution; one-step calibration does not validate its multi-step joint distribution.
  • Scenario evaluation. Evaluate explicit parameter and disturbance choices. A finite scenario set is inspectable, but checking it does not prove safety for unsampled conditions. Scenario-optimization guarantees require additional sampling, optimization, and support assumptions; merely naming a chosen schedule worst case supplies none.

The code combines alternative fitted models with residual-noise draws. It does not explicitly add total predictive variance on top of ensemble variation. Nevertheless, held-out residual variance can itself include fitting error, so this construction is not a decomposition into independent uncertainty sources. Its joint rollout spread requires validation; over- or under-dispersion and missed model families can affect planning.

Conditional value at risk

For a random cost CC with E∣C∣<∞\mathbb E|C|<\infty and α∈(0,1)\alpha\in(0,1), CVaR has the threshold representation

CVaRα(C)=min⁡τ{τ+11−αE[(C−τ)+]}.\mathrm{CVaR}_\alpha(C) = \min_{\tau} \left\{ \tau + \frac{1}{1-\alpha} \mathbb{E}\left[(C - \tau)^+ \right] \right\}.

where:

  • CC: the random episode cost
  • α∈(0,1)\alpha \in (0,1): the confidence level, where 1−α1-\alpha is the fraction of the distribution treated as the tail
  • τ\tau: a scalar threshold; an α\alpha-quantile is a minimizer, with possible non-uniqueness for discrete distributions
  • (C−τ)+=max⁡(C−τ,0)(C - \tau)^+ = \max(C - \tau, 0): the positive part, counting only how far each outcome exceeds the threshold

The expression includes the threshold itself plus scaled expected excess. It is convex in τ\tau but generally non-smooth. Pointwise convex loss in controller parameters together with a parameter-independent sampling law is sufficient for convexity of CVaR in those parameters, not necessary in every instance. Nonlinear learned rollouts provide no such guarantee automatically. See Rockafellar and Uryasev's general-loss treatment.

For equal-weight samples, sort costs in descending order, D1≥⋯≥DSD_1\ge\cdots\ge D_S. Let m=(1−α)Sm=(1-\alpha)S, q=⌊m⌋q=\lfloor m\rfloor, and r=m−qr=m-q. The exact empirical-distribution CVaR includes fractional boundary mass:

CVaR^α(C)=∑k=1qDk+rDq+1m.\widehat{\mathrm{CVaR}}_\alpha(C)=\frac{\sum_{k=1}^{q}D_k+rD_{q+1}}{m}.

When mm is an integer, average the largest mm values and omit the boundary term entirely. Otherwise the next value contributes fraction rr. This also avoids indexing past the array when floating-point arithmetic rounds mm to SS at a tiny positive α\alpha. Averaging the largest ⌈m⌉\lceil m\rceil values is generally an approximation. At S=18S=18 and α=0.75\alpha=0.75, four costs contribute fully and the fifth contributes half. Such a small effective tail sample is noisy; evaluate selected controllers independently of the search samples.

The running environment already includes Gaussian process noise. We now add a soft envelope penalty to stage cost when ∣p∣|p| exceeds a chosen threshold. This can amplify expensive excursions, but it is not a control barrier function or a hard constraint. Quadratic costs can also have substantial tails, and neither this penalty nor CVaR guarantees different actions or improved realized tail costs. The experiment measures those outcomes rather than assuming them.

The distinction between averaging across all outcomes and averaging across the worst outcomes is easiest to see directly on a cost distribution. The cell below draws a right-skewed set of synthetic episode costs and computes both summaries, using the same sample estimator the planner optimizes.

In[20]:
Code
# A synthetic right-skewed cost distribution, used only to make the CVaR idea
# concrete. The seed is fixed so the figure is reproducible.
CVAR_RNG = np.random.default_rng(31337)
COST_SAMPLES = CVAR_RNG.lognormal(mean=0.30, sigma=0.60, size=4000)

CVAR_ALPHA = 0.75
cost_expectation = float(COST_SAMPLES.mean())
cvar_k = max(1, int(np.ceil((1.0 - CVAR_ALPHA) * COST_SAMPLES.size)))
cost_cvar = float(np.sort(COST_SAMPLES)[-cvar_k:].mean())
cost_tail_cut = float(np.quantile(COST_SAMPLES, CVAR_ALPHA))
Out[21]:
Visualization
Histogram of synthetic costs with expectation and CVaR lines marked.
Histogram of a right-skewed synthetic distribution of episode costs, with the expectation and the conditional value at risk marked as vertical lines. The expectation lands near the bulk of the distribution, while the CVaR averages only the worst quarter and sits well into the tail that a safety objective cares about, making concrete how a tail-sensitive objective differs from an average one.
In[22]:
Code
SOFT_LIMIT = 0.50
BARRIER_WEIGHT = 5.0
W_P, W_V, W_U = 1.0, 0.05, 0.01

W_STACK = np.stack([W for W, _ in members])  # (M, F, 2)
M_MODELS, F_FEAT = W_STACK.shape[0], W_STACK.shape[1]


def plan(
    state,
    rng_,
    mode="mean",
    horizon=8,
    n_cand=128,
    n_draws=2,
    cvar_alpha=0.75,
    u_max=U_VALID,
    return_sequence=False,
):
    """Random-shooting MPC. Return the first action, or the selected sequence."""
    if mode not in ("mean", "cvar"):
        raise ValueError("mode must be mean or cvar")
    for name, value in (
        ("horizon", horizon),
        ("n_cand", n_cand),
        ("n_draws", n_draws),
    ):
        if (
            isinstance(value, (bool, np.bool_))
            or not isinstance(value, (int, np.integer))
            or value <= 0
        ):
            raise ValueError(f"{name} must be a positive integer")
    if not 0.0 < cvar_alpha < 1.0:
        raise ValueError(
            "CVaR confidence level must be strictly between zero and one"
        )
    S = M_MODELS * n_draws
    W_rows = W_STACK[np.arange(S) % M_MODELS]
    A = rng_.uniform(-u_max, u_max, size=(horizon, n_cand))
    s = np.tile(np.asarray(state, dtype=float), (S, n_cand, 1))
    costs = np.zeros((S, n_cand))
    for t in range(horizon):
        u = np.broadcast_to(A[t], (S, n_cand))
        Phi = features(
            np.column_stack([s[:, :, 0].ravel(), s[:, :, 1].ravel(), u.ravel()])
        )
        delta = np.einsum(
            "snf,sfj->snj", Phi.reshape(S, n_cand, F_FEAT), W_rows
        )
        # A velocity innovation also shifts position by DT times that innovation.
        noise_v = rng_.normal(0.0, np.sqrt(ALEATORIC[1]), size=(S, n_cand))
        delta = delta + np.stack([DT * noise_v, noise_v], axis=-1)
        s = s + delta
        over = np.maximum(0.0, np.abs(s[:, :, 0]) - SOFT_LIMIT)
        costs += (
            W_P * s[:, :, 0] ** 2
            + W_V * s[:, :, 1] ** 2
            + W_U * A[t] ** 2
            + BARRIER_WEIGHT * over**2
        )
    if mode == "mean":
        score = costs.mean(axis=0)
    else:
        tail_mass = (1.0 - cvar_alpha) * S
        whole = int(np.floor(tail_mass))
        fraction = tail_mass - whole
        descending = np.sort(costs, axis=0)[::-1]
        tail_sum = descending[:whole].sum(axis=0)
        if fraction > 0.0 and whole < S:
            tail_sum += fraction * descending[whole]
        score = tail_sum / tail_mass
    selected = A[:, int(np.argmin(score))]
    return selected.copy() if return_sequence else float(selected[0])

At the same state and RNG state, both modes generate the same candidate actions, member assignments, and linked noise draws. Only their cost aggregation changes: mean versus empirical CVaR. Once actions differ, closed-loop states and therefore imagined futures differ too. Using the same seeds pairs the search randomness; it does not make later state-conditioned predictions identical.

Running the comparison

We pair environment noise streams and search seeds across controllers. Different actions still lead to different states. Common random numbers reduce the variance of a difference when paired outcomes have positive covariance: Var(A−B)=Var(A)+Var(B)−2Cov(A,B)\mathrm{Var}(A-B)=\mathrm{Var}(A)+\mathrm{Var}(B)-2\mathrm{Cov}(A,B). They can increase it when covariance is negative. This experiment reports a paired finite comparison, not a measured reduction in required episode count; see Glasserman and Yao's conditions for common random numbers.

In[23]:
Code
N_EPISODES = 30
N_STEPS = 32

env_sampler = np.random.default_rng(4242)
EPISODES = []
for _ in range(N_EPISODES):
    params = sample_nominal(env_sampler)
    p0 = env_sampler.uniform(0.20, 0.40) * env_sampler.choice([-1.0, 1.0])
    v0 = np.sign(p0) * env_sampler.uniform(0.20, 0.50)
    EPISODES.append((params, (p0, v0)))


def run_regulation(mode, params, s0, steps, env_rng, plan_rng):
    p, v = float(s0[0]), float(s0[1])
    total = 0.0
    for _ in range(steps):
        u = plan(np.array([p, v]), plan_rng, mode=mode)
        p, v = simulate(params, (p, v), [u], env_rng, SIGMA_P)[1]
        over = max(0.0, abs(p) - SOFT_LIMIT)
        total += (
            W_P * p * p
            + W_V * v * v
            + W_U * u * u
            + BARRIER_WEIGHT * over * over
        )
    return total


def evaluate_planner(mode, plan_seed):
    env_rng = np.random.default_rng(9999)
    plan_rng = np.random.default_rng(plan_seed)
    return np.array(
        [
            run_regulation(mode, prm, s0, N_STEPS, env_rng, plan_rng)
            for prm, s0 in EPISODES
        ]
    )


costs_mean = evaluate_planner("mean", 101)
costs_cvar = evaluate_planner("cvar", 101)
Out[24]:
Console
planner                mean cost    median   90th pct       max
expected-cost MPC          1.600     1.670      2.372     2.593
CVaR MPC                   1.673     1.727      2.463     2.853

The table gives mean, median, 90th percentile, and maximum episode cost for each planner across thirty paired episodes. These are empirical cost summaries, not population tail guarantees or safety outcomes. Reporting several summaries makes tradeoffs visible that a mean alone would hide.

The executed CVaR controller has mean cost 1.673, 90th-percentile cost 2.463, and maximum 2.853, compared with 1.600, 2.372, and 2.593 for expected-cost MPC. It does not improve the realized upper tail on these thirty episodes. Model mismatch, finite candidate search, and tail-sampling error are possible explanations, not isolated causal findings. Tune α\alpha, sample counts, and cost weights on separate validation populations, then evaluate across independent seeds. Optimizing an imagined tail is not the same as improving the actual one.

Out[25]:
Visualization
Grouped bars comparing empirical cost summaries for two controllers.
Mean, median, and 90th-percentile costs across thirty paired episodes. CVaR has higher realized costs on these summaries; optimizing a modeled tail does not guarantee improving actual outcomes.
Out[26]:
Visualization
Episode-cost histograms comparing expected-cost and CVaR controllers.
Episode-cost histograms for thirty paired initial conditions and process-noise streams. This sample shows no CVaR tail improvement, and one seed design is not a population guarantee.

From soft penalties to explicit constraints

A finite soft penalty permits a tradeoff: a violating candidate can win if reductions in other cost terms outweigh its extra penalty. Our zero-target position cost does not make ∣p∣=0.7|p|=0.7 intrinsically better than ∣p∣=0.55|p|=0.55. Nor does this example establish that no penalty choice could enforce feasibility in any problem: some bounded or finite problems admit exact penalties. The quadratic penalty here supplies no proof of pointwise safety. If an envelope is a requirement, encode and justify it separately rather than treating a tuned weight as a certificate.

The alternatives each have costs:

  • Hard constraints on a nominal rollout enforce ∣p∣≤pmax⁡|p|\le p_{\max} at modeled steps. Feasibility establishes that modeled property, not automatically the real plant's safety. Connecting the two requires justified error and disturbance assumptions.
  • Chance constraints enforce Pr⁡[∣p∣>pmax⁡]≤δ\Pr[|p|>p_{\max}]\le\delta under a specified probability law. Computing or estimating that probability can be difficult. Finite samples can under- or overestimate it, and rare violations can be absent from the sample. A bound on violation probability is a different requirement from all-disturbance invariance.
  • Runtime assurance. Check a proposal against an independently justified safety condition and select a verified fallback when necessary. Guarantees require a sound decision module, an appropriate initial condition, and a fallback with proven properties under the declared plant and disturbance assumptions. Our next experiment illustrates the switching architecture without satisfying those proof obligations.

The code above implements a soft penalty and sampled CVaR, not constrained optimization. Zero observed violations among eighteen scenarios does not imply zero violation probability. A predictive safety filter needs justified uncertainty bounds and recursive feasibility; see Wabersich and Zeilinger. For continuous control-affine dynamics s˙=f(s)+g(s)a\dot s=f(s)+g(s)a, a continuously differentiable barrier hh describes h(s)≥0h(s)\ge0 and constrains actions through h˙(s,a)+γ(h(s))≥0\dot h(s,a)+\gamma(h(s))\ge0, with an appropriate extended class-K function γ\gamma (for example γ(r)=λr\gamma(r)=\lambda r, λ>0\lambda>0). Forward invariance additionally needs regularity, feasible actions, correct dynamics or robust error bounds, an admissible initial state, and satisfaction over time. Sampling and delay require additional treatment. Our quadratic penalty is not this condition; see Ames et al..