Skip to content

Commit

Permalink
Merge pull request #724 from JuliaRobotics/master
Browse files Browse the repository at this point in the history
v0.24.1-rc1
  • Loading branch information
dehann committed Jan 22, 2024
2 parents ba0e029 + 0e2ce86 commit f0f6e3f
Show file tree
Hide file tree
Showing 17 changed files with 603 additions and 597 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
julia-version: ['1.9', '~1.10.0-0', 'nightly']
julia-version: ['1.10', 'nightly']
os: [ubuntu-latest]
arch: [x64]
steps:
Expand All @@ -42,7 +42,7 @@ jobs:
- uses: julia-actions/julia-runtest@latest
continue-on-error: ${{ matrix.julia-version == 'nightly' }}
- uses: julia-actions/julia-processcoverage@v1
if: ${{ matrix.julia-version == '1.9' }}
if: ${{ matrix.julia-version == '1.10' }}
- uses: codecov/codecov-action@v1
with:
file: lcov.info
Expand All @@ -58,7 +58,7 @@ jobs:

- uses: julia-actions/setup-julia@v1
with:
version: 1.9
version: '1.10'
arch: x64

- uses: actions/cache@v1
Expand Down
14 changes: 13 additions & 1 deletion NEWS.md
Expand Up @@ -2,6 +2,18 @@

RoME.jl follows semver, with only a few case specific exceptions. Please see repo's [Milestones](https://github.com/JuliaRobotics/RoME.jl/milestones?state=closed) page for a more complete list of changes. This NEWS file lists select changes like to produce breaking changes downstream. Note serious efforts are taken to have both breaking and smaller changes go through a proper deprecation and warning printout cycle, consistent with JuliaLang convention.

## v0.24

- Manifolds based inertial odometry (preintegration). Replaces previous 2016-2016 generation `InertialPose3` variables and factors.
- Testing enhancements and fixes to restore tests for RoMEPlotting and Caesar Docs.
- Minor code updates for standardized usage of new PyCaesar.jl.

## v0.23

- Bug fixes and maintenance.
- Transfer work to using Manopt.jl as new solver, slowly replacing previous Optim.jl approach (see IncrementalInference.jl).
- Extensions (weakdeps) replacement for legacy `Requires.jl`.

## v0.21

- Add `SnoopPrecompile` and Julia v1.8 min compat.
Expand Down Expand Up @@ -34,7 +46,7 @@ RoME.jl follows semver, with only a few case specific exceptions. Please see re
- Graph generator API changing to `generateGraph_ABC`.
- Factors that can default to field `.Z` for easier/better use of dispatch (#538).

## v0.15.1 -> v0.15.2 (New graph generators)
## v0.15

- A new canonical generator's name is changed to `generateCanonicalFG_Honeycomb!` (#445), and instead keeping the previous but recent function name (#440) `Beehive` available for a different upcoming canonical graph generator.
- Adding new `generateCanonicalFG_Helix2D!` plus convenience wrappers `Slew` and `Spiral`.
Expand Down
32 changes: 20 additions & 12 deletions Project.toml
Expand Up @@ -2,7 +2,7 @@ name = "RoME"
uuid = "91fb55c2-4c03-5a59-ba21-f4ea956187b8"
keywords = ["SLAM", "state-estimation", "MM-iSAM", "MM-iSAMv2", "inference", "robotics"]
desc = "Non-Gaussian simultaneous localization and mapping"
version = "0.24.0"
version = "0.24.1"

[deps]
ApproxManifoldProducts = "9bbbb610-88a1-53cd-9763-118ce10c1f89"
Expand All @@ -16,6 +16,7 @@ DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534"
IncrementalInference = "904591bb-b899-562f-9e6f-b8df64c7d480"
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
KernelDensityEstimate = "2472808a-b354-52ea-a80e-1658a3c6056d"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Manifolds = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e"
Expand All @@ -30,51 +31,58 @@ Rotations = "6038ab10-8711-5258-84ad-4b1120ba62dc"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
TensorCast = "02d47bb6-7ce6-556a-be16-bb1710789e2b"
TimeZones = "f269a46b-ccf7-5d73-abea-4c690281aa53"
TransformUtils = "9b8138ad-1b09-5408-aa39-e87ed6d21b63"

[weakdeps]
CameraModels = "0d57b887-6120-40e6-8b8c-29d3116bc0c1"
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"

[extensions]
RoMECameraModelsExt = "CameraModels"
RoMEDiffEqExt = "DifferentialEquations"
RoMEFluxExt = "Flux"
RoMEImageIOExt = "ImageIO"

[compat]
ApproxManifoldProducts = "0.7, 0.8"
ApproxManifoldProducts = "0.8"
CoordinateTransformations = "0.5, 0.6"
Dates = "1.9"
Dates = "1.10"
DelimitedFiles = "1"
Distributed = "1.9"
Distributed = "1.10"
DistributedFactorGraphs = "0.23"
Distributions = "0.24, 0.25"
DocStringExtensions = "0.8, 0.9"
FileIO = "1"
ImageCore = "0.9, 0.10"
IncrementalInference = "0.35"
Interpolations = "0.14, 0.15"
KernelDensityEstimate = "0.5.1, 0.6"
LinearAlgebra = "1.9"
LinearAlgebra = "1.10"
Manifolds = "0.9"
ManifoldsBase = "0.15"
Optim = "0.22, 1"
OrderedCollections = "1"
PrecompileTools = "1"
ProgressMeter = "1"
Random = "1.9"
Reexport = "0.2, 1"
Random = "1.10"
Reexport = "1"
Rotations = "1.1"
StaticArrays = "1"
Statistics = "1.9"
Statistics = "1.10"
TensorCast = "0.3.3, 0.4"
TransformUtils = "0.2.11"
julia = "1.9"
TimeZones = "1"
TransformUtils = "0.2.17"
julia = "1.10"

[extras]
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
CameraModels = "0d57b887-6120-40e6-8b8c-29d3116bc0c1"
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["CameraModels", "Flux", "ImageIO", "Interpolations", "JSON3", "Test"]
test = ["CameraModels", "DifferentialEquations", "Flux", "ImageIO", "JSON3", "Test"]
63 changes: 63 additions & 0 deletions ext/RoMEDiffEqExt.jl
@@ -0,0 +1,63 @@
module RoMEDiffEqExt

using DifferentialEquations
using Manifolds
using Dates, TimeZones
using Interpolations
using TensorCast
# using RoME
import RoME: imuKinematic!, RotVelPos, InertialDynamic
import RoME: getPointIdentity
import IncrementalInference: DERelative

function InertialDynamic(
tspan::Tuple{<:Real, <:Real}, # = _calcTimespan(Xi),
dt::Real,
gyros::AbstractVector,
accels::AbstractVector;
N::Integer = size(gyros,1),
timestamps = collect(range(tspan[1]; step=dt, length=N)),
)
# use data interpolation
gyros_t = linear_interpolation(timestamps, gyros)
accels_t = linear_interpolation(timestamps, accels)

data = Ref((gyro=gyros_t, accel=accels_t))

domain = RotVelPos
state0 = allocate(getPointIdentity(domain))
state1 = allocate(getPointIdentity(domain))

problemType = ODEProblem
# forward time problem
fproblem = problemType(imuKinematic!, state0, tspan, data; dt)
# backward time problem
bproblem = problemType(imuKinematic!, state1, (tspan[2], tspan[1]), data; dt = -dt)

# build the IIF recognizable object
return DERelative(domain, fproblem, bproblem, data)
end

# function InertialDynamic(
# tspan::Tuple{<:Real, <:Real}, # = _calcTimespan(Xi),
# dt::Real,
# gyros::AbstractVector,
# accels::AbstractVector;
# kw...
# )
# @cast gyros_[i,d] := gyros[i][d]
# @cast accels_[i,d] := accels[i][d]
# InertialDynamic(tspan,dt,gyros_,accels_;kw...)
# end

function InertialDynamic(
tspan::Tuple{<:ZonedDateTime, <:ZonedDateTime},
w...;
kw...
)
tspan_ = map(t -> datetime2unix(DateTime(t)), tspan)
InertialDynamic(tspan_, w...; kw...)
end


end # weakmod
108 changes: 108 additions & 0 deletions ext/factors/InertialDynamic.jl
@@ -0,0 +1,108 @@

@kwdef struct InertialDynamic{D<:SamplableBelief} <: AbstractManifoldMinimize
Z::D
end

getManifold(::InertialDynamic) = getManifold(RotVelPos)





## TODO consolidate inside module as RoME.imuKinematic
## du = f(u, params, t) # then solve ODE
function imuKinematic!(du, u, p, t; g=SA[0; 0; 9.81])
# p is IMU input (assumed [.gyro; .accel])
M = SpecialOrthogonal(3)

R = u.x[1] # i_R_b = w_R_b Rotation
V = u.x[2] # Velocity
# P = u.x[3] # Position unused here
# ω_b = u.x[4] # Gyroscope bias
# A_b = u.x[5] # Accelerometer bias

ω_m = p[].gyro(t)
Ω = hat(M, Identity(M), ω_m) # + ω_b) # b_Ωbi skew symmetric (Lie algebra element)
= R * Ω # w_Ṙ_b = i_Ṙ_b = d/dt R = d/dt exp(Ω*Δt) => Ṙ = exp(ΩΔt)*d(ΩΔt)/dt = exp(ΩΔt)*Ω

A_m = p[].accel(t) # b_Abi
= R * A_m - g # i_V̇ = w_V̇ = R * (A_m + A_b) - g
= V # i_Ṗ = w_Ṗ

du.x[1] .=
du.x[2] .=
du.x[3] .=

nothing
end



## ==========================================================
## LEGACY BELOW


# a user specified ODE in standard form
# inplace `xdot = f(x, u, t)`
# if linear, `xdot = F*x(t) + G*u(t)`
function insKinematic!(dstate, state, u, t; i_G = SA[0; 0; -9.81])
# x is a VelPose3 point (assumed ArrayPartition)
# u is IMU input (assumed [rate; accel])

# switch variable order for legacy case
dstate_ = ArrayPartition(dstate.x[2],dstate.x[3],dstate.x[1])
state_ = ArrayPartition(state.x[2],state.x[3],state.x[1])
# Using robotics frame fwd-std-dwn <==> North-East-Down
# ODE cross check taken from Farrell 2008, section 11.2.1, p.388
# NOTE, Farrell 2008 has gravity logic flipped in some of his equations.
# WE TAKE gravity as up is positive (think a pendulum hanging back during acceleration)
# expected gravity in FSD frame (akin to NED). This is a model of gravity we expect to measure.
return imuKinematic!(dstate_, state_, u, t; g = i_G)
end
# Mt = TranslationGroup(3)
# Mr = SpecialOrthogonal(3)
# # convention
# # b is real time body
# # b1 is one discete timestep in the past, equivalent to `r_Sk = r_Sk1 + r_dSk := r_S{k-1} + r_dSk`

# # Using robotics frame fwd-std-dwn <==> North-East-Down
# # ODE cross check taken from Farrell 2008, section 11.2.1, p.388
# # NOTE, Farrell 2008 has gravity logic flipped in some of his equations.
# # WE TAKE gravity as up is positive (think a pendulum hanging back during acceleration)
# # expected gravity in FSD frame (akin to NED). This is a model of gravity we expect to measure.
# i_G = [0; 0; -9.81]

# # attitude computer
# w_R_b = state.x[2] # Rotation element
# i_R_b = w_R_b
# # assume body-frame := imu-frame
# b_Ωbi = hat(Mr, Identity(Mr), u[].gyro(t)) # so(3): skew symmetric Lie algebra element
# # assume perfect measurement, i.e. `i` here means measured against native inertial (no coriolis, transport rate, error corrections)
# i_Ṙ_b = i_R_b * b_Ωbi
# # assume world-frame := inertial-frame
# w_Ṙ_b = i_Ṙ_b
# # tie back to the ODE solver

# dstate.x[2] .= w_Ṙ_b
# # Note closed form post integration result (remember exp is solution to first order diff equation)
# # w_R_b = exp(Mr, w_R_b1, b_Ωbi)

# # measured inertial acceleration
# b_Abi = u[].accel(t) # already a tangent vector
# # inertial (i.e. world) velocity-dot (accel) by compensating (i.e. removing) expected gravity measurement
# i_V̇ = i_R_b * b_Abi - i_G
# # assume world is inertial frame
# w_V̇ = i_V̇
# dstate.x[3] .= w_V̇ # velocity state

# # position-dot (velocity)
# w_V = state.x[3]
# i_V = w_V
# i_Ṗ = i_V
# w_Ṗ = i_Ṗ
# dstate.x[1] .= w_Ṗ

# # TODO add biases, see RoME.InertialPose
# # state[4] := gyro bias
# # state[5] := acce bias
# nothing
15 changes: 15 additions & 0 deletions src/Deprecated.jl
@@ -1,4 +1,19 @@

##==============================================================================
## Legacy, remove once AMP #41 is resolved
##==============================================================================


Base.convert(
::Type{<:Tuple},
::IIF.InstanceType{typeof(getManifold(RotVelPos))}
) = (
:Circular,:Circular,:Circular,
:Euclid,:Euclid,:Euclid,
:Euclid,:Euclid,:Euclid
)


##==============================================================================
## Legacy, remove some time after RoME v0.22
##==============================================================================
Expand Down
10 changes: 7 additions & 3 deletions src/ExportAPI.jl
Expand Up @@ -17,7 +17,7 @@ export
pol2cart,

# Didson model
evalPotential,
# evalPotential,
LinearRangeBearingElevation,
project!,
project,
Expand All @@ -41,9 +41,9 @@ export
PriorPoint2,
PackedPriorPoint2,
Pose2Point2BearingRange,
Pose2Point2BearingRangeMH,
# Pose2Point2BearingRangeMH,
PackedPose2Point2BearingRange,
PackedPose2Point2BearingRangeMH,
# PackedPose2Point2BearingRangeMH,
Pose2Point2Bearing,
PackedPose2Point2Bearing,
Pose2Point2Range,
Expand Down Expand Up @@ -105,6 +105,10 @@ export
PackedPriorPose3ZRP,
Pose3Pose3Rotation,
PackedPose3Pose3Rotation,

RotVelPos,
InertialDynamic,

# Various utilities
passTypeThrough,
buildGraphChain!,
Expand Down
1 change: 1 addition & 0 deletions src/RoME.jl
Expand Up @@ -126,6 +126,7 @@ include("services/ScalarFields.jl")

include("../ext/WeakdepsPrototypes.jl")
include("../ext/factors/GenericProjection.jl")
include("../ext/factors/InertialDynamic.jl")
include("../ext/factors/MixtureFluxPose2Pose2.jl")


Expand Down

0 comments on commit f0f6e3f

Please sign in to comment.