Skip to content

Commit a824889

Browse files
authored
Feature/skeleton dfg (#162)
* working skeleton dfg variables and factors. label, tags and order * addFactor!(dfg::LightDFG{<:AbstractParams, <:AbstractDFGVariable, F}, factor::F) * SkeletonDFG tests
1 parent 10978ed commit a824889

File tree

7 files changed

+139
-102
lines changed

7 files changed

+139
-102
lines changed

src/DistributedFactorGraphs.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ include("entities/AbstractDFGSummary.jl")
1818

1919
export AbstractDFG
2020
export AbstractParams, NoSolverParams
21-
export DFGNode, DFGVariable, DFGFactor
21+
export DFGNode, DFGVariable, DFGFactor, AbstractDFGVariable, AbstractDFGFactor
2222
export InferenceType, PackedInferenceType, FunctorInferenceType, InferenceVariable, ConvolutionObject
2323
export FunctorSingleton, FunctorPairwise, FunctorPairwiseMinimize
2424
export label, timestamp, tags, estimates, estimate, data, softtype, solverData, getData, solverDataDict, setSolverData, internalId, smallData, bigData
2525
export DFGVariableSummary, DFGFactorSummary, AbstractDFGSummary
2626

27+
#Skeleton types
28+
export SkeletonDFGVariable, SkeletonDFGFactor
29+
2730
#graph small data
2831
export getUserData, setUserData, getRobotData, setRobotData, getSessionData, setSessionData
2932
export pushUserData!, pushRobotData!, pushSessionData!, popUserData!, popRobotData!, popSessionData!

src/LightDFG/services/LightDFG.jl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ function addFactor!(dfg::LightDFG{<:AbstractParams, V, F}, variables::Vector{V},
8888

8989
variableLabels = map(v->v.label, variables)
9090

91-
factor._variableOrderSymbols = copy(variableLabels)
92-
91+
resize!(factor._variableOrderSymbols, length(variableLabels))
92+
factor._variableOrderSymbols .= variableLabels
93+
# factor._variableOrderSymbols = copy(variableLabels)
9394

9495
return FactorGraphs.addFactor!(dfg.g, variableLabels, factor)
9596
end
@@ -104,12 +105,23 @@ function addFactor!(dfg::LightDFG{<:AbstractParams, <:AbstractDFGVariable, F}, v
104105
error("Factor '$(factor.label)' already exists in the factor graph")
105106
end
106107

107-
factor._variableOrderSymbols = variableLabels
108+
resize!(factor._variableOrderSymbols, length(variableLabels))
109+
factor._variableOrderSymbols .= variableLabels
110+
# factor._variableOrderSymbols = copy(variableLabels)
108111

109112
return FactorGraphs.addFactor!(dfg.g, variableLabels, factor)
110113
end
111114

112115

116+
function addFactor!(dfg::LightDFG{<:AbstractParams, <:AbstractDFGVariable, F}, factor::F)::Bool where F <: AbstractDFGFactor
117+
#TODO should this be an error
118+
if haskey(dfg.g.factors, factor.label)
119+
error("Factor '$(factor.label)' already exists in the factor graph")
120+
end
121+
122+
return FactorGraphs.addFactor!(dfg.g, variableLabels, factor)
123+
end
124+
113125
"""
114126
$(SIGNATURES)
115127
Get a DFGVariable from a DFG using its label.

src/entities/DFGFactor.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,19 @@ label(f::DFGFactorSummary) = f.label
103103
data(f::DFGFactorSummary) = f.data
104104
tags(f::DFGFactorSummary) = f.tags
105105
internalId(f::DFGFactorSummary) = f._internalId
106+
107+
108+
# SKELETON DFG
109+
"""
110+
$(TYPEDEF)
111+
Skeleton variable with essentials.
112+
"""
113+
struct SkeletonDFGVariable <: AbstractDFGVariable
114+
label::Symbol
115+
tags::Vector{Symbol}
116+
end
117+
118+
SkeletonDFGVariable(label::Symbol) = SkeletonDFGVariable(label, Symbol[])
119+
120+
label(v::SkeletonDFGVariable) = v.label
121+
tags(v::SkeletonDFGVariable) = v.tags

src/entities/DFGVariable.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,22 @@ estimates(v::DFGVariableSummary) = v.estimateDict
174174
estimate(v::DFGVariableSummary, key::Symbol=:default) = haskey(v.estimateDict, key) ? v.estimateDict[key] : nothing
175175
softtype(v::DFGVariableSummary)::Symbol = v.softtypename
176176
internalId(v::DFGVariableSummary) = v._internalId
177+
178+
179+
180+
# SKELETON DFG
181+
"""
182+
$(TYPEDEF)
183+
Skeleton factor with essentials.
184+
"""
185+
struct SkeletonDFGFactor <: AbstractDFGFactor
186+
label::Symbol
187+
tags::Vector{Symbol}
188+
_variableOrderSymbols::Vector{Symbol}
189+
end
190+
191+
#NOTE I feel like a want to force a variableOrderSymbols
192+
SkeletonDFGFactor(label::Symbol, variableOrderSymbols::Vector{Symbol} = Symbol[]) = SkeletonDFGFactor(label, Symbol[], variableOrderSymbols)
193+
194+
label(f::SkeletonDFGFactor) = f.label
195+
tags(f::SkeletonDFGFactor) = f.tags

src/services/DFGVariable.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ Equality check for AbstractPointParametricEst.
120120
mapreduce(n -> :(x.$n == y.$n), (a,b)->:($a && $b), fieldnames(x))
121121
end
122122

123+
@generated function Base.:(==)(x::T, y::T) where T <: Union{DFGFactorSummary, DFGVariableSummary, SkeletonDFGVariable, SkeletonDFGFactor}
124+
mapreduce(n -> :(x.$n == y.$n), (a,b)->:($a && $b), fieldnames(x))
125+
end
126+
123127
"""
124128
$(SIGNATURES)
125129
Equality check for DFGVariable.

test/LightDFGSummaryTypes.jl

Lines changed: 72 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
1-
dfg = LightDFG{NoSolverParams, DFGVariableSummary, DFGFactorSummary}()
21

2+
dfg = LightDFG{NoSolverParams, VARTYPE, FACTYPE}()
33
DistributedFactorGraphs.DFGVariableSummary(label::Symbol) = DFGVariableSummary(label, DistributedFactorGraphs.now(), Symbol[], Dict{Symbol, MeanMaxPPE}(), :NA, 0)
4-
54
DistributedFactorGraphs.DFGFactorSummary(label::Symbol) = DFGFactorSummary(label, Symbol[], 0, Symbol[])
65

7-
v1 = DFGVariableSummary(:a)
8-
v2 = DFGVariableSummary(:b)
9-
f1 = DFGFactorSummary(:f1)
6+
v1 = VARTYPE(:a)
7+
v2 = VARTYPE(:b)
8+
f1 = FACTYPE(:f1)
109

1110
#add tags for filters
1211
append!(v1.tags, [:VARIABLE, :POSE])
1312
append!(v2.tags, [:VARIABLE, :LANDMARK])
1413
append!(f1.tags, [:FACTOR])
1514

1615
#Force softtypename
17-
v1.softtypename = :Pose2
16+
isa(v1, DFGVariableSummary) && (v1.softtypename = :Pose2)
1817

1918
# @testset "Creating Graphs" begin
2019
global dfg,v1,v2,f1
2120
addVariable!(dfg, v1)
2221
addVariable!(dfg, v2)
2322
addFactor!(dfg, [v1, v2], f1)
24-
@test_throws Exception addFactor!(dfg, DFGFactorSummary("f2"), [v1, DFGVariableSummary("Nope")])
23+
@test_throws Exception addFactor!(dfg, FACTYPE("f2"), [v1, VARTYPE("Nope")])
2524
# end
2625

2726
@testset "Adding Removing Nodes" begin
28-
dfg2 = LightDFG{NoSolverParams, DFGVariableSummary, DFGFactorSummary}()
29-
v1 = DFGVariableSummary(:a)
30-
v2 = DFGVariableSummary(:b)
31-
v3 = DFGVariableSummary(:c)
32-
f1 = DFGFactorSummary(:f1)
33-
f2 = DFGFactorSummary(:f2)
27+
dfg2 = LightDFG{NoSolverParams, VARTYPE, FACTYPE}()
28+
v1 = VARTYPE(:a)
29+
v2 = VARTYPE(:b)
30+
v3 = VARTYPE(:c)
31+
f1 = FACTYPE(:f1)
32+
f2 = FACTYPE(:f2)
3433
# @testset "Creating Graphs" begin
3534
@test addVariable!(dfg2, v1)
3635
@test addVariable!(dfg2, v2)
@@ -79,6 +78,8 @@ end
7978
# Gets
8079
@testset "Gets, Sets, and Accessors" begin
8180
global dfg,v1,v2,f1
81+
82+
8283
@test getVariable(dfg, v1.label) == v1
8384
@test getFactor(dfg, f1.label) == f1
8485
@test_throws Exception getVariable(dfg, :nope)
@@ -88,22 +89,25 @@ end
8889

8990
# Sets
9091
v1Prime = deepcopy(v1)
91-
@test updateVariable!(dfg, v1Prime) != v1
92+
@test updateVariable!(dfg, v1Prime) == v1
9293
f1Prime = deepcopy(f1)
93-
@test updateFactor!(dfg, f1Prime) != f1
94+
@test updateFactor!(dfg, f1Prime) == f1
9495

9596
# Accessors
9697
@test label(v1) == v1.label
9798
@test tags(v1) == v1.tags
98-
@test timestamp(v1) == v1.timestamp
99-
@test estimates(v1) == v1.estimateDict
100-
@test estimate(v1, :notfound) == nothing
101-
@test softtype(v1) == :Pose2
99+
100+
if VARTYPE == DFGVariableSummary
101+
@test timestamp(v1) == v1.timestamp
102+
@test estimates(v1) == v1.estimateDict
103+
@test estimate(v1, :notfound) == nothing
104+
@test softtype(v1) == :Pose2
105+
@test internalId(v1) == v1._internalId
106+
end
102107
# @test solverData(v1) === v1.solverDataDict[:default]
103108
# @test getData(v1) === v1.solverDataDict[:default]
104109
# @test solverData(v1, :default) === v1.solverDataDict[:default]
105110
# @test solverDataDict(v1) == v1.solverDataDict
106-
@test internalId(v1) == v1._internalId
107111

108112
@test label(f1) == f1.label
109113
@test tags(f1) == f1.tags
@@ -112,44 +116,46 @@ end
112116
# @test data(f1) == f1.data
113117
# @test getData(f1) == f1.data
114118
# Internal function
115-
@test internalId(f1) == f1._internalId
119+
if FACTYPE == DFGFactorSummary
120+
@test internalId(f1) == f1._internalId
121+
end
116122

117-
@test getSolverParams(dfg) != nothing
118-
@test setSolverParams(dfg, getSolverParams(dfg)) == getSolverParams(dfg)
119123
end
120124

121125
@testset "Updating Nodes" begin
122-
global dfg
123-
#get the variable
124-
var = getVariable(dfg, :a)
125-
#make a copy and simulate external changes
126-
newvar = deepcopy(var)
127-
estimates(newvar)[:default] = MeanMaxPPE(:default, [100.0], [50.0])
128-
#update
129-
mergeUpdateVariableSolverData!(dfg, newvar)
130-
#For now spot check
131-
# @test solverDataDict(newvar) == solverDataDict(var)
132-
@test estimates(newvar) == estimates(var)
126+
if VARTYPE == DFGVariableSummary
127+
global dfg
128+
#get the variable
129+
var = getVariable(dfg, :a)
130+
#make a copy and simulate external changes
131+
newvar = deepcopy(var)
132+
estimates(newvar)[:default] = MeanMaxPPE(:default, [100.0], [50.0])
133+
#update
134+
mergeUpdateVariableSolverData!(dfg, newvar)
135+
#For now spot check
136+
# @test solverDataDict(newvar) == solverDataDict(var)
137+
@test estimates(newvar) == estimates(var)
133138

134-
# Delete :default and replace to see if new ones can be added
135-
delete!(estimates(newvar), :default)
136-
estimates(newvar)[:second] = MeanMaxPPE(:second, [10.0], [5.0])
139+
# Delete :default and replace to see if new ones can be added
140+
delete!(estimates(newvar), :default)
141+
estimates(newvar)[:second] = MeanMaxPPE(:second, [10.0], [5.0])
137142

138-
# Persist to the original variable.
139-
mergeUpdateVariableSolverData!(dfg, newvar)
140-
# At this point newvar will have only :second, and var should have both (it is the reference)
141-
@test symdiff(collect(keys(estimates(var))), [:default, :second]) == Symbol[]
142-
@test symdiff(collect(keys(estimates(newvar))), [:second]) == Symbol[]
143-
# Get the source too.
144-
@test symdiff(collect(keys(estimates(getVariable(dfg, :a)))), [:default, :second]) == Symbol[]
143+
# Persist to the original variable.
144+
mergeUpdateVariableSolverData!(dfg, newvar)
145+
# At this point newvar will have only :second, and var should have both (it is the reference)
146+
@test symdiff(collect(keys(estimates(var))), [:default, :second]) == Symbol[]
147+
@test symdiff(collect(keys(estimates(newvar))), [:second]) == Symbol[]
148+
# Get the source too.
149+
@test symdiff(collect(keys(estimates(getVariable(dfg, :a)))), [:default, :second]) == Symbol[]
150+
end
145151
end
146152

147153
# Connectivity test
148154
@testset "Connectivity Test" begin
149155
global dfg,v1,v2,f1
150156
@test isFullyConnected(dfg) == true
151157
@test hasOrphans(dfg) == false
152-
addVariable!(dfg, DFGVariableSummary(:orphan))
158+
addVariable!(dfg, VARTYPE(:orphan))
153159
@test isFullyConnected(dfg) == false
154160
@test hasOrphans(dfg) == true
155161
end
@@ -191,13 +197,13 @@ end
191197

192198
# Now make a complex graph for connectivity tests
193199
numNodes = 10
194-
dfg = LightDFG{NoSolverParams, DFGVariableSummary, DFGFactorSummary}()
195-
verts = map(n -> DFGVariableSummary(Symbol("x$n")), 1:numNodes)
200+
dfg = LightDFG{NoSolverParams, VARTYPE, FACTYPE}()
201+
verts = map(n -> VARTYPE(Symbol("x$n")), 1:numNodes)
196202
#change ready and backendset for x7,x8 for improved tests on x7x8f1
197203
# verts[7].ready = 1
198204
# verts[8].backendset = 1
199205
map(v -> addVariable!(dfg, v), verts)
200-
map(n -> addFactor!(dfg, [verts[n], verts[n+1]], DFGFactorSummary(Symbol("x$(n)x$(n+1)f1"))), 1:(numNodes-1))
206+
map(n -> addFactor!(dfg, [verts[n], verts[n+1]], FACTYPE(Symbol("x$(n)x$(n+1)f1"))), 1:(numNodes-1))
201207

202208
@testset "Getting Neighbors" begin
203209
global dfg,verts
@@ -211,20 +217,6 @@ map(n -> addFactor!(dfg, [verts[n], verts[n+1]], DFGFactorSummary(Symbol("x$(n)x
211217
@test getNeighbors(dfg, getFactor(dfg, :x1x2f1)) == ls(dfg, getFactor(dfg, :x1x2f1))
212218
@test getNeighbors(dfg, :x1x2f1) == ls(dfg, :x1x2f1)
213219

214-
# ready and backendset
215-
# @test getNeighbors(dfg, :x5, ready=1) == Symbol[]
216-
# @test getNeighbors(dfg, :x5, ready=0) == [:x4x5f1,:x5x6f1]
217-
# @test getNeighbors(dfg, :x5, backendset=1) == Symbol[]
218-
# @test getNeighbors(dfg, :x5, backendset=0) == [:x4x5f1,:x5x6f1]
219-
# @test getNeighbors(dfg, :x7x8f1, ready=0) == [:x8]
220-
# @test getNeighbors(dfg, :x7x8f1, backendset=0) == [:x7]
221-
# @test getNeighbors(dfg, :x7x8f1, ready=1) == [:x7]
222-
# @test getNeighbors(dfg, :x7x8f1, backendset=1) == [:x8]
223-
# @test getNeighbors(dfg, verts[1], ready=0) == [:x1x2f1]
224-
# @test getNeighbors(dfg, verts[1], ready=1) == Symbol[]
225-
# @test getNeighbors(dfg, verts[1], backendset=0) == [:x1x2f1]
226-
# @test getNeighbors(dfg, verts[1], backendset=1) == Symbol[]
227-
228220
end
229221

230222
@testset "Getting Subgraphs" begin
@@ -256,41 +248,27 @@ end
256248
end
257249

258250
@testset "Summaries and Summary Graphs" begin
259-
factorFields = fieldnames(DFGFactorSummary)
260-
variableFields = fieldnames(DFGVariableSummary)
251+
if VARTYPE == DFGVariableSummary
252+
factorFields = fieldnames(FACTYPE)
253+
variableFields = fieldnames(VARTYPE)
261254

262-
summary = getSummary(dfg)
263-
@test symdiff(collect(keys(summary.variables)), ls(dfg)) == Symbol[]
264-
@test symdiff(collect(keys(summary.factors)), lsf(dfg)) == Symbol[]
255+
summary = getSummary(dfg)
256+
@test symdiff(collect(keys(summary.variables)), ls(dfg)) == Symbol[]
257+
@test symdiff(collect(keys(summary.factors)), lsf(dfg)) == Symbol[]
265258

266-
summaryGraph = getSummaryGraph(dfg)
267-
@test symdiff(ls(summaryGraph), ls(dfg)) == Symbol[]
268-
@test symdiff(lsf(summaryGraph), lsf(dfg)) == Symbol[]
269-
# Check all fields are equal for all variables
270-
for v in ls(summaryGraph)
271-
for field in variableFields
272-
@test getfield(getVariable(dfg, v), field) == getfield(getVariable(summaryGraph, v), field)
259+
summaryGraph = getSummaryGraph(dfg)
260+
@test symdiff(ls(summaryGraph), ls(dfg)) == Symbol[]
261+
@test symdiff(lsf(summaryGraph), lsf(dfg)) == Symbol[]
262+
# Check all fields are equal for all variables
263+
for v in ls(summaryGraph)
264+
for field in variableFields
265+
@test getfield(getVariable(dfg, v), field) == getfield(getVariable(summaryGraph, v), field)
266+
end
273267
end
274-
end
275-
for f in lsf(summaryGraph)
276-
for field in factorFields
277-
@test getfield(getFactor(dfg, f), field) == getfield(getFactor(summaryGraph, f), field)
268+
for f in lsf(summaryGraph)
269+
for field in factorFields
270+
@test getfield(getFactor(dfg, f), field) == getfield(getFactor(summaryGraph, f), field)
271+
end
278272
end
279273
end
280274
end
281-
282-
# @testset "Producing Dot Files" begin
283-
# # create a simpler graph for dot testing
284-
# dotdfg = LightDFG{NoSolverParams, DFGVariableSummary, DFGFactorSummary}()
285-
# v1 = DFGVariableSummary(:a)
286-
# v2 = DFGVariableSummary(:b)
287-
# f1 = DFGFactorSummary(:f1)
288-
# addVariable!(dotdfg, v1)
289-
# addVariable!(dotdfg, v2)
290-
# addFactor!(dotdfg, [v1, v2], f1)
291-
#
292-
# @test toDot(dotdfg) == "graph graphname {\n2 [\"label\"=\"b\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n2 -- 3\n3 [\"label\"=\"f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n1 [\"label\"=\"a\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n1 -- 3\n}\n"
293-
# @test toDotFile(dotdfg, "something.dot") == nothing
294-
# Base.rm("something.dot")
295-
#
296-
# end

test/runtests.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,17 @@ end
3737
include("plottingTest.jl")
3838
end
3939

40-
@testset "SummaryDFG test" begin
41-
@info "Testing LightDFG Variable and Factor Subtypes"
42-
include("LightDFGSummaryTypes.jl")
40+
@testset "LightDFG subtype tests" begin
41+
for type in [(var=DFGVariableSummary, fac=DFGFactorSummary), (var=SkeletonDFGVariable,fac=SkeletonDFGFactor)]
42+
@testset "$(type.var) and $(type.fac) tests" begin
43+
@info "Testing $(type.var) and $(type.fac)"
44+
global VARTYPE = type.var
45+
global FACTYPE = type.fac
46+
include("LightDFGSummaryTypes.jl")
47+
end
48+
end
4349
end
4450

45-
4651
if get(ENV, "IIF_TEST", "") == "true"
4752

4853
# Pkg.add("IncrementalInference")

0 commit comments

Comments
 (0)