9 个版本
0.2.1 | 2024年5月25日 |
---|---|
0.2.0 | 2024年5月25日 |
0.1.6 | 2024年5月17日 |
0.1.2 | 2024年4月26日 |
0.1.1 | 2024年2月24日 |
#317 in 算法
516 每月下载量
用于 2 crates
35KB
641 行
syunit
一个小型库,包含一些基本单位,以帮助在 Rust 中构建运动学和机器人编程。该库使用 Rust 的 元组结构体 来创建零开销和编译时检查正确单位、变量和函数使用。
快速入门
在许多运动学和机器人函数中,有时不清楚希望使用哪种类型的单位,尤其是在距离方面。
/// Relative movement
fn move_distance(dist : f32, speed : f32) {
// ...
}
/// Absolute movement
fn move_to_distance(dist : f32, speed : f32) {
// ...
}
即使大多数代码没有如此糟糕的文档,并使用如此糟糕的名称,也无法阻止开发者不小心将绝对距离插入到接受相对距离的函数中。这时这个库就派上用场了
use syunit::*;
/// Relative movement
fn move_distance(dist : Delta, speed : Velocity) {
// ...
}
/// Absolute movement
fn move_to_distance(dist : Gamma, speed : Velocity) {
// ...
}
// Delta => Relative distance
// Gamma => Absolute distance
//
// Naming choice will be explained later
每个单位都由一个包含在 元组结构体 中的 32 位浮点数表示。为什么这些单位不仅对文档有帮助,在接下来的章节中将进行解释
创建和转换
由于 Rust 总是更喜欢隐式语法,因此此库也是如此。如果没有调用 into()
,则无法将单位类型转换回 f32
。
use syunit::*;
fn requires_f32(value : f32) {
// ...
}
fn requires_velocity(value : Velocity) {
// ...
}
// Every unit is created by the tuple struct constructor using a `f32` value
let gamma = Gamma(10.0);
requires_f32(gamma);
// error[E0308]: mismatched types
// | requires_f32(gamma) // ERROR! => Type `Gamma` cannot be used as `f32`
// | ------------ ^^^^^ expected `f32`, found `Gamma`
// | |
// | arguments to this function are incorrect
// |
requires_velocity(gamma);
// error[E0308]: mismatched types
// |
// | requires_f32(gamma);
// | ------------ ^^^^^ expected `Velocity`, found `Gamma`
// | |
// | arguments to this function are incorrect
// |
命名
由于单位都是以它们的用途命名的,因此函数、它们的参数和其他变量的上下文更容易理解。然而,该库在命名方面并不区分线性运动和旋转运动。
但是,有三个具有不同名称的距离单位
Gamma
:表示在执行器“视角”中的绝对距离,通常称为组件角度/距离Phi
:表示在机器“视角”中的绝对距离,在许多文档中通常称为数学角度/距离。这个角度用于描述机器人关节的旋转,其中Gamma
角度相对于Phi
角度有偏移。Delta
:表示相对距离
操作和自动类型评估
尤其是在距离方面,它们之间的许多操作都受到限制,因为它们无法表达任何意义。例如,无法将 Gamma
距离与 Phi
或另一个 Gamma
距离相加,因为将两个绝对距离相加没有任何意义。然而,可以将 Delta
距离添加到 Gamma
或 Phi
距离中,以延长或缩短该 Gamma
或 Phi
距离。
use syunit::*;
let gamma = Gamma(2.0);
let phi = Phi(4.0);
let delta = Delta(1.0);
assert_eq!(gamma + delta, Gamma(3.0));
assert_eq!(phi + delta, Phi(5.0));
例如,还可以减去两个绝对距离,这给出它们之间的相对 Delta
距离。
use syunit::*;
assert_eq!(Gamma(5.0) - Gamma(3.0), Delta(2.0));
一个非常特殊的单位是 Time
,除以或乘以它通常会改变单位。
use syunit::*;
// Travelling a distance of 6mm in 2 seconds gives a velocity of 3mm/s
assert_eq!(Delta(6.0) / Time(2.0), Velocity(3.0));
// Accelerating to a velocity of 3mm/s in 2 seconds gives an acceleration of 1.5mm/s^2
assert_eq!(Velocity(3.0) / Time(2.0), Acceleration(1.5));
// Travelling with 3mm/s for 3 seconds gives a total distance of 9mm
assert_eq!(Velocity(3.0) * Time(3.0), Delta(9.0));
物理背景
每个单位当然代表一个物理单位,几乎在所有情况下都是它们的标准化值。唯一不同的是距离,它由 毫米 表示。这意味着速度变为 每秒毫米,加速度变为 每秒平方毫米 ...
serde
实现
如果启用 "serde" 功能(默认情况下总是启用),所有这些单位都实现了 serde::Serialize
和 serde::Deserialize
。
问题和改进
请随时在 github 仓库 上创建问题或直接联系我。
依赖项
~0.4–1MB
~23K SLoC