Solving OCPs
opengen version 0.10.0a1. The API is still young and is likely to change in version 0.11.
After an OCP optimizer has been built, it can be called using the method
solve(...). The main difference compared to the low-level interface is that
the OCP optimizer accepts named parameters rather than a manually packed
parameter vector.
For example, if the OCP declares the parameters x0, xref, q, and r,
the optimizer can be called as
result = ocp_optimizer.solve(
x0=[0.4, 0.2],
xref=[0.0, 0.0],
q=30.0,
r=1.0,
)
Any parameter with a default value may be omitted. For example, if xref,
q, and r have defaults, then the following is also valid:
result = ocp_optimizer.solve(x0=[0.4, 0.2])
Optional warm-start information may also be provided:
result = ocp_optimizer.solve(
x0=[0.4, 0.2],
initial_guess=[0.0] * 20,
initial_lagrange_multipliers=[0.0] * 5,
initial_penalty=10.0,
)
Solution object
The method solve(...) returns an object of type OcpSolution. This object
contains both the raw low-level solver status and OCP-oriented views such as
the stage-wise inputs and the state trajectory.
The most commonly used fields are:
result.inputs: sequence of optimal inputsresult.states: sequence of statesresult.cost: value of the objective at the solutionresult.exit_status: solver exit statusresult.solve_time_ms: total solver time in milliseconds
Additional solver diagnostics are also available:
result.penaltyresult.num_outer_iterationsresult.num_inner_iterationsresult.last_problem_norm_fprresult.f1_infeasibilityresult.f2_normresult.lagrange_multipliers
For convenience, the solution object can be printed directly:
print(result)
This displays a compact summary of the solution, including inputs, states, and solver diagnostics.
Direct bindings and TCP
The same high-level solve(...) interface is used regardless of whether the
optimizer was built with direct Python bindings or with the TCP interface.
When TCP is used, the underlying server is managed automatically by the
generated optimizer wrapper.
When the optimizer is accessed over TCP, the server is started automatically
the first time solve(...) is called and remains alive for subsequent calls.
When you are done with the optimizer, you should stop the TCP server
explicitly by calling:
ocp_optimizer.kill()
This has no effect for optimizers using direct Python bindings.
Reloading a generated optimizer
Generated OCP optimizers save a manifest automatically when they are built. They can later be reloaded without rebuilding:
optimizer = og.ocp.GeneratedOptimizer.load(
"path/to/optimizer_manifest.json"
)
result = optimizer.solve(x0=[0.4, 0.2], xref=[0.0, 0.0])
This is useful when you want to reuse a previously generated solver across Python sessions.
