Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/control_affine_system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ Control affine system described by the dynamics ``ẋ = f(x) + g(x)u`` where ``x
- `f::Function` : drift dynamics
- `g::Function` : control directions
"""
struct ControlAffineSystem
struct ControlAffineSystem{F,G}
name::String
n::Int
m::Int
f::Function
g::Function
f::F
g::G
end

"""
Expand Down
14 changes: 7 additions & 7 deletions src/control_barrier_function.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ Control barrier function (CBF) defining a safe set as its zero superlevel set.
- `Lfh::Function` : Lie derivative of CBF along drift vector field `f`
- `Lgh::Function` : Lie derivative of CBF along control directions `g`
"""
struct ControlBarrierFunction
h::Function
α::Function
∇h::Function
Lfh::Function
Lgh::Function
struct ControlBarrierFunction{Th, Tα, T∇h, TLfh, TLgh}
h::Th
α::
∇h::T∇h
Lfh::TLfh
Lgh::TLgh
end

"""
Expand Down Expand Up @@ -44,4 +44,4 @@ end
If no extended class K function provided, default to the identify function.
"""
ControlBarrierFunction(h::Function, Σ::ControlAffineSystem) =
ControlBarrierFunction(h, Σ, r -> r)
ControlBarrierFunction(h, Σ, identity)
30 changes: 10 additions & 20 deletions src/explicit_safety_filter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ Controller that uses the closed-form solution to a control barrier function quad
# Fields
- `k::Function` : function that computes safe control actions
"""
struct ExplicitSafetyFilter <: SafetyFilter
k::Function
struct ExplicitSafetyFilter{T} <: SafetyFilter
k::T
end

"""
(k::ExplicitSafetyFilter)(x)

Functors for evaluating explicit safety filter
"""
(k::ExplicitSafetyFilter)(x) = k.k(x)
(k::ExplicitSafetyFilter)(x, t) = k.k(x, t)
(k::ExplicitSafetyFilter)(args...) = k.k(args...)

"""
ExplicitSafetyFilter(cbf::ControlBarrierFunction, Σ::ControlAffineSystem, kd::Function)
Expand All @@ -26,23 +25,14 @@ Construct an ExplicitSafetyFilter from a cbf and a desired controller.
function ExplicitSafetyFilter(
cbf::ControlBarrierFunction, Σ::ControlAffineSystem, kd::Function
)
try
kd(Σ.n == 1 ? rand() : rand(Σ.n), 0.0)
catch e
if isa(e, MethodError)
a(x) = cbf.Lfh(x) + cbf.Lgh(x) * kd(x) + cbf.α(cbf(x))
k(x) = kd(x) + λQP(a(x), norm(cbf.Lgh(x))^2) * cbf.Lgh(x)'

return ExplicitSafetyFilter(k)
else
return e
end
else
a(x, t) = cbf.Lfh(x) + cbf.Lgh(x) * kd(x, t) + cbf.α(cbf(x))
k(x, t) = kd(x, t) + λQP(a(x, t), norm(cbf.Lgh(x))^2) * cbf.Lgh(x)'

return ExplicitSafetyFilter(k)
function k(x, args...)
Lgh = cbf.Lgh(x)
Lfh = cbf.Lfh(x)
kdx = kd(x, args...)
a = Lfh + Lgh * kdx + cbf.α(cbf(x))
kdx + λQP(a, norm(Lgh)^2) * Lgh'
end
ExplicitSafetyFilter{typeof(k)}(k)
end

"""
Expand Down
24 changes: 12 additions & 12 deletions src/qp_safety_filter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ Functors for evaluating QP-based safety filter
(k::QPSafetyFilter)(x, t) = k.k(x, t)

"""
QPSafetyFilter(cbfs::Vector{ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function)
QPSafetyFilter(cbfs::Vector{<:ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function)

Construct an QPSafetyFilter from a cbf and a desired controller.
"""
function QPSafetyFilter(
cbfs::Vector{ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function
cbfs::Vector{<:ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function
)
try
kd(Σ.n == 1 ? rand() : rand(Σ.n), 0.0) # See if desired controller is time-varying
Expand All @@ -43,13 +43,13 @@ end

"""
QPSafetyFilter(
cbfs::Vector{ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function, umin, umax
cbfs::Vector{<:ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function, umin, umax
)

Construct an QPSafetyFilter from a cbf and a desired controller.
"""
function QPSafetyFilter(
cbfs::Vector{ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function, umin, umax
cbfs::Vector{<:ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function, umin, umax
)
try
kd(Σ.n == 1 ? rand() : rand(Σ.n), 0.0) # See if desired controller is time-varying
Expand Down Expand Up @@ -80,12 +80,12 @@ function QPSafetyFilter(
end

"""
solve_cbf_qp(x, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function)
solve_cbf_qp(x, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function)

Solve CBF-QP using OSQP and JuMP.
"""
function solve_cbf_qp(
x, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function
x, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function
)
model = Model(OSQP.Optimizer)
set_silent(model)
Expand All @@ -101,15 +101,15 @@ end

"""
solve_cbf_qp(
x, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function, umin, umax
x, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function, umin, umax
)

Solve CBF-QP using OSQP and JuMP while satisfying input bounds `umin ≤ u ≤ umax`.
"""
function solve_cbf_qp(
x,
Σ::ControlAffineSystem,
cbfs::Vector{ControlBarrierFunction},
cbfs::Vector{<:ControlBarrierFunction},
kd::Function,
umin,
umax,
Expand All @@ -129,12 +129,12 @@ function solve_cbf_qp(
end

"""
solve_time_varying_cbf_qp(x, t, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function)
solve_time_varying_cbf_qp(x, t, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function)

Solve CBF-QP where desired controller is time-varying
"""
function solve_time_varying_cbf_qp(
x, t, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function
x, t, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function
)
model = Model(OSQP.Optimizer)
set_silent(model)
Expand All @@ -149,15 +149,15 @@ function solve_time_varying_cbf_qp(
end

"""
solve_time_varying_cbf_qp(x, t, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function, umin, umax)
solve_time_varying_cbf_qp(x, t, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function, umin, umax)

Solve CBF-QP where desired controller is time-varying with input bounds.
"""
function solve_time_varying_cbf_qp(
x,
t,
Σ::ControlAffineSystem,
cbfs::Vector{ControlBarrierFunction},
cbfs::Vector{<:ControlBarrierFunction},
kd::Function,
umin,
umax,
Expand Down
12 changes: 6 additions & 6 deletions src/tunable_qp_safety_filter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ Functors for evaluating QP-based safety filter
(k::TunableQPSafetyFilter)(x, t) = k.k(x, t)

"""
TunableQPSafetyFilter(cbfs::Vector{ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function; tunable=false)
TunableQPSafetyFilter(cbfs::Vector{<:ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function; tunable=false)

Construct an TunableQPSafetyFilter from a cbf and a desired controller.

# Keywork arguments
- `tunable::Bool` : boolean to decide if coefficients on extended class K functions should be decision variables
"""
function TunableQPSafetyFilter(
cbfs::Vector{ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function
cbfs::Vector{<:ControlBarrierFunction}, Σ::ControlAffineSystem, kd::Function
)
try
kd(Σ.n == 1 ? rand() : rand(Σ.n), 0.0) # See if desired controller is time-varying
Expand All @@ -55,12 +55,12 @@ TunableQPSafetyFilter(cbf::ControlBarrierFunction, Σ::ControlAffineSystem, kd::
TunableQPSafetyFilter([cbf], Σ, kd)

"""
solve_tunable_cbf_qp(x, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function)
solve_tunable_cbf_qp(x, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function)

Solve CBF-QP where coefficients on extended class K functions are decision variables
"""
function solve_tunable_cbf_qp(
x, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function
x, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function
)
model = Model(OSQP.Optimizer)
set_silent(model)
Expand All @@ -78,12 +78,12 @@ function solve_tunable_cbf_qp(
end

"""
solve_time_varying_tunable_cbf_qp(x, t, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function)
solve_time_varying_tunable_cbf_qp(x, t, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function)

Solve CBF-QP where coefficients on extended class K functions are decision variables and desired controller depends on time
"""
function solve_time_varying_tunable_cbf_qp(
x, t, Σ::ControlAffineSystem, cbfs::Vector{ControlBarrierFunction}, kd::Function
x, t, Σ::ControlAffineSystem, cbfs::Vector{<:ControlBarrierFunction}, kd::Function
)
model = Model(OSQP.Optimizer)
set_silent(model)
Expand Down