@@ -6,6 +6,7 @@ using OrdinaryDiffEqSDIRK
66using Ipopt
77using BenchmarkTools
88using CairoMakie
9+ using DataInterpolations
910const 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)
7778end
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 (
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 ###
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
138161end
139162
140163@testset " Rocket launch" begin
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
166200end
167201
168202@testset " Free final time problem" begin
189223 @test isapprox (isol. sol. t[end ], 10.0 , rtol = 1e-3 )
190224end
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