A small library that contains some basic units to help structuring kinematics and robotic programming in rust. The library uses rusts tuple structs to create a compile-time checking of correct unit, variable and function usage.
Quick introduction
In many functions for kinematics and robotics, it sometimes becomes unclear which type of unit is desired to be used.
/// Relative movement
/// Absolute movement
Even if most code is not as horribly documented, nothing stops a developer from accidently plugging in an absolute distance into a function that takes a relative one. Here comes this library into play:
use *;
/// Relative movement
/// Absolute movement
Each unit is represented by a f32 enclosed into a tuple struct, making them simple but also their own type!
Why these units are helpful not only for documentation is explained in the flowing chapters:
Explicit syntax
As rust always prefers explicit syntax, so does this library. The unit types cannot be converted back to a f32 without calling into().
use *;
// Every unit is created by the tuple struct constructor using a `f32` value
let abs_pos = PositionMM;
requires_f32;
// error[E0308]: mismatched types
// |
// | requires_f32(abs_pos) // ERROR! => Type `PositionMM` cannot be used as `f32`
// | ------------ ^^^^^ expected `f32`, found `PositionMM`
// | |
// | arguments to this function are incorrect
// |
requires_velocity;
// error[E0308]: mismatched types
// |
// | requires_f32(abs_pos);
// | ------------ ^^^^^ expected `MMPerSecond`, found `PositionMM`
// | |
// | arguments to this function are incorrect
// |
Operations and automatic type evaluation
The library comes with a lot of implementations in addition to the units, making it possible to do a lot of operations with these units and letting the compiler automatically evaluate the resulting units for you
use *;
// Radial / Linear
assert_eq!;
assert_eq!;
// Seconds / Hertz
assert_eq!;
assert_eq!;
// Time to build up speed
assert_eq!;
// Forces
assert_eq!;
assert!; // Automatic conversion
// ...
Another helpful unit type are Positions, they help differentiating between absolute and relative distances.
use *;
// Difference between two positions is a relative distance
assert_eq!;
// Radial position math
assert_eq!;
assert_eq!;
A very special unit is Seconds, dividing or multipling by it often changes units.
use *;
// Travelling a distance of 6mm in 2 seconds gives a velocity of 3mm/s
assert_eq!;
// Accelerating to a velocity of 3mm/s in 2 seconds gives an acceleration of 1.5mm/s^2
assert_eq!;
// Travelling with 3mm/s for 3 seconds gives a total distance of 9mm
assert_eq!;
Unitsets
There is also a tool for defining functions in a more general way, with the help of UnitSets!
use *;
assert_eq!; // Using linear metric mm
assert_eq!; // Using rotary units
Metric and Imperial
The library also includes imperial units and conversions between them.
use *;
use *;
let millimeters = Millimeters;
assert_eq!;
assert_eq!;
serde implementation
All the units implement serde::Serialize and serde::Deserialize if the "serde" feature is enabled, which is the case by default.
Issues and improvements
Please feel free to create issues on the github repo!