Skip to content

Commit 5e88af4

Browse files
authored
Merge pull request #7 from janbruedigam/small_fixes
Small fixes
2 parents ce3acfd + 7e31c23 commit 5e88af4

File tree

2 files changed

+38
-52
lines changed

2 files changed

+38
-52
lines changed

src/ConstrainedControl.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ using ConstrainedDynamics: svcat, szeros
55
using LinearAlgebra
66
using StaticArrays
77
using Rotations
8+
using Rotations: rotation_error
89

910
export PID,
1011
LQR,

src/control/lqr.jl

Lines changed: 37 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,33 @@ mutable struct LQR{T,N,NK} <: Controller
1515
control!::Function
1616

1717

18+
function LQR(A, Bu, Bλ, G, Q, R, horizon, eqcids, xd, vd, qd, ωd, Fτd, Δt, ::Type{T}) where {T}
19+
Q = cat(Q...,dims=(1,2))
20+
R = cat(R...,dims=(1,2))
21+
22+
N = horizon/Δt
23+
if N<Inf
24+
N = Integer(ceil(horizon/Δt))
25+
Ntemp = N
26+
else
27+
Ntemp = Integer(ceil(10/Δt)) # 10 second time horizon as maximal horizon for convergence for Inf
28+
end
29+
30+
# calculate K
31+
if size(G)[1] == 0
32+
@assert size(Bλ)[2] ==0
33+
Ku = dlqr(A, Bu, Q, R, N) # can be calculated directly
34+
else
35+
Ku = dlqr(A, Bu, Bλ, G, Q, R, Ntemp)
36+
if N == Inf
37+
Ku[1] != Ku[2] && @info "Riccati recursion did not converge."
38+
Ku = [Ku[1]]
39+
end
40+
end
41+
42+
new{T, N, size(Ku[1][1])[2]}(Ku, xd, vd, qd, ωd, eqcids, Fτd, control_lqr!)
43+
end
44+
1845
function LQR(mechanism::Mechanism{T,Nn,Nb}, bodyids::AbstractVector{<:Integer}, eqcids::AbstractVector{<:Integer},
1946
Q::Vector{<:AbstractMatrix{T}}, R::Vector{<:AbstractMatrix{T}}, horizon;
2047
xd::Vector{<:AbstractVector{T}} = [SA{T}[0; 0; 0] for i=1:Nb],
@@ -27,28 +54,10 @@ mutable struct LQR{T,N,NK} <: Controller
2754
@assert length(bodyids) == length(Q) == length(xd) == length(vd) == length(qd) == length(ωd) == Nb "Missmatched length for bodies"
2855
@assert length(eqcids) == length(R) == length(Fτd) "Missmatched length for constraints"
2956

30-
Δt = mechanism.Δt
31-
32-
N = horizon/Δt
33-
if N<Inf
34-
N = Integer(ceil(horizon/Δt))
35-
end
36-
3757
# linearize
3858
A, Bu, Bλ, G = linearsystem(mechanism, xd, vd, qd, ωd, Fτd, bodyids, eqcids)
3959

40-
Q = cat(Q...,dims=(1,2))
41-
R = cat(R...,dims=(1,2))
42-
43-
# calculate K
44-
if size(G)[1] == 0
45-
@assert size(Bλ)[2] ==0
46-
Ku = dlqr(A, Bu, Q, R, N)
47-
else
48-
Ku = dlqr(A, Bu, Bλ, G, Q, R, N)
49-
end
50-
51-
new{T, N, size(Ku[1][1])[2]}(Ku, xd, vd, qd, ωd, eqcids, Fτd, control_lqr!)
60+
LQR(A, Bu, Bλ, G, Q, R, horizon, eqcids, xd, vd, qd, ωd, Fτd, mechanism.Δt, T)
5261
end
5362

5463
function LQR(mechanism::Mechanism{T,Nn,Nb}, controlledids::AbstractVector{<:Integer}, controlids::AbstractVector{<:Integer},
@@ -61,35 +70,19 @@ mutable struct LQR{T,N,NK} <: Controller
6170
@assert length(controlledids) == length(Q) == length(xθd) == length(vωd) == Nb "Missmatched length for bodies"
6271
@assert length(controlids) == length(R) == length(Fτd) "Missmatched length for constraints"
6372

64-
Δt = mechanism.Δt
65-
66-
N = horizon/Δt
67-
if N<Inf
68-
N = Integer(ceil(horizon/Δt))
69-
end
70-
7173
# linearize
7274
A, Bu, Bλ, G, xd, vd, qd, ωd = linearsystem(mechanism, xθd, vωd, Fτd, controlledids, controlids)
7375

7476
Q = [diagm(ones(12))*Q[i] for i=1:length(Q)]
7577
R = [diagm(ones(1))*R[i] for i=1:length(R)]
76-
Q = cat(Q...,dims=(1,2))
77-
R = cat(R...,dims=(1,2))
7878

79-
# calculate K
80-
if size(G)[1] == 0
81-
@assert size(Bλ)[2] ==0
82-
Ku = dlqr(A, Bu, Q, R, N)
83-
else
84-
Ku = dlqr(A, Bu, Bλ, G, Q, R, N)
85-
end
86-
87-
new{T, N, size(Ku[1][1])[2]}(Ku, xd, vd, qd, ωd, controlids, [[Fτd[i]] for i=1:length(Fτd)], control_lqr!)
79+
LQR(A, Bu, Bλ, G, Q, R, horizon, controlids, xd, vd, qd, ωd, [[Fτd[i]] for i=1:length(Fτd)], mechanism.Δt, T)
8880
end
8981
end
9082

9183
function control_lqr!(mechanism::Mechanism{T,Nn,Nb}, lqr::LQR{T,N}, k) where {T,Nn,Nb,N}
9284
Δz = zeros(T,Nb*12)
85+
qvm = QuatVecMap()
9386
for (id,body) in pairs(mechanism.bodies)
9487
colx = (id-1)*12+1:(id-1)*12+3
9588
colv = (id-1)*12+4:(id-1)*12+6
@@ -99,7 +92,8 @@ function control_lqr!(mechanism::Mechanism{T,Nn,Nb}, lqr::LQR{T,N}, k) where {T,
9992
state = body.state
10093
Δz[colx] = state.xsol[2]-lqr.xd[id]
10194
Δz[colv] = state.vsol[2]-lqr.vd[id]
102-
Δz[colq] = ConstrainedDynamics.VLᵀmat(lqr.qd[id]) * Rotations.params(state.qsol[2])
95+
# Δz[colq] = ConstrainedDynamics.VLᵀmat(lqr.qd[id]) * Rotations.params(state.qsol[2])
96+
Δz[colq] = rotation_error(state.qsol[2],lqr.qd[id],qvm)
10397
Δz[colω] = state.ωsol[2]-lqr.ωd[id]
10498
end
10599

@@ -115,6 +109,7 @@ end
115109

116110
function control_lqr!(mechanism::Mechanism{T,Nn,Nb}, lqr::LQR{T,Inf}, k) where {T,Nn,Nb}
117111
Δz = zeros(T,Nb*12)
112+
qvm = QuatVecMap()
118113
for (id,body) in pairs(mechanism.bodies)
119114
colx = (id-1)*12+1:(id-1)*12+3
120115
colv = (id-1)*12+4:(id-1)*12+6
@@ -124,7 +119,7 @@ function control_lqr!(mechanism::Mechanism{T,Nn,Nb}, lqr::LQR{T,Inf}, k) where {
124119
state = body.state
125120
Δz[colx] = state.xsol[2]-lqr.xd[id]
126121
Δz[colv] = state.vsol[2]-lqr.vd[id]
127-
Δz[colq] = ConstrainedDynamics.VLᵀmat(lqr.qd[id]) * Rotations.params(state.qsol[2])
122+
Δz[colq] = rotation_error(state.qsol[2],lqr.qd[id],qvm)
128123
Δz[colω] = state.ωsol[2]-lqr.ωd[id]
129124
end
130125

@@ -147,12 +142,6 @@ function dlqr(A,B,Q,R,N)
147142
end
148143

149144
function dlqr(A,Bu,Bλ,G,Q,R,N)
150-
infflag = false
151-
if N == Inf
152-
infflag = true
153-
N = 1000
154-
end
155-
156145
mx = size(A)[2]
157146
mu = size(Bu)[2]
158147
= size(Bλ)[2]
@@ -182,19 +171,15 @@ function dlqr(A,Bu,Bλ,G,Q,R,N)
182171
Abar = A-Bu*Kuk-*Kλk
183172
Pkp1 = Q + Kuk'*R*Kuk + Abar'*Pk*Abar
184173

185-
if infflag && norm(Pk-Pkp1) < 1e-5
174+
if norm(Pk-Pkp1) < 1e-5
186175
break
187176
end
188177

189178
Pk = Pkp1
190179
end
191180

192-
if infflag
193-
if k==1
194-
@info "Riccati recursion did not converge."
195-
else
196-
Ku = [Ku[k]]
197-
end
181+
for k2=k-1:-1:1
182+
Ku[k2] = Ku[k2+1]
198183
end
199184

200185
return Ku

0 commit comments

Comments
 (0)