Skip to content

Commit f2fc7c0

Browse files
committed
File loading and saving
1 parent a9ca114 commit f2fc7c0

File tree

2 files changed

+106
-6
lines changed

2 files changed

+106
-6
lines changed

src/FileDFG/services/FileDFG.jl

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,30 @@ function _packVariable(dfg::G, v::DFGVariable)::Dict{String, Any} where G <: Abs
1212
return props
1313
end
1414

15+
function _unpackVariable(dfg::G, packedProps::Dict{String, Any})::DFGVariable where G <: AbstractDFG
16+
label = Symbol(packedProps["label"])
17+
timestamp = DateTime(packedProps["timestamp"])
18+
tags = JSON2.read(packedProps["tags"], Vector{Symbol})
19+
estimateDict = JSON2.read(packedProps["estimateDict"], Dict{Symbol, VariableEstimate})
20+
smallData = nothing
21+
smallData = JSON2.read(packedProps["smallData"], Dict{String, String})
22+
23+
packed = JSON2.read(packedProps["solverDataDict"], Dict{String, PackedVariableNodeData})
24+
solverData = Dict(Symbol.(keys(packed)) .=> map(p -> unpack(dfg, p), values(packed)))
25+
26+
# Rebuild DFGVariable
27+
variable = DFGVariable(Symbol(packedProps["label"]))
28+
variable.timestamp = timestamp
29+
variable.tags = tags
30+
variable.estimateDict = estimateDict
31+
variable.solverDataDict = solverData
32+
variable.smallData = smallData
33+
variable.ready = packedProps["ready"]
34+
variable.backendset = packedProps["backendset"]
35+
36+
return variable
37+
end
38+
1539
function _packFactor(dfg::G, f::DFGFactor)::Dict{String, Any} where G <: AbstractDFG
1640
# Construct the properties to save
1741
props = Dict{String, Any}()
@@ -31,6 +55,39 @@ function _packFactor(dfg::G, f::DFGFactor)::Dict{String, Any} where G <: Abstrac
3155
return props
3256
end
3357

58+
59+
function _unpackFactor(dfg::G, packedProps::Dict{String, Any}, iifModule)::DFGFactor where G <: AbstractDFG
60+
label = packedProps["label"]
61+
tags = JSON2.read(packedProps["tags"], Vector{Symbol})
62+
63+
data = packedProps["data"]
64+
datatype = packedProps["fnctype"]
65+
packtype = getfield(Main, Symbol("Packed"*datatype))
66+
packed = JSON2.read(data, GenericFunctionNodeData{packtype,String})
67+
fullFactor = iifModule.decodePackedType(dfg, packed)
68+
# fullFactor = dfg.decodePackedTypeFunc(dfg, packed)
69+
70+
# Include the type
71+
_variableOrderSymbols = JSON2.read(packedProps["_variableOrderSymbols"], Vector{Symbol})
72+
backendset = packedProps["backendset"]
73+
ready = packedProps["ready"]
74+
75+
# Rebuild DFGVariable
76+
factor = DFGFactor{typeof(fullFactor.fnc), Symbol}(Symbol(label))
77+
factor.tags = tags
78+
factor.data = fullFactor
79+
factor._variableOrderSymbols = _variableOrderSymbols
80+
factor.ready = ready
81+
factor.backendset = backendset
82+
83+
# GUARANTEED never to bite us in the ass in the future...
84+
# ... TODO: refactor if changed: https://github.com/JuliaRobotics/IncrementalInference.jl/issues/350
85+
getData(factor).fncargvID = _variableOrderSymbols
86+
87+
# Note, once inserted, you still need to call IIF.rebuildFactorMetadata!
88+
return factor
89+
end
90+
3491
function saveDFG(dfg::G, folder::String) where G <: AbstractDFG
3592
variables = getVariables(dfg)
3693
factors = getFactors(dfg)
@@ -62,6 +119,43 @@ function saveDFG(dfg::G, folder::String) where G <: AbstractDFG
62119
end
63120
end
64121

65-
function loadDFG(folderName::String, dfgLoadInto::G=GraphsDFG{NoSolverParams}()) where G <: AbstractDFG
122+
function loadDFG(folder::String, iifModule, dfgLoadInto::G=GraphsDFG{NoSolverParams}()) where G <: AbstractDFG
123+
variables = DFGVariable[]
124+
factors = DFGFactor[]
125+
varFolder = "$folder/variables"
126+
factorFolder = "$folder/factors"
127+
# Folder preparations
128+
!isdir(folder) && error("Can't load DFG graph - folder '$folder' doesn't exist")
129+
!isdir(varFolder) && error("Can't load DFG graph - folder '$folder' doesn't exist")
130+
!isdir(factorFolder) && error("Can't load DFG graph - folder '$folder' doesn't exist")
131+
132+
varFiles = readdir(varFolder)
133+
factorFiles = readdir(factorFolder)
134+
for varFile in varFiles
135+
io = open("$varFolder/$varFile")
136+
packedData = JSON2.read(io, Dict{String, Any})
137+
push!(variables, _unpackVariable(dfgLoadInto, packedData))
138+
end
139+
@info "Loaded $(length(variables)) variables - $(map(v->v.label, variables))"
140+
@info "Inserting variables into graph..."
141+
# Adding variables
142+
map(v->addVariable!(dfgLoadInto, v), variables)
143+
144+
for factorFile in factorFiles
145+
io = open("$factorFolder/$factorFile")
146+
packedData = JSON2.read(io, Dict{String, Any})
147+
push!(factors, _unpackFactor(dfgLoadInto, packedData, iifModule))
148+
end
149+
@info "Loaded $(length(variables)) factors - $(map(f->f.label, factors))"
150+
@info "Inserting factors into graph..."
151+
# # Adding factors
152+
map(f->addFactor!(dfgLoadInto, f._variableOrderSymbols, f), factors)
153+
154+
# Finally, rebuild the CCW's for the factors to completely reinflate them
155+
@info "Rebuilding CCW's for the factors..."
156+
for factor in factors
157+
iifModule.rebuildFactorMetadata!(dfgLoadInto, factor)
158+
end
159+
66160
return dfgLoadInto
67161
end

test/FileDFG.jl

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,10 @@ using IncrementalInference, RoME
55

66
# Make a simple graph
77
dfg = GraphsDFG{SolverParams}(params=SolverParams())
8-
98
# Add the first pose :x0
109
x0 = addVariable!(dfg, :x0, Pose2)
11-
IncrementalInference.compareVariable(x0, getVariable(dfg, :x0))
12-
1310
# Add at a fixed location PriorPose2 to pin :x0 to a starting location (10,10, pi/4)
1411
prior = addFactor!(dfg, [:x0], PriorPose2( MvNormal([10; 10; 1.0/8.0], Matrix(Diagonal([0.1;0.1;0.05].^2))) ) )
15-
1612
# Drive around in a hexagon
1713
for i in 0:5
1814
psym = Symbol("x$i")
@@ -22,4 +18,14 @@ for i in 0:5
2218
addFactor!(dfg, [psym;nsym], pp )
2319
end
2420

25-
saveDFG(dfg "/tmp/fileDFG")
21+
# Save it
22+
saveFolder = "/tmp/fileDFG"
23+
saveDFG(dfg, saveFolder)
24+
@test readdir("$saveFolder/variables") == ["x0.json", "x1.json", "x2.json", "x3.json", "x4.json", "x5.json", "x6.json"]
25+
@test readdir("$saveFolder/factors") == ["x0f1.json", "x0x1f1.json", "x1x2f1.json", "x2x3f1.json", "x3x4f1.json", "x4x5f1.json", "x5x6f1.json"]
26+
27+
retDFG = loadDFG(saveFolder, IncrementalInference)
28+
@test symdiff(ls(dfg), ls(dfg)) == []
29+
@test symdiff(lsf(dfg), lsf(retDFG)) == []
30+
31+
# Success!

0 commit comments

Comments
 (0)