evian_tracking/
lib.rs

1//! Robot localization and tracking.
2//! 
3//! This crate provides traits and systems for tracking and localizing the position, orientation,
4//! velocity, and forward travel of a mobile robot in a 2D environment. The goal is to measure
5//! accurate data about the robot and provide it to motion algorithms.
6//! 
7//! The traits provided in this crate allow for motion algorithms to operate generically over any
8//! tracking system implementation, provided that the implementation measures the necessary data.
9//! 
10//! Tracking systems may choose to implement the following traits for motion algorithms to use:
11//! 
12//! - [`TracksPosition`], for tracking the robot's 2D position (odometry).
13//! - [`TracksHeading`], for tracking the robot's absolute orientation (heading).
14//! - [`TracksVelocity`], for tracking the robot's linear and angular velocity.
15//! - [`TracksForwardTravel`], for tracking the robot's signed forward wheel travel.
16//! 
17//! Below is an example of a motion algorithm function that is generic across all differential
18//! drivetrains with tracking systems that measure a robot's forward wheel travel:
19//! 
20//! ```
21//! async fn motion(drivetrain: &mut Drivetrain<Differential, impl TracksForwardTravel>) {
22//!     // Motion goes here...
23//! }
24//! ```
25//! 
26//! Additionally, a reference implementation of a tracking system that performs wheeled odometry is
27//! provided by the [`wheeled`] module.
28//! 
29//! # A quick note about units!
30//! 
31//! `evian` made the intentional choice to be primarily unitless, mainly because stable Rust
32//! currently lacks many of the features needed to provide a good developer experience using
33//! typed units. Although several widely-used libraries exist in stable Rust (such as
34//! [`uom`](http://crates.io/crates/uom)), there is no single obvious choice to be made here and
35//! this region of the Rust ecosystem seems to be in a fairly volatile state that would make it
36//! dangerous to fully commit to a single library this early on.
37//! 
38//! As such, evian made the decision to forego requiring specific units of measure where possible,
39//! particular in measures of *length*. Instead, length is typically provided in **wheel units**,
40//! which is defined as "whatever the user measured their wheels with". This gives users a choice
41//! of what units to use and keeps everything generally stable while the Rust ecosystem tries to
42//! figure out what typed units library to go with.
43
44#![no_std]
45
46extern crate alloc;
47
48mod sensor;
49pub mod wheeled;
50
51pub use sensor::RotarySensor;
52
53use evian_math::{Angle, Vec2};
54
55/// A tracking system that localizes a robot's 2D position.
56/// 
57/// This trait defines a system for tracking and reporting the position of a mobile robot in a
58/// 2D environment. The process of localizing a mobile robot's position is also commonly known
59/// as odometry.
60/// 
61/// # Coordinate System
62/// 
63/// Implementors of this trait MUST provide their position estimate in the [*cartesian coordinate
64/// system*](https://en.wikipedia.org/wiki/Cartesian_coordinate_system). Units are expected to be
65/// in *wheel units* — the same units that were used to measure the robot's wheel diameter.
66pub trait TracksPosition {
67    /// Return's the robot's position on a 2D cartesian coordinate plane measured
68    /// in wheel units.
69    fn position(&self) -> Vec2<f64>;
70}
71
72/// A tracking system that tracks a robot's absolute orientation.
73/// 
74/// This trait defines a system for tracking and reporting the orientation (heading) of a mobile
75/// robot in a 2D environment. The robot's orientation refers to its direction of travel relative
76/// to a fixed reference frame. 
77/// 
78/// # Angle System
79/// 
80/// Implementors of this trait MUST provide their angles in a system compatible with cartesian
81/// coordinates in *standard position*. This means that anticlockwise motion is considered a
82/// positive rotation, and a rotation of zero degrees is inline with the x-axis.
83pub trait TracksHeading {
84    /// Returns the robot's orientation bounded from [0, 2π] radians.
85    fn heading(&self) -> Angle;
86}
87
88/// A tracking system that tracks a robot's linear and angular velocity.
89/// 
90/// # Units
91/// 
92/// - Linear velocity is measured in *wheel units per second*. In this instance, *wheel units*
93///   refer to whatever units the user measured their wheel diameter with.
94/// 
95/// - Angular velocity is measured in *radians per second*.
96pub trait TracksVelocity {
97    /// Returns the robot's estimated linear velocity in wheel units per second.
98    fn linear_velocity(&self) -> f64;
99
100    /// Returns the robot's estimated angular velocity in radians per second.
101    fn angular_velocity(&self) -> f64;
102}
103
104/// A tracking system that tracks a robot's signed forward wheel travel.
105/// 
106/// # Units
107/// 
108/// Units are expected to be returned in *wheel units* — the same units that were used to measure the
109/// robot's wheel diameter.
110pub trait TracksForwardTravel {
111    /// Returns the signed forward wheel travel of the robot in wheel units.
112    /// 
113    /// Positive values indicate forward movement from the origin of tracking, while negative
114    /// values indicate backwards movement from the origin.
115    fn forward_travel(&self) -> f64;
116}