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