Skip to content

Commit f13b0e2

Browse files
committed
Use cellular sheaves for multi-agent control
1 parent 4416689 commit f13b0e2

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,10 @@ version = "0.1.0"
77
AlgebraicOptimization = "a72ceada-00ec-4ad9-90d3-37b40eaed052"
88
Convex = "f65535da-76fb-5f13-bab9-19810c17039a"
99
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
10+
ProximalAlgorithms = "140ffc9f-1907-541a-a177-7475e0a401e9"
11+
ProximalOperators = "a725b495-10eb-56fe-b38b-717eba820537"
1012
SCS = "c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13"
13+
14+
[compat]
15+
ProximalAlgorithms = "0.5.4"
16+
ProximalOperators = "0.16.1"

examples/multi_agent.jl

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using AlgebraicOptimization
2+
using AlgebraicControl
3+
using Convex
4+
using LinearAlgebra
5+
using ProximalAlgorithms
6+
7+
# Set up each agent's dynamics: x' = Ax + Bu
8+
dt = 0.1 # Discretization step size
9+
A = [1 dt 0 0; 0 1 0 0; 0 0 1 dt; 0 0 0 1]
10+
B = [0 0; dt 0; 0 0; 0 dt]
11+
C = [1.0 0 0 0; 0 0 1.0 0] # Output agent's position
12+
Q = Matrix{Float64}(I(4))
13+
Q[1, 1] = 0.0
14+
Q[3, 3] = 0.0 # No objective on positions, just make velocities go to 0
15+
R = Matrix{Float64}(I(2))
16+
17+
sys = LinearSystem(A, B)
18+
19+
# Stage cost function: minimize control effort and deviation from origin
20+
stage_cost(u, x) = quadform(x, Q) + quadform(u, R)
21+
stage_constraints = Function[]
22+
# Create a multi-stage program for a horizon of N steps
23+
N = 10
24+
mpc_program = multi_stage_program(stage_cost, stage_constraints, sys, N)
25+
26+
# Create a proxable MPC program
27+
agent1_obj, agent2_obj, agent3_obj = ProxableMPCProgram(mpc_program), ProxableMPCProgram(mpc_program), ProxableMPCProgram(mpc_program)
28+
29+
set_x0!(agent1_obj, rand(4))
30+
set_x0!(agent2_obj, rand(4))
31+
set_x0!(agent3_obj, rand(4))
32+
33+
s = @cellular_sheaf C begin
34+
x::Stalk{4}, y::Stalk{4}, z::Stalk{4}
35+
36+
C(x) == C(y)
37+
C(x) == C(z)
38+
C(y) == C(z)
39+
end
40+
41+
42+
p = HomologicalProgram([agent1_obj, agent2_obj, agent3_obj], s)
43+
44+
solve(p, ProximalAlgorithms.DouglasRachford(maxit=10))
45+
46+
sim_length = 100
47+
48+
for i in 1:sim_length
49+
solve(p, ProximalAlgorithms.DouglasRachford(maxit=10))
50+
x1_curr = evaluate(agent1_obj.input_var)
51+
x2_curr = evaluate(agent2_obj.input_var)
52+
x3_curr = evaluate(agent3_obj.input_var)
53+
54+
u1_curr = evaluate(agent1_obj.control_vars[1])
55+
u2_curr = evaluate(agent2_obj.control_vars[1])
56+
u3_curr = evaluate(agent3_obj.control_vars[1])
57+
58+
x1_next = sys(x1_curr, u1_curr)
59+
x2_next = sys(x2_curr, u2_curr)
60+
x3_next = sys(x3_curr, u3_curr)
61+
62+
set_x0!(agent1_obj, x1_next)
63+
set_x0!(agent2_obj, x2_next)
64+
set_x0!(agent3_obj, x3_next)
65+
end
66+
67+
x1_f = evaluate(agent1_obj.input_var)
68+
x2_f = evaluate(agent2_obj.input_var)
69+
x3_f = evaluate(agent3_obj.input_var)
70+
71+
72+

src/AlgebraicControl.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ using Convex
99
using SCS
1010
using LinearAlgebra
1111

12+
import ProximalOperators: prox, prox!
13+
1214
struct LinearSystem
1315
A::Matrix{Float64}
1416
B::Matrix{Float64}
@@ -68,20 +70,21 @@ function set_x0!(P::ProxableMPCProgram, x0_val::Vector{Float64})
6870
fix!(P.input_var, x0_val)
6971
end
7072

71-
function prox(P::ProxableMPCProgram, x::Vector{Float64}, γ=1.0)
73+
function prox(P::ProxableMPCProgram, x, γ=1.0)
7274
#fix!(P.y, x)
7375
#fix!(P.γ, γ)
7476
prob = P.program(x, γ)
7577
solve!(prob, SCS.Optimizer; silent=true)
76-
return evaluate(P.output_var)
78+
return evaluate(P.output_var), prob.optval
7779
end
7880

79-
function prox!(y, P::ProxableMPCProgram, x::Vector{Float64}, γ=1.0)
81+
function prox!(y, P::ProxableMPCProgram, x, γ=1.0)
8082
#fix!(P.y, x)
8183
#fix!(P.γ[], γ)
8284
prob = P.program(x, γ)
83-
solve!(prob, SCS.Optimizer; silent_solver=true)
85+
solve!(prob, SCS.Optimizer; silent=true)
8486
copy!(y, evaluate(P.output_var))
87+
return prob.optval
8588
end
8689

8790

0 commit comments

Comments
 (0)