@@ -37,32 +37,42 @@ struct TrajectoryOptimizationIndices
3737 stage_con:: Vector{Vector{Int}}
3838 stage_jac:: Vector{Vector{Int}}
3939 stage_hess:: Vector{Vector{Int}}
40+ gen_con:: Vector{Int}
41+ gen_jac:: Vector{Int}
42+ gen_hess:: Vector{Int}
4043 x:: Vector{Vector{Int}}
4144 u:: Vector{Vector{Int}}
4245 xu:: Vector{Vector{Int}}
4346 xuy:: Vector{Vector{Int}}
4447end
4548
46- function indices (obj:: Objective{T} , dyn:: Vector{Dynamics{T}} , cons:: Constraints{T} , key :: Vector{Tuple{Int,Int} } ,
47- nx:: Vector{Int} , nu:: Vector{Int} ) where T
49+ function indices (obj:: Objective{T} , dyn:: Vector{Dynamics{T}} , cons:: Constraints{T} , gc :: GeneralConstraint{T } ,
50+ key :: Vector{Tuple{Int,Int}} , nx:: Vector{Int} , nu:: Vector{Int} , nz :: Int ) where T
4851 # Jacobians
4952 dyn_con = constraint_indices (dyn, shift= 0 )
5053 dyn_jac = jacobian_indices (dyn, shift= 0 )
5154 stage_con = constraint_indices (cons, shift= num_con (dyn))
5255 stage_jac = jacobian_indices (cons, shift= num_jac (dyn))
56+ gen_con = constraint_indices (gc, shift= (num_con (dyn) + num_con (cons)))
57+ gen_jac = jacobian_indices (gc, shift= (num_jac (dyn) + num_jac (cons)))
5358
5459 # Hessian of Lagrangian
5560 obj_hess = hessian_indices (obj, key, nx, nu)
5661 dyn_hess = hessian_indices (dyn, key, nx, nu)
5762 stage_hess = hessian_indices (cons, key, nx, nu)
63+ gen_hess = hessian_indices (gc, key, nz)
5864
5965 # indices
6066 x_idx = x_indices (dyn)
6167 u_idx = u_indices (dyn)
6268 xu_idx = xu_indices (dyn)
6369 xuy_idx = xuy_indices (dyn)
6470
65- return TrajectoryOptimizationIndices (obj_hess, dyn_con, dyn_jac, dyn_hess, stage_con, stage_jac, stage_hess,
71+ return TrajectoryOptimizationIndices (
72+ obj_hess,
73+ dyn_con, dyn_jac, dyn_hess,
74+ stage_con, stage_jac, stage_hess,
75+ gen_con, gen_jac, gen_hess,
6676 x_idx, u_idx, xu_idx, xuy_idx)
6777end
6878
@@ -78,6 +88,9 @@ struct NLPData{T} <: MOI.AbstractNLPEvaluator
7888 sp_jac
7989 sp_hess_lag
8090 hess_lag:: Bool
91+ gc:: GeneralConstraint{T}
92+ w:: Vector{T}
93+ λ_gen:: Vector{T}
8194end
8295
8396function primal_bounds (bnds:: Bounds{T} , nz:: Int , x_idx:: Vector{Vector{Int}} , u_idx:: Vector{Vector{Int}} ) where T
@@ -91,55 +104,79 @@ function primal_bounds(bnds::Bounds{T}, nz::Int, x_idx::Vector{Vector{Int}}, u_i
91104 return zl, zu
92105end
93106
94- function constraint_bounds (cons:: Constraints{T} , nc:: Int , idx:: TrajectoryOptimizationIndices ) where T
107+ function constraint_bounds (cons:: Constraints{T} , gc:: GeneralConstraint{T} ,
108+ nc_dyn:: Int , nc_con:: Int , idx:: TrajectoryOptimizationIndices ) where T
109+ # total constraints
110+ nc = nc_dyn + nc_con + gc. nc
111+ # bounds
95112 cl, cu = zeros (nc), zeros (nc)
113+ # stage
96114 for (t, con) in enumerate (cons)
97115 cl[idx. stage_con[t][con. idx_ineq]] .= - Inf
98116 end
117+ # general
118+ cl[collect (nc_dyn + nc_con .+ gc. idx_ineq)] .= - Inf
99119 return cl, cu
100120end
101121
102- function NLPData (trajopt:: TrajectoryOptimizationData ; eval_hess= false )
122+ function NLPData (trajopt:: TrajectoryOptimizationData ;
123+ eval_hess= false ,
124+ general_constraint= GeneralConstraint ())
125+
103126 # number of variables
104127 nz = sum (trajopt. x_dim) + sum (trajopt. u_dim)
105128
106129 # number of constraints
107130 nc_dyn = num_con (trajopt. dyn)
108131 nc_con = num_con (trajopt. cons)
109- nc = nc_dyn + nc_con
132+ nc_gen = num_con (general_constraint)
133+ nc = nc_dyn + nc_con + nc_gen
110134
111135 # number of nonzeros in constraint Jacobian
112136 nj_dyn = num_jac (trajopt. dyn)
113137 nj_con = num_jac (trajopt. cons)
114- nj = nj_dyn + nj_con
138+ nj_gen = num_jac (general_constraint)
139+ nj = nj_dyn + nj_con + nj_gen
115140
116141 # number of nonzeros in Hessian of Lagrangian
117142 nh = 0
118143
119144 # constraint Jacobian sparsity
120145 sp_dyn = sparsity_jacobian (trajopt. dyn, trajopt. x_dim, trajopt. u_dim, row_shift= 0 )
121146 sp_con = sparsity_jacobian (trajopt. cons, trajopt. x_dim, trajopt. u_dim, row_shift= nc_dyn)
122- sp_jac = collect ([sp_dyn... , sp_con... ])
147+ sp_gen = sparsity_jacobian (general_constraint, nz, row_shift= (nc_dyn + nc_con))
148+ sp_jac = collect ([sp_dyn... , sp_con... , sp_gen... ])
123149
124150 # Hessian of Lagrangian sparsity
125151 sp_obj_hess = sparsity_hessian (trajopt. obj, trajopt. x_dim, trajopt. u_dim)
126152 sp_dyn_hess = sparsity_hessian (trajopt. dyn, trajopt. x_dim, trajopt. u_dim)
127153 sp_con_hess = sparsity_hessian (trajopt. cons, trajopt. x_dim, trajopt. u_dim)
128- sp_hess_lag = [sp_obj_hess... , sp_dyn_hess... , sp_con_hess... ]
154+ sp_gen_hess = sparsity_hessian (general_constraint, nz)
155+ sp_hess_lag = [sp_obj_hess... , sp_dyn_hess... , sp_con_hess... , sp_gen_hess... ]
129156 sp_hess_lag = ! isempty (sp_hess_lag) ? sp_hess_lag : Tuple{Int,Int}[]
130157 sp_hess_key = sort (unique (sp_hess_lag))
131- # sp_hess_status = [!isempty(sp_obj_hess), !isempty(sp_dyn_hess), !isempty(sp_con_hess)]
132158
133159 # indices
134- idx = indices (trajopt. obj, trajopt. dyn, trajopt. cons, sp_hess_key, trajopt. x_dim, trajopt. u_dim)
160+ idx = indices (trajopt. obj, trajopt. dyn, trajopt. cons,
161+ general_constraint,
162+ sp_hess_key,
163+ trajopt. x_dim, trajopt. u_dim, nz)
135164
136165 # primal variable bounds
137166 zl, zu = primal_bounds (trajopt. bnds, nz, idx. x, idx. u)
138167
139168 # nonlinear constraint bounds
140- cl, cu = constraint_bounds (trajopt. cons, nc, idx)
141-
142- NLPData (trajopt, nz, nc, nj, nh, [zl, zu], [cl, cu], idx, sp_jac, sp_hess_key, eval_hess)
169+ cl, cu = constraint_bounds (trajopt. cons, general_constraint, nc_dyn, nc_con, idx)
170+
171+ NLPData (trajopt,
172+ nz, nc, nj, nh,
173+ [zl, zu], [cl, cu],
174+ idx,
175+ sp_jac, sp_hess_key,
176+ eval_hess,
177+ general_constraint,
178+ vcat (trajopt. w... ),
179+ zeros (general_constraint. nc))
143180end
144181
145182struct SolverData
@@ -186,14 +223,15 @@ function trajectory!(x::Vector{Vector{T}}, u::Vector{Vector{T}}, z::Vector{T},
186223 end
187224end
188225
189- function duals! (λ_dyn:: Vector{Vector{T}} , λ_stage:: Vector{Vector{T}} , λ,
190- idx_dyn:: Vector{Vector{Int}} , idx_stage:: Vector{Vector{Int}} ) where T
226+ function duals! (λ_dyn:: Vector{Vector{T}} , λ_stage:: Vector{Vector{T}} , λ_gen :: Vector{T} , λ,
227+ idx_dyn:: Vector{Vector{Int}} , idx_stage:: Vector{Vector{Int}} , idx_gen :: Vector{Int} ) where T
191228 for (t, idx) in enumerate (idx_dyn)
192229 λ_dyn[t] .= @views λ[idx]
193230 end
194231 for (t, idx) in enumerate (idx_stage)
195232 λ_stage[t] .= @views λ[idx]
196233 end
234+ λ_gen .= λ[idx_gen]
197235end
198236
199237struct ProblemData{T} <: MOI.AbstractNLPEvaluator
@@ -202,11 +240,13 @@ struct ProblemData{T} <: MOI.AbstractNLPEvaluator
202240end
203241
204242function ProblemData (obj:: Objective{T} , dyn:: Vector{Dynamics{T}} , cons:: Constraints{T} , bnds:: Bounds{T} ;
205- eval_hess= false , options= Options (),
243+ eval_hess= false ,
244+ general_constraint= GeneralConstraint (),
245+ options= Options (),
206246 w= [[zeros (nw) for nw in dimensions (dyn)[3 ]]. .. , zeros (0 )]) where T
207247
208248 trajopt = TrajectoryOptimizationData (obj, dyn, cons, bnds, w= w)
209- nlp = NLPData (trajopt, eval_hess= eval_hess)
249+ nlp = NLPData (trajopt, general_constraint = general_constraint, eval_hess= eval_hess)
210250 s_data = SolverData (nlp, options= options)
211251
212252 ProblemData (nlp, s_data)
236276
237277function solve! (p:: ProblemData )
238278 MOI. optimize! (p. s_data. solver)
239- end
240-
241- # struct Solver{T}
242- # p::Problem{T}
243- # nlp_bounds::Vector{MOI.NLPBoundsPair}
244- # block_data::MOI.NLPBlockData
245- # solver::Ipopt.Optimizer
246- # z::Vector{MOI.VariableIndex}
247- # end
248-
249- # function Solver(trajopt::TrajectoryOptimizationProblem; eval_hess=false, options=Options())
250- # p = Problem(trajopt, eval_hess=eval_hess)
251-
252- # nlp_bounds = MOI.NLPBoundsPair.(p.con_bnds...)
253- # block_data = MOI.NLPBlockData(nlp_bounds, NLPEvaluator(), true)
254-
255- # # instantiate NLP solver
256- # solver = Ipopt.Optimizer()
257-
258- # # set NLP solver options
259- # for name in fieldnames(typeof(options))
260- # solver.options[String(name)] = getfield(options, name)
261- # end
262-
263- # z = MOI.add_variables(solver, nz)
264-
265- # for i = 1:p.num_var
266- # MOI.add_constraint(solver, z[i], MOI.LessThan(p.var_bnds[2][i]))
267- # MOI.add_constraint(solver, z[i], MOI.GreaterThan(p.var_bnds[1][i]))
268- # end
269-
270- # MOI.set(solver, MOI.NLPBlock(), block_data)
271- # MOI.set(solver, MOI.ObjectiveSense(), MOI.MIN_SENSE)
272-
273- # return Solver(p, nlp_bounds, block_data, solver, z)
274- # end
275-
276- # using MathOptInterface
277- # const MOI = MathOptInterface
278-
279- # MOI.AbstractNLPEvaluator
280-
281- # nlp_bounds = MOI.NLPBoundsPair.([-ones(10), ones(10)]...)
282-
283- # struct MOIEval <: MOI.AbstractNLPEvaluator end
284- # block_data = MOI.NLPBlockData(nlp_bounds, a(), true)
279+ end
0 commit comments