Skip to content

Commit a2eb13c

Browse files
committed
Experimental Parametric RANSAC solver
1 parent 2d42ae3 commit a2eb13c

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

IncrementalInference/src/IncrementalInference.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ include("parametric/services/ParametricCSMFunctions.jl")
218218
include("parametric/services/ParametricUtils.jl")
219219
include("parametric/services/ParametricOptim.jl")
220220
include("parametric/services/ParametricManopt.jl")
221+
include("parametric/services/ParametricRANSAC.jl")
221222
include("services/MaxMixture.jl")
222223

223224
#X-stroke
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
2+
#TODO upstream to DFG
3+
function listNeighborhood(fg, variableFactorLabels, distance; filterOrphans=true)
4+
allvarfacs = getNeighborhood(fg, variableFactorLabels, distance)
5+
variableLabels = intersect(listVariables(fg), allvarfacs)
6+
factorLabels = intersect(listFactors(fg), allvarfacs)
7+
if filterOrphans
8+
filter!(factorLabels) do lbl
9+
issubset(getVariableOrder(fg, lbl), variableLabels)
10+
end
11+
end
12+
return variableLabels, factorLabels
13+
end
14+
15+
function calcResidualInliers(subfg, faclabels; kσ=1)
16+
varlabels = setdiff(getNeighborhood(subfg, faclabels, 1), faclabels)
17+
18+
vars = getVariable.(subfg, varlabels)
19+
M, varTypes, vartypeslist = IIF.buildGraphSolveManifold(vars)
20+
varIntLabel, varlabelsAP = IIF.getVarIntLabelMap(vartypeslist)
21+
22+
p0 = map(varlabelsAP) do label
23+
getVal(subfg, label, solveKey = :parametric)[1]
24+
end
25+
26+
# create an ArrayPartition{CalcFactorResidual} for faclabels
27+
calcfacs = IIF.CalcFactorResidualAP(subfg, faclabels, varIntLabel)
28+
29+
# remember res = cf.sqrt_iΣ * factor res with calcfacs, so should be sigma scaled
30+
res = reduce(vcat, map(f -> f(p0), Vector(calcfacs)))
31+
# findfirst(==(median(res)), res)
32+
33+
res_labels = getproperty.(Vector(calcfacs), :faclbl)
34+
# findfirst(==(:cD1l2000cD1l2000_cD1l5611f1), res_labels)
35+
36+
# 3
37+
inlierlabels = deepcopy(res_labels)
38+
for (i,l) in (enumerate(faclabels))
39+
if abs(res[i]) >
40+
setdiff!(inlierlabels, [l])
41+
end
42+
end
43+
44+
return res_labels.=>res, inlierlabels
45+
end
46+
47+
function solveGraphParametricRansac!(
48+
fg,
49+
comb_on_fac_labels,
50+
min_factors = 3,
51+
include_vars = Symbol[];
52+
n_iters = 50,
53+
stop_ratio = 0.7,
54+
kwargs...
55+
)
56+
# intersect!(comb_on_fac_labels, listNeighbors(fg, ls(fg, r"^x")[1]))
57+
all_fac_combinations = combinations(comb_on_fac_labels, min_factors)
58+
59+
do_combinations = length(all_fac_combinations) < n_iters ?
60+
collect(all_fac_combinations) : rand(collect(all_fac_combinations), n_iters)
61+
# collect(all_fac_combinations) : all_fac_combinations[rand(1:length(all_fac_combinations), n_iters)]
62+
63+
best_ratio = 0.0
64+
best_inlierlabels = Symbol[]
65+
for (i, maybe_inliers) = enumerate(do_combinations)
66+
67+
solveVariableLabels, solveFactorLabels = listNeighborhood(fg, union(include_vars, maybe_inliers), 2)
68+
69+
# TODO do better
70+
subfg = deepcopy(fg)
71+
# @info solveFactorLabels
72+
# M, v, r, Σ = IIF.solve_RLM(fg, variableLabels, factorLabels;
73+
try
74+
IIF.solveGraphParametric!(subfg, solveVariableLabels, solveFactorLabels; kwargs...)
75+
# IIF.solveGraphParametric!(subfg, kwargs...)
76+
catch er
77+
@warn "Error on iter $i" er
78+
continue
79+
end
80+
81+
residuals, inlierlabels = calcResidualInliers(subfg, comb_on_fac_labels)
82+
83+
ratio_inliers = length(inlierlabels) ./ length(comb_on_fac_labels)
84+
85+
if ratio_inliers > best_ratio
86+
best_ratio = ratio_inliers
87+
@info "new best $best_ratio"
88+
best_inlierlabels = inlierlabels
89+
end
90+
if ratio_inliers > stop_ratio
91+
@info "stop ratio met $best_ratio"
92+
break
93+
end
94+
# res_vals = last.(residuals)
95+
96+
end
97+
try
98+
solveVariableLabels, solveFactorLabels = listNeighborhood(fg, union(include_vars, best_inlierlabels), 2)
99+
IIF.solveGraphParametric!(fg, solveVariableLabels, solveFactorLabels; kwargs...)
100+
catch er
101+
@error "solveGraphParametric of inliers failed" er
102+
end
103+
104+
return best_inlierlabels
105+
end
106+
107+
if false
108+
## get factor residuals to solve with
109+
comb_on_fac_labels = lsfTypesDict(subfg)[:Pose2Point2Bearing]
110+
# intersect!(faclabels, listNeighbors(subfg, ls(subfg, r"^cD1l\d+$")[1]))
111+
stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-12) | StopWhenStepsizeLess(1e-12)
112+
113+
inlierlabels = solveGraphParametricRansac!(subfg, comb_on_fac_labels;
114+
n_iters = 500,
115+
stopping_criterion,
116+
# debug,
117+
is_sparse=false,
118+
damping_term_min=1e-12,
119+
finiteDiffCovariance=true
120+
)
121+
122+
end

0 commit comments

Comments
 (0)