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]) > kσ
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