Skip to content

Commit 3bd143e

Browse files
committed
zero allocs rcs
1 parent bef8a3f commit 3bd143e

File tree

3 files changed

+84
-25
lines changed

3 files changed

+84
-25
lines changed

src/JTools.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ include("functions/gradientDescent.jl")
6161
export psd, psd2var
6262
include("functions/psd.jl")
6363

64-
export rcsMixMatrix, rcsAllocation, rcsAnalysis, rcsEnvelope, plotRcs, plotRcs!, rcsAllocationSimplex, rcsAllocationSimplex!
64+
export rcsMixMatrix, rcsAllocation, rcsAnalysis, rcsEnvelope, plotRcs, plotRcs!, rcsAllocationSimplex, rcsAllocationSimplex!, RcsAllocator
6565
include("functions/rcsTools.jl")
6666

6767
export mesh2obj, ObjModel, readObj, writeObj, grid2mesh

src/functions/rcsTools.jl

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ function rcsAllocation(u, My, c=ones(size(My, 2)))
238238
return yv
239239
end
240240

241-
xsign(u) = u < 0.0 ? -1.0 : 1.0
241+
# xsign(u) = u < 0.0 ? -1.0 : 1.0
242242

243243
#rcsAllocationSimplex
244244
# This function solves the thrusters selection problem using the
@@ -266,15 +266,57 @@ xsign(u) = u < 0.0 ? -1.0 : 1.0
266266
#
267267
# Author: F. Capolupo
268268
# function rcsAllocationSimplex(u, My, c=ones(size(My, 2)); maxIter=30)
269-
function rcsAllocationSimplex(u, My; maxIter=30)
270-
y = Vector{eltype(u)}(undef, size(My, 2))
271-
rcsAllocationSimplex!(y, u, My; maxIter=maxIter)
272-
return y
269+
mutable struct RcsAllocator{T}
270+
m::Int # Number of dof
271+
n::Int # Number of RCS
272+
My::Matrix{T}
273+
y::Vector{T}
274+
c::Vector{T}
275+
maxIter::Int
276+
277+
# Allocations
278+
E::Matrix{T}
279+
∇z::Vector{T}
280+
e::Vector{T}
281+
iBase::Vector{Int}
282+
Yn::Vector{T}
283+
yb::Vector{T}
284+
Ymax::Vector{T}
285+
eNew::Vector{T}
286+
cs::Vector{T}
273287
end
274288

275-
function rcsAllocationSimplex!(y, u, My; maxIter=30)
276-
m, n = size(My) # m = number of dof, n = number of thrusters
277-
if iszero(u); y .= 0.0; return; end
289+
function RcsAllocator(My, c=ones(size(My, 2)); maxIter=30, yMaxSlack=1e8, cSlack=1e3*maximum(c))
290+
m, n = size(My)
291+
Ymax = [ones(n); yMaxSlack*ones(m)]
292+
return RcsAllocator(m, n, My, zeros(n), c, maxIter, zeros(m, n), zeros(n), zeros(m), ones(Int, m), zeros(n + m), zeros(m), Ymax, zeros(n), cSlack*ones(m))
293+
end
294+
295+
function rcsAllocationSimplex(u, My, c=ones(size(My, 2)); maxIter=30)
296+
r = RcsAllocator(My, c; maxIter=maxIter)
297+
rcsAllocationSimplex!(r, u)
298+
return r.y
299+
end
300+
301+
function rcsAllocationSimplex!(r::RcsAllocator, u)
302+
r.y .= 0.0
303+
if iszero(u); return; end
304+
305+
# Aliases
306+
m = r.m # Number of dof (output size)
307+
n = r.n # Number of thrusters
308+
My = r.My # Dimensional mixing matrix
309+
c = r.c # [n x 1] Cost coefficients vector
310+
E = r.E
311+
∇z = r.∇z # [n x 1] Cost change when bringing in the base a thruster which is out of the basis (i.e., increasing Yn[i])
312+
e = r.e
313+
iBase = r.iBase # [m x 1] Global indices (i.e., within the vector Y) of thrusters in the basis. Initial solution is y = s
314+
Yn = r.Yn # [n+m x 1] Thrusters out of the basis, either at zero (Yn[i] = 0) or at max (Yn[i] = Ymax[i])
315+
yb = r.yb # [m x 1] Basis vector (i.e., y of the m thrusters that form the basis)
316+
Ymax = r.Ymax # [n+m x 1] Parameters upper bounds, 0 <= Y <= Ymax, where Y = [y; s] TODO: Caution, this was creating problems when it was (maximum(yb) + 1.0)
317+
eNew = r.eNew
318+
cs = r.cs # [m x 1] Slack variables cost vector
319+
y = r.y
278320

279321
# # Variable change to have ylb = 0
280322
# off = false;
@@ -284,24 +326,26 @@ function rcsAllocationSimplex!(y, u, My; maxIter=30)
284326
# off = true;
285327
# end
286328

287-
# maxIter = 30#3m + 1 # was 3m + 10, but needed to heuristically increase a bit
288-
# cs = 1e3*maximum(c)*ones(m) # [OLD with c] [m x 1] Slack variables cost vector
289-
cs = 1e3*ones(m) # [m x 1] Slack variables cost vector
290-
291329
# Setup the initial solution
292-
E = -xsign.(u).*My # [m x n]
293-
# ∇z = c + E'*cs # [OLD with c] [n x 1] Cost change when bringing in the base a thruster which is out of the basis (i.e., increasing Yn[i])
294-
∇z = 1.0 .+ E'*cs # [n x 1] Cost change when bringing in the base a thruster which is out of the basis (i.e., increasing Yn[i])
295-
e = zeros(m)
296-
297-
iBase = Integer.(n+1:n+m) # [m x 1] Global indices (i.e., within the vector Y) of thrusters in the basis. Initial solution is y = s
298-
Yn = zeros(n + m) # [n+m x 1] Thrusters out of the basis, either at zero (Yn[i] = 0) or at max (Yn[i] = Ymax[i])
299-
yb = abs.(u) # [m x 1] Basis vector (i.e., y of the m thrusters that form the basis)
300-
Ymax = [ones(n); 1e8*ones(m)] # [n+m x 1] Parameters upper bounds, 0 <= Y <= Ymax, where Y = [y; s] TODO: Caution, this was creating problems when it was (maximum(yb) + 1.0)
301-
eNew = zeros(n)
330+
# E .= -xsign.(u).*My
331+
E .= My
332+
@inbounds for i in 1:m
333+
if u[i] > 0.0
334+
@inbounds for j in 1:n
335+
E[i, j] *= -1.0
336+
end
337+
end
338+
iBase[i] = n + i
339+
yb[i] = abs(u[i])
340+
end
341+
mul!(∇z, E', cs)
342+
∇z .+= c
343+
e .= 0.0
344+
eNew .= 0.0
345+
Yn .= 0.0
302346

303347
# Loop until all gradient components are positive
304-
@inbounds for _ in 1:maxIter
348+
@inbounds for _ in 1:r.maxIter
305349

306350
# Find the non-basis thruster that is candidate to enter the basis
307351
# The thrusters which maximize '∇z' is invited in the basis

test/testSimplex.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using LinearAlgebra
22
using JTools
3+
using BenchmarkTools
34

45
function Conf1()
56
rCoM = [0.011492287518140363, 0.013142790801125676, 1.4899054489372667]
@@ -188,14 +189,16 @@ function testsplx(data)
188189
# Random.seed!(13085610)
189190
N = size(My, 2)
190191
maxErr = -1.0
192+
r = RcsAllocator(My)
191193
uerr = []; yerr = []
192194
for i in 1:100000
193195
y = rand(N)
194196
# y[5] = 1.0
195197
# y[9] = 1.0
196198
# y[20] = 1.0
197199
u = My * y
198-
yr = rcsAllocationSimplex(u, My)
200+
rcsAllocationSimplex!(r, u)
201+
yr = r.y
199202
if minimum(yr) < 0.0 || maximum(yr) > 1.0
200203
@show "err"
201204
end
@@ -212,6 +215,18 @@ function testsplx(data)
212215
return maxErr
213216
end
214217

218+
function testsplxAlloc(data)
219+
posOR_B, dirR_B, rCoM = data
220+
My = rcsMixMatrix(posOR_B, dirR_B, [], rCoM)
221+
N = size(My, 2)
222+
r = RcsAllocator(My)
223+
y = rand(N)
224+
u = My * y
225+
@btime rcsAllocationSimplex!($r, $u)
226+
return
227+
end
228+
215229
@show testsplx(Conf1())
216230
@show testsplx(Conf2())
217231
@show testsplx(Conf3())
232+
testsplxAlloc(Conf1())

0 commit comments

Comments
 (0)