Skip to content

Commit f8dc7e7

Browse files
committed
wip, standardize old ScalarField test code
1 parent 8ad743d commit f8dc7e7

File tree

7 files changed

+162
-2
lines changed

7 files changed

+162
-2
lines changed

Project.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ julia = "1.4"
5555

5656
[extras]
5757
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
58+
ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534"
5859
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
5960

6061
[targets]
61-
test = ["Test", "Flux"]
62+
test = ["Flux", "ImageCore", "Test"]

data/CanyonDEM.png

1.6 MB
Loading

src/RoME.jl

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ using Reexport
1010

1111
using
1212
Dates,
13+
FileIO,
1314
Distributed,
1415
LinearAlgebra,
1516
Statistics,
@@ -294,6 +295,8 @@ include("canonical/GenerateHelix.jl")
294295
include("AdditionalUtils.jl")
295296
include("g2oParser.jl")
296297

298+
# ScalarFields
299+
include("services/ScalarFields.jl")
297300

298301
# things on their way out
299302
include("Deprecated.jl")
@@ -304,10 +307,19 @@ using Requires
304307
function __init__()
305308
# combining neural networks natively into the non-Gaussian factor graph object
306309
@require Flux="587475ba-b771-5e3f-ad9e-33799f191a9c" begin
307-
@info "RoME is adding Flux related functionality."
310+
@info "Loading RoME.jl tools related to Flux.jl."
308311
include("factors/flux/models/Pose2OdoNN_01.jl") # until a better way is found to deserialize
309312
include("factors/flux/MixtureFluxPose2Pose2.jl")
310313
end
314+
315+
# Scalar field specifics
316+
317+
@require ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" include("services/RequiresImages.jl")
318+
# Images="916415d5-f1e6-5110-898d-aaa5f9f070e0"
319+
320+
# @require Interpolations="a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" begin
321+
# include("services/ScalarFieldsInterpolations.jl")
322+
# end
311323
end
312324

313325
# manifold conversions required during transformation

src/services/RequiresImages.jl

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ScalarField functions related to Images.jl
2+
3+
@info "Loading RoME.jl tools related to ImageCore.jl"
4+
5+
using .ImageCore
6+
7+
export generateField_CanyonDEM
8+
9+
10+
"""
11+
$SIGNATURES
12+
13+
Loads a sample DEM (as if simulated) on a regular grid... It's the Grand Canyon, 18x18km, 17m
14+
"""
15+
function generateField_CanyonDEM( scale=1, N=100;
16+
x_is_north=true,
17+
x_min::Real=-9000, x_max::Real=9000,
18+
y_min::Real=-9000, y_max::Real=9000)
19+
#
20+
img_ = load(dirname(dirname(@__DIR__)), "data","CanyonDEM.png") .|> Gray
21+
img_ = scale.*Float64.(img_)
22+
23+
N_ = minimum([N; size(img_)...])
24+
img = img_[1:N_, 1:N_]
25+
26+
# flip image so x-axis in plot is North and y-axis is West (ie img[-north,west], because top left is 0,0)
27+
_img_ = if x_is_north
28+
_img = collect(img')
29+
reverse(_img, dims=2)
30+
else
31+
img
32+
end
33+
34+
x = range(x_min, x_max, length = size(_img_,1)) # North
35+
y = range(y_min, y_max, length = size(_img_,2)) # East
36+
37+
return (x, y, _img_)
38+
end
39+
40+
41+
42+
#

src/services/ScalarFields.jl

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# ScalarField related functions loaded when Interpolations.jl is available.
2+
3+
4+
"""
5+
$SIGNATURES
6+
7+
Load gridded elevation data `dem` into a factor graph `fg` as a collection
8+
of Point3 variables. Each variable is connected to its 4-neighborhood by
9+
relative Point3Point3 MvNormal constraints with mean defined by their
10+
relative position on the grid (`x`, `y`) and covariance `meshEdgeSigma`.
11+
"""
12+
function _buildGraphScalarField!( fg::AbstractDFG,
13+
dem::AbstractMatrix, # assume grayscale image for now
14+
x::AbstractVector,
15+
y::AbstractVector;
16+
solvable::Int=0,
17+
marginalized::Bool=true,
18+
meshEdgeSigma=diagm([1;1;1]),
19+
refKey::Symbol = :simulated )
20+
#
21+
# assume regular grid
22+
dx, dy = x[2]-x[1], y[2]-y[1]
23+
for i in 1:length(x)
24+
for j in 1:length(y)
25+
s = Symbol("pt$(i)_$(j)") # unique identifier
26+
pt = addVariable!(fg, s, Point3, solvable=solvable)
27+
setMarginalized!(pt, marginalized) # assume solveKey=:default
28+
29+
# ...
30+
refVal = [x[i];y[j];dem[i,j]]
31+
simPPE = DFG.MeanMaxPPE(refKey, refVal, refVal, refVal)
32+
setPPE!(pt, refKey, typeof(simPPE), simPPE)
33+
34+
# Regular grid triangulation:
35+
# add factor to (i-1,j) |
36+
# add factor to (i, j-1) -
37+
# add factor to (i-1, j-1) \
38+
39+
# no edges to prev row on first row
40+
if i>1
41+
dVal1 = dem[i,j]-dem[i-1,j]
42+
f = Point3Point3(MvNormal([dx, 0, dVal1], meshEdgeSigma))
43+
addFactor!(fg, [Symbol("pt$(i-1)_$(j)"), s], f, solvable=solvable, graphinit=false)
44+
end
45+
46+
# no edges to prev column on first column
47+
if j>1
48+
dVal2 = dem[i,j]-dem[i,j-1]
49+
f = Point3Point3(MvNormal([0, dy, dVal2], meshEdgeSigma))
50+
addFactor!(fg, [Symbol("pt$(i)_$(j-1)"),s], f, solvable=solvable, graphinit=false)
51+
end
52+
53+
# no edges to add on first element
54+
if i>1 && j>1
55+
dVal3 = dem[i,j]-dem[i-1,j-1]
56+
f = Point3Point3(MvNormal([dx, dy, dVal3], meshEdgeSigma))
57+
addFactor!(fg,[Symbol("pt$(i-1)_$(j-1)"),s], f, solvable=solvable, graphinit=false)
58+
end
59+
60+
end
61+
end
62+
63+
nothing
64+
end
65+
66+
67+
68+
69+
#

test/runtests.jl

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ using Statistics
1515
@error("add test for generateCanonicalFG_Beehive, norm( simulated - default ) < tol")
1616

1717
testfiles = [
18+
# new tests wip
19+
"testScalarFields.jl"
20+
1821
# any wip fail-fast dev testing
1922
"testPartialPose3.jl";
2023

test/testScalarFields.jl

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# test scalar field
2+
3+
using Test
4+
using ImageCore
5+
using RoME
6+
7+
##
8+
9+
@testset "Basic low-res ScalarField localization" begin
10+
##
11+
12+
# # load dem (18x18km span, ~17m/px)
13+
x_min, x_max = -9000, 9000
14+
y_min, y_max = -9000, 9000
15+
# north is regular map image up
16+
x, y, img_ = RoME.generateField_CanyonDEM(1, 100, x_is_north=false, x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max)
17+
# flip so north is down along with Images.jl [i,j] --> (x,y)
18+
img = reverse(img_, dims=1)
19+
20+
21+
22+
23+
24+
25+
26+
##
27+
end
28+
29+
30+
31+
32+
33+
##

0 commit comments

Comments
 (0)