acados saved iterates: restore the problem data beside the solver vectors

An acados iterate file stores the optimizer’s current variables. load_iterate() puts those values into an already-created solver; the problem parameters and internal integrator iterates are supplied separately. When a restored run behaves differently, first distinguish the vectors you loaded from the problem those vectors now belong to.

This matters when moving a useful initial guess between processes or reproducing a difficult solve. The saved trajectory may be intact while a model coefficient, reference or bound has changed. An iterate is a point at which to continue optimization, including intermediate guesses—not necessarily a converged solution.

What the JSON actually contains

The official Python interface documents store_iterate() as an export of the current OCP iterate. Its implementation makes the boundary concrete: it collects seven field families, removes empty arrays and writes the remaining stage-indexed values to JSON.

Saved field Value represented
x, u, z State, control and algebraic-variable values
pi, lam Multipliers for dynamics equalities and inequalities
sl, su Soft-constraint slack values

The terminal node has a different field set. The exporter visits stages 0 through N, but at N it includes only x, sl, su and lam; u, z and pi are collected before the terminal node. An absent terminal control is therefore consistent with this exporter. An empty array also disappears during serialization, so missing keys need to be interpreted with the problem’s dimensions.

Parameters named p are outside that field list. The API also explicitly excludes the integrators’ internal iterates. A saved algebraic variable z should therefore be read as the exported OCP quantity, rather than as an export of every internal integration buffer.

Loading sets values in the solver you already have

In the source, load_iterate() reads each JSON key, separates its field and stage, and passes the array to set(). It works on an existing solver object. It does not use that file to construct a new model, choose a horizon or recreate cost and constraint definitions.

That distinction is useful during diagnosis. A dimension mismatch can be caught when the setter compares an array against the receiving solver. Matching dimensions are a narrower result: two models may both use one state and one input while assigning different equations to them.

Runtime references and bounds belong to the receiving problem as well. The cost and constraint setters update that problem data through their own interface. If an application changed these values after constructing the original solver, its restoration procedure needs those updates alongside the iterate file.

The same guess can have a different dynamics residual

Consider this hypothetical scalar problem, with dimensionless values:

x[k+1] = a × x[k] + u[k]

Suppose the saved guess contains x[0] = 1, u[0] = 0.2 and x[1] = 1. In this example, a is a stage parameter supplied through p. The old problem used a = 0.8, while a newly constructed solver currently holds a = 1.2.

Receiving problem Next state implied by its equation Saved guess for the next state Difference: saved minus implied
a = 0.8 0.8 × 1 + 0.2 = 1.0 1.0 0.0
a = 1.2 1.2 × 1 + 0.2 = 1.4 1.0 −0.4

The JSON can reproduce all three saved values in both cases. The residual differs because the equation changed. Looking only at the loaded state and control arrays would miss that cause; comparing the stage parameter reveals it directly.

The practical repair is to decide which problem is intended. To reconstruct the old one, restore its parameter values and other runtime problem updates. To initialize a genuinely new problem, keep its new parameters and treat the imported trajectory as an initial guess that may need adjustment. These are different uses of the same file.

Restore the problem first, then choose how to use the guess

For a fresh process, construct the intended OCP with the same stage structure, variable ordering and relevant solver settings. Apply the recorded runtime parameters, references and bounds, then load the iterate into that compatible solver. The initial-state constraint and the initial state guess deserve separate attention: fixing a bound specifies the problem’s starting state, while writing x supplies an optimization variable value.

Keep the exported file tied to the problem description that gives its arrays meaning. For the scalar example, a useful restoration record would identify the state equation and the value of a, not just record that three arrays loaded successfully. For a larger robot OCP, the corresponding record includes its parameter schedule and any runtime changes to references or constraints.

Once the problem data and iterate agree, the separate acados QP warm-start options determine how eligible QPs reuse numerical information. A loaded NLP iterate and a backend’s retained QP state are different inputs to that choice. This is why changing a warm-start level cannot substitute for restoring a missing model parameter.

The explanation follows the official documentation and Python source checked on October 16, 2026. The scalar arithmetic is illustrative; no acados solver or robot was run for this article.