Moved some of the things from the "communicatinon" subsection of core directly into core. This is because some of these structs will be needed for logic as well.

This commit is contained in:
2026-05-23 17:45:06 -05:00
parent eb29b97f9b
commit b7393971e2
5 changed files with 96 additions and 38 deletions
-24
View File
@@ -1,24 +0,0 @@
use serde::{Deserialize, Serialize};
///Represents the unit this struct is carrying. Combining the Unit + Trait it impls lets you determine what this message contatains
/// A value of 0 or Unknown means the data is malformed or something is was wrong on the sending side, it should be treated a failure case.
/// If you need to send a unit not listed here please use Unit::Custom instead of Unit::Unknown
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug, )]
#[repr(u8)]
pub enum Unit {
Unknown = 0,
Meters = 1,
Radians = 2,
Custom = 3,
}
impl From<u8> for Unit {
fn from(value: u8) -> Self {
match value {
1 => {Self::Meters}
2 => {Self::Radians}
3 => {Self::Custom}
_ => {Self::Unknown}
}
}
}
-2
View File
@@ -1,6 +1,4 @@
pub mod sensing;
pub mod motor;
pub mod positional;
pub mod general;
pub mod drivetrain;
pub mod wheel;
+64 -3
View File
@@ -1,4 +1,65 @@
use serde::{Deserialize, Serialize};
pub struct MotorRPM{
use core::fmt::Display;
use serde::{Deserialize, Serialize};
///Motor Drivers reported shaft speed. This can be in any of the given unit types by the Unit enum and timescalse given by the TimeScales enum
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct MotorDriverShaftSpeed {
shaft_speed: Option<f32>,
unit: Unit,
time_scale: TimeScale,
}
impl MotorDriverShaftSpeed {
}
impl Display for MotorDriverShaftSpeed {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.shaft_speed {
Some(speed) => {
let unit = match self.unit {
Unit::Radians => "rad",
Unit::Rotations => "R",
_ => "",
};
write!(f, "")
}
None => {write!(f, "No Given Speeds")}
}
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[repr(u8)]
pub enum Unit {
Unknown = 0,
Rotations = 1,
Radians = 2,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[repr(u8)]
pub enum TimeScale {
Unknown = 0,
PerSecond = 1,
PerMinute = 2,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub struct MotorDriverDiagData {
///Current draw of the motor if readable, reported in microAmps
current: Option<i32>,
///Voltage of the motor if readable, reported in microVolts
voltage: Option<i32>,
///Shaft speed of the motor if readable.
shaft_speed: Option<MotorDriverShaftSpeed>,
///Status of the hardware brake if present, none if not present.
brake_status: Option<bool>,
}
}
-244
View File
@@ -1,244 +0,0 @@
use core::{fmt::{Display}, u8};
use serde::{Deserialize, Serialize};
use crate::core::communication::general::Unit;
///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"}
_ => {return write!(f, "Unknown Data");}
};
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"}
_ => {return write!(f, "Unknown Data");}
};
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"}
_ => {return write!(f, "Unknown Data");}
};
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.
trait Position : XYZData {
}
///Structs that impl this trait mean they are Velocities. Determine the type of velocity by reading the unit.
trait Velocity : XYZData{
}
///Structs that impl this trait mean they are Accelerations. Determine the type of Acceleration by reading the unit.
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
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] {
let arr = [self.x().unwrap_or(0.0), self.y().unwrap_or(0.0), self.z().unwrap_or(0.0)];
arr
}
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(),
}
}
}