Constraint Interface
Constraint Type
All constraints inherit from AbstractConstraint{S<:ConstraintSense,W<:ConstraintType,P}
, where ConstraintSense
specifies Inequality
or Equality
, ConstraintType
specifies the "bandedness" of the constraint (will be discussed more later), and P
is the dimension of the constraint. This allows the software to easily dispatch over the type of constraint. Each constraint type represents a vector-valued constraint. The intention is that each constraint type represent one line in the constraints of problem definition (where they may be vector or scalar-valued).
TrajectoryOptimization.jl assumes equality constraints are of the form $g(x) = 0$ and inequality constraints are of the form $h(x) \leq 0$.
TrajectoryOptimization.AbstractConstraint
— Typeabstract type AbstractConstraint <: TrajectoryOptimization.GeneralConstraint
Abstract vector-valued constraint of size P
for a trajectory optimization problem. May be either inequality or equality (specified by S<:ConstraintSense
), and be function of single, adjacent, or all knotpoints (specified by W<:ConstraintType
).
Interface: Any constraint type must implement the following interface:
n = state_dim(::MyCon)
m = control_dim(::MyCon)
p = Base.length(::MyCon)
c = evaluate(::MyCon, args...) # args determined by W
∇c = jacobian(::MyCon, args...) # args determined by W
The evaluate
and jacobian
(identical signatures) methods should have the following signatures
- W <: State:
evaluate(::MyCon, x::SVector)
- W <: Control:
evaluate(::MyCon, u::SVector)
- W <: Stage:
evaluate(::MyCon, x, u)
- W <: Dynamical:
evaluate(::MyCon, x′, x, u)
- W <: Coupled:
evaluate(::MyCon, x′, u′ x, u)
Or alternatively,
- W <: Stage:
evaluate(::MyCon, z::KnotPoint)
- W <: Coupled:
evaluate(::MyCon, z′::KnotPoint, z::KnotPoint)
The Jacobian method for State
or Control
is optional, since it will be automatically computed using ForwardDiff. Automatic differentiation for other types of constraints is not yet supported.
For W <: State, control_dim(::MyCon)
doesn't need to be defined. Equivalently, for W <: Control, state_dim(::MyCon)
doesn't need to be defined.
For W <: General, the more general evaluate
and jacobian
methods must be used
evaluate!(vals::Vector{<:AbstractVector}, ::MyCon, Z::Traj, inds=1:length(Z)-1)
jacobian!(∇c::Vector{<:AbstractMatrix}, ::MyCon, Z::Traj, inds=1:length(Z)-1)
These methods can be specified for any constraint, instead of the not-in-place functions above.
TrajectoryOptimization.ConstraintSense
— TypeSpecifies whether the constraint is an equality or inequality constraint. Valid subtypes are Equality
, Inequality
, and Null
TrajectoryOptimization.ConstraintType
— TypeSpecifies the ``bandedness'' of the constraint. This ends up being the width of the constraint Jacobian, or the total number of input variables. This is important to reduce the size of arrays needed to store the Jacobian, as well as special-case the block matrix algebra.
Current subtypes:
Stage
State
<:Stage
Control
<:Stage
Coupled
Dynamical
<:Coupled
CoupledState
<:Coupled
CoupledControl
<:Coupled
General
GeneralState
<:General
GeneralControl
<:General
Methods
The following methods are defined for all AbstractConstraint
s
TrajectoryOptimization.state_dims
— FunctionSize of control vector
TrajectoryOptimization.control_dims
— FunctionSize of state vector
TrajectoryOptimization.evaluate!
— Functionevaluate!(vals::Vector{<:AbstractVector}, con::AbstractConstraint{S,W,P},
Z, inds=1:length(Z)-1)
Evaluate constraints for entire trajectory. This is the most general method used to evaluate constraints, and should be the one used in other functions.
For W<:Stage this will loop over calls to evaluate(con,Z[k])
For W<:Coupled this will loop over calls to evaluate(con,Z[k+1],Z[k])
For W<:General,this must function must be explicitly defined. Other types may define it if desired.
evaluate!(conSet::ConstraintSet, Z::Traj)
Compute constraint values for all constraints for the entire trajectory
TrajectoryOptimization.jacobian!
— Function∇f = jacobian!(∇c, model, z::KnotPoint)
∇f = jacobian!(∇c, model, z::SVector)
Compute the Jacobian of the continuous-time dynamics using ForwardDiff. The input can be either a static vector of the concatenated state and control, or a KnotPoint. They must be concatenated to avoid unnecessary memory allocations.
jacobian!(vals::Vector{<:AbstractVector}, con::AbstractConstraint{S,W,P},
Z, inds=1:length(Z)-1)
Evaluate constraint Jacobians for entire trajectory. This is the most general method used to evaluate constraint Jacobians, and should be the one used in other functions.
For W<:Stage this will loop over calls to jacobian(con,Z[k])
For W<:Coupled this will loop over calls to jacobian(con,Z[k+1],Z[k])
For W<:General,this must function must be explicitly defined. Other types may define it if desired.
jacobian!(conSet::ConstraintSet, Z::Traj)
Compute constraint Jacobians for all constraints for the entire trajectory
TrajectoryOptimization.contype
— FunctionGet type of constraint (bandedness)
TrajectoryOptimization.sense
— FunctionGet constraint sense (Inequality vs Equality)
TrajectoryOptimization.width
— FunctionReturns the width of the constraint Jacobian, i.e. the total number of inputs to the constraint
TrajectoryOptimization.upper_bound
— FunctionUpper bound of the constraint, as a vector, which is 0 for all constraints (except bound constraints)
TrajectoryOptimization.lower_bound
— FunctionUpper bound of the constraint, as a vector, which is 0 equality and -Inf for inequality (except bound constraints)
TrajectoryOptimization.is_bound
— FunctionIs the constraint a bound constraint or not
TrajectoryOptimization.check_dims
— FunctionCheck whether the constraint is consistent with the specified state and control dimensions
Adding a New Constraint
See interface description in documentation for AbstractConstraint
. The interface allows for a lot of flexibility, but let's do a simple example. Let's say we have a 2-norm constraint on the controls at each time step, e.g. $||u|| \leq a$. We can do this with just a few lines of code:
struct ControlNorm{T} <: AbstractConstraint{Inequality,Control,1}
m::Int
a::T
end
control_dim(con::ControlNorm) = con.m
evaluate(con::ControlNorm, u::SVector) = @SVector [norm(u) - con.a] # needs to be a vector output
jacobian(con::ControlNorm, u::SVector) = u'/norm(u) # optional
Importantly, note that the inheritance specifies the constraint applies only to individual controls, the constraint in an inequality, and has dimension 1.
Let's say the bound $a$ varied by time-step. We could handle this easily by instead defining the methods operating on the entire trajectory:
struct ControlNorm2{T} <: AbstractConstraint{Inequality,Control,1}
m::Int
a::Vector{T}
end
control_dim(con::ControlNorm) = con.m
function evaluate!(vals::Vector{<:AbstractVector}, con::ControlNorm,
Z, inds=1:length(Z)-1)
for (i,k) in enumerate(inds)
u = control(Z[k])
vals[i] = @SVector [norm(u) - con.a[k]]
end
end
function jacobian!(∇c::Vector{<:AbstractMatrix}, con::ControlNorm,
Z, inds=1:length(Z)-1)
for (i,k) in enumerate(inds)
u = control(Z[k])
∇c[i] = u'/norm(u)
end
end
Constraint Types
The ConstraintType
defines the "bandedness" of the constraint, or the number of adjacent state or constraint values needed to calculate the constraint.
TrajectoryOptimization.Stage
— TypeOnly a function of states and controls at a single knotpoint
TrajectoryOptimization.State
— TypeOnly a function of states at a single knotpoint
TrajectoryOptimization.Control
— TypeOnly a function of controls at a single knotpoint
TrajectoryOptimization.Coupled
— TypeOnly a function of states and controls at two adjacent knotpoints
TrajectoryOptimization.Dynamical
— TypeOnly a function of states and two adjacent knotpoints, and the control at the previous knotpoint, i.e. f(x,u) - x′
TrajectoryOptimization.CoupledState
— TypeOnly a function of states at adjacent knotpoints
TrajectoryOptimization.CoupledControl
— TypeOnly a function of controls at adjacent knotpoints
TrajectoryOptimization.General
— TypeA function of all states and controls in the trajectory
TrajectoryOptimization.GeneralState
— TypeA function of all states in the trajectory
TrajectoryOptimization.GeneralControl
— TypeA function of all controls in the trajectory