Hi, I am trying to implement energy-efficient optimal control for vehicles, which includes traffic lights in the setup.
The following problem is described as:
\text{minimize}_{u^+, u^-} \int_{0}^{S} \frac{u^+}{\eta_1} - \eta_2u^- \mathrm{d}s
\text{subject to} \quad t'(s) = \frac{1}{v}
\quad \quad \quad \quad \quad v'(s) = \frac{u^+ - u^-}{mv} + \frac{a(s)}{mv},
where s is traveled distance, t is time, v is speed of the vehicle and a(s), where a = g\sin(\alpha(s)) is the gravity-induced acceleration and m is weight of the vehicle.The problem I am facing is that i would like to express constraints on the vehicle speed as a function of distance s (leading to static speed limits based on traveled distance) but also on time t. The dependence on time is motivated by the traffic lights, which are at known distance s with a known red/green phases, something like
v(s) <= V_{max}(s,t(s)) (e.g. at s = 2000 the red phase is for t \in [200, 240], therefore the maximum speed should be zero - or at least small enough).
The problem is discretized using implicit trapezoid method and formulated in JuMP, however I find incorporating the traffic lights constraint challenging. It will probably involve mixed-integer techniques (something like modeling if-else statements). I also tried to wrap it around complementarity constraints, but I guess that won’t fit there.
My question is, how to grasp and formulate the traffic lights constraints in JuMP. Below is MWE (for \alpha = 0).
using JuMP, Ipopt
N = 1000 # Number of discretization points
S = 10e3 # Total distance - 10 km
h = S/N
g = 9.81
m = 1
# Flat track
alpha = zeros(N+1)
# Dynamics
function f(x, u, k)
return [
1/x[2],
u/(m * x[2]) - g*sin(alpha[k])/x[2]
]
end
model = Model(Ipopt.Optimizer)
T = 1400 # Total trip time
v0 = 0.5 # Initial & minimum speed
eta1 = 1
eta2 = 0.6
# States & inputs
@variable(model, x[1:2,1:N+1])
@variable(model, u_plus[1:N] >= 0)
@variable(model, u_minus[1:N] >= 0)
@expression(model, u[i=1:N], u_plus[i] - u_minus[i])
# Initial and terminal constraints on state
@constraint(model, x[:,1] == [0, v0])
@constraint(model, x[:, end] == [T, v0])
# Static speed limits
@constraint(model, [i=1:N+1], x[2,i] >= v0)
@constraint(model, [i=1:N+1], x[2,i] <= 9)
# Traction characteristic constraint on input
@constraint(model, [i=1:N], u_plus[i] <= 3/max(x[2,i], 5))
@constraint(model, [i=1:N], u_minus[i] <= 3/max(x[2,i], 5))
# Implicit trapezoid method
@constraint(model, [i=1:N-1], x[:, i+1] == x[:, i] + 1/2 * h * (f(x[:, i], u[i], i) + f(x[:, i+1], u[i+1], i+1)))
@constraint(model, x[:, N+1] == x[:, N] + 1/2 * h *(f(x[:, N], u[N], N) + f(x[:, N+1], u[N], N+1)))
@objective(model, Min, sum([1/2 * h * ((u_plus[i]/eta1) - (eta2 * u_minus[i]) + (u_plus[i+1]/eta1) - (eta2 * u_minus[i+1])) for i = 1:N-1]))
# Initial guess for NLP
set_start_value.(x[1,:], LinRange(0, T, N+1))
set_start_value.(x[2,:], v0*ones(1:N+1))
fix.(x[:, 1], [0,v0])
fix.(x[:, end], [T, v0])
optimize!(model)