Compare commits

...
4 Commits
Author SHA1 Message Date
melfely d4809beee7 Merge pull request 'Repo rebuild' (#2) from repo-rebuild into master
Reviewed-on: #2
2026-07-31 02:43:07 +00:00
melfely 69deda596e Merge branch 'repo-rebuild' 2026-07-30 21:38:16 -05:00
melfely 3703ca664e Added in the Pid and Motor Code
Pid was added to rnavp, since it can be used in alot of different things.
2026-07-30 21:20:30 -05:00
melfely 4b06468ff4 Rebuild the repo as a workspace
This replaces the existing single lib project repo, and replaces it with a workspace containing a large number of crates, this will allow for a much better structure and less feature flags being needed for reducing the feature scope for each user.
2026-07-30 20:35:13 -05:00
25 changed files with 371 additions and 527 deletions
Generated
+237 -17
View File
@@ -3,35 +3,193 @@
version = 4 version = 4
[[package]] [[package]]
name = "proc-macro2" name = "atomic-polyfill"
version = "1.0.106" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
dependencies = [
"critical-section",
]
[[package]]
name = "autocfg"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cobs"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
dependencies = [
"thiserror",
]
[[package]]
name = "critical-section"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "hash32"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
dependencies = [
"byteorder",
]
[[package]]
name = "hash32"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
dependencies = [
"byteorder",
]
[[package]]
name = "heapless"
version = "0.7.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
dependencies = [
"atomic-polyfill",
"hash32 0.2.1",
"rustc_version",
"serde",
"spin",
"stable_deref_trait",
]
[[package]]
name = "heapless"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4"
dependencies = [
"hash32 0.3.1",
"serde_core",
"stable_deref_trait",
]
[[package]]
name = "lock_api"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
"scopeguard",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "postcard"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
dependencies = [
"cobs",
"heapless 0.7.17",
"postcard-derive",
"serde",
]
[[package]]
name = "postcard-derive"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0232bd009a197ceec9cc881ba46f727fcd8060a2d8d6a9dde7a69030a6fe2bb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.45" version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
name = "rnavp" name = "rnavp"
version = "0.3.0" version = "0.1.0"
dependencies = [ dependencies = [
"heapless 0.9.3",
"postcard",
"serde", "serde",
"thiserror",
"uom",
] ]
[[package]] [[package]]
name = "serde" name = "rnavp_communication"
version = "1.0.228" version = "0.1.0"
[[package]]
name = "rnavp_logic"
version = "0.1.0"
dependencies = [
"rnavp",
"serde",
"uom",
]
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
[[package]]
name = "serde"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [ dependencies = [
"serde_core", "serde_core",
"serde_derive", "serde_derive",
@@ -39,37 +197,99 @@ dependencies = [
[[package]] [[package]]
name = "serde_core" name = "serde_core"
version = "1.0.228" version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.228" version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 3.0.3",
] ]
[[package]] [[package]]
name = "syn" name = "spin"
version = "2.0.117" version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
dependencies = [
"lock_api",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
[[package]]
name = "syn"
version = "2.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "syn"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "2.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
dependencies = [
"proc-macro2",
"quote",
"syn 3.0.3",
]
[[package]]
name = "typenum"
version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.24" version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "uom"
version = "0.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a739f83872836c82a4f2527d4e54b37007b3de68cafe7edde95fd695968bf4b9"
dependencies = [
"num-traits",
"typenum",
]
+4 -19
View File
@@ -1,19 +1,4 @@
[package] [workspace]
name = "rnavp" members = ["rnavp"
version = "0.1.0" , "rnavp_communication", "rnavp_controller"]
edition = "2024" resolver = "3"
publish = ["gitea"]
license = "MIT OR Apache-2.0"
[features]
default= ["embassy"]
std = []
embassy = ["core_full"]
core = []
core_full = ["core_communication", "core_logic"]
core_communication = ["core"]
core_logic = ["core"]
host = ["std", "core_full"]
[dependencies]
serde = { version = "1.0.228", features = ["derive"], default-features = false }
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "rnavp"
version = "0.1.0"
edition = "2024"
[dependencies]
heapless = { version = "0.9.3", features = ["serde"] }
postcard = { version = "1.1.3", features = ["postcard-derive"] }
serde = { version = "1.0.229", default-features = false, features = ["derive"] }
thiserror = { version = "2.0.19", default-features = false }
uom = { version = "0.38.0", default-features = false, features = ["autoconvert", "f32", "si"] }
+69
View File
@@ -0,0 +1,69 @@
use serde::{Deserialize, Serialize};
///A simple enum for Counterclockwise or Clockwise direction semantics. Makes it easier much clear than a true/false bool
/// IF you use this to convert to a signed number note that CW is negative and CCW is positive
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum Direction {
///CounterClockWise
CCW,
///ClockWise
CW,
}
impl Direction {
///Inverts the direction currently stored in this.
/// Helps with a simple direction change without knowing the current direction.
pub fn inv_dir(&mut self) {
match *self {
Self::CCW => {
*self = Self::CW;
}
Self::CW => {
*self = Self::CCW;
}
}
}
///Changes the current direction based on the sign of the float.
///Recommended to use this over the "From" impl for directions that already exist, to prevent werid 0.0 case and NaN problems
/// This handles 0.0 and NaN by just doing nothing. The "From" impl defualts to CCW for both
pub fn dir_from_f32(&mut self, value: f32) {
if value == 0.0 || value.is_nan() {
return;
}
*self = value.into();
}
///Changes the current direction based on the sign of the int.
///Recommended to use this over the "From" impl for directions that already exist, to prevent weird 0 case problems
///This handles 0 by just doing nothing. The "From" impl defaults to CCW
pub fn dir_from_i32(&mut self, value: i32) {
if value == 0 {
return;
}
*self = value.into();
}
}
///Converts F32 to direction using the number's sign.
/// This defaults to CCW for 0.0 and NaN.
impl From<f32> for Direction {
fn from(value: f32) -> Self {
if value < 0.0 {
Direction::CW
} else {
Direction::CCW
}
}
}
/// Converts i32 to direction using the number's sign.
/// This defaults to CCW for 0.
impl From<i32> for Direction {
fn from(value: i32) -> Self {
if value < 0 {
Direction::CW
} else {
Direction::CCW
}
}
}
+5
View File
@@ -0,0 +1,5 @@
mod direction;
pub mod error;
pub mod motor;
pub mod pid;
pub mod positional;
+5 -114
View File
@@ -1,115 +1,6 @@
use core::fmt::Display; use uom::si::f32::{Angle, AngularVelocity, ElectricCurrent, ElectricPotential};
use serde::{Deserialize, Serialize}; pub use crate::direction::Direction;
use crate::core::{
motor::Direction::{CCW, CW},
units::{Angle, Current, Voltage},
};
///A simple enum for Counterclockwise or Clockwise direction semantics. Makes it easier much clear than a true/false bool
/// IF you use this to convert to a signed number note that CW is negative and CCW is positive
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum Direction {
///CounterClockWise
CCW,
///ClockWise
CW,
}
impl Direction {
///Inverts the direction currently stored in this.
/// Helps with a simple direction change without knowing the current direction.
pub fn inv_dir(&mut self) {
match *self {
Self::CCW => {
*self = Self::CW;
}
Self::CW => {
*self = Self::CCW;
}
}
}
///Changes the current direction based on the sign of the float.
///Recommended to use this over the "From" impl for directions that already exist, to prevent werid 0.0 case and NaN problems
/// This handles 0.0 and NaN by just doing nothing. The "From" impl defualts to CCW for both
pub fn dir_from_f32(&mut self, value: f32) {
if value == 0.0 || value.is_nan() {
return;
}
*self = value.into();
}
///Changes the current direction based on the sign of the int.
///Recommended to use this over the "From" impl for directions that already exist, to prevent weird 0 case problems
///This handles 0 by just doing nothing. The "From" impl defaults to CCW
pub fn dir_from_i32(&mut self, value: i32) {
if value == 0 {
return;
}
*self = value.into();
}
}
///Converts F32 to direction using the number's sign.
/// This defaults to CCW for 0.0 and NaN.
impl From<f32> for Direction {
fn from(value: f32) -> Self {
if value < 0.0 { CW } else { CCW }
}
}
/// Converts i32 to direction using the number's sign.
/// This defaults to CCW for 0.
impl From<i32> for Direction {
fn from(value: i32) -> Self {
if value < 0 { CW } else { CCW }
}
}
///A enum for containerizing speeds easily
/// Lets the backend take in a Rotations per minute value from a user Sensor implementation and convert it to a Radians per second value
///Pay attention to the units of each term
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
pub enum Speed {
///Rotations per minute
RPM(f32),
///Radians per second
RADS(f32),
}
///Used to convert from Rotations per minute to radians per second
const RPM_TO_RADS: f32 = core::f32::consts::TAU / 60.0;
///Used to convert from Radians per second to Rotations per minute
const RADS_TO_RPM: f32 = 60.0 / core::f32::consts::TAU;
impl Speed {
///Returns the value as Radians Per Second regardless of what the enum contains
/// Uses no runtime division
#[inline]
pub fn rads(&self) -> f32 {
match *self {
Self::RPM(rpm) => rpm * RADS_TO_RPM,
Self::RADS(rps) => rps,
}
}
///Returns the value as Rotations Per minute regardles of what the enum contains
/// Uses no runtime division
#[inline]
pub fn rpm(&self) -> f32 {
match *self {
Self::RPM(rpm) => rpm,
Self::RADS(rps) => rps * RPM_TO_RADS,
}
}
}
impl Display for Speed {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "")
}
}
/// # Motor Driver /// # Motor Driver
/// ///
@@ -160,15 +51,15 @@ pub trait Sensor {
///Returns the speed struct value from the motors sensor. ///Returns the speed struct value from the motors sensor.
/// ///
/// IF properly returned in the correct Enum Data field, all other systems will use the value propely, being unit agnostic later. /// IF properly returned in the correct Enum Data field, all other systems will use the value propely, being unit agnostic later.
async fn get_speed(&self) -> Speed; async fn get_speed(&self) -> AngularVelocity;
///Returns the current from the sensor, if it capable. ///Returns the current from the sensor, if it capable.
/// This should be non-blocking. Keep a cached value ready. /// This should be non-blocking. Keep a cached value ready.
async fn get_current(&self) -> Option<Current>; async fn get_current(&self) -> Option<ElectricCurrent>;
///Returns the current voltage from the sensro, if it is capable. ///Returns the current voltage from the sensro, if it is capable.
/// This should be non-blocking. Keep a cached value ready. /// This should be non-blocking. Keep a cached value ready.
async fn get_voltage(&self) -> Option<Voltage>; async fn get_voltage(&self) -> Option<ElectricPotential>;
///Returns the current angle from the sensor if it is capable. ///Returns the current angle from the sensor if it is capable.
/// This should be non-blocking. Keep a cached value ready. /// This should be non-blocking. Keep a cached value ready.
+6
View File
@@ -0,0 +1,6 @@
[package]
name = "rnavp_communication"
version = "0.1.0"
edition = "2024"
[dependencies]
+14
View File
@@ -0,0 +1,14 @@
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
+9
View File
@@ -0,0 +1,9 @@
[package]
name = "rnavp_logic"
version = "0.1.0"
edition = "2024"
[dependencies]
rnavp = {path = "../rnavp"}
serde = { version = "1.0.229", default-features = false, features = ["derive"] }
uom = { version = "0.38.0", default-features = false, features = ["si", "f32"] }
+1
View File
@@ -0,0 +1 @@
pub mod motor;
@@ -1,7 +1,6 @@
use crate::core::motor; use rnavp::motor::{self, Direction};
use crate::core::motor::{Direction, Speed}; use rnavp::pid;
use uom::si::f32::AngularVelocity;
use crate::core::logic::pid;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
/// # Motor Controller /// # Motor Controller
@@ -17,7 +16,7 @@ where
T: motor::Driver + motor::Sensor, T: motor::Driver + motor::Sensor,
{ {
motor: T, motor: T,
max_speed: Speed, max_speed: AngularVelocity,
pid: pid::PID, pid: pid::PID,
current_direction: Direction, current_direction: Direction,
} }
@@ -25,12 +24,12 @@ where
///Controller Impl for the adding the PID logic for handling the motor compiston ///Controller Impl for the adding the PID logic for handling the motor compiston
impl<T: motor::Driver + motor::Sensor> Controller<T> { impl<T: motor::Driver + motor::Sensor> Controller<T> {
///Uses the given set_speed and then will handle the rest of the control logic to accurately* hit the requested speed ///Uses the given set_speed and then will handle the rest of the control logic to accurately* hit the requested speed
pub async fn control(&mut self, set_speed: Speed) { pub async fn control(&mut self, set_speed: AngularVelocity) {
let max_speed_rads = self.max_speed.rads(); let max_speed_rads = self.max_speed.value;
let set_speed_rads = set_speed.rads().clamp(-max_speed_rads, max_speed_rads); let set_speed_rads = set_speed.value.clamp(-max_speed_rads, max_speed_rads);
self.pid.set_point(set_speed_rads).await; self.pid.set_point(set_speed_rads).await;
let pid_output = self.pid.pid_step(self.motor.get_speed().await.rads()).await; let pid_output = self.pid.pid_step(self.motor.get_speed().await.value).await;
self.current_direction.dir_from_f32(pid_output); self.current_direction.dir_from_f32(pid_output);
@@ -43,13 +42,13 @@ impl<T: motor::Driver + motor::Sensor> Controller<T> {
///Retrieve the speed from the motor inside the controller. ///Retrieve the speed from the motor inside the controller.
/// This allows you to get a speed value from behind the move. /// This allows you to get a speed value from behind the move.
pub async fn retrieve(&self) -> motor::Speed { pub async fn retrieve(&self) -> AngularVelocity {
self.motor.get_speed().await self.motor.get_speed().await
} }
///Creates a new Controller with a motor (of type T), a max speed and a pid::Config ///Creates a new Controller with a motor (of type T), a max speed and a pid::Config
/// This then allows for you to use the controller with the provided types /// This then allows for you to use the controller with the provided types
pub fn new(motor: T, max_speed: Speed, config: pid::Config) -> Self { pub fn new(motor: T, max_speed: AngularVelocity, config: pid::Config) -> Self {
Controller { Controller {
motor: motor, motor: motor,
max_speed: max_speed, max_speed: max_speed,
-4
View File
@@ -1,4 +0,0 @@
pub mod drivetrain;
pub mod motor;
pub mod sensing;
pub mod wheel;
-1
View File
@@ -1 +0,0 @@
-1
View File
@@ -1 +0,0 @@
-1
View File
@@ -1 +0,0 @@
-3
View File
@@ -1,3 +0,0 @@
pub mod kinematics;
pub mod motor;
pub mod pid;
-10
View File
@@ -1,10 +0,0 @@
#[cfg(feature = "core_communication")]
pub mod communication;
#[cfg(feature = "core_logic")]
pub mod logic;
pub mod error;
pub mod motor;
pub mod positional;
pub mod units;
-250
View File
@@ -1,250 +0,0 @@
use core::fmt::Display;
use serde::{Deserialize, Serialize};
///Generic Positional Data Struct, This can contain XYZ positions in meters or Radians
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Debug)]
pub struct XYZPos {
x: Option<f32>,
y: Option<f32>,
z: Option<f32>,
unit: Unit,
}
///Generic Velocity Data Struct, This can contain XYZ velocities in Meters Per Second or Radians Per Second
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Debug)]
pub struct XYZVel {
x: Option<f32>,
y: Option<f32>,
z: Option<f32>,
unit: Unit,
}
///Generic Acceleration Data Struct, This can contain XYZ accelerations in Meters Per Second Squared or Radians Per Second
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Debug)]
pub struct XYZAccel {
x: Option<f32>,
y: Option<f32>,
z: Option<f32>,
unit: Unit,
}
impl XYZData for XYZPos {
fn x(&self) -> Option<f32> {
self.x
}
fn y(&self) -> Option<f32> {
self.y
}
fn z(&self) -> Option<f32> {
self.z
}
fn unit(&self) -> Unit {
self.unit
}
fn is_pos(&self) -> bool {
true
}
}
impl XYZData for XYZVel {
fn x(&self) -> Option<f32> {
self.x
}
fn y(&self) -> Option<f32> {
self.y
}
fn z(&self) -> Option<f32> {
self.z
}
fn unit(&self) -> Unit {
self.unit
}
fn is_vel(&self) -> bool {
true
}
}
impl XYZData for XYZAccel {
fn x(&self) -> Option<f32> {
self.x
}
fn y(&self) -> Option<f32> {
self.y
}
fn z(&self) -> Option<f32> {
self.z
}
fn unit(&self) -> Unit {
self.unit
}
fn is_accel(&self) -> bool {
true
}
}
impl Position for XYZPos {}
impl Velocity for XYZVel {}
impl Acceleration for XYZAccel {}
impl Display for XYZPos {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let unit_str = match self.unit {
Unit::Meters => "m",
Unit::Radians => "rad",
Unit::Custom => "custom",
};
write!(
f,
"[X: {:?}{unit_str} | Y: {:?}{unit_str} | Z: {:?}{unit_str}]",
self.x, self.y, self.z
)
}
}
impl Display for XYZVel {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let unit_str = match self.unit {
Unit::Meters => "m",
Unit::Radians => "rad",
Unit::Custom => "custom",
};
write!(
f,
"[X: {:?}{unit_str}/s | Y: {:?}{unit_str}/s | Z: {:?}{unit_str}/s]",
self.x, self.y, self.z
)
}
}
impl Display for XYZAccel {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let unit_str = match self.unit {
Unit::Meters => "m",
Unit::Radians => "rad",
Unit::Custom => "custom",
};
write!(
f,
"[X: {:?}{unit_str}/s^2 | Y: {:?}{unit_str}/s^2 | Z: {:?}{unit_str}/s^2]",
self.x, self.y, self.z
)
}
}
///Structs that impl this trait, mean they are positions. Determine what type of position by reading the unit.
pub trait Position: XYZData {}
///Structs that impl this trait mean they are Velocities. Determine what type of velocity by reading the unit.
pub trait Velocity: XYZData {}
///Structs that impl this trait mean they are Accelerations. Determine what type of Acceleration by reading the unit.
pub trait Acceleration: XYZData {}
///This is the data backbone for the XYZ Position, Velocity, and Acceleration Data structs.
///They MUST implmenent this so it possible to easily and quickly get the data from the struct.
///Provides methods to check what type this is
pub trait XYZData {
fn x(&self) -> Option<f32>;
fn y(&self) -> Option<f32>;
fn z(&self) -> Option<f32>;
fn unit(&self) -> Unit;
///Returns an array of f32s that are the XYZ position, velocity or accel, based on the implemented traits.
///Any option field in the array that are None are returned as 0.0 here.
///Do not forget to check the unit, this may be in radians or meters.
fn xyz_array(&self) -> [f32; 3] {
[
self.x().unwrap_or(0.0),
self.y().unwrap_or(0.0),
self.z().unwrap_or(0.0),
]
}
fn is_pos(&self) -> bool {
false
}
fn is_vel(&self) -> bool {
false
}
fn is_accel(&self) -> bool {
false
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
pub enum XYZDataBucket {
Pos(XYZPos),
Vel(XYZVel),
Accel(XYZAccel),
}
impl XYZData for XYZDataBucket {
fn is_pos(&self) -> bool {
matches!(self, Self::Pos(_))
}
fn is_vel(&self) -> bool {
matches!(self, Self::Vel(_))
}
fn is_accel(&self) -> bool {
matches!(self, Self::Accel(_))
}
fn x(&self) -> Option<f32> {
match self {
Self::Pos(p) => p.x(),
Self::Vel(v) => v.x(),
Self::Accel(a) => a.x(),
}
}
fn y(&self) -> Option<f32> {
match self {
Self::Pos(p) => p.y(),
Self::Vel(v) => v.y(),
Self::Accel(a) => a.y(),
}
}
fn z(&self) -> Option<f32> {
match self {
Self::Pos(p) => p.z(),
Self::Vel(v) => v.z(),
Self::Accel(a) => a.z(),
}
}
fn unit(&self) -> Unit {
match self {
Self::Pos(p) => p.unit(),
Self::Vel(v) => v.unit(),
Self::Accel(a) => a.unit(),
}
}
}
///Represents the unit this position struct is carrying. Combining the Unit + Trait it impls lets you determine what this message contains
/// If you need to send a unit not listed here please use Unit::Custom
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
pub enum Unit {
Meters,
Radians,
Custom,
}
-75
View File
@@ -1,75 +0,0 @@
use serde::{Deserialize, Serialize};
///Standard conversion constant to convert to micro from base unit
pub const TO_MICRO: f32 = 1_000_000.0;
///Standard conversion constant to convert from micro to base unit;
pub const FROM_MICRO: f32 = 1.0 / 1_000_000.0;
///Standard conversion constant to convert to milli from base unit;
pub const TO_MILLI: f32 = 1_000.0;
///Standard conversion constant to convert from milli to base unit;
pub const FROM_MILLI: f32 = 1.0 / 1_000.0;
///Standard way for the RNavP system to transfer around Current measurements.
/// This system by default uses Amps as f32.
/// Offers MilliAmps and MicroAmps for utilizing higher precision raw data for when needed.
/// Implements all needed conversions for handling f32 into and from this data type.
/// Uses Amps by default, please use MicroAmps and MilliVolts when needed for higher precision.
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Current {
Amps(f32),
MilliAmps(i32),
MicroAmps(i32),
}
impl From<f32> for Current {
fn from(value: f32) -> Self {
Self::Amps(value)
}
}
impl Into<f32> for Current {
fn into(self) -> f32 {
match self {
Self::MicroAmps(micro) => micro as f32 * FROM_MICRO,
Self::MilliAmps(milli) => milli as f32 * FROM_MILLI,
Self::Amps(amps) => amps,
}
}
}
///Standard way for the RNavP system to transfer around voltage measurements.
/// This system by default uses Volts as f32.
/// Offers MilliVolts and MicroVolts for utilizing higher precison raw data for when needed.
/// Implements all needed conversions for handling f32 into and from this dataType.
/// Uses Volts by default, please use MicroVolts and MilliVolts when needed for higher precision.
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Voltage {
Volts(f32),
MilliVolts(i32),
MicroVolts(i32),
}
impl From<f32> for Voltage {
fn from(value: f32) -> Self {
Self::Volts(value)
}
}
impl Into<f32> for Voltage {
fn into(self) -> f32 {
match self {
Self::MicroVolts(micro) => micro as f32 * FROM_MICRO,
Self::MilliVolts(milli) => milli as f32 * FROM_MILLI,
Self::Volts(volts) => volts,
}
}
}
///Standard way for the RnavP system for handling angles.
/// The system does use a f32, so no conversions needed.
/// Has methods for returning the wanted unit type regardless of what is stored.
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Angle {
Degrees(f32),
Radians(f32),
}
-7
View File
@@ -1,7 +0,0 @@
#[cfg(feature = "std")]
compile_error!(
"The 'std' feature is enabled, which is incompatible with 'embassy'. \n\
The 'host' feature (enabled by default) turns on 'std'. \n\
Please use '--no-default-features --features embassy' to build for MCU\n\
or verify that you have not included a different feature that requires'std'"
);
-1
View File
@@ -1 +0,0 @@
-13
View File
@@ -1,13 +0,0 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "core")]
pub mod core;
#[cfg(feature = "embassy")]
pub mod embassy;
#[cfg(feature = "host")]
pub mod host;