Skip to content

Commit e551d2d

Browse files
authored
Merge pull request #752 from JuliaRobotics/21Q4/ex/analyzescatteralign
analysis code for radar scatter map alignments
2 parents 52781be + 0b0fd15 commit e551d2d

File tree

13 files changed

+320
-187
lines changed

13 files changed

+320
-187
lines changed

examples/marine/asv/rex/RExFeed_Bag.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ rostypegen()
4646
# No using needed because we're specifying by full name.
4747
# using .sensor_msgs.msg
4848
# using .seagrant_msgs.msg
49-
49+
5050
## Load Caesar mmisam stuff
5151
using Caesar
5252
using RoME
@@ -246,7 +246,7 @@ function main(;iters::Integer=50)
246246

247247
init_node("rex_feed")
248248
# find the bagfile
249-
bagfile = joinpath(ENV["HOME"],"data","Marine","lidar_radar.bag")
249+
bagfile = joinpath(ENV["HOME"],"data","Marine","basin_radar.bag") # lidar_radar.bag
250250
bagSubscriber = RosbagSubscriber(bagfile)
251251

252252
# Initialization
@@ -296,7 +296,9 @@ end
296296
##
297297

298298

299-
main(iters=300) # 275
299+
main(iters=100)
300+
301+
# 275
300302

301303

302304
## after the graph is saved it can be loaded and the datastores retrieved

examples/marine/asv/rex/ScanMatcher.jl

Lines changed: 9 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,11 @@ using Manifolds
99

1010
using ImageView
1111

12-
# using GraphPlot
13-
# using DistributedFactorGraphs
14-
# using IncrementalInference, RoME
15-
# using DocStringExtensions
16-
17-
import Rotations as _Rot
18-
# using CoordinateTransformations
19-
# using ImageTransformations
20-
21-
# using LinearAlgebra
22-
# using Optim
12+
# import Rotations as _Rot
2313

2414
# using Caesar: ScatterAlignPose2
2515

16+
2617
##
2718

2819
# Where to fetch data
@@ -81,70 +72,32 @@ sweeps = map(s -> s/maximum(s), sweeps);
8172
# newfg = loadDFG("$dfgDataFolder/newfg")
8273

8374
startsweep = 5
84-
endsweep = 20
75+
endsweep = 26
8576
graphinit = true
8677

8778
len = size(sweeps[5],1)
8879
domain = (range(-100,100,length=976),range(-100,100,length=976))
8980

9081
## use a standard builder
9182

92-
STEP = 3
83+
STEP = 20
9384
sweeps_ = sweeps[startsweep:STEP:endsweep]
9485

9586
# build the graph
9687
newfg = buildGraphChain!( sweeps_,
9788
ScatterAlignPose2,
9889
(_, data) -> (data.currData,data.nextData,domain),
99-
stopAfter=5,
90+
stopAfter=1,
10091
doRef = false,
10192
inflation_fct=0.0,
10293
solverParams=SolverParams(graphinit=true, inflateCycles=1) )
10394
#
10495

10596

10697

107-
## plotting function for understanding
108-
109-
110-
111-
112-
113-
## dev testing on one scatter image with known transform
114-
115-
# sweeps_ = sweeps[5:6]
116-
# sweeps_[2] =sweeps[5]
117-
118-
# domain = (range(-100,100,length=976),range(-100,100,length=976))
119-
120-
# newfg = buildGraphChain!( sweeps_,
121-
# ScatterAlignPose2,
122-
# (_, data) -> (data.currData,data.nextData,domain),
123-
# stopAfter=1,
124-
# doRef = false,
125-
# inflation_fct=0.0,
126-
# solverParams=SolverParams(graphinit=false, inflateCycles=1) )
127-
# #
128-
129-
##
130-
131-
# fct = getFactorType(newfg, :x0x1f1)
132-
# Xtup = sampleFactor(newfg, :x0x1f1)
133-
# e0 = identity_element(SpecialEuclidean(2))
134-
# δ = calcFactorResidualTemporary(fct, (Pose2,Pose2), Xtup, (e0, e0))
135-
13698
##
13799

138100

139-
# Run the initialization (very slow right now)
140-
# initAll!(newfg)
141-
142-
# Factor debugging
143-
# fs = getFactorFunction.(getFactor.(newfg, lsf(newfg)))
144-
# fs = filter(f -> f isa ScanMatcherPose2, fs)
145-
# pf = convert.(PackedAlignRadarPose3, fs)
146-
# convert.(ScanMatcherPose2, pf)
147-
148101
# Save the graph
149102
saveDFG("$dfgDataFolder/segment_test.tar.gz", newfg);
150103

@@ -158,63 +111,11 @@ pts = getPoints(X1_)
158111
# solving will internally call initAll!(newfg)
159112
tree = solveTree!(newfg)
160113

161-
## Looking at the results
162-
using Plots
163-
164-
ppes = map(v -> getSuggestedPPE(getPPE(getVariable(newfg, v))), ls(newfg))
165-
x = map(ppe -> ppe[1], ppes); y = map(ppe -> ppe[2], ppes); h = map(ppe -> ppe[3], ppes)
166-
Plots.plot(x, y, title="Path Plot", lw=3)
167-
168-
169-
## Stuff
170-
using Optim
171-
172-
173-
cost(tf, im1, im2) = evaluateTransform(im1,im2, tf )
174-
175-
176-
# Plotting
177-
xrange = -100.0:1.0:100.0
178-
hrange = -pi:0.1:pi
179-
val = reshape(
180-
[sweepx(sweeps[10],sweeps[11],xrange); sweepx(sweep_original[10],sweep_original[11],xrange)],
181-
length(xrange), 2)
182-
Plots.plot(xrange,val)
183-
# Heading
184-
val = reshape(
185-
[sweeph(sweeps[10],sweeps[11],hrange); sweeph(sweep_original[10],sweep_original[11],hrange)],
186-
length(hrange), 2)
187-
Plots.plot(hrange,val)
188-
189-
corr_func = (a,b)->sqrt(sum((a .- 0.5).*(b .- 0.5)))
190-
val = reshape(
191-
[sweepx(sweeps[10],sweeps[11],xrange,diff_func=corr_func);
192-
sweepx(sweep_original[10],sweep_original[11],xrange,diff_func=corr_func)],
193-
length(xrange), 2)
194-
Plots.plot(xrange,val)
195-
196-
## Sweep plotting
197-
# sanity check: identity transform should yield zero cost
198-
# @assert evaluateTransform(sweeps[11],sweeps[11],0.,0.,0.) == 0 "There's error with no transform!"
199-
200-
# let's try small displacements:
201-
# sweepx(im1, im2, xrange) = (x->@show evaluateTransform(im1,im2,x,0.,0.)).(xrange)
202-
# sweepy(im1, im2, yrange) = (y->@show evaluateTransform(im1,im2,0.,y,0.)).(yrange)
203-
# sweeph(im1, im2, hrange) = (h->@show evaluateTransform(im1,im2,0.,0.,h)).(hrange)
204114

115+
##
205116

206-
# using Plots
207-
# xrange = -10:0.1:10
208-
# hrange = -pi:0.1:pi
209-
# Plots.plot(xrange,sweepx(sweeps[10],sweeps[11],xrange))
210-
# Plots.plot(xrange,sweepy(sweeps[10],sweeps[11],xrange))
211-
# Plots.plot(hrange,sweeph(sweeps[10],sweeps[11],hrange))
117+
using Cairo, Gadfly
118+
Gadfly.set_default_plot_size(40cm,20cm)
212119

213120

214-
# fs10 = imfilter(sweeps[10],Kernel.gaussian(3))
215-
# fs11 = imfilter(sweeps[11],Kernel.gaussian(3))
216-
# ffs10 = imfilter(fs10,Kernel.gaussian(3))
217-
# ffs11 = imfilter(fs11,Kernel.gaussian(3))
218-
#
219-
# Plots.plot(xrange,sweepx(ffs10,ffs11,xrange))
220-
# Plots.plot(xrange,sweepy(fs10,fs11,xrange))
121+
#
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
3+
## Looking at the results
4+
using Plots
5+
6+
ppes = map(v -> getPPE(getVariable(newfg, v)).suggested, ls(newfg))
7+
x = map(ppe -> ppe[1], ppes); y = map(ppe -> ppe[2], ppes); h = map(ppe -> ppe[3], ppes)
8+
Plots.plot(x, y, title="Path Plot", lw=3)
9+
10+
11+
## Stuff
12+
using Optim
13+
14+
15+
cost(tf, im1, im2) = evaluateTransform(im1,im2, tf )
16+
17+
18+
# Plotting
19+
xrange = -100.0:1.0:100.0
20+
hrange = -pi:0.1:pi
21+
val = reshape(
22+
[sweepx(sweeps[10],sweeps[11],xrange); sweepx(sweep_original[10],sweep_original[11],xrange)],
23+
length(xrange), 2)
24+
Plots.plot(xrange,val)
25+
# Heading
26+
val = reshape(
27+
[sweeph(sweeps[10],sweeps[11],hrange); sweeph(sweep_original[10],sweep_original[11],hrange)],
28+
length(hrange), 2)
29+
Plots.plot(hrange,val)
30+
31+
corr_func = (a,b)->sqrt(sum((a .- 0.5).*(b .- 0.5)))
32+
val = reshape(
33+
[sweepx(sweeps[10],sweeps[11],xrange,diff_func=corr_func);
34+
sweepx(sweep_original[10],sweep_original[11],xrange,diff_func=corr_func)],
35+
length(xrange), 2)
36+
Plots.plot(xrange,val)
37+
38+
## Sweep plotting
39+
# sanity check: identity transform should yield zero cost
40+
# @assert evaluateTransform(sweeps[11],sweeps[11],0.,0.,0.) == 0 "There's error with no transform!"
41+
42+
# let's try small displacements:
43+
# sweepx(im1, im2, xrange) = (x->@show evaluateTransform(im1,im2,x,0.,0.)).(xrange)
44+
# sweepy(im1, im2, yrange) = (y->@show evaluateTransform(im1,im2,0.,y,0.)).(yrange)
45+
# sweeph(im1, im2, hrange) = (h->@show evaluateTransform(im1,im2,0.,0.,h)).(hrange)
46+
47+
48+
# using Plots
49+
# xrange = -10:0.1:10
50+
# hrange = -pi:0.1:pi
51+
# Plots.plot(xrange,sweepx(sweeps[10],sweeps[11],xrange))
52+
# Plots.plot(xrange,sweepy(sweeps[10],sweeps[11],xrange))
53+
# Plots.plot(hrange,sweeph(sweeps[10],sweeps[11],hrange))
54+
55+
56+
# fs10 = imfilter(sweeps[10],Kernel.gaussian(3))
57+
# fs11 = imfilter(sweeps[11],Kernel.gaussian(3))
58+
# ffs10 = imfilter(fs10,Kernel.gaussian(3))
59+
# ffs11 = imfilter(fs11,Kernel.gaussian(3))
60+
#
61+
# Plots.plot(xrange,sweepx(ffs10,ffs11,xrange))
62+
# Plots.plot(xrange,sweepy(fs10,fs11,xrange))
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
2+
3+
using Statistics
4+
using DataFrames
5+
using JLD2, FileIO
6+
7+
using Cairo, Gadfly
8+
Gadfly.set_default_plot_size(40cm,20cm)
9+
10+
## plotting
11+
12+
sap_ = getFactorType(newfg, :x0x1f1)
13+
14+
##
15+
16+
Caesar.plotScatterAlign(sap_, bw=0.001)
17+
18+
##
19+
20+
# snt_ = deepcopy(snt)
21+
snt = overlayScatterMutate(sap_; user_offset=[-20.0;+100; pi/4], sample_count=200, bw=1e-4, user_coords=[0;-50;0.]) #, user_coords=snt_.best_coords)
22+
plotScatterAlign(snt)
23+
24+
25+
26+
27+
## sensitivity sweep on bw
28+
29+
30+
SNT_10 = [[overlayScatterMutate(sap_; user_offset=[-20.0;+20;pi/4], sample_count=100, bw) for i in 1:200] for bw in exp10.(-6:1:-1)];
31+
32+
mkdir("/tmp/caesar/rex/SNT_10")
33+
@save "/tmp/caesar/rex/SNT_10/SNT_10.jld2" SNT_10
34+
35+
## histogram sensitivities
36+
37+
df = DataFrame(s=Int[], bw=Float64[], group=Symbol[], μ=Float64[], σ=Float64[], _μ=Float64[], μ_=Float64[] )
38+
39+
for (i,s) in enumerate(-6:-1)
40+
41+
tl = "e$s"
42+
X_ = (x->x.best_coords[1]).(SNT[i])
43+
Y_ = (x->x.best_coords[2]).(SNT[i])
44+
R_ = (x->x.best_coords[3]).(SNT[i])
45+
46+
μ_x = Statistics.mean(X_); σ_x = Statistics.std(X_)
47+
μ_y = Statistics.mean(Y_); σ_y = Statistics.std(Y_)
48+
μ_r = Statistics.mean(R_); σ_r = Statistics.std(R_)
49+
50+
_μx, μx_ = μ_x - σ_x, μ_x + σ_x
51+
_μy, μy_ = μ_y - σ_y, μ_y + σ_y
52+
_μr, μr_ = μ_r - σ_r, μ_r + σ_r
53+
54+
push!( df, ( s,exp10(s),:x, μ_x,σ_x, _μx,μx_ ) )
55+
push!( df, ( s,exp10(s),:y, μ_y,σ_y, _μy,μy_ ) )
56+
push!( df, ( s,exp10(s),:r, μ_r,σ_r, _μr,μr_ ) )
57+
58+
# Hx = Gadfly.plot(x=X_, Geom.histogram, Guide.title("X, $tl"))
59+
# Hy = Gadfly.plot(x=Y_, Geom.histogram, Guide.title("Y, $tl"))
60+
# Ht = Gadfly.plot(x=R_, Geom.histogram, Guide.title("θ, $tl"))
61+
# hstack(Hx, Hy, Ht);
62+
end
63+
64+
##
65+
66+
df_xy = filter( row -> row.group != :r, df )
67+
df_r = filter( row -> row.group == :r, df )
68+
69+
p_xy = Gadfly.plot(df_xy, x=:bw, y=, ymin=:_μ, ymax=:μ_, color=:group, Geom.line, Geom.errorbar, Scale.x_log10)
70+
p_r = Gadfly.plot(df_r, x=:bw, y=, ymin=:_μ, ymax=:μ_, color=:group, Geom.line, Geom.errorbar, Scale.x_log10)
71+
72+
hstack(p_xy, p_r)
73+
74+
75+
76+
##=============================================================================================
77+
## dev testing on one scatter image with known transform
78+
79+
# sweeps_ = sweeps[5:6]
80+
# sweeps_[2] = sweeps[5]
81+
82+
# domain = (range(-100,100,length=976),range(-100,100,length=976))
83+
84+
# newfg = buildGraphChain!( sweeps_,
85+
# ScatterAlignPose2,
86+
# (_, data) -> (data.currData,data.nextData,domain),
87+
# stopAfter=1,
88+
# doRef = false,
89+
# inflation_fct=0.0,
90+
# solverParams=SolverParams(graphinit=false, inflateCycles=1) )
91+
# #
92+
93+
##
94+
95+
# fct = getFactorType(newfg, :x0x1f1)
96+
# Xtup = sampleFactor(newfg, :x0x1f1)
97+
# e0 = identity_element(SpecialEuclidean(2))
98+
# δ = calcFactorResidualTemporary(fct, (Pose2,Pose2), Xtup, (e0, e0))
99+
100+
101+
#

examples/marine/rov/highend/lcmserver/pointclouddev.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function lcmpointcloudmsg!(vc, slaml::SLAMWrapper,
3131
# push to DrakeVisualizer
3232
#=
3333
position = Translation(msg[:pos]...)
34-
orientation = Rotations.Quat(msg[:orientation]...)
34+
orientation = _Rot.UnitQuaternion(msg[:orientation]...)
3535
Tf = position ∘ LinearMap(orientation)
3636
vsym = Symbol(vert.label)
3737
setgeometry!(vc[:submaps][vsym], Triad())

examples/marine/rov/highend/lcmserver/resolvingPartialXYH.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ import DrakeVisualizer: Triad
88
import Base: convert
99
using Base: Test
1010

11-
11+
import Rotations as _Rot
1212

1313

1414
# random testing and converstion to be moved out
1515

1616
function convert{T <: CoordinateTransformations.AffineMap}(::Type{T}, x::SE3)
1717
q = convert(TransformUtils.Quaternion, x.R)
18-
Translation(x.t...) LinearMap( Rotations.Quat(q.s, q.v...) )
18+
Translation(x.t...) LinearMap( _Rot.UnitQuaternion(q.s, q.v...) )
1919
end
20-
function convert{T <: CoordinateTransformations.AffineMap{Rotations.Quat{Float64}}}(::Type{SE3}, x::T)
20+
function convert{T <: CoordinateTransformations.AffineMap{_Rot.UnitQuaternion{Float64}}}(::Type{SE3}, x::T)
2121
SE3(x.v[1:3], TransformUtils.Quaternion(x.m.w, [x.m.x,x.m.y,x.m.z]) )
2222
end
2323

0 commit comments

Comments
 (0)