Skip to content

Commit 775d2dc

Browse files
authored
Feature add nanosecond time to DFGVariable and DFGFactor (#478)
* Add nstime to DFGVariable and DFGFactor * pack/unpack nstime
1 parent 3463d2e commit 775d2dc

File tree

8 files changed

+35
-21
lines changed

8 files changed

+35
-21
lines changed

src/entities/DFGFactor.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ struct DFGFactor{T, N} <: AbstractDFGFactor
101101
"""Variable timestamp.
102102
Accessors: [`getTimestamp`](@ref), [`setTimestamp`](@ref)"""
103103
timestamp::DateTime
104+
"""Nano second time, for more resolution on timestamp (only subsecond information)"""
105+
nstime::Nanosecond
104106
"""Factor tags, e.g [:FACTOR].
105107
Accessors: [`getTags`](@ref), [`mergeTags!`](@ref), and [`removeTags!`](@ref)"""
106108
tags::Set{Symbol}
@@ -113,15 +115,15 @@ struct DFGFactor{T, N} <: AbstractDFGFactor
113115
"""Internal cache of the ordering of the neighbor variables. Rather use getVariableOrder to get the list as this is an internal value.
114116
Accessors: [`getVariableOrder`](@ref)"""
115117
_variableOrderSymbols::NTuple{N,Symbol}
116-
117118
# Inner constructor
118119
DFGFactor{T}(label::Symbol,
119120
timestamp::DateTime,
121+
nstime::Nanosecond,
120122
tags::Set{Symbol},
121123
solverData::GenericFunctionNodeData{T},
122124
solvable::Int,
123125
_variableOrderSymbols::NTuple{N,Symbol}) where {T,N} =
124-
new{T,N}(label, timestamp, tags, Ref(solverData), Ref(solvable), _variableOrderSymbols)
126+
new{T,N}(label, timestamp, nstime, tags, Ref(solverData), Ref(solvable), _variableOrderSymbols)
125127

126128
end
127129

@@ -135,24 +137,26 @@ Construct a DFG factor given a label.
135137
"""
136138
DFGFactor(label::Symbol,
137139
timestamp::DateTime,
140+
nstime::Nanosecond,
138141
tags::Set{Symbol},
139142
solverData::GenericFunctionNodeData{T},
140143
solvable::Int,
141144
_variableOrderSymbols::Tuple) where {T} =
142-
DFGFactor{T}(label, timestamp, tags, solverData, solvable, _variableOrderSymbols)
145+
DFGFactor{T}(label, timestamp, nstime, tags, solverData, solvable, _variableOrderSymbols)
143146

144147

145148
DFGFactor{T}(label::Symbol, variableOrderSymbols::Vector{Symbol}, timestamp::DateTime=now(), data::GenericFunctionNodeData{T} = GenericFunctionNodeData{T}()) where {T} =
146-
DFGFactor(label, timestamp, Set{Symbol}(), data, 1, Tuple(variableOrderSymbols))
149+
DFGFactor(label, timestamp, Nanosecond(0), Set{Symbol}(), data, 1, Tuple(variableOrderSymbols))
147150

148151

149152
DFGFactor(label::Symbol,
150153
variableOrderSymbols::Vector{Symbol},
151154
data::GenericFunctionNodeData{T};
152155
tags::Set{Symbol}=Set{Symbol}(),
153156
timestamp::DateTime=now(),
154-
solvable::Int=1) where {T} =
155-
DFGFactor{T}(label, timestamp, tags, data, solvable, Tuple(variableOrderSymbols))
157+
solvable::Int=1,
158+
nstime::Nanosecond = Nanosecond(0)) where {T} =
159+
DFGFactor{T}(label, timestamp, nstime, tags, data, solvable, Tuple(variableOrderSymbols))
156160

157161

158162

src/entities/DFGVariable.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ struct DFGVariable{T<:InferenceVariable} <: AbstractDFGVariable
185185
"""Variable timestamp.
186186
Accessors: [`getTimestamp`](@ref), [`setTimestamp`](@ref)"""
187187
timestamp::DateTime
188+
"""Nano second time, for more resolution on timestamp (only subsecond information)"""
189+
nstime::Nanosecond
188190
"""Variable tags, e.g [:POSE, :VARIABLE, and :LANDMARK].
189191
Accessors: [`getTags`](@ref), [`mergeTags!`](@ref), and [`removeTags!`](@ref)"""
190192
tags::Set{Symbol}
@@ -214,24 +216,26 @@ The default DFGVariable constructor.
214216
"""
215217
DFGVariable(label::Symbol, softtype::T;
216218
timestamp::DateTime=now(),
219+
nstime::Nanosecond = Nanosecond(0),
217220
tags::Set{Symbol}=Set{Symbol}(),
218221
estimateDict::Dict{Symbol, <: AbstractPointParametricEst}=Dict{Symbol, MeanMaxPPE}(),
219222
solverDataDict::Dict{Symbol, VariableNodeData{T}}=Dict{Symbol, VariableNodeData{T}}(),
220223
smallData::Dict{String, String}=Dict{String, String}(),
221224
bigData::Dict{Symbol, AbstractBigDataEntry}=Dict{Symbol,AbstractBigDataEntry}(),
222225
solvable::Int=1) where {T <: InferenceVariable} =
223-
DFGVariable{T}(label, timestamp, tags, estimateDict, solverDataDict, smallData, bigData, Ref(solvable))
226+
DFGVariable{T}(label, timestamp, nstime, tags, estimateDict, solverDataDict, smallData, bigData, Ref(solvable))
224227

225228

226229
DFGVariable(label::Symbol,
227230
solverData::VariableNodeData{T};
228231
timestamp::DateTime=now(),
232+
nstime::Nanosecond = Nanosecond(0),
229233
tags::Set{Symbol}=Set{Symbol}(),
230234
estimateDict::Dict{Symbol, <: AbstractPointParametricEst}=Dict{Symbol, MeanMaxPPE}(),
231235
smallData::Dict{String, String}=Dict{String, String}(),
232236
bigData::Dict{Symbol, AbstractBigDataEntry}=Dict{Symbol,AbstractBigDataEntry}(),
233237
solvable::Int=1) where {T <: InferenceVariable} =
234-
DFGVariable{T}(label, timestamp, tags, estimateDict, Dict{Symbol, VariableNodeData{T}}(:default=>solverData), smallData, bigData, Ref(solvable))
238+
DFGVariable{T}(label, timestamp, nstime, tags, estimateDict, Dict{Symbol, VariableNodeData{T}}(:default=>solverData), smallData, bigData, Ref(solvable))
235239

236240
Base.getproperty(x::DFGVariable,f::Symbol) = begin
237241
if f == :solvable
@@ -251,11 +255,12 @@ end
251255

252256

253257
##------------------------------------------------------------------------------
254-
function Base.copy(o::DFGVariable)::DFGVariable
255-
return DFGVariable(o.label, getSofttype(o)(), tags=copy(o.tags), estimateDict=copy(o.estimateDict),
256-
solverDataDict=copy(o.solverDataDict), smallData=copy(o.smallData),
257-
bigData=copy(o.bigData), solvable=getSolvable(o))
258-
end
258+
# TODO: can't see the reason to overwrite copy, leaving it here for now
259+
# function Base.copy(o::DFGVariable)::DFGVariable
260+
# return DFGVariable(o.label, getSofttype(o)(), tags=copy(o.tags), estimateDict=copy(o.estimateDict),
261+
# solverDataDict=copy(o.solverDataDict), smallData=copy(o.smallData),
262+
# bigData=copy(o.bigData), solvable=getSolvable(o))
263+
# end
259264

260265
##------------------------------------------------------------------------------
261266
## DFGVariableSummary lv1

src/services/AbstractDFG.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ function addFactor!(dfg::AbstractDFG, variables::Vector{<:AbstractDFGVariable},
394394

395395
if factor isa DFGFactor
396396
f = factor
397-
newfactor = DFGFactor(f.label, f.timestamp, f.tags, f.solverData, f.solvable, Tuple(variableLabels))
397+
newfactor = DFGFactor(f.label, f.timestamp, f.nstime, f.tags, f.solverData, f.solvable, Tuple(variableLabels))
398398
return addFactor!(dfg, newfactor)
399399
else
400400
resize!(factor._variableOrderSymbols, length(variableLabels))
@@ -413,7 +413,7 @@ function addFactor!(dfg::AbstractDFG, variableLabels::Vector{Symbol}, factor::F)
413413

414414
if factor isa DFGFactor
415415
f = factor
416-
newfactor = DFGFactor(f.label, f.timestamp, f.tags, f.solverData, f.solvable, Tuple(variableLabels))
416+
newfactor = DFGFactor(f.label, f.timestamp, f.nstime, f.tags, f.solverData, f.solvable, Tuple(variableLabels))
417417
return addFactor!(dfg, newfactor)
418418
else
419419
resize!(factor._variableOrderSymbols, length(variableLabels))

src/services/DFGFactor.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ end
6969

7070

7171
function setTimestamp(f::DFGFactor, ts::DateTime)
72-
return DFGFactor(f.label, ts, f.tags, f.solverData, f.solvable, getfield(f,:_variableOrderSymbols))
72+
return DFGFactor(f.label, ts, f.nstime, f.tags, f.solverData, f.solvable, getfield(f,:_variableOrderSymbols))
7373
end
7474

7575
function setTimestamp(f::DFGFactorSummary, ts::DateTime)

src/services/DFGVariable.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ function setTimestamp(v::DFGVariable, ts::DateTime; verbose::Bool=true)
166166
if verbose
167167
@warn "verbose=true: setTimestamp(::DFGVariable,...) creates a returns a new immutable DFGVariable object (and didn't change a distributed factor graph object), make sure you are using the right pointers: getVariable(...). See setTimestamp!(...) and note suggested use is at addVariable!(..., [timestamp=...]). See DFG #315 for explanation."
168168
end
169-
return DFGVariable(v.label, ts, v.tags, v.ppeDict, v.solverDataDict, v.smallData, v.bigData, Ref(v.solvable))
169+
return DFGVariable(v.label, ts, v.nstime, v.tags, v.ppeDict, v.solverDataDict, v.smallData, v.bigData, Ref(v.solvable))
170170
end
171171

172172
function setTimestamp(v::DFGVariableSummary, ts::DateTime; verbose::Bool=true)

src/services/Serialization.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function packVariable(dfg::G, v::DFGVariable)::Dict{String, Any} where G <: Abst
99
props = Dict{String, Any}()
1010
props["label"] = string(v.label)
1111
props["timestamp"] = string(v.timestamp)
12+
props["nstime"] = string(v.nstime.value)
1213
props["tags"] = JSON2.write(v.tags)
1314
props["ppeDict"] = JSON2.write(v.ppeDict)
1415
props["solverDataDict"] = JSON2.write(Dict(keys(v.solverDataDict) .=> map(vnd -> packVariableNodeData(dfg, vnd), values(v.solverDataDict))))
@@ -23,6 +24,7 @@ end
2324
function unpackVariable(dfg::G, packedProps::Dict{String, Any})::DFGVariable where G <: AbstractDFG
2425
label = Symbol(packedProps["label"])
2526
timestamp = DateTime(packedProps["timestamp"])
27+
nstime = Nanosecond(get(packedProps, "nstime", 0))
2628
tags = JSON2.read(packedProps["tags"], Vector{Symbol})
2729
#TODO this will work for some time, but unpacking in an <: AbstractPointParametricEst would be lekker.
2830
ppeDict = JSON2.read(packedProps["ppeDict"], Dict{Symbol, MeanMaxPPE})
@@ -37,7 +39,7 @@ function unpackVariable(dfg::G, packedProps::Dict{String, Any})::DFGVariable whe
3739
solverData = Dict(Symbol.(keys(packed)) .=> map(p -> unpackVariableNodeData(dfg, p), values(packed)))
3840

3941
# Rebuild DFGVariable using the first solver softtype in solverData
40-
variable = DFGVariable{softtype}(Symbol(packedProps["label"]), timestamp, Set(tags), ppeDict, solverData, smallData, Dict{Symbol,AbstractBigDataEntry}(), Ref(packedProps["solvable"]))
42+
variable = DFGVariable{softtype}(Symbol(packedProps["label"]), timestamp, nstime, Set(tags), ppeDict, solverData, smallData, Dict{Symbol,AbstractBigDataEntry}(), Ref(packedProps["solvable"]))
4143

4244
# Now rehydrate complete bigData type.
4345
for (k,bdeInter) in bigDataIntermed
@@ -96,6 +98,7 @@ function packFactor(dfg::G, f::DFGFactor)::Dict{String, Any} where G <: Abstract
9698
props = Dict{String, Any}()
9799
props["label"] = string(f.label)
98100
props["timestamp"] = string(f.timestamp)
101+
props["nstime"] = string(f.nstime.value)
99102
props["tags"] = JSON2.write(f.tags)
100103
# Pack the node data
101104
fnctype = getSolverData(f).fnc.usrfnc!
@@ -132,6 +135,7 @@ end
132135
function unpackFactor(dfg::G, packedProps::Dict{String, Any})::DFGFactor where G <: AbstractDFG
133136
label = packedProps["label"]
134137
timestamp = DateTime(packedProps["timestamp"])
138+
nstime = Nanosecond(get(packedProps, "nstime", 0))
135139
tags = JSON2.read(packedProps["tags"], Vector{Symbol})
136140

137141
data = packedProps["data"]
@@ -161,6 +165,7 @@ function unpackFactor(dfg::G, packedProps::Dict{String, Any})::DFGFactor where G
161165
#TODO use constuctor to create factor
162166
factor = DFGFactor(Symbol(label),
163167
timestamp,
168+
nstime,
164169
Set(tags),
165170
fullFactorData,
166171
solvable,

test/interfaceTests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ end
4949
@test printVariable(var1) == nothing
5050
@test printFactor(fac1) == nothing
5151

52-
@test printVariable(iobuf, var1, skipfields=[:timestamp, :solver, :ppe]) == nothing
52+
@test printVariable(iobuf, var1, skipfields=[:timestamp, :solver, :ppe, :nstime]) == nothing
5353
@test String(take!(iobuf)) == "DFGVariable{TestSofttype1}\nlabel:\n:a\ntags:\nSet([:VARIABLE, :POSE])\nsmallData:\nDict(\"small\"=>\"data\")\nbigData:\nDict{Symbol,AbstractBigDataEntry}()\nsolvable:\n0\n"
5454

5555
@test printVariable(iobuf, var1, short=true) == nothing
5656
@test String(take!(iobuf)) == "DFGVariable{TestSofttype1}\nlabel: a\ntags: Set([:VARIABLE, :POSE])\nsize marginal samples: (1, 1)\nkde bandwidths: [0.0]\nNo PPEs\n"
5757

5858

59-
@test printFactor(iobuf, fac1, skipfields=[:timestamp, :solver]) == nothing
59+
@test printFactor(iobuf, fac1, skipfields=[:timestamp, :solver, :nstime]) == nothing
6060
@test occursin(r"DFGFactor.*\nlabel:\n:abf1", String(take!(iobuf)))
6161

6262
String(take!(iobuf)) == "DFGFactor{TestCCW{TestFunctorInferenceType1}}\nlabel:\n:abf1\ntags:\nSet([:tag1, :tag2])\nsolvable:\n0\nsolvable:\n1\n_variableOrderSymbols:\n[:a, :b]\n"

test/testBlocks.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ function VariablesandFactorsCRUD_SET!(fg, v1, v2, v3, f0, f1, f2)
410410

411411

412412
if f2 isa DFGFactor
413-
f2_mod = DFGFactor(f2.label, f2.timestamp, f2.tags, f2.solverData, f2.solvable, (:a,))
413+
f2_mod = DFGFactor(f2.label, f2.timestamp, f2.nstime, f2.tags, f2.solverData, f2.solvable, (:a,))
414414
else
415415
f2_mod = deepcopy(f2)
416416
pop!(f2_mod._variableOrderSymbols)

0 commit comments

Comments
 (0)