control.optimal.solve_ocp(sys, timepts, X0, cost, trajectory_constraints=None, terminal_cost=None, terminal_constraints=None, initial_guess=None, basis=None, squeeze=None, transpose=None, return_states=True, print_summary=True, log=False, **kwargs)[source]

Compute the solution to an optimal control problem.

The optimal trajectory (states and inputs) is computed so as to approximately mimimize a cost function of the following form (for continuous time systems):

J(x(.), u(.)) = int_0^T L(x(t), u(t)) dt + V(x(T)),

where T is the time horizon.

Discrete time systems use a similar formulation, with the integral replaced by a sum:

J(x[.], u[.]) = sum_0^{N-1} L(x_k, u_k) + V(x_N),

where N is the time horizon (corresponding to timepts[-1]).

  • sys (InputOutputSystem) – I/O system for which the optimal input will be computed.

  • timepts (1D array_like) – List of times at which the optimal input should be computed.

  • X0 (array-like or number, optional) – Initial condition (default = 0).

  • cost (callable) – Function that returns the integral cost (L) given the current state and input. Called as cost(x, u).

  • trajectory_constraints (list of tuples, optional) –

    List of constraints that should hold at each point in the time vector. Each element of the list should consist of a tuple with first element given by scipy.optimize.LinearConstraint() or scipy.optimize.NonlinearConstraint() and the remaining elements of the tuple are the arguments that would be passed to those functions. The following tuples are supported:

    • (LinearConstraint, A, lb, ub): The matrix A is multiplied by stacked vector of the state and input at each point on the trajectory for comparison against the upper and lower bounds.

    • (NonlinearConstraint, fun, lb, ub): a user-specific constraint function fun(x, u) is called at each point along the trajectory and compared against the upper and lower bounds.

    The constraints are applied at each time point along the trajectory.

  • terminal_cost (callable, optional) – Function that returns the terminal cost (V) given the final state and input. Called as terminal_cost(x, u). (For compatibility with the form of the cost function, u is passed even though it is often not part of the terminal cost.)

  • terminal_constraints (list of tuples, optional) – List of constraints that should hold at the end of the trajectory. Same format as constraints.

  • initial_guess (1D or 2D array_like) – Initial inputs to use as a guess for the optimal input. The inputs should either be a 2D vector of shape (ninputs, len(timepts)) or a 1D input of shape (ninputs,) that will be broadcast by extension of the time axis.

  • log (bool, optional) – If True, turn on logging messages (using Python logging module).

  • print_summary (bool, optional) – If True (default), print a short summary of the computation.

  • return_states (bool, optional) – If True, return the values of the state at each time (default = True).

  • squeeze (bool, optional) – If True and if the system has a single output, return the system output as a 1D array rather than a 2D array. If False, return the system output as a 2D array even if the system is SISO. Default value set by config.defaults[‘control.squeeze_time_response’].

  • transpose (bool, optional) – If True, assume that 2D input arrays are transposed from the standard format. Used to convert MATLAB-style inputs to our format.


  • res (OptimalControlResult) – Bundle object with the results of the optimal control problem.

  • res.success (bool) – Boolean flag indicating whether the optimization was successful.

  • res.time (array) – Time values of the input.

  • res.inputs (array) – Optimal inputs for the system. If the system is SISO and squeeze is not True, the array is 1D (indexed by time). If the system is not SISO or squeeze is False, the array is 2D (indexed by the output number and time).

  • res.states (array) – Time evolution of the state vector (if return_states=True).


  1. For discrete time systems, the final value of the timepts vector specifies the final time t_N, and the trajectory cost is computed from time t_0 to t_{N-1}. Note that the input u_N does not affect the state x_N and so it should always be returned as 0. Further, if neither a terminal cost nor a terminal constraint is given, then the input at time point t_{N-1} does not affect the cost function and hence u_{N-1} will also be returned as zero. If you want the trajectory cost to include state costs at time t_{N}, then you can set terminal_cost to be the same function as cost.

  2. Additional keyword parameters can be used to fine-tune the behavior of the underlying optimization and integration functions. See OptimalControlProblem() for more information.