Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sophus_{autodiff,geo,lie} docs #74

Merged
merged 1 commit into from
Feb 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
steps:
- name: Checkout workspace
uses: actions/checkout@v3
- uses: extractions/setup-just@v1
- name: Install pre-commit and install
run: |
pip install pre-commit
Expand All @@ -22,8 +23,13 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
- name: cargo fmt
run: |
rustup default nightly
rustup component add rustfmt
just format
- name: cargo doc
run: |
rustup default nightly
rustup component add rustfmt
cargo fmt
just doc
17 changes: 5 additions & 12 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,22 @@ jobs:
run: ${SCCACHE_PATH} --show-stats
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2024-12-01
toolchain: nightly
- uses: extractions/setup-just@v1
- name: cargo build
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
run: |
rustup default nightly-2024-12-01
cargo build --release --all-targets --all-features
rustup default nightly
just build-simd
- name: cargo test
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
run: |
rustup default nightly-2024-12-01
just test
- name: cargo docs
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
run: |
rustup default nightly-2024-12-01
cargo doc --no-deps --all-features
rustup default nightly
just test-simd
- name: Run sccache stat for check after
shell: bash
run: ${SCCACHE_PATH} --show-stats
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ nalgebra = { version = "0.33.2", features = ["rand", "bytemuck"] }
ndarray = { version = "0.15", features = ["approx-0_5"] }
num-traits = "0.2"
rand = "0.8"
rustc_version = "0.4"
snafu = "0.8.5"
typenum = { version = "1.17", features = ["const-generics"] }
winit = { version = "0.30.5", features = ["android-native-activity"] }
Expand Down
144 changes: 133 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,108 @@ sophus-rs is a Rust library for 2d and 3d geometry for Computer Vision and Robot
It is a spin-off of the [Sophus](https://github.com/strasdat/Sophus) C++ library which
focuses on *Lie groups* (e.g. rotations and transformations in 2d and 3d).

In addition to Lie groups, sophus-rs also includes other geometric/maths concepts such unit vector,
splines, image classes, camera models as well as a other utilities such as a non-linear least
squares optimization.
In addition to Lie groups, sophus-rs also includes other geometric/maths concepts.

## Status
## Automatic differentiation

This library is in an early development stage - hence API is highly unstable. It is likely that
existing features will be removed or changed in the future.
sophus-rs provides an automatic differentiation using dual numbers such as
[autodiff::dual::DualScalar] and [autodiff::dual::DualVector].

```
use sophus::prelude::*;
use sophus::autodiff::dual::{DualScalar, DualVector};
use sophus::autodiff::linalg::VecF64;
use sophus::autodiff::maps::VectorValuedVectorMap;

// [[ x ]] [[ x / z ]]
// proj [[ y ]] = [[ ]]
// [[ z ]] [[ y / z ]]
fn proj_fn<S: IsSingleScalar<DM, DN>, const DM: usize, const DN: usize>(
v: S::Vector<3>,
) -> S::Vector<2> {
let x = v.elem(0);
let y = v.elem(1);
let z = v.elem(2);
S::Vector::<2>::from_array([x / z, y / z])
}

let a = VecF64::<3>::new(1.0, 2.0, 3.0);
// Finite difference Jacobian
let finite_diff = VectorValuedVectorMap::<f64, 1>::sym_diff_quotient_jacobian(
proj_fn::<f64, 0, 0>,
a,
0.0001,
);
// Automatic differentiation Jacobian
let auto_diff = proj_fn::<DualScalar<3, 1>, 3, 1>(DualVector::var(a)).jacobian();

approx::assert_abs_diff_eq!(finite_diff, auto_diff, epsilon = 0.0001);
```

Note that proj_fn is a function that takes a 3D vector and returns a 2D vector. The Jacobian of
proj_fn is 2x3 matrix. When a (three dimensional) dual vector is passed to proj_fn, then
a 2d dual vector is returned. Since we are expecting a 2x3 Jacobian, each element of the 2d dual
vector must represent 3x1 Jacobian. This is why we use DualScalar<3, 1> as the scalar type.

## Lie Groups

sophus-rs provides a number of Lie groups, including:

* The group of 2D rotations, [lie::Rotation2], also known as the special orthogonal group SO(2),
* the group of 3D rotations, [lie::Rotation3], also known as the special orthogonal group SO(3),
* the group of 2d isometries, [lie::Isometry2], also known as the Euclidean group SE(2), and
* the group of 3d isometries, [lie::Isometry3], also known as the Euclidean group SE(3).


```
use sophus::autodiff::linalg::VecF64;
use sophus::lie::{Rotation3F64, Isometry3F64};
use std::f64::consts::FRAC_PI_4;

// Create a rotation around the z-axis by 45 degrees.
let world_from_foo_rotation = Rotation3F64::rot_z(FRAC_PI_4);

// Create a translation in 3D.
let foo_in_world = VecF64::<3>::new(1.0, 2.0, 3.0);

// Combine them into an SE(3) transform.
let world_from_foo_isometry
= Isometry3F64::from_translation_and_rotation(foo_in_world, world_from_foo_rotation);

// Apply world_from_foo_isometry to a 3D point in the foo reference frame.
let point_in_foo = VecF64::<3>::new(10.0, 0.0, 0.0);
let point_in_world = world_from_foo_isometry.transform(&point_in_foo);

// Manually compute the expected transformation:
// - rotate (10, 0, 0) around z by 45°
// - then translate by (1, 2, 3)
let angle = FRAC_PI_4;
let cos = angle.cos();
let sin = angle.sin();
let expected_point_in_world = VecF64::<3>::new(1.0 + 10.0 * cos, 2.0 + 10.0 * sin, 3.0);

approx::assert_abs_diff_eq!(point_in_world[0], expected_point_in_world[0], epsilon = 1e-9);
approx::assert_abs_diff_eq!(point_in_world[1], expected_point_in_world[1], epsilon = 1e-9);
approx::assert_abs_diff_eq!(point_in_world[2], expected_point_in_world[2], epsilon = 1e-9);

// Map isometry to 6-dimensional tangent space.
let omega = world_from_foo_isometry.log();
// Map tangent space element back to the manifold.
let roundtrip_world_from_foo_isometry = Isometry3F64::exp(&omega);
approx::assert_abs_diff_eq!(roundtrip_world_from_foo_isometry.matrix(),
world_from_foo_isometry.matrix(),
epsilon = 1e-9);

// Compose with another isometry.
let world_from_bar_isometry = Isometry3F64::rot_y(std::f64::consts::FRAC_PI_6);
let bar_from_foo_isometry = world_from_bar_isometry.inverse() * world_from_foo_isometry;
```

## And more...

such unit vector, splines, image classes, camera models, non-linear least squares optimization and
some visualization tools. Check out the [documentation](https://docs.rs/sophus) for more information.

However, the intend is to stride for correctness, facilitated by a comprehensive test suite.

## Building

Expand All @@ -31,12 +123,42 @@ sophus-rs builds on stable.
sophus = "0.12.0"
```

```toml
[dependencies]
sophus = { version = "0.12.0", features = ["simd"] }
```

To allow for batch types, such as BatchScalarF64, the 'simd' feature is required. This feature
depends on [`portable-simd`](https://doc.rust-lang.org/std/simd/index.html), which is currently
only available on [nightly](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html). There
are no plans to rely on any other nightly features.

```toml
[dependencies]
sophus = { version = "0.12.0", features = ["simd"] }
```
## Crate Structure and Usage

sophus-rs is an **umbrella crate** that provides a single entry point to multiple
sub-crates (modules) under the `sophus::` namespace. For example, the automatic differentiation
sub-crate can be accessed via `use sophus::autodiff`, and the lie group sub-crate via
`use sophus::lie`, etc.

- If you want all of sophus’s functionalities at once (geometry, AD, manifolds, etc.),
simply add `sophus` in your `Cargo.toml`, and then in your Rust code:

```rust
use sophus::prelude::*;
use sophus::autodiff::dual::DualScalar;
// ...
```

- If you only need the autodiff functionalities in isolation, you can also depend on the
standalone crate underlying `sophus_autodiff`.

```rust
use sophus_autodiff::prelude::*;
use sophus_autodiff::dual::DualScalar;
// ...
```

## Status

This library is in an early development stage - hence API is highly unstable. It is likely that
existing features will be removed or changed in the future.
3 changes: 3 additions & 0 deletions crates/sophus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ thingbuf.workspace = true
tokio = { version = "1", features = ["full"] }
wgpu.workspace = true

[build-dependencies]
rustc_version.workspace = true


[features]
simd = [
Expand Down
10 changes: 10 additions & 0 deletions crates/sophus/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fn main() {
println!("cargo:rustc-check-cfg=cfg(nightly)"); // Declares 'nightly' as a valid cfg condition

let is_nightly =
rustc_version::version_meta().unwrap().channel == rustc_version::Channel::Nightly;

if is_nightly {
println!("cargo:rustc-cfg=nightly");
}
}
15 changes: 15 additions & 0 deletions crates/sophus/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#![cfg_attr(feature = "simd", feature(portable_simd))]
#![allow(clippy::needless_range_loop)]
#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
#![cfg_attr(nightly, feature(doc_auto_cfg))]

#[doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
#[cfg(doctest)]
pub struct ReadmeDoctests;

#[doc(inline)]
pub use sophus_autodiff as autodiff;
Expand All @@ -27,12 +32,22 @@ pub use sophus_timeseries as timeseries;
#[doc(inline)]
pub use sophus_viewer as viewer;

/// Examples for the `sophus` umbrella crate. Note that this is not a comprehensive list of
/// examples, and most usage examples are found in the individual sub-crates. In particular, the
/// unit tests in each sub-crate are a good source of examples.
pub mod examples;
pub use eframe;
pub use nalgebra;
pub use ndarray;
pub use thingbuf;

/// sophus prelude.
///
/// It is recommended to import this prelude when working with `sophus` types:
///
/// ```
/// use sophus_autodiff::prelude::*;
/// ```
pub mod prelude {
pub use crate::{
autodiff::prelude::*,
Expand Down
5 changes: 4 additions & 1 deletion crates/sophus_autodiff/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
description = "sophus - geometry for robotics and computer vision"
name = "sophus_autodiff"
readme = "../../README.md"
readme = "../README.md"

edition.workspace = true
include.workspace = true
Expand All @@ -21,6 +21,9 @@ typenum.workspace = true

sleef = {version = "0.3", optional = true}

[build-dependencies]
rustc_version.workspace = true

[features]
simd = ["sleef"]
std = []
Expand Down
Loading
Loading