Skip to content

Commit

Permalink
Version 0.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelNoesslboeck committed Feb 24, 2024
1 parent 3e15318 commit 78ace0e
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
[package]
name = "syunit"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
authors = [ "Samuel Nösslböck <samuel.noesslboeck@gmail.com>" ]
description = "A small library that contains some basic units to help structuring kinematics and robotic programming in rust."
description = "A small library that contains some basic units to help structuring kinematics and robotic programming in rust"
repository = "https://github.com/SamuelNoesslboeck/syunit"
readme = "README.md"
license-file = "LICENSE"
keywords = [ "robotics", "kinematics", "unit-system", "math" ]

[dependencies]
serde = { version = "1.0.196", features = [ "derive" ] }
serde = { version = "1.0.196", features = [ "derive" ], optional = true }

[features]
default = [ "serde" ]
serde = [ "dep:serde" ]
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# syunit
## syunit

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 zero-overhead and compile-time checking of correct unit, variable and function usage.

## Quick introduction
### Quick introduction

In many functions for kinematics and robotics, it sometimes becomes unclear which type of unit is desired to be used, especially when it
comes to distances.
Expand Down Expand Up @@ -42,7 +42,7 @@ fn move_to_distance(dist : Gamma, speed : Velocity) {

Each unit is represented by a 32bit float enclosed into a *tuple struct*. Why these units are helpful not only for documentation is explained in the flowing chapters:

### Creation and conversion
#### Creation and conversion

As rust always prefers implicit syntax, so does this library. The unit types cannot be converted back to a `f32` without calling `into()`.

Expand Down Expand Up @@ -78,7 +78,7 @@ requires_velocity(gamma);
// |
```

### Naming
#### Naming

As the units are all named after their purpose, the context of functions, their parameters and other variables becomes clear easier. However the library does *not* differentiate between linear and rotary movement in terms of naming.

Expand All @@ -88,7 +88,7 @@ However there are three units for distances with different names:
- `Phi`: Represents an absolute distance in the machines "perspective", often refered to as *mathematical angle/distance* in a lot of documentations. This angle is for example used to describe the rotation of a robot joint, where the `Gamma` angle has an offset compared to the `Phi` angle.
- `Delta`: Represents a relative distance

### Operations and automatic type evaluation
#### Operations and automatic type evaluation

Especially with distances, a lot of operations between them are restricted, as they would fail to make any sense. For example a `Gamma` distance cannot be added with either a `Phi` or another `Gamma` distance, as it does not make any sense to add two absolute distances. However a `Delta` distance can be added to a `Gamma` or `Phi` distance to extend/shorten said `Gamma` or `Phi` distance.

Expand Down Expand Up @@ -124,10 +124,14 @@ assert_eq!(Velocity(3.0) / Time(2.0), Acceleration(1.5));
assert_eq!(Velocity(3.0) * Time(3.0), Delta(9.0));
```

### Physical background
#### Physical background

Each unit of course represents a physical unit, in almost all cases their standardized values. Only difference is distance, it is represented by *millimeters*. Meaning velocity becomes *millimeters per second*, acceleration becomes *millimeters per second squared* ...

## Issues and improvements
### `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](https://github.com/SamuelNoesslboeck/syunit) or contact me directly.
39 changes: 30 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
#![crate_name = "syunit"]
#![doc = include_str!("../README.md")]
#![no_std]
#![deny(missing_docs)]

// Units
use core::ops::{Add, AddAssign, Div, Sub, SubAssign};
use core::time::Duration;

#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};

// Helper import for local macro definitions
use crate as syunit;

/// General marker trait for all units
pub trait Unit : Into<f32> {
/// Creates a new value of this unit using a `f32` value
fn new(v : f32) -> Self
where
Self : Sized;
}

/// Helper macro that implements everything needed to do +,-,+=,-= operations with the unit itself
#[macro_export]
macro_rules! additive_unit {
( $unit:ident ) => {
Expand Down Expand Up @@ -55,6 +59,7 @@ macro_rules! additive_unit {
};
}

/// Implements the basics for a unit
#[macro_export]
macro_rules! basic_unit {
( $a:ident ) => {
Expand Down Expand Up @@ -98,6 +103,12 @@ macro_rules! basic_unit {
Self(self.0.powi(pow))
}

/// Returns the unit raised to the given power `pow`
#[inline(always)]
pub fn powf(self, pow : f32) -> Self {
Self(self.0.powf(pow))
}

/// Returns the sin of this units value
#[inline(always)]
pub fn sin(self) -> f32 {
Expand Down Expand Up @@ -249,6 +260,7 @@ macro_rules! basic_unit {
};
}

/// Implements everything required to form a "derive over time like"-connection between the given units
#[macro_export]
macro_rules! derive_units {
( $dist:ident, $vel:ident, $time:ident ) => {
Expand Down Expand Up @@ -302,7 +314,8 @@ macro_rules! derive_units {
/// // Comparisions
/// assert!(Time(1.0) > Time(-1.0));
/// ```
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Time(pub f32);
basic_unit!(Time);
additive_unit!(Time);
Expand Down Expand Up @@ -345,7 +358,8 @@ impl Div<Time> for f32 {
/// assert_eq!(Gamma(2.0) + Delta(1.0), Gamma(3.0));
/// assert_eq!(Gamma(2.0) - Delta(1.0), Gamma(1.0));
/// ```
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Gamma(pub f32);
basic_unit!(Gamma);

Expand Down Expand Up @@ -431,7 +445,8 @@ pub fn force_gammas_from_phis<const N : usize>(phis : [Phi; N]) -> [Gamma; N] {
/// # Unit
///
/// - Can be either radians or millimeters
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Phi(pub f32);
basic_unit!(Phi);

Expand Down Expand Up @@ -503,7 +518,8 @@ impl SubAssign<Delta> for Phi {
/// assert_eq!(Delta(5.0), Delta(2.5) * 2.0);
/// assert_eq!(Delta(2.0), Gamma(4.0) - Gamma(2.0));
/// ```
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Delta(pub f32);
basic_unit!(Delta);
additive_unit!(Delta);
Expand All @@ -521,7 +537,8 @@ impl Delta {
/// # Unit
///
/// - Can be either radians per second or millimeters per second
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Velocity(pub f32);
basic_unit!(Velocity);
additive_unit!(Velocity);
Expand All @@ -547,7 +564,8 @@ impl Div<Velocity> for f32 {
///
/// assert_eq!(Velocity(5.0), Acceleration(2.5) * Time(2.0));
/// assert_eq!(Acceleration(2.5), Velocity(5.0) / Time(2.0));
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Acceleration(pub f32);
basic_unit!(Acceleration);
additive_unit!(Acceleration);
Expand All @@ -559,7 +577,8 @@ derive_units!(Force, Acceleration, Inertia);
/// # Unit
///
/// - Can be either radians per second^3 or millimeters per second^3
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Jolt(pub f32);
basic_unit!(Jolt);
additive_unit!(Jolt);
Expand All @@ -570,7 +589,8 @@ derive_units!(Acceleration, Jolt, Time);
/// # Unit
///
/// - Can be either kilogramm or kilogramm times meter^2
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Inertia(pub f32);
basic_unit!(Inertia);
additive_unit!(Inertia);
Expand All @@ -580,7 +600,8 @@ additive_unit!(Inertia);
/// # Unit
///
/// - Can be either Newton or Newtonmeter
#[derive(Clone, Copy, Default, Serialize, Deserialize, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Force(pub f32);
basic_unit!(Force);
additive_unit!(Force);
Expand Down

0 comments on commit 78ace0e

Please sign in to comment.