Skip to content

Commit 67f213d

Browse files
authored
Merge pull request #1343 from JuliaRobotics/21Q3/refac/consolsfparam
consolidate solveFactorParametric, and deprs
2 parents 4bf95c6 + 5608a56 commit 67f213d

15 files changed

+211
-191
lines changed

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ The list below highlights major breaking changes, and please note that significa
2020
- New helper function `randToPoints(::SamplableBelief, N=1)::Vector{P}` to help with `getSample` for cases with new `ManifoldKernelDensity` beliefs for manifolds containing points of type `P`.
2121
- Upstream `calcHelix_T` canonical generator utility from RoME.jl.
2222
- Deserialization of factors with DFG needs new API and change of solverData and CCW type in factor.
23+
- Deprecate use of `getParametricMeasurement` and use `getMeasurementParametric` instead, and add `<:AbstractManifold` to API.
24+
- Deprecate use of `solveBinaryFactorParameteric`, instead use `solveFactorParameteric`.
25+
- Deprecating `approxConvBinary`, use `approxConvBelief` instead.
26+
- Deprecating `accumulateFactorChain`, use `approxConvBelief` instead.
27+
2328

2429
# Major changes in v0.24
2530

src/Deprecated.jl

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,91 @@ end
2626
##==============================================================================
2727

2828

29+
# """
30+
# $SIGNATURES
31+
32+
# Calculate both measured and predicted relative variable values, starting with `from` at zeros up to `to::Symbol`.
33+
34+
# Notes
35+
# - assume single variable separators only.
36+
37+
# DevNotes
38+
# - TODO better consolidate with [`approxConvBelief`](@ref) which can now also work with factor chains.
39+
# """
40+
# function accumulateFactorChain( dfg::AbstractDFG,
41+
# from::Symbol,
42+
# to::Symbol,
43+
# fsyms::Vector{Symbol}=findFactorsBetweenNaive(dfg, from, to);
44+
# initval=zeros(size(getVal(dfg, from))))
45+
46+
# # get associated variables
47+
# svars = union(ls.(dfg, fsyms)...)
48+
49+
# # use subgraph copys to do calculations
50+
# tfg_meas = buildSubgraph(dfg, [svars;fsyms])
51+
# tfg_pred = buildSubgraph(dfg, [svars;fsyms])
52+
53+
# # drive variable values manually to ensure no additional stochastics are introduced.
54+
# nextvar = from
55+
# initManual!(tfg_meas, nextvar, initval)
56+
# initManual!(tfg_pred, nextvar, initval)
57+
58+
# # nextfct = fsyms[1] # for debugging
59+
# for nextfct in fsyms
60+
# nextvars = setdiff(ls(tfg_meas,nextfct),[nextvar])
61+
# @assert length(nextvars) == 1 "accumulateFactorChain requires each factor pair to separated by a single variable"
62+
# nextvar = nextvars[1]
63+
# meas, pred = approxDeconv(dfg, nextfct) # solveFactorMeasurements
64+
# pts_meas = approxConv(tfg_meas, nextfct, nextvar, (meas,ones(Int,100),collect(1:100)))
65+
# pts_pred = approxConv(tfg_pred, nextfct, nextvar, (pred,ones(Int,100),collect(1:100)))
66+
# initManual!(tfg_meas, nextvar, pts_meas)
67+
# initManual!(tfg_pred, nextvar, pts_pred)
68+
# end
69+
# return getVal(tfg_meas,nextvar), getVal(tfg_pred,nextvar)
70+
# end
71+
72+
73+
# # TODO should this be consolidated with regular approxConv?
74+
# # TODO, perhaps pass Xi::Vector{DFGVariable} instead?
75+
# function approxConvBinary(arr::Vector{Vector{Float64}},
76+
# meas::AbstractFactor,
77+
# outdims::Int,
78+
# fmd::FactorMetadata,
79+
# measurement::Tuple=(Vector{Vector{Float64}}(),);
80+
# varidx::Int=2,
81+
# N::Int=length(arr),
82+
# vnds=DFGVariable[],
83+
# _slack=nothing )
84+
# #
85+
# # N = N == 0 ? size(arr,2) : N
86+
# pts = [zeros(outdims) for _ in 1:N];
87+
# ptsArr = Vector{Vector{Vector{Float64}}}()
88+
# push!(ptsArr,arr)
89+
# push!(ptsArr,pts)
90+
91+
# fmd.arrRef = ptsArr
92+
93+
# # TODO consolidate with ccwl??
94+
# # FIXME do not divert Mixture for sampling
95+
# # cf = _buildCalcFactorMixture(ccwl, fmd, 1, ccwl.measurement, ARR) # TODO perhaps 0 is safer
96+
# # FIXME 0, 0, ()
97+
# cf = CalcFactor( meas, fmd, 0, 0, (), ptsArr)
98+
99+
# measurement = length(measurement[1]) == 0 ? sampleFactor(cf, N) : measurement
100+
# # measurement = size(measurement[1],2) == 0 ? sampleFactor(meas, N, fmd, vnds) : measurement
101+
102+
# zDim = length(measurement[1][1])
103+
# ccw = CommonConvWrapper(meas, ptsArr[varidx], zDim, ptsArr, fmd, varidx=varidx, measurement=measurement) # N=> size(measurement[1],2)
104+
105+
# for n in 1:N
106+
# ccw.cpt[Threads.threadid()].particleidx = n
107+
# _solveCCWNumeric!( ccw, _slack=_slack )
108+
# end
109+
# return pts
110+
# end
111+
112+
@deprecate getParametricMeasurement(w...;kw...) getMeasurementParametric(w...;kw...)
113+
29114
# function prtslperr(s)
30115
# println(s)
31116
# sleep(0.1)
@@ -203,7 +288,7 @@ end
203288

204289
@deprecate ensureAllInitialized!(w...;kw...) initAll!(w...;kw...)
205290

206-
@deprecate getFactorMean(w...) IIF.getParametricMeasurement(w...)[1]
291+
@deprecate getFactorMean(w...) IIF.getMeasurementParametric(w...)[1]
207292

208293
# """
209294
# $SIGNATURES

src/FGOSUtils.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ Related
251251
"""
252252
function calcPPE( var::DFGVariable,
253253
varType::InferenceVariable=getVariableType(var);
254-
ppeType::Type{MeanMaxPPE}=MeanMaxPPE,
254+
ppeType::Type{<:MeanMaxPPE}=MeanMaxPPE,
255255
solveKey::Symbol=:default,
256256
ppeKey::Symbol=solveKey,
257257
timestamp=now() )
@@ -265,7 +265,7 @@ function calcPPE( var::DFGVariable,
265265
# returns coordinates at identify
266266
Pma = getKDEMax(P, addop=ops[1], diffop=ops[2])
267267
# calculate point
268-
268+
269269
## TODO make PPE only use getCoordinates for now (IIF v0.25)
270270
Pme_ = getCoordinates(typeof(varType),Pme)
271271
# Pma_ = getCoordinates(M,Pme)

src/FactorGraph.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ function DFG.addFactor!(dfg::AbstractDFG,
752752
suppressChecks::Bool=false,
753753
inflation::Real=getSolverParams(dfg).inflation,
754754
namestring::Symbol = assembleFactorName(dfg, Xi),
755-
_blockRecursion::Bool=false )
755+
_blockRecursion::Bool=!getSolverParams(dfg).attemptGradients )
756756
#
757757

758758
varOrderLabels = Symbol[v.label for v=Xi]

src/IncrementalInference.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,7 @@ export *,
392392
getPointType,
393393
getPointIdentity,
394394
setVariableRefence!,
395-
reshapeVec2Mat,
396-
accumulateFactorChain
395+
reshapeVec2Mat
397396

398397
# more optional exports
399398
export HeatmapDensityRegular

src/NumericalCalculations.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,13 @@ function _solveLambdaNumeric( fcttype::Union{F,<:Mixture{N_,F,S,T}},
103103
return sum(residual.^2)
104104
end
105105

106-
alg = islen1 ? Optim.BFGS() : Optim.NelderMead()
106+
# separate statements to try improve type-stability
107+
r = if islen1
108+
Optim.optimize(cost, X0c, Optim.BFGS())
109+
else
110+
Optim.optimize(cost, X0c, Optim.NelderMead())
111+
end
107112

108-
r = Optim.optimize(cost, X0c, alg)
109-
110113
return exp(M, ϵ, hat(M, ϵ, r.minimizer))
111114

112115
end

src/ODE/DERelative.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using .DifferentialEquations
55

66
import .DifferentialEquations: solve
77

8-
import IncrementalInference: getSample
8+
import IncrementalInference: getSample, getManifold
99

1010
export DERelative
1111

@@ -38,6 +38,7 @@ struct DERelative{T <:InferenceVariable, P, D} <: AbstractRelativeRoots
3838
specialSampler::Function
3939
end
4040

41+
getManifold(de::DERelative{T}) where T = getManifold(de.domain)
4142

4243
"""
4344
$SIGNATURES

src/ParametricUtils.jl

Lines changed: 20 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -45,100 +45,52 @@ Defaults to find the parametric measurement at field `Z` followed by `z`.
4545
Notes
4646
- Users should overload this method should their factor not default to `.Z<:ParametricType` or `.z<:ParametricType`
4747
"""
48-
function getParametricMeasurement end
48+
function getMeasurementParametric end
4949

50-
function getParametricMeasurement(Z)
50+
function getMeasurementParametric(Z)
5151
error("$(typeof(Z)) is not supported, please use non-parametric or open an issue if it should be")
5252
end
5353

54-
function getParametricMeasurement(Z::Normal)
54+
function getMeasurementParametric(M::AbstractManifold, Z::Normal)
5555
meas = mean(Z)
5656
= 1/std(Z)^2
5757
return [meas], reshape([iσ],1,1)
5858
end
5959

60-
function getParametricMeasurement(Z::MvNormal)
60+
function getMeasurementParametric(M::AbstractManifold, Z::MvNormal)
6161
meas = mean(Z)
6262
= invcov(Z)
63-
return meas, iΣ
63+
p_μ = exp(M, identity_element(M), hat(M, identity_element(M), meas))
64+
return p_μ, iΣ
6465
end
6566

67+
getMeasurementParametric(Z::Normal) = getMeasurementParametric(TranslationGroup(1), Z)
68+
getMeasurementParametric(Z::MvNormal) = getMeasurementParametric(TranslationGroup(length(mean(Z))), Z)
69+
6670
# the point `p` on the manifold is the mean
67-
function getParametricMeasurement(s::ManifoldPrior)
71+
function getMeasurementParametric(s::ManifoldPrior)
6872
meas = s.p
6973
= invcov(s.Z)
7074
return meas, iΣ
7175
end
72-
73-
function getParametricMeasurement(s::FunctorInferenceType)
76+
77+
function getMeasurementParametric(s::AbstractFactor)
7478
if hasfield(typeof(s), :Zij)
7579
Z = s.Zij
76-
@info "getParametricMeasurement falls back to using field `.Zij` by default. Extend it for more complex factors." maxlog=1
80+
@info "getMeasurementParametric falls back to using field `.Zij` by default. Extend it for more complex factors." maxlog=1
7781
elseif hasfield(typeof(s), :Z)
7882
Z = s.Z
79-
@info "getParametricMeasurement falls back to using field `.Z` by default. Extend it for more complex factors." maxlog=1
83+
@info "getMeasurementParametric falls back to using field `.Z` by default. Extend it for more complex factors." maxlog=1
8084
elseif hasfield(typeof(s), :z)
8185
Z = s.z
82-
@info "getParametricMeasurement falls back to using field `.z` by default. Extend it for more complex factors." maxlog=1
86+
@info "getMeasurementParametric falls back to using field `.z` by default. Extend it for more complex factors." maxlog=1
8387
else
8488
error("$(typeof(s)) not supported, please use non-parametric or open an issue if it should be")
8589
end
86-
return getParametricMeasurement(Z)
90+
return getMeasurementParametric(Z)
8791
end
8892

8993

90-
## ================================================================================================
91-
## Parametric binary factor utility function, used by DRT
92-
## ================================================================================================
93-
94-
"""
95-
$SIGNATURES
96-
97-
Helper function to propagate a parametric estimate along a factor chain.
98-
99-
Notes
100-
- Not used during mmisam inference.
101-
- Expected uses are for user analysis of factors and estimates.
102-
- real-time dead reckoning chain prediction.
103-
104-
DevNotes
105-
- FIXME consolidate with `approxConv`
106-
107-
Related:
108-
109-
[`getParametricMeasurement`](@ref), [`approxConv`](@ref), [`accumulateFactorMeans`](@ref), [`MutablePose2Pose2Gaussian`](@ref)
110-
"""
111-
function solveBinaryFactorParameteric(dfg::AbstractDFG,
112-
fct::DFGFactor,
113-
currval::Vector{Float64},
114-
srcsym::Symbol,
115-
trgsym::Symbol )::Vector{Float64}
116-
#
117-
outdims = getVariableDim(getVariable(dfg, trgsym))
118-
meas = getFactorType(fct)
119-
mea, = getParametricMeasurement(meas)
120-
# mea = getFactorMean(fct)
121-
mea_ = Vector{Vector{Float64}}()
122-
push!(mea_, mea)
123-
measT = (mea_,)
124-
125-
# upgrade part of #639
126-
varSyms = getVariableOrder(fct)
127-
Xi = getVariable.(dfg, varSyms) # (v->getVariable(dfg, v)).(varSyms)
128-
129-
# calculate the projection
130-
varmask = (1:2)[varSyms .== trgsym][1]
131-
132-
fmd = FactorMetadata(Xi, getLabel.(Xi), Vector{Vector{Vector{Float64}}}(), :null, nothing)
133-
currval_ = Vector{Vector{Float64}}()
134-
push!(currval_, currval)
135-
pts_ = approxConvBinary( currval_, meas, outdims, fmd, measT, varidx=varmask )
136-
137-
# return the result
138-
@assert length(pts_[1]) == outdims
139-
return pts_[1]
140-
end
141-
14294

14395
## ================================================================================================
14496
## Parametric solve with Mahalanobis distance - CalcFactor
@@ -153,7 +105,7 @@ function CalcFactorMahalanobis(fct::DFGFactor)
153105
cf = getFactorType(fct)
154106
varOrder = getVariableOrder(fct)
155107

156-
_meas, _iΣ = getParametricMeasurement(cf)
108+
_meas, _iΣ = getMeasurementParametric(cf)
157109
meas = typeof(_meas) <: Tuple ? _meas : (_meas,)
158110
= typeof(_iΣ) <: Tuple ? _iΣ : (_iΣ,)
159111

@@ -694,9 +646,9 @@ struct MaxMixture
694646
choice::Base.RefValue{Int}
695647
end
696648

697-
function getParametricMeasurement(s::Mixture{N,F,S,T}) where {N,F,S,T}
698-
meas = map(c->getParametricMeasurement(c)[1], values(s.components))
699-
= map(c->getParametricMeasurement(c)[2], values(s.components))
649+
function getMeasurementParametric(s::Mixture{N,F,S,T}) where {N,F,S,T}
650+
meas = map(c->getMeasurementParametric(c)[1], values(s.components))
651+
= map(c->getMeasurementParametric(c)[2], values(s.components))
700652
return meas, iΣ
701653
end
702654

src/SolverUtilities.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ Notes
182182
- This function does not add new variables or factors to `fg`, user must do that themselves after.
183183
- Useful to use in combination with `setPPE!` on new variable.
184184
- At time of writing `accumulateFactorMeans` could only incorporate priors or binary relative factors.
185-
- internal info, see [`solveBinaryFactorParameteric`](@ref),
185+
- internal info, see [`solveFactorParameteric`](@ref),
186186
- This means at time of writing `factor` must be a binary factor.
187187
- Tip, if simulations are inducing odometry bias, think of using two factors from caller (e.g. simPerfect and simBias).
188188
@@ -273,7 +273,7 @@ function _checkVariableByReference( fg::AbstractDFG,
273273
factor::AbstractPrior;
274274
srcType::Type{<:InferenceVariable} = getVariableType(fg, srcLabel) |> typeof,
275275
refKey::Symbol=:simulated,
276-
prior = typeof(factor)( MvNormal(getParametricMeasurement(factor)...) ),
276+
prior = typeof(factor)( MvNormal(getMeasurementParametric(factor)...) ),
277277
atol::Real = 1e-3,
278278
destPrefix::Symbol = match(r"[a-zA-Z_]+", destRegex.pattern).match |> Symbol,
279279
srcNumber = match(r"\d+", string(srcLabel)).match |> x->parse(Int,x),
@@ -283,7 +283,7 @@ function _checkVariableByReference( fg::AbstractDFG,
283283
refVal = if overridePPE !== nothing
284284
overridePPE
285285
else
286-
getParametricMeasurement(factor)[1]
286+
getMeasurementParametric(factor)[1]
287287
end
288288

289289
ppe = DFG.MeanMaxPPE(refKey, refVal, refVal, refVal)

0 commit comments

Comments
 (0)