Skip to content

Commit 6988707

Browse files
committed
test: add trasncription tests
1 parent cd9b039 commit 6988707

File tree

2 files changed

+54
-13
lines changed

2 files changed

+54
-13
lines changed

ext/MTKJuMPControlExt.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ end
4040
JuMPControlProblem(sys::ODESystem, u0, tspan, p; dt)
4141
4242
Convert an ODESystem representing an optimal control system into a JuMP model
43-
for solving using optimization. Must provide `dt` for determining the length
44-
of the interpolation arrays.
43+
for solving using optimization. Must provide either `dt`, the timestep between collocation
44+
points (which, along with the timespan, determines the number of points), or directly
45+
provide the number of points as `nsteps`.
4546
4647
The optimization variables:
4748
- a vector-of-vectors U representing the unknowns as an interpolation array

test/extensions/jump_control.jl

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ using OrdinaryDiffEqSDIRK
66
using Ipopt
77
using BenchmarkTools
88
using CairoMakie
9+
using DataInterpolations
910
const M = ModelingToolkit
1011

1112
@testset "ODE Solution, no cost" begin
@@ -76,21 +77,26 @@ const M = ModelingToolkit
7677
@test all(u -> u .> [3, 4], sol.u)
7778
end
7879

79-
@testset "Linear systems" begin
80-
function is_bangbang(input_sol, lbounds, ubounds, rtol = 1e-4)
81-
bangbang = true
82-
for v in 1:(length(input_sol.u[1]) - 1)
83-
all(i -> (i[v], bounds[v]; rtol) || (i[v], bounds[u]; rtol), input_sol.u) ||
84-
(bangbang = false)
85-
end
86-
bangbang
80+
function is_bangbang(input_sol, lbounds, ubounds, rtol = 1e-4)
81+
for v in 1:(length(input_sol.u[1]) - 1)
82+
all(i -> (i[v], bounds[v]; rtol) || (i[v], bounds[u]; rtol), input_sol.u) ||
83+
return false
8784
end
85+
true
86+
end
87+
88+
function ctrl_to_spline(inputsol, splineType)
89+
us = reduce(vcat, inputsol.u)
90+
ts = reduce(vcat, inputsol.t)
91+
splineType(us, ts)
92+
end
8893

94+
@testset "Linear systems" begin
8995
# Double integrator
9096
t = M.t_nounits
9197
D = M.D_nounits
9298
@variables x(..) [bounds = (0.0, 0.25)] v(..)
93-
@variables u(t) [bounds = (-1.0, 1.0), input = true]
99+
@variables u(..) [bounds = (-1.0, 1.0), input = true]
94100
constr = [v(1.0) ~ 0.0]
95101
cost = [-x(1.0)] # Maximize the final distance.
96102
@named block = ODESystem(
@@ -99,18 +105,27 @@ end
99105

100106
u0map = [x(t) => 0.0, v(t) => 0.0]
101107
tspan = (0.0, 1.0)
102-
parammap = [u => 0.0]
108+
parammap = [u(t) => 0.0]
103109
jprob = JuMPControlProblem(block, u0map, tspan, parammap; dt = 0.01)
104110
jsol = solve(jprob, Ipopt.Optimizer, :Verner8)
105111
# Linear systems have bang-bang controls
106112
@test is_bangbang(jsol.input_sol, [-1.0], [1.0])
107113
# Test reached final position.
108114
@test (jsol.sol.u[end][1], 0.25, rtol = 1e-5)
115+
# Test dynamics
116+
@parameters (u_interp::LinearInterpolation)(..)
117+
block_ode = ODESystem([D(x(t)) ~ v(t), D(v(t)) ~ u_interp(t)], t)
118+
spline = ctrl_to_spline(jsol.input_sol, LinearInterpolation)
119+
oprob = ODEProblem(block, u0map, tspan, [u_interp => spline])
120+
osol = solve(oprob, Vern8())
121+
@test jsol.sol.u osol.u
109122

110123
iprob = InfiniteOptControlProblem(block, u0map, tspan, parammap; dt = 0.01)
111124
isol = solve(iprob, Ipopt.Optimizer; silent = true)
112125
@test is_bangbang(isol.input_sol, [-1.0], [1.0])
113126
@test (isol.sol.u[end][1], 0.25, rtol = 1e-5)
127+
osol = solve(oprob, ImplicitEuler())
128+
@test isol.sol.u osol.u
114129

115130
###################
116131
### Bee example ###
@@ -133,8 +148,16 @@ end
133148
jsol = solve(jprob, Ipopt.Optimizer, :Tsitouras5)
134149
@test is_bangbang(jsol.input_sol, [0.0], [1.0])
135150
iprob = InfiniteOptControlProblem(beesys, u0map, tspan, pmap, dt = 0.01)
136-
isol = solve(jprob, Ipopt.Optimizer, :Tsitouras5)
151+
isol = solve(iprob, Ipopt.Optimizer; silent = true)
137152
@test is_bangbang(isol.input_sol, [0.0], [1.0])
153+
154+
@parameters (α_interp::LinearInterpolation)(..)
155+
eqs = [D(w(t)) ~ -μ * w(t) + b * s * α_interp(t) * w(t),
156+
D(q(t)) ~ -ν * q(t) + c * (1 - α_interp(t)) * s * w(t)]
157+
beesys_ode = ODESystem(eqs, t)
158+
oprob = ODEProblem(beesys_ode, u0map, tspan, [α_interp => ctrl_to_spline(jsol.input_sol, LinearInterpolation)])
159+
osol = solve(oprob, Tsit5())
160+
@test osol.u jsol.sol.u
138161
end
139162

140163
@testset "Rocket launch" begin
@@ -163,6 +186,17 @@ end
163186
jprob = JuMPControlProblem(rocket, u0map, (ts, te), pmap; dt = 0.005, cse = false)
164187
jsol = solve(jprob, Ipopt.Optimizer, :RadauIA3)
165188
@test jsol.sol.u[end][1] > 1.012
189+
190+
# Test solution
191+
@parameters (T_interp::CubicSpline)(..)
192+
eqs = [D(h(t)) ~ v(t),
193+
D(v(t)) ~ (T_interp(t) - drag(h(t), v(t))) / m(t) - gravity(h(t)),
194+
D(m(t)) ~ -T_interp(t) / c]
195+
rocket_ode = ODESystem(eqs, t)
196+
interpmap = Dict(T_interp => ctrl_to_spline(jsol.inputsol, CubicSpline))
197+
oprob = ODEProblem(rocket_ode, u0map, tspan, merge(pmap, interpmap))
198+
osol = solve(oprob, RadauIA3())
199+
@test jsol.sol.u osol.u
166200
end
167201

168202
@testset "Free final time problem" begin
@@ -189,5 +223,11 @@ end
189223
@test isapprox(isol.sol.t[end], 10.0, rtol = 1e-3)
190224
end
191225

226+
using JuliaSimCompiler
227+
using Multibody.PlanarMechanics
228+
229+
@testset "Cart-pole problem" begin
230+
end
231+
192232
#@testset "Constrained optimal control problems" begin
193233
#end

0 commit comments

Comments
 (0)