diff --git a/src/Common.jl b/src/Common.jl index b67e7841..ac637093 100644 --- a/src/Common.jl +++ b/src/Common.jl @@ -129,7 +129,7 @@ function getfnctype(data::GenericFunctionNodeData) return data.fnc.usrfnc! end function getfnctype(fact::DFGFactor; solveKey::Symbol=:default) - data = getData(fact) # TODO , solveKey=solveKey) + data = solverData(fact) # TODO , solveKey=solveKey) return getfnctype(data) end function getfnctype(dfg::T, lbl::Symbol; solveKey::Symbol=:default) where T <: AbstractDFG @@ -145,7 +145,7 @@ Notes - Replaces older `getfnctype`. """ getFactorType(data::GenericFunctionNodeData) = data.fnc.usrfnc! -getFactorType(fct::DFGFactor) = getFactorType(getData(fct)) +getFactorType(fct::DFGFactor) = getFactorType(solverData(fct)) function getFactorType(dfg::G, lbl::Symbol) where G <: AbstractDFG getFactorType(getFactor(dfg, lbl)) end @@ -190,7 +190,7 @@ function getSofttype(vnd::VariableNodeData) return vnd.softtype end function getSofttype(v::DFGVariable; solveKey::Symbol=:default) - return getSofttype(getData(v, solveKey=solveKey)) + return getSofttype(solverData(v, solveKey)) end """ diff --git a/src/DistributedFactorGraphs.jl b/src/DistributedFactorGraphs.jl index 0a52dcf7..9b1c47a5 100644 --- a/src/DistributedFactorGraphs.jl +++ b/src/DistributedFactorGraphs.jl @@ -21,7 +21,7 @@ export AbstractParams, NoSolverParams export DFGNode, DFGVariable, DFGFactor export InferenceType, PackedInferenceType, FunctorInferenceType, InferenceVariable, ConvolutionObject export FunctorSingleton, FunctorPairwise, FunctorPairwiseMinimize -export label, timestamp, tags, estimates, estimate, data, solverData, getData, solverDataDict, setSolverData, internalId, smallData, bigData +export label, timestamp, tags, estimates, estimate, data, softtype, solverData, getData, solverDataDict, setSolverData, internalId, smallData, bigData export DFGVariableSummary, DFGFactorSummary, AbstractDFGSummary # Services/AbstractDFG Exports diff --git a/src/entities/DFGVariable.jl b/src/entities/DFGVariable.jl index 84e7fa38..ab638b5b 100644 --- a/src/entities/DFGVariable.jl +++ b/src/entities/DFGVariable.jl @@ -77,9 +77,22 @@ mutable struct PackedVariableNodeData x15::Bool ) = new(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15) end -struct VariableEstimate + +abstract type AbstractVariableEstimate end +""" + $TYPEDEF + +Data container to store Parameteric Point Estimate (PPE) from a variety of types. + +Notes +- `ppeType` is something like `:max/:mean/:modefit` etc. +- `solveKey` is from super-solve concept, starting with `:default`, +- `estimate` is the actual numerical estimate value, +- Additional information such as how the data is represented (ie softtype) is stored alongside this data container in the `DFGVariableSummary` container. +""" +struct VariableEstimate <: AbstractVariableEstimate solverKey::Symbol - type::Symbol + ppeType::Symbol estimate::Vector{Float64} lastUpdatedTimestamp::DateTime VariableEstimate(solverKey::Symbol, type::Symbol, estimate::Vector{Float64}, lastUpdatedTimestamp::DateTime=now()) = new(solverKey, type, estimate, lastUpdatedTimestamp) @@ -93,7 +106,7 @@ mutable struct DFGVariable <: AbstractDFGVariable label::Symbol timestamp::DateTime tags::Vector{Symbol} - estimateDict::Dict{Symbol, Dict{Symbol, VariableEstimate}} + estimateDict::Dict{Symbol, Dict{Symbol, <: AbstractVariableEstimate}} solverDataDict::Dict{Symbol, VariableNodeData} smallData::Dict{String, String} bigData::Any @@ -110,6 +123,14 @@ timestamp(v::DFGVariable) = v.timestamp tags(v::DFGVariable) = v.tags estimates(v::DFGVariable) = v.estimateDict estimate(v::DFGVariable, key::Symbol=:default) = haskey(v.estimateDict, key) ? v.estimateDict[key] : nothing + +""" + $SIGNATURES + +Retrieve the soft type name symbol for a DFGVariable or DFGVariableSummary. ie :Point2, Pose2, etc. +""" +softtype(v::DFGVariable)::Symbol = Symbol(typeof(getSofttype(v))) + """ $SIGNATURES @@ -145,7 +166,8 @@ mutable struct DFGVariableSummary <: AbstractDFGVariable label::Symbol timestamp::DateTime tags::Vector{Symbol} - estimateDict::Dict{Symbol, Dict{Symbol, VariableEstimate}} + estimateDict::Dict{Symbol, Dict{Symbol, <:AbstractVariableEstimate}} + softtypename::Symbol _internalId::Int64 end label(v::DFGVariableSummary) = v.label @@ -153,4 +175,5 @@ timestamp(v::DFGVariableSummary) = v.timestamp tags(v::DFGVariableSummary) = v.tags estimates(v::DFGVariableSummary) = v.estimateDict estimate(v::DFGVariableSummary, key::Symbol=:default) = haskey(v.estimateDict, key) ? v.estimateDict[key] : nothing +softtype(v::DFGVariableSummary)::Symbol = v.softtypename internalId(v::DFGVariableSummary) = v._internalId diff --git a/src/services/DFGVariable.jl b/src/services/DFGVariable.jl index 866dc40a..f9363049 100644 --- a/src/services/DFGVariable.jl +++ b/src/services/DFGVariable.jl @@ -103,5 +103,5 @@ function ==(a::VariableNodeData,b::VariableNodeData, nt::Symbol=:var) end function convert(::Type{DFGVariableSummary}, v::DFGVariable) - return DFGVariableSummary(v.label, v.timestamp, deepcopy(v.tags), deepcopy(v.estimateDict), v._internalId) + return DFGVariableSummary(v.label, v.timestamp, deepcopy(v.tags), deepcopy(v.estimateDict), Symbol(typeof(getSofttype(v))), v._internalId) end diff --git a/test/LightDFGSummaryTypes.jl b/test/LightDFGSummaryTypes.jl index ed502d26..bab3f36e 100644 --- a/test/LightDFGSummaryTypes.jl +++ b/test/LightDFGSummaryTypes.jl @@ -1,6 +1,6 @@ dfg = LightDFG{NoSolverParams, DFGVariableSummary, DFGFactorSummary}() -DistributedFactorGraphs.DFGVariableSummary(label::Symbol) = DFGVariableSummary(label, DistributedFactorGraphs.now(), Symbol[], Dict{Symbol, VariableEstimate}(), 0) +DistributedFactorGraphs.DFGVariableSummary(label::Symbol) = DFGVariableSummary(label, DistributedFactorGraphs.now(), Symbol[], Dict{Symbol, VariableEstimate}(), :NA, 0) DistributedFactorGraphs.DFGFactorSummary(label::Symbol) = DFGFactorSummary(label, Symbol[], 0, Symbol[]) @@ -13,6 +13,9 @@ append!(v1.tags, [:VARIABLE, :POSE]) append!(v2.tags, [:VARIABLE, :LANDMARK]) append!(f1.tags, [:FACTOR]) +#Force softtypename +v1.softtypename = :Pose2 + # @testset "Creating Graphs" begin global dfg,v1,v2,f1 addVariable!(dfg, v1) @@ -95,6 +98,7 @@ end @test timestamp(v1) == v1.timestamp @test estimates(v1) == v1.estimateDict @test estimate(v1, :notfound) == nothing + @test softtype(v1) == :Pose2 # @test solverData(v1) === v1.solverDataDict[:default] # @test getData(v1) === v1.solverDataDict[:default] # @test solverData(v1, :default) === v1.solverDataDict[:default] @@ -123,13 +127,13 @@ end estimates(newvar)[:default] = Dict{Symbol, VariableEstimate}( :max => VariableEstimate(:default, :max, [100.0]), :mean => VariableEstimate(:default, :mean, [50.0]), - :ppe => VariableEstimate(:default, :ppe, [75.0])) + :modefit => VariableEstimate(:default, :modefit, [75.0])) #update updateVariableSolverData!(dfg, newvar) #TODO maybe implement ==; @test newvar==var Base.:(==)(varest1::VariableEstimate, varest2::VariableEstimate) = begin varest1.lastUpdatedTimestamp == varest2.lastUpdatedTimestamp || return false - varest1.type == varest2.type || return false + varest1.ppeType == varest2.ppeType || return false varest1.solverKey == varest2.solverKey || return false varest1.estimate == varest2.estimate || return false return true diff --git a/test/interfaceTests.jl b/test/interfaceTests.jl index 1d38d623..67829c8e 100644 --- a/test/interfaceTests.jl +++ b/test/interfaceTests.jl @@ -8,6 +8,24 @@ append!(v1.tags, [:VARIABLE, :POSE]) append!(v2.tags, [:VARIABLE, :LANDMARK]) append!(f1.tags, [:FACTOR]) +#add types for softtypes +# Simple test for the soft type. +mutable struct TestSoftType <: InferenceVariable + a + b + TestSoftType(a, b) = new(a, b) +end +import Base.== +function ==(a::TestSoftType, b::TestSoftType)::Bool + a.a != b.a && return false + a.b != b.b && return false + return true +end +st1 = TestSoftType(1,2) +st2 = TestSoftType(1.0,2.0) +v1.solverDataDict[:default].softtype = deepcopy(st1) +v2.solverDataDict[:default].softtype = deepcopy(st2) + # @testset "Creating Graphs" begin global dfg,v1,v2,f1 addVariable!(dfg, v1) @@ -96,6 +114,10 @@ end @test solverDataDict(v1) == v1.solverDataDict @test internalId(v1) == v1._internalId + @test softtype(v1) == Symbol(typeof(st1)) + @test softtype(v2) == Symbol(typeof(st2)) + @test getSofttype(v1) == st1 + @test label(f1) == f1.label @test tags(f1) == f1.tags @test solverData(f1) == f1.data @@ -115,7 +137,7 @@ end #TODO Should the next test work? @test_broken !isInitialized(dfg, :f1) @test_broken !isInitialized(f1) - + end @testset "Updating Nodes" begin @@ -127,13 +149,13 @@ end estimates(newvar)[:default] = Dict{Symbol, VariableEstimate}( :max => VariableEstimate(:default, :max, [100.0]), :mean => VariableEstimate(:default, :mean, [50.0]), - :ppe => VariableEstimate(:default, :ppe, [75.0])) + :modefit => VariableEstimate(:default, :modefit, [75.0])) #update updateVariableSolverData!(dfg, newvar) #TODO maybe implement ==; @test newvar==var Base.:(==)(varest1::VariableEstimate, varest2::VariableEstimate) = begin varest1.lastUpdatedTimestamp == varest2.lastUpdatedTimestamp || return false - varest1.type == varest2.type || return false + varest1.ppeType == varest2.ppeType || return false varest1.solverKey == varest2.solverKey || return false varest1.estimate == varest2.estimate || return false return true @@ -147,7 +169,7 @@ end estimates(newvar)[:second] = Dict{Symbol, VariableEstimate}( :max => VariableEstimate(:default, :max, [10.0]), :mean => VariableEstimate(:default, :mean, [5.0]), - :ppe => VariableEstimate(:default, :ppe, [7.0])) + :modefit => VariableEstimate(:default, :modefit, [7.0])) # Persist to the original variable. updateVariableSolverData!(dfg, newvar) @@ -210,6 +232,11 @@ verts = map(n -> DFGVariable(Symbol("x$n")), 1:numNodes) #change ready and backendset for x7,x8 for improved tests on x7x8f1 verts[7].ready = 1 verts[8].backendset = 1 + +#force softytypes to first 2 vertices. +verts[1].solverDataDict[:default].softtype = deepcopy(st1) +verts[2].solverDataDict[:default].softtype = deepcopy(st2) + map(v -> addVariable!(dfg, v), verts) map(n -> addFactor!(dfg, [verts[n], verts[n+1]], DFGFactor{Int, :Symbol}(Symbol("x$(n)x$(n+1)f1"))), 1:(numNodes-1)) @@ -283,7 +310,11 @@ end # Check all fields are equal for all variables for v in ls(summaryGraph) for field in variableFields - @test getfield(getVariable(dfg, v), field) == getfield(getVariable(summaryGraph, v), field) + if field != :softtypename + @test getfield(getVariable(dfg, v), field) == getfield(getVariable(summaryGraph, v), field) + else + @test softtype(getVariable(dfg, v)) == softtype(getVariable(summaryGraph, v)) + end end end for f in lsf(summaryGraph)