From 12c08f9442b74abd74d029555e3bcd3201e31d1d Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:55:13 -0600 Subject: [PATCH 01/96] feat: AdiAddrLed & AdiSolenoid --- packages/pros/Cargo.toml | 3 +- packages/pros/src/devices/adi/addrled.rs | 129 ++++++++++++++++++++++ packages/pros/src/devices/adi/mod.rs | 5 + packages/pros/src/devices/adi/solenoid.rs | 61 ++++++++++ packages/pros/src/lib.rs | 2 + 5 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 packages/pros/src/devices/adi/addrled.rs create mode 100644 packages/pros/src/devices/adi/solenoid.rs diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 8da5e111..261baabb 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -32,6 +32,7 @@ hashbrown = { version = "0.14.1", default-features = true } async-task = { version = "4.5.0", default-features = false } waker-fn = "1.1.1" libc-print = "0.1.22" +smart-leds-trait = { version = "0.3.0", optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] -dlmalloc = { version = "0.2.4", features = ["global"] } +dlmalloc = { version = "0.2.4", features = ["global"] } \ No newline at end of file diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs new file mode 100644 index 00000000..a38d63a3 --- /dev/null +++ b/packages/pros/src/devices/adi/addrled.rs @@ -0,0 +1,129 @@ +use alloc::vec::Vec; + +use pros_sys::{ext_adi_led_t, PROS_ERR}; + +use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; +use crate::{devices::smart::vision::Rgb, error::bail_on}; + +#[derive(Debug, Eq, PartialEq)] +pub struct AdiAddrLed { + raw: ext_adi_led_t, + buffer: Vec, + port: AdiPort, +} + +impl AdiAddrLed { + pub fn new(port: AdiPort, length: usize) -> Result { + let raw = bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_init(port.internal_expander_index(), port.index()) + }); + + Ok(Self { + port, + raw, + buffer: Vec::with_capacity(length), + }) + } + + pub fn clear_all(&mut self) -> Result<(), AdiError> { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_clear_all( + self.raw, + self.buffer.as_mut_ptr(), + self.buffer.len() as u32, + ) + }); + + Ok(()) + } + + pub fn set_all(&mut self, color: Rgb) -> Result<(), AdiError> { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_set_all( + self.raw, + self.buffer.as_mut_ptr(), + self.buffer.len() as u32, + u32::from(color), + ) + }); + + Ok(()) + } + + pub fn set_buffer(&mut self, buffer: T) -> Result<(), AdiError> + where + T: IntoIterator, + I: Into, + { + self.buffer = buffer.into_iter().map(|i| i.into()).collect::>(); + + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) + }); + + Ok(()) + } + + pub fn set_pixel(&mut self, index: u32, color: Rgb) -> Result<(), AdiError> { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_set_pixel( + self.raw, + self.buffer.as_mut_ptr(), + self.buffer.len() as u32, + u32::from(color), + index, + ) + }); + + Ok(()) + } + + pub fn clear_pixel(&mut self, index: u32) -> Result<(), AdiError> { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_clear_pixel( + self.raw, + self.buffer.as_mut_ptr(), + self.buffer.len() as u32, + index, + ) + }); + + Ok(()) + } +} + +impl AdiDevice for AdiAddrLed { + type PortIndexOutput = u8; + + fn port_index(&self) -> Self::PortIndexOutput { + self.port.index() + } + + fn expander_port_index(&self) -> Option { + self.port.expander_index() + } + + fn device_type(&self) -> AdiDeviceType { + AdiDeviceType::LegacyPwm + } +} + +#[cfg(feature = "smart-leds-trait")] +impl smart_leds_trait::SmartLedsWrite for AdiAddrLed { + type Error = AdiError; + type Color = u32; + + fn write(&mut self, iterator: T) -> Result<(), Self::Error> + where + T: IntoIterator, + I: Into, + { + self.buffer = iterator.into_iter().map(|i| i.into()).collect::>(); + + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) + }); + + Ok(()) + } +} diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros/src/devices/adi/mod.rs index 22938896..192d527c 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros/src/devices/adi/mod.rs @@ -7,18 +7,23 @@ use crate::error::{bail_on, map_errno, PortError}; pub mod analog; pub mod digital; + +pub mod addrled; pub mod encoder; pub mod gyro; pub mod motor; pub mod potentiometer; +pub mod solenoid; pub mod ultrasonic; +pub use addrled::AdiAddrLed; pub use analog::{AdiAnalogIn, AdiAnalogOut}; pub use digital::{AdiDigitalIn, AdiDigitalOut}; pub use encoder::AdiEncoder; pub use gyro::AdiGyro; pub use motor::AdiMotor; pub use potentiometer::AdiPotentiometer; +pub use solenoid::AdiSolenoid; pub use ultrasonic::AdiUltrasonic; /// Represents an ADI (three wire) port on a V5 Brain or V5 Three Wire Expander. diff --git a/packages/pros/src/devices/adi/solenoid.rs b/packages/pros/src/devices/adi/solenoid.rs new file mode 100644 index 00000000..c4234fbe --- /dev/null +++ b/packages/pros/src/devices/adi/solenoid.rs @@ -0,0 +1,61 @@ +use pros_sys::PROS_ERR; + +use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; +use crate::error::bail_on; + +#[derive(Debug, Eq, PartialEq)] +pub struct AdiSolenoid { + port: AdiPort, + value: bool, +} + +impl AdiSolenoid { + /// Create an AdiSolenoid. + pub fn new(port: AdiPort) -> Self { + Self { port, value: false } + } + + pub fn set_value(&mut self, value: bool) -> Result { + self.value = true; + + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_digital_write( + self.port.internal_expander_index(), + self.port.index(), + value, + ) + })) + } + + pub fn value(&self) -> bool { + self.value + } + + pub fn open(&mut self) -> Result { + self.set_value(true) + } + + pub fn close(&mut self) -> Result { + self.set_value(false) + } + + pub fn toggle(&mut self) -> Result { + self.set_value(!self.value) + } +} + +impl AdiDevice for AdiSolenoid { + type PortIndexOutput = u8; + + fn port_index(&self) -> Self::PortIndexOutput { + self.port.index() + } + + fn expander_port_index(&self) -> Option { + self.port.expander_index() + } + + fn device_type(&self) -> AdiDeviceType { + AdiDeviceType::DigitalOut + } +} diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index a6ca81df..93382097 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -376,12 +376,14 @@ pub mod prelude { async_runtime::*, devices::{ adi::{ + addrled::AdiAddrLed, analog::{AdiAnalogIn, AdiAnalogOut}, digital::{AdiDigitalIn, AdiDigitalOut}, encoder::AdiEncoder, gyro::AdiGyro, motor::AdiMotor, potentiometer::{AdiPotentiometer, AdiPotentiometerType}, + solenoid::AdiSolenoid, ultrasonic::AdiUltrasonic, AdiDevice, AdiPort, }, From c86379e9a0b5cee6583d9ac00b7cac4c3ffe4bef Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 17 Jan 2024 23:06:38 -0600 Subject: [PATCH 02/96] feat: ADI Expander --- packages/pros/src/devices/smart/expander.rs | 44 +++++++++++++++++++++ packages/pros/src/devices/smart/mod.rs | 2 + packages/pros/src/lib.rs | 1 + 3 files changed, 47 insertions(+) create mode 100644 packages/pros/src/devices/smart/expander.rs diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs new file mode 100644 index 00000000..5f1ff36c --- /dev/null +++ b/packages/pros/src/devices/smart/expander.rs @@ -0,0 +1,44 @@ +use super::{SmartDevice, SmartDeviceType, SmartPort}; +use crate::devices::adi::AdiPort; + +#[derive(Debug, Eq, PartialEq)] +pub struct AdiExpander { + pub port_a: AdiPort, + pub port_b: AdiPort, + pub port_c: AdiPort, + pub port_d: AdiPort, + pub port_e: AdiPort, + pub port_f: AdiPort, + pub port_g: AdiPort, + pub port_h: AdiPort, + port: SmartPort, +} + +impl AdiExpander { + /// Create a new expander from a smart port index. + pub fn new(port: SmartPort) -> Self { + unsafe { + Self { + port_a: AdiPort::new(1, Some(port.index())), + port_b: AdiPort::new(2, Some(port.index())), + port_c: AdiPort::new(3, Some(port.index())), + port_d: AdiPort::new(4, Some(port.index())), + port_e: AdiPort::new(5, Some(port.index())), + port_f: AdiPort::new(6, Some(port.index())), + port_g: AdiPort::new(7, Some(port.index())), + port_h: AdiPort::new(8, Some(port.index())), + port, + } + } + } +} + +impl SmartDevice for AdiExpander { + fn port_index(&self) -> u8 { + self.port.index() + } + + fn device_type(&self) -> SmartDeviceType { + SmartDeviceType::Adi + } +} diff --git a/packages/pros/src/devices/smart/mod.rs b/packages/pros/src/devices/smart/mod.rs index 61b00cca..f24d827c 100644 --- a/packages/pros/src/devices/smart/mod.rs +++ b/packages/pros/src/devices/smart/mod.rs @@ -15,6 +15,7 @@ //! More specific info for each device is availible in their respective modules. pub mod distance; +pub mod expander; pub mod gps; pub mod imu; pub mod link; @@ -24,6 +25,7 @@ pub mod rotation; pub mod vision; pub use distance::DistanceSensor; +pub use expander::AdiExpander; pub use gps::GpsSensor; pub use imu::InertialSensor; pub use link::{Link, RxLink, TxLink}; diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index a6ca81df..5351b107 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -388,6 +388,7 @@ pub mod prelude { position::Position, smart::{ distance::DistanceSensor, + expander::AdiExpander, gps::GpsSensor, imu::InertialSensor, link::{Link, RxLink, TxLink}, From 27ebaa711f4d650debef36b02535e65eb47ce212 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 17 Jan 2024 23:13:51 -0600 Subject: [PATCH 03/96] refactor: prefix adi ports with `adi_` --- packages/pros/src/devices/smart/expander.rs | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs index 5f1ff36c..1bd5ab11 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros/src/devices/smart/expander.rs @@ -3,14 +3,14 @@ use crate::devices::adi::AdiPort; #[derive(Debug, Eq, PartialEq)] pub struct AdiExpander { - pub port_a: AdiPort, - pub port_b: AdiPort, - pub port_c: AdiPort, - pub port_d: AdiPort, - pub port_e: AdiPort, - pub port_f: AdiPort, - pub port_g: AdiPort, - pub port_h: AdiPort, + pub adi_port_a: AdiPort, + pub adi_port_b: AdiPort, + pub adi_port_c: AdiPort, + pub adi_port_d: AdiPort, + pub adi_port_e: AdiPort, + pub adi_port_f: AdiPort, + pub adi_port_g: AdiPort, + pub adi_port_h: AdiPort, port: SmartPort, } @@ -19,14 +19,14 @@ impl AdiExpander { pub fn new(port: SmartPort) -> Self { unsafe { Self { - port_a: AdiPort::new(1, Some(port.index())), - port_b: AdiPort::new(2, Some(port.index())), - port_c: AdiPort::new(3, Some(port.index())), - port_d: AdiPort::new(4, Some(port.index())), - port_e: AdiPort::new(5, Some(port.index())), - port_f: AdiPort::new(6, Some(port.index())), - port_g: AdiPort::new(7, Some(port.index())), - port_h: AdiPort::new(8, Some(port.index())), + adi_port_a: AdiPort::new(1, Some(port.index())), + adi_port_b: AdiPort::new(2, Some(port.index())), + adi_port_c: AdiPort::new(3, Some(port.index())), + adi_port_d: AdiPort::new(4, Some(port.index())), + adi_port_e: AdiPort::new(5, Some(port.index())), + adi_port_f: AdiPort::new(6, Some(port.index())), + adi_port_g: AdiPort::new(7, Some(port.index())), + adi_port_h: AdiPort::new(8, Some(port.index())), port, } } From e1606f73eceb945023e7240d805021f156a619a8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jan 2024 17:59:09 -0600 Subject: [PATCH 04/96] refactor: match port naming with peripherals --- packages/pros/src/devices/smart/expander.rs | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs index 1bd5ab11..1ca0dd86 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros/src/devices/smart/expander.rs @@ -3,14 +3,14 @@ use crate::devices::adi::AdiPort; #[derive(Debug, Eq, PartialEq)] pub struct AdiExpander { - pub adi_port_a: AdiPort, - pub adi_port_b: AdiPort, - pub adi_port_c: AdiPort, - pub adi_port_d: AdiPort, - pub adi_port_e: AdiPort, - pub adi_port_f: AdiPort, - pub adi_port_g: AdiPort, - pub adi_port_h: AdiPort, + pub adi_1: AdiPort, + pub adi_2: AdiPort, + pub adi_3: AdiPort, + pub adi_4: AdiPort, + pub adi_5: AdiPort, + pub adi_6: AdiPort, + pub adi_7: AdiPort, + pub adi_8: AdiPort, port: SmartPort, } @@ -19,14 +19,14 @@ impl AdiExpander { pub fn new(port: SmartPort) -> Self { unsafe { Self { - adi_port_a: AdiPort::new(1, Some(port.index())), - adi_port_b: AdiPort::new(2, Some(port.index())), - adi_port_c: AdiPort::new(3, Some(port.index())), - adi_port_d: AdiPort::new(4, Some(port.index())), - adi_port_e: AdiPort::new(5, Some(port.index())), - adi_port_f: AdiPort::new(6, Some(port.index())), - adi_port_g: AdiPort::new(7, Some(port.index())), - adi_port_h: AdiPort::new(8, Some(port.index())), + adi_1: AdiPort::new(1, Some(port.index())), + adi_2: AdiPort::new(2, Some(port.index())), + adi_3: AdiPort::new(3, Some(port.index())), + adi_4: AdiPort::new(4, Some(port.index())), + adi_5: AdiPort::new(5, Some(port.index())), + adi_6: AdiPort::new(6, Some(port.index())), + adi_7: AdiPort::new(7, Some(port.index())), + adi_8: AdiPort::new(8, Some(port.index())), port, } } From 1d9de96c109395fcdecdf072c12e225190394aa7 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jan 2024 18:02:11 -0600 Subject: [PATCH 05/96] docs: update changelog, document struct --- CHANGELOG.md | 1 + packages/pros/src/devices/smart/expander.rs | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f263e691..42fb3479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Before releasing: - Macros for printing to stdout (`println`, `print`, `eprintln`, etc...) (#30) - All ADI device bindings (#55) - `LocalKey` now has `Cell`/`RefCell`-specific methods for setting and taking values. (#42) +- Support for ADI Expander modules with `AdiExpander`. (#63) ### Fixed diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs index 1ca0dd86..ed4064f5 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros/src/devices/smart/expander.rs @@ -1,6 +1,13 @@ use super::{SmartDevice, SmartDeviceType, SmartPort}; use crate::devices::adi::AdiPort; +/// Represents an ADI expander module plugged into a smart port. +/// +/// ADI Expanders allow a smart port to be used as an "adapter" for eight additional ADI slots +/// if all onboard [`AdiPorts`] are used. +/// +/// This struct gives access to [`AdiPort`]s similarly to how [`Peripherals`] works. Ports may +/// be partially moved out of this struct to create devices. #[derive(Debug, Eq, PartialEq)] pub struct AdiExpander { pub adi_1: AdiPort, From bd3e964d6d2fe973d9b35d1f510610e5187c9dcc Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jan 2024 18:03:30 -0600 Subject: [PATCH 06/96] refactor: use letters rather than numbers to distinguish adi ports --- packages/pros/src/devices/smart/expander.rs | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs index ed4064f5..087b1d93 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros/src/devices/smart/expander.rs @@ -10,14 +10,14 @@ use crate::devices::adi::AdiPort; /// be partially moved out of this struct to create devices. #[derive(Debug, Eq, PartialEq)] pub struct AdiExpander { - pub adi_1: AdiPort, - pub adi_2: AdiPort, - pub adi_3: AdiPort, - pub adi_4: AdiPort, - pub adi_5: AdiPort, - pub adi_6: AdiPort, - pub adi_7: AdiPort, - pub adi_8: AdiPort, + pub adi_a: AdiPort, + pub adi_b: AdiPort, + pub adi_c: AdiPort, + pub adi_d: AdiPort, + pub adi_e: AdiPort, + pub adi_f: AdiPort, + pub adi_g: AdiPort, + pub adi_h: AdiPort, port: SmartPort, } @@ -26,14 +26,14 @@ impl AdiExpander { pub fn new(port: SmartPort) -> Self { unsafe { Self { - adi_1: AdiPort::new(1, Some(port.index())), - adi_2: AdiPort::new(2, Some(port.index())), - adi_3: AdiPort::new(3, Some(port.index())), - adi_4: AdiPort::new(4, Some(port.index())), - adi_5: AdiPort::new(5, Some(port.index())), - adi_6: AdiPort::new(6, Some(port.index())), - adi_7: AdiPort::new(7, Some(port.index())), - adi_8: AdiPort::new(8, Some(port.index())), + adi_a: AdiPort::new(1, Some(port.index())), + adi_b: AdiPort::new(2, Some(port.index())), + adi_c: AdiPort::new(3, Some(port.index())), + adi_d: AdiPort::new(4, Some(port.index())), + adi_e: AdiPort::new(5, Some(port.index())), + adi_f: AdiPort::new(6, Some(port.index())), + adi_g: AdiPort::new(7, Some(port.index())), + adi_h: AdiPort::new(8, Some(port.index())), port, } } From b04b8d84d926c7384267dbeb1005ab46dfe4396e Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jan 2024 18:04:07 -0600 Subject: [PATCH 07/96] docs: fix link to `AdiPort` --- packages/pros/src/devices/smart/expander.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs index 087b1d93..105e16d1 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros/src/devices/smart/expander.rs @@ -4,7 +4,7 @@ use crate::devices::adi::AdiPort; /// Represents an ADI expander module plugged into a smart port. /// /// ADI Expanders allow a smart port to be used as an "adapter" for eight additional ADI slots -/// if all onboard [`AdiPorts`] are used. +/// if all onboard [`AdiPort`]s are used. /// /// This struct gives access to [`AdiPort`]s similarly to how [`Peripherals`] works. Ports may /// be partially moved out of this struct to create devices. From 75a861142ce359b666fe682ec46586be9c1ac91c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:16:14 -0600 Subject: [PATCH 08/96] docs: add example for battery API --- packages/pros/examples/battery.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 packages/pros/examples/battery.rs diff --git a/packages/pros/examples/battery.rs b/packages/pros/examples/battery.rs new file mode 100644 index 00000000..a8ab4bda --- /dev/null +++ b/packages/pros/examples/battery.rs @@ -0,0 +1,22 @@ +#![no_std] +#![no_main] + +use pros::prelude::*; + +#[derive(Default)] +pub struct Robot; + +impl AsyncRobot for Robot { + async fn opcontrol(&mut self) -> pros::Result { + if pros::battery::capacity()? < 20.0 { + println!("WARNING: Battery Low!"); + } + + if pros::battery::temperature()? > 999.0 { + println!("WARNING: Battery is on fire!"); + } + + Ok(()) + } +} +async_robot!(Robot); From f1f67b2e70da195d6192eb2426592f26cd5df91a Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:16:39 -0600 Subject: [PATCH 09/96] Revert "docs: add example for battery API" This reverts commit 75a861142ce359b666fe682ec46586be9c1ac91c. --- packages/pros/examples/battery.rs | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 packages/pros/examples/battery.rs diff --git a/packages/pros/examples/battery.rs b/packages/pros/examples/battery.rs deleted file mode 100644 index a8ab4bda..00000000 --- a/packages/pros/examples/battery.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![no_std] -#![no_main] - -use pros::prelude::*; - -#[derive(Default)] -pub struct Robot; - -impl AsyncRobot for Robot { - async fn opcontrol(&mut self) -> pros::Result { - if pros::battery::capacity()? < 20.0 { - println!("WARNING: Battery Low!"); - } - - if pros::battery::temperature()? > 999.0 { - println!("WARNING: Battery is on fire!"); - } - - Ok(()) - } -} -async_robot!(Robot); From 954262b0b8ce71b655cafa8da2f83bcb12750cac Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:21:18 -0600 Subject: [PATCH 10/96] docs: add example for `AdiExpander` --- packages/pros/examples/adi_expander.rs | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 packages/pros/examples/adi_expander.rs diff --git a/packages/pros/examples/adi_expander.rs b/packages/pros/examples/adi_expander.rs new file mode 100644 index 00000000..2672451b --- /dev/null +++ b/packages/pros/examples/adi_expander.rs @@ -0,0 +1,33 @@ +#![no_std] +#![no_main] + +use core::time::Duration; + +use pros::prelude::*; + +pub struct Robot { + encoder: AdiEncoder, +} +impl Robot { + fn new(peripherals: Peripherals) -> Self { + // Create an expander on smart port 1 + let expander = AdiExpander::new(peripherals.port_1); + + Self { + // Create an encoder on the expander's A and B ports. + encoder: AdiEncoder::new((expander.adi_a, expander.adi_b), false), + } + } +} + +impl AsyncRobot for Robot { + async fn opcontrol(&mut self) -> pros::Result { + // Read from the encoder every second. + loop { + println!("Encoder value: {}", self.encoder.value()?); + + pros::task::delay(Duration::from_secs(1)); + } + } +} +async_robot!(Robot, Robot::new(Peripherals::take().unwrap())); From ae58b7ba0f8a041b3b11c944250e18b5ad1180f8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 22 Jan 2024 15:10:09 -0600 Subject: [PATCH 11/96] refactor: don't require buffer length in leds --- packages/pros/src/devices/adi/addrled.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs index a38d63a3..20f52ee5 100644 --- a/packages/pros/src/devices/adi/addrled.rs +++ b/packages/pros/src/devices/adi/addrled.rs @@ -13,7 +13,7 @@ pub struct AdiAddrLed { } impl AdiAddrLed { - pub fn new(port: AdiPort, length: usize) -> Result { + pub fn new(port: AdiPort) -> Result { let raw = bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_init(port.internal_expander_index(), port.index()) }); @@ -21,7 +21,7 @@ impl AdiAddrLed { Ok(Self { port, raw, - buffer: Vec::with_capacity(length), + buffer: Vec::new(), }) } From 305ee37371902543a6c3c3d775408203d4daecb7 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 22 Jan 2024 19:52:46 -0600 Subject: [PATCH 12/96] refactor: addrled api --- packages/pros/src/devices/adi/addrled.rs | 64 ++++++++++++++++++++---- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs index 20f52ee5..73a5c889 100644 --- a/packages/pros/src/devices/adi/addrled.rs +++ b/packages/pros/src/devices/adi/addrled.rs @@ -1,9 +1,13 @@ use alloc::vec::Vec; use pros_sys::{ext_adi_led_t, PROS_ERR}; +use snafu::Snafu; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::{devices::smart::vision::Rgb, error::bail_on}; +use crate::{ + devices::smart::vision::Rgb, + error::{bail_on, map_errno}, +}; #[derive(Debug, Eq, PartialEq)] pub struct AdiAddrLed { @@ -13,19 +17,35 @@ pub struct AdiAddrLed { } impl AdiAddrLed { - pub fn new(port: AdiPort) -> Result { + /// Initialize an LED strip on an ADI port from a buffer of light colors. + pub fn new(port: AdiPort, buf: T) -> Result + where + T: IntoIterator, + I: Into, + { let raw = bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_init(port.internal_expander_index(), port.index()) }); - Ok(Self { + let mut device = Self { port, raw, - buffer: Vec::new(), - }) + buffer: buf.into_iter().map(|i| i.into()).collect::>(), + }; + + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_set( + device.raw, + device.buffer.as_mut_ptr(), + device.buffer.len() as u32, + ) + }); + + Ok(device) } - pub fn clear_all(&mut self) -> Result<(), AdiError> { + /// Clear the entire led strip of color. + pub fn clear_all(&mut self) -> Result<(), AddrLedError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_clear_all( self.raw, @@ -37,7 +57,8 @@ impl AdiAddrLed { Ok(()) } - pub fn set_all(&mut self, color: Rgb) -> Result<(), AdiError> { + /// Set the entire led strip to one color + pub fn set_all(&mut self, color: Rgb) -> Result<(), AddrLedError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_set_all( self.raw, @@ -50,7 +71,8 @@ impl AdiAddrLed { Ok(()) } - pub fn set_buffer(&mut self, buffer: T) -> Result<(), AdiError> + /// Set the entire led strip using the colors contained in a new buffer. + pub fn set_buffer(&mut self, buffer: T) -> Result<(), AddrLedError> where T: IntoIterator, I: Into, @@ -64,7 +86,8 @@ impl AdiAddrLed { Ok(()) } - pub fn set_pixel(&mut self, index: u32, color: Rgb) -> Result<(), AdiError> { + /// Set one pixel on the led strip. + pub fn set_pixel(&mut self, index: u32, color: Rgb) -> Result<(), AddrLedError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_set_pixel( self.raw, @@ -78,7 +101,8 @@ impl AdiAddrLed { Ok(()) } - pub fn clear_pixel(&mut self, index: u32) -> Result<(), AdiError> { + /// Clear one pixel on the LED strip. + pub fn clear_pixel(&mut self, index: u32) -> Result<(), AddrLedError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_clear_pixel( self.raw, @@ -110,7 +134,7 @@ impl AdiDevice for AdiAddrLed { #[cfg(feature = "smart-leds-trait")] impl smart_leds_trait::SmartLedsWrite for AdiAddrLed { - type Error = AdiError; + type Error = AddrLedError; type Color = u32; fn write(&mut self, iterator: T) -> Result<(), Self::Error> @@ -127,3 +151,21 @@ impl smart_leds_trait::SmartLedsWrite for AdiAddrLed { Ok(()) } } + +#[derive(Debug, Snafu)] +pub enum AddrLedError { + #[snafu(display( + "Failed to access LED buffer. A given value is not correct, or the buffer is null." + ))] + InvalidBufferAccess, + + #[snafu(display("{source}"), context(false))] + Adi { source: AdiError }, +} + +map_errno! { + AddrLedError { + EINVAL => Self::InvalidBufferAccess, + } + inherit AdiError; +} From ea9e9395c165b68890e6ba2d9dbc26b38a19ff21 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 22 Jan 2024 20:29:22 -0600 Subject: [PATCH 13/96] refactor: various conversion consistencies --- packages/pros/src/devices/adi/addrled.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs index 73a5c889..4e532e07 100644 --- a/packages/pros/src/devices/adi/addrled.rs +++ b/packages/pros/src/devices/adi/addrled.rs @@ -4,10 +4,7 @@ use pros_sys::{ext_adi_led_t, PROS_ERR}; use snafu::Snafu; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::{ - devices::smart::vision::Rgb, - error::{bail_on, map_errno}, -}; +use crate::error::{bail_on, map_errno}; #[derive(Debug, Eq, PartialEq)] pub struct AdiAddrLed { @@ -16,6 +13,8 @@ pub struct AdiAddrLed { port: AdiPort, } +pub const MAX_LED_LENGTH: usize = 64; + impl AdiAddrLed { /// Initialize an LED strip on an ADI port from a buffer of light colors. pub fn new(port: AdiPort, buf: T) -> Result @@ -58,13 +57,13 @@ impl AdiAddrLed { } /// Set the entire led strip to one color - pub fn set_all(&mut self, color: Rgb) -> Result<(), AddrLedError> { + pub fn set_all(&mut self, color: impl Into) -> Result<(), AddrLedError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_set_all( self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32, - u32::from(color), + color.into(), ) }); @@ -72,12 +71,12 @@ impl AdiAddrLed { } /// Set the entire led strip using the colors contained in a new buffer. - pub fn set_buffer(&mut self, buffer: T) -> Result<(), AddrLedError> + pub fn set_buffer(&mut self, buf: T) -> Result<(), AddrLedError> where T: IntoIterator, I: Into, { - self.buffer = buffer.into_iter().map(|i| i.into()).collect::>(); + self.buffer = buf.into_iter().map(|i| i.into()).collect::>(); bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) @@ -87,13 +86,13 @@ impl AdiAddrLed { } /// Set one pixel on the led strip. - pub fn set_pixel(&mut self, index: u32, color: Rgb) -> Result<(), AddrLedError> { + pub fn set_pixel(&mut self, index: u32, color: impl Into) -> Result<(), AddrLedError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_set_pixel( self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32, - u32::from(color), + color.into(), index, ) }); From 6795c4383e93d67aa0607970b6c04202cc6a3571 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 23 Jan 2024 18:58:20 -0600 Subject: [PATCH 14/96] fix: `set_pixel` --- packages/pros/examples/addrled.rs | 79 ++++++++++++++++++++++++ packages/pros/src/devices/adi/addrled.rs | 41 +++++------- 2 files changed, 96 insertions(+), 24 deletions(-) create mode 100644 packages/pros/examples/addrled.rs diff --git a/packages/pros/examples/addrled.rs b/packages/pros/examples/addrled.rs new file mode 100644 index 00000000..c64e09dd --- /dev/null +++ b/packages/pros/examples/addrled.rs @@ -0,0 +1,79 @@ +#![no_std] +#![no_main] + +extern crate alloc; + +use core::time::Duration; + +use alloc::vec; + +use pros::{devices::smart::vision::Rgb, prelude::*}; + +pub struct Robot { + led_strip: AdiAddrLed, +} + +fn wheel(mut wheel_pos: u8) -> Rgb { + wheel_pos = 255 - wheel_pos; + if wheel_pos < 85 { + return Rgb::new(255 - wheel_pos * 3, 0, wheel_pos * 3); + } + if wheel_pos < 170 { + wheel_pos -= 85; + return Rgb::new(0, wheel_pos * 3, 255 - wheel_pos * 3); + } + wheel_pos -= 170; + + Rgb::new(wheel_pos * 3, 255 - wheel_pos * 3, 0) +} + + +impl Robot { + pub fn new(peripherals: Peripherals) -> Self { + Self { + led_strip: AdiAddrLed::new(peripherals.adi_d, vec![Rgb::new(0, 0, 0); 10]) + .unwrap_or_else(|err| { + panic!("Failed to construct LED strip! Error: {err:?}"); + }), + } + } +} + +impl SyncRobot for Robot { + fn opcontrol(&mut self) -> pros::Result { + println!("==== ADDRLED TEST ===="); + println!("This will run a few basic test procedures on an AddrLed strip."); + println!("There will be a two second sleep between each procedure.\n"); + + println!("Test 1: Setting all LEDs to rgb(255, 0, 0)."); + self.led_strip.set_all(Rgb::new(255, 0, 0)).unwrap(); + + println!("Test 2: Clearing all LEDs"); + self.led_strip.clear_all().unwrap(); + + println!("Test 3: Setting first LED to rgb(255, 0, 0)."); + self.led_strip.set_pixel(0, Rgb::new(255, 0, 0)).unwrap(); + + println!("Test 4: Clearing first pixel"); + self.led_strip.clear_pixel(0).unwrap(); + + println!("Test 5: Rainbow Buffer"); + let mut data = [0u32; 10]; + + loop { + for j in 0..(256 * 5) { + for i in 0..10 { + data[i] = wheel((((i * 256) as u16 / 10 as u16 + j as u16) & 255) as u8).into(); + } + + self.led_strip.set_buffer(data.iter().cloned()).unwrap(); + + pros::task::delay(Duration::from_millis(10)); + } + } + + Ok(()) + } +} + +sync_robot!(Robot, Robot::new(Peripherals::take().unwrap())); diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs index 4e532e07..a59a6df6 100644 --- a/packages/pros/src/devices/adi/addrled.rs +++ b/packages/pros/src/devices/adi/addrled.rs @@ -85,31 +85,24 @@ impl AdiAddrLed { Ok(()) } - /// Set one pixel on the led strip. - pub fn set_pixel(&mut self, index: u32, color: impl Into) -> Result<(), AddrLedError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_set_pixel( - self.raw, - self.buffer.as_mut_ptr(), - self.buffer.len() as u32, - color.into(), - index, - ) - }); - - Ok(()) + /// Set the color of a single LED on the strip. + pub fn set_pixel(&mut self, index: usize, color: impl Into) -> Result<(), AddrLedError> { + if self.buffer.get(index).is_some() { + self.buffer[index] = color.into(); + + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) + }); + + Ok(()) + } else { + Err(AddrLedError::InvalidBufferAccess) + } } - /// Clear one pixel on the LED strip. - pub fn clear_pixel(&mut self, index: u32) -> Result<(), AddrLedError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_clear_pixel( - self.raw, - self.buffer.as_mut_ptr(), - self.buffer.len() as u32, - index, - ) - }); + /// Clear one LED on the strip. + pub fn clear_pixel(&mut self, index: usize) -> Result<(), AddrLedError> { + self.set_pixel(index, 0u32)?; Ok(()) } @@ -127,7 +120,7 @@ impl AdiDevice for AdiAddrLed { } fn device_type(&self) -> AdiDeviceType { - AdiDeviceType::LegacyPwm + AdiDeviceType::DigitalOut } } From e5416e7ec498e8770833742c874ea4930d2912f2 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 23 Jan 2024 18:59:37 -0600 Subject: [PATCH 15/96] chore: remove test code --- packages/pros/examples/addrled.rs | 79 ------------------------ packages/pros/src/devices/adi/addrled.rs | 6 +- 2 files changed, 5 insertions(+), 80 deletions(-) delete mode 100644 packages/pros/examples/addrled.rs diff --git a/packages/pros/examples/addrled.rs b/packages/pros/examples/addrled.rs deleted file mode 100644 index c64e09dd..00000000 --- a/packages/pros/examples/addrled.rs +++ /dev/null @@ -1,79 +0,0 @@ -#![no_std] -#![no_main] - -extern crate alloc; - -use core::time::Duration; - -use alloc::vec; - -use pros::{devices::smart::vision::Rgb, prelude::*}; - -pub struct Robot { - led_strip: AdiAddrLed, -} - -fn wheel(mut wheel_pos: u8) -> Rgb { - wheel_pos = 255 - wheel_pos; - if wheel_pos < 85 { - return Rgb::new(255 - wheel_pos * 3, 0, wheel_pos * 3); - } - if wheel_pos < 170 { - wheel_pos -= 85; - return Rgb::new(0, wheel_pos * 3, 255 - wheel_pos * 3); - } - wheel_pos -= 170; - - Rgb::new(wheel_pos * 3, 255 - wheel_pos * 3, 0) -} - - -impl Robot { - pub fn new(peripherals: Peripherals) -> Self { - Self { - led_strip: AdiAddrLed::new(peripherals.adi_d, vec![Rgb::new(0, 0, 0); 10]) - .unwrap_or_else(|err| { - panic!("Failed to construct LED strip! Error: {err:?}"); - }), - } - } -} - -impl SyncRobot for Robot { - fn opcontrol(&mut self) -> pros::Result { - println!("==== ADDRLED TEST ===="); - println!("This will run a few basic test procedures on an AddrLed strip."); - println!("There will be a two second sleep between each procedure.\n"); - - println!("Test 1: Setting all LEDs to rgb(255, 0, 0)."); - self.led_strip.set_all(Rgb::new(255, 0, 0)).unwrap(); - - println!("Test 2: Clearing all LEDs"); - self.led_strip.clear_all().unwrap(); - - println!("Test 3: Setting first LED to rgb(255, 0, 0)."); - self.led_strip.set_pixel(0, Rgb::new(255, 0, 0)).unwrap(); - - println!("Test 4: Clearing first pixel"); - self.led_strip.clear_pixel(0).unwrap(); - - println!("Test 5: Rainbow Buffer"); - let mut data = [0u32; 10]; - - loop { - for j in 0..(256 * 5) { - for i in 0..10 { - data[i] = wheel((((i * 256) as u16 / 10 as u16 + j as u16) & 255) as u8).into(); - } - - self.led_strip.set_buffer(data.iter().cloned()).unwrap(); - - pros::task::delay(Duration::from_millis(10)); - } - } - - Ok(()) - } -} - -sync_robot!(Robot, Robot::new(Peripherals::take().unwrap())); diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs index a59a6df6..793fe916 100644 --- a/packages/pros/src/devices/adi/addrled.rs +++ b/packages/pros/src/devices/adi/addrled.rs @@ -91,7 +91,11 @@ impl AdiAddrLed { self.buffer[index] = color.into(); bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) + pros_sys::ext_adi_led_set( + self.raw, + self.buffer.as_mut_ptr(), + self.buffer.len() as u32, + ) }); Ok(()) From ed3b8c3c83084f22000dc89f6b04c391e7143cb6 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:33:16 -0600 Subject: [PATCH 16/96] fix: ADI error handling --- packages/pros/src/devices/adi/mod.rs | 30 ++++++++----------- .../pros/src/devices/adi/potentiometer.rs | 4 +-- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros/src/devices/adi/mod.rs index 4cc6aa2a..f040532d 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros/src/devices/adi/mod.rs @@ -1,6 +1,6 @@ //! ADI (Triport) devices on the Vex V5. -use pros_sys::{adi_port_config_e_t, PROS_ERR}; +use pros_sys::{adi_port_config_e_t, E_ADI_ERR, PROS_ERR}; use snafu::Snafu; use crate::error::{bail_on, map_errno, PortError}; @@ -119,6 +119,8 @@ impl TryFrom for AdiDeviceType { type Error = AdiError; fn try_from(value: adi_port_config_e_t) -> Result { + bail_on!(E_ADI_ERR, value); + match value { pros_sys::E_ADI_ANALOG_IN => Ok(AdiDeviceType::AnalogIn), pros_sys::E_ADI_ANALOG_OUT => Ok(AdiDeviceType::AnalogOut), @@ -133,7 +135,7 @@ impl TryFrom for AdiDeviceType { pros_sys::E_ADI_LEGACY_ENCODER => Ok(AdiDeviceType::LegacyEncoder), pros_sys::E_ADI_LEGACY_ULTRASONIC => Ok(AdiDeviceType::LegacyUltrasonic), - _ => Err(AdiError::InvalidConfigType), + _ => Err(AdiError::UnknownDeviceType), } } } @@ -149,25 +151,18 @@ pub enum AdiError { #[snafu(display("Another resource is currently trying to access the ADI."))] AlreadyInUse, - #[snafu(display( - "The port specified has been reconfigured or is not configured for digital input." - ))] - DigitalInputNotConfigured, - - #[snafu(display( - "The port type specified is invalid, and cannot be used to configure a port." - ))] - InvalidConfigType, + #[snafu(display("PROS returned an unrecognized device type."))] + UnknownDeviceType, - #[snafu(display("The port has already been configured."))] - AlreadyConfigured, - - #[snafu(display("The port specified is invalid."))] - InvalidPort, + #[snafu(display("The port specified has not been configured for the device type specified."))] + PortNotConfigured, #[snafu(display("ADI devices may only be initialized from one expander port."))] ExpanderPortMismatch, + #[snafu(display("A given value is not correct, or the buffer is null."))] + InvalidValue, + #[snafu(display("{source}"), context(false))] Port { source: PortError }, } @@ -175,7 +170,8 @@ pub enum AdiError { map_errno! { AdiError { EACCES => Self::AlreadyInUse, - EADDRINUSE => Self::DigitalInputNotConfigured, + EADDRINUSE => Self::PortNotConfigured, + EINVAL => Self::InvalidValue, } inherit PortError; } diff --git a/packages/pros/src/devices/adi/potentiometer.rs b/packages/pros/src/devices/adi/potentiometer.rs index 240122f5..ec82ee3f 100644 --- a/packages/pros/src/devices/adi/potentiometer.rs +++ b/packages/pros/src/devices/adi/potentiometer.rs @@ -1,4 +1,4 @@ -use pros_sys::{adi_potentiometer_type_e_t, ext_adi_potentiometer_t, PROS_ERR}; +use pros_sys::{adi_potentiometer_type_e_t, ext_adi_potentiometer_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; @@ -39,7 +39,7 @@ impl AdiPotentiometer { /// Potentiometer V2 rotates 330 degrees /// thus returning an angle between 0-330 degrees. pub fn angle(&self) -> Result { - Ok(bail_on!(PROS_ERR.into(), unsafe { + Ok(bail_on!(PROS_ERR_F, unsafe { pros_sys::ext_adi_potentiometer_get_angle(self.raw) })) } From 7077ffebbe44f0d097b9dc158c31913165d81ab0 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 27 Jan 2024 22:32:30 -0600 Subject: [PATCH 17/96] fix: AdiGyro error handling --- packages/pros/src/devices/adi/gyro.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros/src/devices/adi/gyro.rs index 939e6e3c..3e959a68 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros/src/devices/adi/gyro.rs @@ -1,4 +1,4 @@ -use pros_sys::{ext_adi_gyro_t, PROS_ERR}; +use pros_sys::{ext_adi_gyro_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; @@ -12,7 +12,7 @@ pub struct AdiGyro { impl AdiGyro { /// Create a new gyro from an [`AdiPort`]. pub fn new(port: AdiPort, multiplier: f64) -> Result { - let raw = bail_on!(PROS_ERR.into(), unsafe { + let raw = bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_gyro_init(port.internal_expander_index(), port.index(), multiplier) }); @@ -23,14 +23,14 @@ impl AdiGyro { /// /// There are 360 degrees in a circle, thus the gyro will return 3600 for one whole rotation. pub fn value(&self) -> Result { - Ok(bail_on!(PROS_ERR.into(), unsafe { + Ok(bail_on!(PROS_ERR_F, unsafe { pros_sys::ext_adi_gyro_get(self.raw) })) } /// Reset the current gyro angle to zero degrees. pub fn zero(&mut self) -> Result<(), AdiError> { - bail_on!(PROS_ERR.into(), unsafe { + bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_gyro_reset(self.raw) }); Ok(()) From 144e11f81562e268689562dc2ebde52fff6e8aed Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 1 Feb 2024 13:36:19 -0600 Subject: [PATCH 18/96] refactor: remove useless early return --- packages/pros/src/devices/adi/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros/src/devices/adi/mod.rs index f040532d..4e7e8e9a 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros/src/devices/adi/mod.rs @@ -72,10 +72,10 @@ impl AdiPort { /// Get the type of device this port is currently configured as. pub fn configured_type(&self) -> Result { - Ok(bail_on!(PROS_ERR, unsafe { + bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi::ext_adi_port_get_config(self.internal_expander_index(), self.index()) }) - .try_into()?) + .try_into() } } From dcae8d8b77f923e3d4f2f77af715503b25d2e4d8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 5 Feb 2024 13:41:50 -0600 Subject: [PATCH 19/96] refactor: digital i/o --- packages/pros/src/devices/adi/analog.rs | 1 + packages/pros/src/devices/adi/digital.rs | 82 +++++++++++++++-------- packages/pros/src/devices/adi/mod.rs | 1 + packages/pros/src/devices/adi/solenoid.rs | 34 +++++----- packages/pros/src/devices/adi/switch.rs | 63 +++++++++++++++++ packages/pros/src/devices/mod.rs | 4 +- 6 files changed, 141 insertions(+), 44 deletions(-) create mode 100644 packages/pros/src/devices/adi/switch.rs diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros/src/devices/adi/analog.rs index 2023c4ea..a322a56d 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros/src/devices/adi/analog.rs @@ -3,6 +3,7 @@ use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; +/// Generic analog input ADI device. #[derive(Debug, Eq, PartialEq)] pub struct AdiAnalogIn { port: AdiPort, diff --git a/packages/pros/src/devices/adi/digital.rs b/packages/pros/src/devices/adi/digital.rs index 00f2b84e..43bf5a90 100644 --- a/packages/pros/src/devices/adi/digital.rs +++ b/packages/pros/src/devices/adi/digital.rs @@ -3,6 +3,37 @@ use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LogicLevel { + High, + Low, +} + +impl LogicLevel { + pub fn is_high(&self) -> bool { + match self { + Self::High => true, + Self::Low => false, + } + } + + pub fn is_low(&self) -> bool { + !self.is_high() + } +} + +impl core::ops::Not for LogicLevel { + type Output = Self; + + fn not(self) -> Self::Output { + match self { + Self::Low => Self::High, + Self::High => Self::Low, + } + } +} + +/// Generic digital input ADI device. #[derive(Debug, Eq, PartialEq)] pub struct AdiDigitalIn { port: AdiPort, @@ -14,29 +45,15 @@ impl AdiDigitalIn { Self { port } } - /// Gets a rising-edge case for a digital button press. - pub fn new_press(&mut self) -> Result { - Ok(unsafe { - bail_on!( - PROS_ERR, - pros_sys::ext_adi_digital_get_new_press( - self.port.internal_expander_index(), - self.port.index() - ) - ) != 0 - }) - } + /// Gets the current logic level of a digital input pin. + pub fn level(&self) -> Result { + let value = bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_digital_read(self.port.internal_expander_index(), self.port.index()) + }) != 0; - /// Gets the current value of a digital input pin. - pub fn value(&self) -> Result { - Ok(unsafe { - bail_on!( - PROS_ERR, - pros_sys::ext_adi_digital_read( - self.port.internal_expander_index(), - self.port.index() - ) - ) != 0 + Ok(match value { + true => LogicLevel::High, + false => LogicLevel::Low, }) } } @@ -57,6 +74,7 @@ impl AdiDevice for AdiDigitalIn { } } +/// Generic digital output ADI device. #[derive(Debug, Eq, PartialEq)] pub struct AdiDigitalOut { port: AdiPort, @@ -68,15 +86,25 @@ impl AdiDigitalOut { Self { port } } - /// Sets the digital value (1 or 0) of a pin. - pub fn set_value(&mut self, value: bool) -> Result { - Ok(bail_on!(PROS_ERR, unsafe { + /// Sets the digital logic level (high or low) of a pin. + pub fn set_level(&mut self, level: LogicLevel) -> Result<(), AdiError> { + bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_digital_write( self.port.internal_expander_index(), self.port.index(), - value, + level.is_high(), ) - })) + }); + + Ok(()) + } + + pub fn set_high(&mut self) -> Result<(), AdiError> { + self.set_level(LogicLevel::High) + } + + pub fn set_low(&mut self) -> Result<(), AdiError> { + self.set_level(LogicLevel::Low) } } diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros/src/devices/adi/mod.rs index a2668655..2e30ab9f 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros/src/devices/adi/mod.rs @@ -15,6 +15,7 @@ pub mod motor; pub mod potentiometer; pub mod solenoid; pub mod ultrasonic; +pub mod switch; pub use addrled::AdiAddrLed; pub use analog::{AdiAnalogIn, AdiAnalogOut}; diff --git a/packages/pros/src/devices/adi/solenoid.rs b/packages/pros/src/devices/adi/solenoid.rs index c4234fbe..d058f946 100644 --- a/packages/pros/src/devices/adi/solenoid.rs +++ b/packages/pros/src/devices/adi/solenoid.rs @@ -1,46 +1,48 @@ use pros_sys::PROS_ERR; -use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; +use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; #[derive(Debug, Eq, PartialEq)] pub struct AdiSolenoid { port: AdiPort, - value: bool, + level: LogicLevel, } impl AdiSolenoid { /// Create an AdiSolenoid. pub fn new(port: AdiPort) -> Self { - Self { port, value: false } + Self { port, level: LogicLevel::Low } } - pub fn set_value(&mut self, value: bool) -> Result { - self.value = true; + pub fn set_level(&mut self, level: LogicLevel) -> Result<(), AdiError> { + self.level = level; - Ok(bail_on!(PROS_ERR, unsafe { + bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_digital_write( self.port.internal_expander_index(), self.port.index(), - value, + level.is_high(), ) - })) + }); + + Ok(()) } - pub fn value(&self) -> bool { - self.value + pub fn level(&self) -> LogicLevel { + self.level } - pub fn open(&mut self) -> Result { - self.set_value(true) + pub fn open(&mut self) -> Result<(), AdiError> { + self.set_level(LogicLevel::High) } - pub fn close(&mut self) -> Result { - self.set_value(false) + pub fn close(&mut self) -> Result<(), AdiError> { + self.set_level(LogicLevel::Low) } - pub fn toggle(&mut self) -> Result { - self.set_value(!self.value) + pub fn toggle(&mut self) -> Result<(), AdiError> { + self.set_level(!self.level) } } diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros/src/devices/adi/switch.rs new file mode 100644 index 00000000..b306f936 --- /dev/null +++ b/packages/pros/src/devices/adi/switch.rs @@ -0,0 +1,63 @@ +use pros_sys::PROS_ERR; + +use super::{AdiDevice, AdiDeviceType, AdiDigitalIn, AdiError, AdiPort, digital::LogicLevel}; +use crate::error::bail_on; + +/// Generic digital input ADI device. +#[derive(Debug, Eq, PartialEq)] +pub struct AdiSwitch { + port: AdiPort, +} + +impl AdiSwitch { + /// Create a digital input from an ADI port. + pub const fn new(port: AdiPort) -> Self { + Self { port } + } + + /// Gets the current logic level of a digital switch. + pub fn level(&self) -> Result { + let value = bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_digital_read(self.port.internal_expander_index(), self.port.index()) + }) != 0; + + Ok(match value { + true => LogicLevel::High, + false => LogicLevel::Low, + }) + } + + pub fn pressed(&self) -> Result { + Ok(self.level()?.is_high()) + } + + pub fn pressed_again(&mut self) -> Result { + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_digital_get_new_press(self.port.internal_expander_index(), self.port.index()) + }) != 0) + } +} + +impl From for AdiSwitch { + fn from(device: AdiDigitalIn) -> Self { + Self { + port: unsafe { AdiPort::new(device.port_index(), device.expander_port_index()) }, + } + } +} + +impl AdiDevice for AdiSwitch { + type PortIndexOutput = u8; + + fn port_index(&self) -> Self::PortIndexOutput { + self.port.index() + } + + fn expander_port_index(&self) -> Option { + self.port.expander_index() + } + + fn device_type(&self) -> AdiDeviceType { + AdiDeviceType::DigitalIn + } +} diff --git a/packages/pros/src/devices/mod.rs b/packages/pros/src/devices/mod.rs index 29fa348a..700a576f 100644 --- a/packages/pros/src/devices/mod.rs +++ b/packages/pros/src/devices/mod.rs @@ -4,7 +4,7 @@ //! //! # Overview //! -//! The V5 brain features 21 RJ11 4p4c connector ports (known as "Smart Ports") for communicating with +//! The V5 brain features 21 RJ9 4p4c connector ports (known as "Smart Ports") for communicating with //! newer V5 peripherals, as well as six 3-wire ports with analog-to-digital conversion capability for //! compatibility with legacy cortex devices. This module provides access for both smart devices and //! ADI devices. @@ -24,6 +24,8 @@ pub mod battery; pub mod controller; pub mod peripherals; pub mod position; +pub mod screen; pub use controller::Controller; pub use position::Position; +pub use screen::Screen; From 96ef69979a28b8e6f850d098ba55f07a5d997780 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:37:31 -0600 Subject: [PATCH 20/96] document pressed_again in AdiSwitch --- packages/pros/src/devices/adi/addrled.rs | 8 +------- packages/pros/src/devices/adi/switch.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs index 793fe916..9c0a1aa8 100644 --- a/packages/pros/src/devices/adi/addrled.rs +++ b/packages/pros/src/devices/adi/addrled.rs @@ -138,13 +138,7 @@ impl smart_leds_trait::SmartLedsWrite for AdiAddrLed { T: IntoIterator, I: Into, { - self.buffer = iterator.into_iter().map(|i| i.into()).collect::>(); - - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) - }); - - Ok(()) + self.set_buffer(iterator) } } diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros/src/devices/adi/switch.rs index b306f936..df100973 100644 --- a/packages/pros/src/devices/adi/switch.rs +++ b/packages/pros/src/devices/adi/switch.rs @@ -27,10 +27,26 @@ impl AdiSwitch { }) } + /// Returrns `true` if the switch is currently being pressed. + /// + /// This is equivalent shorthand to calling `Self::level().is_high()`. pub fn pressed(&self) -> Result { Ok(self.level()?.is_high()) } + /// Returns `true` if the switch has been pressed again since the last time this + /// function was called. + /// + /// # Thread Safety + /// + /// This function is not thread-safe. + /// + /// Multiple tasks polling a single button may return different results under the + /// same circumstances, so only one task should call this function for any given + /// switch. E.g., Task A calls this function for buttons 1 and 2. Task B may call + /// this function for button 3, but should not for buttons 1 or 2. A typical + /// use-case for this function is to call inside opcontrol to detect new button + /// presses, and not in any other tasks. pub fn pressed_again(&mut self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_digital_get_new_press(self.port.internal_expander_index(), self.port.index()) From 95fbdd0d88ed0302ff02df2d6edbd3886aab43b2 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Fri, 9 Feb 2024 22:37:50 -0600 Subject: [PATCH 21/96] refactor: digital ADI API --- packages/pros/src/devices/adi/addrled.rs | 48 ++++++++++++++++----- packages/pros/src/devices/adi/digital.rs | 28 ++++++++++++ packages/pros/src/devices/adi/solenoid.rs | 24 +++++++++++ packages/pros/src/devices/adi/switch.rs | 6 ++- packages/pros/src/devices/adi/ultrasonic.rs | 6 ++- 5 files changed, 98 insertions(+), 14 deletions(-) diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs index 9c0a1aa8..b4b27d09 100644 --- a/packages/pros/src/devices/adi/addrled.rs +++ b/packages/pros/src/devices/adi/addrled.rs @@ -1,11 +1,20 @@ +//! ADI Addressable LEDs +//! +//! This module contains abstractions for interacting with WS2812B addressable smart LED +//! strips over ADI ports. + use alloc::vec::Vec; use pros_sys::{ext_adi_led_t, PROS_ERR}; use snafu::Snafu; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::{bail_on, map_errno}; +use crate::{ + color::IntoRgb, + error::{bail_on, map_errno}, +}; +/// WS2812B Addressable LED Strip #[derive(Debug, Eq, PartialEq)] pub struct AdiAddrLed { raw: ext_adi_led_t, @@ -13,6 +22,7 @@ pub struct AdiAddrLed { port: AdiPort, } +/// The max number of LED diodes on one strip that a single ADI port can control. pub const MAX_LED_LENGTH: usize = 64; impl AdiAddrLed { @@ -57,13 +67,13 @@ impl AdiAddrLed { } /// Set the entire led strip to one color - pub fn set_all(&mut self, color: impl Into) -> Result<(), AddrLedError> { + pub fn set_all(&mut self, color: impl IntoRgb) -> Result<(), AddrLedError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_set_all( self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32, - color.into(), + color.into_rgb().into(), ) }); @@ -74,9 +84,12 @@ impl AdiAddrLed { pub fn set_buffer(&mut self, buf: T) -> Result<(), AddrLedError> where T: IntoIterator, - I: Into, + I: IntoRgb, { - self.buffer = buf.into_iter().map(|i| i.into()).collect::>(); + self.buffer = buf + .into_iter() + .map(|i| i.into_rgb().into()) + .collect::>(); bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) @@ -86,9 +99,9 @@ impl AdiAddrLed { } /// Set the color of a single LED on the strip. - pub fn set_pixel(&mut self, index: usize, color: impl Into) -> Result<(), AddrLedError> { + pub fn set_pixel(&mut self, index: usize, color: impl IntoRgb) -> Result<(), AddrLedError> { if self.buffer.get(index).is_some() { - self.buffer[index] = color.into(); + self.buffer[index] = color.into_rgb().into(); bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_led_set( @@ -131,26 +144,41 @@ impl AdiDevice for AdiAddrLed { #[cfg(feature = "smart-leds-trait")] impl smart_leds_trait::SmartLedsWrite for AdiAddrLed { type Error = AddrLedError; - type Color = u32; + type Color = Rgb; fn write(&mut self, iterator: T) -> Result<(), Self::Error> where T: IntoIterator, I: Into, { - self.set_buffer(iterator) + self.buffer = iterator + .into_iter() + .map(|i| i.into().into()) + .collect::>(); + + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) + }); + + Ok(()) } } +/// Errors that can occur when interacting with an Addrled strip. #[derive(Debug, Snafu)] pub enum AddrLedError { + /// Failed to access LED buffer. A given value is not correct, or the buffer is null. #[snafu(display( "Failed to access LED buffer. A given value is not correct, or the buffer is null." ))] InvalidBufferAccess, #[snafu(display("{source}"), context(false))] - Adi { source: AdiError }, + /// Generic ADI related error. + Adi { + /// The source of the error + source: AdiError, + }, } map_errno! { diff --git a/packages/pros/src/devices/adi/digital.rs b/packages/pros/src/devices/adi/digital.rs index 87b7e7a8..d959079f 100644 --- a/packages/pros/src/devices/adi/digital.rs +++ b/packages/pros/src/devices/adi/digital.rs @@ -5,13 +5,26 @@ use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; +/// Represents the logic level of a digital pin. +/// +/// On digital devices, logic levels represent the two possible voltage signals that define +/// the state of a pin. This value is either [`High`] or [`Low`], depending on the intended +/// state of the device. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum LogicLevel { + /// A high digital signal. + /// + /// ADI ports operate on 3.3V logic, so this value indicates a voltage of 3.3V or above. High, + + /// The low digital signal. + /// + /// ADI ports operate on 3.3V logic, so this value indicates a voltage below 3.3V. Low, } impl LogicLevel { + /// Returns `true` if the level is [`High`]. pub fn is_high(&self) -> bool { match self { Self::High => true, @@ -19,6 +32,7 @@ impl LogicLevel { } } + /// Returns `true` if the level is [`Low`]. pub fn is_low(&self) -> bool { !self.is_high() } @@ -59,6 +73,16 @@ impl AdiDigitalIn { false => LogicLevel::Low, }) } + + /// Returns `true` if the digital input's logic level level is [`LogicLevel::High`]. + pub fn is_high(&self) -> Result { + Ok(self.level()?.is_high()) + } + + /// Returns `true` if the digital input's logic level level is [`LogicLevel::Low`]. + pub fn is_low(&self) -> Result { + Ok(self.level()?.is_high()) + } } impl AdiDevice for AdiDigitalIn { @@ -103,10 +127,14 @@ impl AdiDigitalOut { Ok(()) } + /// Set the digital logic level to [`LogicLevel::High`]. Analagous to + /// [`Self::set_level(LogicLevel::High)`]. pub fn set_high(&mut self) -> Result<(), AdiError> { self.set_level(LogicLevel::High) } + /// Set the digital logic level to [`LogicLevel::Low`]. Analagous to + /// [`Self::set_level(LogicLevel::Low)`]. pub fn set_low(&mut self) -> Result<(), AdiError> { self.set_level(LogicLevel::Low) } diff --git a/packages/pros/src/devices/adi/solenoid.rs b/packages/pros/src/devices/adi/solenoid.rs index d058f946..de969f65 100644 --- a/packages/pros/src/devices/adi/solenoid.rs +++ b/packages/pros/src/devices/adi/solenoid.rs @@ -1,8 +1,11 @@ +//! ADI Solenoid Pneumatic Control + use pros_sys::PROS_ERR; use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; +/// Digital pneumatic solenoid valve. #[derive(Debug, Eq, PartialEq)] pub struct AdiSolenoid { port: AdiPort, @@ -15,6 +18,8 @@ impl AdiSolenoid { Self { port, level: LogicLevel::Low } } + /// Sets the digital logic level of the solenoid. [`LogicLevel::Low`] will close the solenoid, + /// and [`LogicLevel::High`] will open it. pub fn set_level(&mut self, level: LogicLevel) -> Result<(), AdiError> { self.level = level; @@ -29,18 +34,37 @@ impl AdiSolenoid { Ok(()) } + /// Returns the current [`LogicLevel`] of the solenoid's digital output state. pub fn level(&self) -> LogicLevel { self.level } + /// Returns `true` if the solenoid is open. + pub fn is_open(&self) -> LogicLevel { + self.level + } + + /// Returns `true` if the solenoid is closed. + pub fn is_closed(&self) -> LogicLevel { + self.level + } + + /// Open the solenoid, allowing air pressure through the "open" valve. pub fn open(&mut self) -> Result<(), AdiError> { self.set_level(LogicLevel::High) } + /// Close the solenoid. + /// + /// - On single-acting solenoids (e.g. SY113-SMO-PM3-F), this will simply block air pressure + /// through the "open" valve. + /// - On double-acting solenoids (e.g. SYJ3120-SMO-M3-F), this will block air pressure through + /// the "open" valve and allow air pressure into the "close" valve. pub fn close(&mut self) -> Result<(), AdiError> { self.set_level(LogicLevel::Low) } + /// Toggle the solenoid's state between open and closed. pub fn toggle(&mut self) -> Result<(), AdiError> { self.set_level(!self.level) } diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros/src/devices/adi/switch.rs index df100973..c5101ff1 100644 --- a/packages/pros/src/devices/adi/switch.rs +++ b/packages/pros/src/devices/adi/switch.rs @@ -1,3 +1,5 @@ +//! ADI Digital Switch + use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiDigitalIn, AdiError, AdiPort, digital::LogicLevel}; @@ -30,7 +32,7 @@ impl AdiSwitch { /// Returrns `true` if the switch is currently being pressed. /// /// This is equivalent shorthand to calling `Self::level().is_high()`. - pub fn pressed(&self) -> Result { + pub fn is_pressed(&self) -> Result { Ok(self.level()?.is_high()) } @@ -47,7 +49,7 @@ impl AdiSwitch { /// this function for button 3, but should not for buttons 1 or 2. A typical /// use-case for this function is to call inside opcontrol to detect new button /// presses, and not in any other tasks. - pub fn pressed_again(&mut self) -> Result { + pub fn was_pressed(&mut self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_digital_get_new_press(self.port.internal_expander_index(), self.port.index()) }) != 0) diff --git a/packages/pros/src/devices/adi/ultrasonic.rs b/packages/pros/src/devices/adi/ultrasonic.rs index 3a3a63ee..d85cb54c 100644 --- a/packages/pros/src/devices/adi/ultrasonic.rs +++ b/packages/pros/src/devices/adi/ultrasonic.rs @@ -39,8 +39,10 @@ impl AdiUltrasonic { }) } - /// Gets the current ultrasonic sensor value in centimeters. - pub fn value(&self) -> Result { + /// Get the distance of a surface to the ultrasonic sensor's mounting point in centimeters. + /// + /// Round and fluffy objects can cause inaccurate values to be returned. + pub fn distance(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_ultrasonic_get(self.raw) })) From eb50b3d1578fc6b29a0e2447b7b068eb83c1ea88 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 10 Feb 2024 13:11:35 -0600 Subject: [PATCH 22/96] refactor: strip out LEDs from this PR --- packages/pros/src/devices/adi/addrled.rs | 189 ------------------ packages/pros/src/devices/adi/gyro.rs | 2 +- packages/pros/src/devices/adi/mod.rs | 2 - .../pros/src/devices/adi/potentiometer.rs | 2 +- packages/pros/src/lib.rs | 1 - 5 files changed, 2 insertions(+), 194 deletions(-) delete mode 100644 packages/pros/src/devices/adi/addrled.rs diff --git a/packages/pros/src/devices/adi/addrled.rs b/packages/pros/src/devices/adi/addrled.rs deleted file mode 100644 index b4b27d09..00000000 --- a/packages/pros/src/devices/adi/addrled.rs +++ /dev/null @@ -1,189 +0,0 @@ -//! ADI Addressable LEDs -//! -//! This module contains abstractions for interacting with WS2812B addressable smart LED -//! strips over ADI ports. - -use alloc::vec::Vec; - -use pros_sys::{ext_adi_led_t, PROS_ERR}; -use snafu::Snafu; - -use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::{ - color::IntoRgb, - error::{bail_on, map_errno}, -}; - -/// WS2812B Addressable LED Strip -#[derive(Debug, Eq, PartialEq)] -pub struct AdiAddrLed { - raw: ext_adi_led_t, - buffer: Vec, - port: AdiPort, -} - -/// The max number of LED diodes on one strip that a single ADI port can control. -pub const MAX_LED_LENGTH: usize = 64; - -impl AdiAddrLed { - /// Initialize an LED strip on an ADI port from a buffer of light colors. - pub fn new(port: AdiPort, buf: T) -> Result - where - T: IntoIterator, - I: Into, - { - let raw = bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_init(port.internal_expander_index(), port.index()) - }); - - let mut device = Self { - port, - raw, - buffer: buf.into_iter().map(|i| i.into()).collect::>(), - }; - - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_set( - device.raw, - device.buffer.as_mut_ptr(), - device.buffer.len() as u32, - ) - }); - - Ok(device) - } - - /// Clear the entire led strip of color. - pub fn clear_all(&mut self) -> Result<(), AddrLedError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_clear_all( - self.raw, - self.buffer.as_mut_ptr(), - self.buffer.len() as u32, - ) - }); - - Ok(()) - } - - /// Set the entire led strip to one color - pub fn set_all(&mut self, color: impl IntoRgb) -> Result<(), AddrLedError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_set_all( - self.raw, - self.buffer.as_mut_ptr(), - self.buffer.len() as u32, - color.into_rgb().into(), - ) - }); - - Ok(()) - } - - /// Set the entire led strip using the colors contained in a new buffer. - pub fn set_buffer(&mut self, buf: T) -> Result<(), AddrLedError> - where - T: IntoIterator, - I: IntoRgb, - { - self.buffer = buf - .into_iter() - .map(|i| i.into_rgb().into()) - .collect::>(); - - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) - }); - - Ok(()) - } - - /// Set the color of a single LED on the strip. - pub fn set_pixel(&mut self, index: usize, color: impl IntoRgb) -> Result<(), AddrLedError> { - if self.buffer.get(index).is_some() { - self.buffer[index] = color.into_rgb().into(); - - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_set( - self.raw, - self.buffer.as_mut_ptr(), - self.buffer.len() as u32, - ) - }); - - Ok(()) - } else { - Err(AddrLedError::InvalidBufferAccess) - } - } - - /// Clear one LED on the strip. - pub fn clear_pixel(&mut self, index: usize) -> Result<(), AddrLedError> { - self.set_pixel(index, 0u32)?; - - Ok(()) - } -} - -impl AdiDevice for AdiAddrLed { - type PortIndexOutput = u8; - - fn port_index(&self) -> Self::PortIndexOutput { - self.port.index() - } - - fn expander_port_index(&self) -> Option { - self.port.expander_index() - } - - fn device_type(&self) -> AdiDeviceType { - AdiDeviceType::DigitalOut - } -} - -#[cfg(feature = "smart-leds-trait")] -impl smart_leds_trait::SmartLedsWrite for AdiAddrLed { - type Error = AddrLedError; - type Color = Rgb; - - fn write(&mut self, iterator: T) -> Result<(), Self::Error> - where - T: IntoIterator, - I: Into, - { - self.buffer = iterator - .into_iter() - .map(|i| i.into().into()) - .collect::>(); - - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_led_set(self.raw, self.buffer.as_mut_ptr(), self.buffer.len() as u32) - }); - - Ok(()) - } -} - -/// Errors that can occur when interacting with an Addrled strip. -#[derive(Debug, Snafu)] -pub enum AddrLedError { - /// Failed to access LED buffer. A given value is not correct, or the buffer is null. - #[snafu(display( - "Failed to access LED buffer. A given value is not correct, or the buffer is null." - ))] - InvalidBufferAccess, - - #[snafu(display("{source}"), context(false))] - /// Generic ADI related error. - Adi { - /// The source of the error - source: AdiError, - }, -} - -map_errno! { - AddrLedError { - EINVAL => Self::InvalidBufferAccess, - } - inherit AdiError; -} diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros/src/devices/adi/gyro.rs index 5cb8ffce..bc48caa7 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros/src/devices/adi/gyro.rs @@ -1,6 +1,6 @@ //! ADI gyro device. -use pros_sys::{ext_adi_gyro_t, PROS_ERR}; +use pros_sys::{ext_adi_gyro_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros/src/devices/adi/mod.rs index 2e2d14bf..d6fc8f11 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros/src/devices/adi/mod.rs @@ -9,7 +9,6 @@ use crate::error::{bail_on, map_errno, PortError}; pub mod analog; pub mod digital; -pub mod addrled; pub mod encoder; pub mod gyro; pub mod motor; @@ -18,7 +17,6 @@ pub mod solenoid; pub mod ultrasonic; pub mod switch; -pub use addrled::AdiAddrLed; pub use analog::{AdiAnalogIn, AdiAnalogOut}; pub use digital::{AdiDigitalIn, AdiDigitalOut}; pub use encoder::AdiEncoder; diff --git a/packages/pros/src/devices/adi/potentiometer.rs b/packages/pros/src/devices/adi/potentiometer.rs index a728508b..8cc66a7a 100644 --- a/packages/pros/src/devices/adi/potentiometer.rs +++ b/packages/pros/src/devices/adi/potentiometer.rs @@ -1,6 +1,6 @@ //! ADI Potentiometer device. -use pros_sys::{adi_potentiometer_type_e_t, ext_adi_potentiometer_t, PROS_ERR}; +use pros_sys::{adi_potentiometer_type_e_t, ext_adi_potentiometer_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index e40c91b2..3d9b0f10 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -377,7 +377,6 @@ pub mod prelude { color::Rgb, devices::{ adi::{ - addrled::AdiAddrLed, analog::{AdiAnalogIn, AdiAnalogOut}, digital::{AdiDigitalIn, AdiDigitalOut}, encoder::AdiEncoder, From e13cc54027655231f590cc0a2fd7abb6fff226f2 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 19:39:09 -0800 Subject: [PATCH 23/96] fix: pin rust toolchain version --- packages/pros/src/lib.rs | 2 +- rust-toolchain.toml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 51bdec2a..4c799b93 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -52,7 +52,7 @@ //! You may have noticed the `#[derive(Default)]` attribute on these Robot structs. //! If you want to learn why, look at the docs for [`async_robot`] or [`sync_robot`]. -#![feature(error_in_core, stdsimd, negative_impls)] +#![feature(error_in_core, negative_impls)] #![no_std] #![warn( missing_docs, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 0a44ea93..a2fae3f5 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly" -components = [ "rust-src" ] -targets = [ "armv7a-none-eabi" ] \ No newline at end of file +channel = "nightly-2024-02-07" +components = ["rust-src"] +targets = ["armv7a-none-eabi"] From 181cc474a38e846149d8311f2469336b920710f0 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 19:46:49 -0800 Subject: [PATCH 24/96] fix: update rust toolchain version in ci --- .github/workflows/rust.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1da706c5..bef8863e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,7 +14,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly + toolchain: nightly-2024-02-07 override: true - name: Check @@ -33,7 +33,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly + toolchain: nightly-2024-02-07 override: true - name: Setup | Install Rustfmt @@ -57,4 +57,4 @@ jobs: with: reporter: 'github-pr-check' github_token: ${{ secrets.GITHUB_TOKEN }} - clippy_flags: --all-targets --all-features \ No newline at end of file + clippy_flags: --all-targets --all-features From 4a93f99c2092df721d5905f50c9043c31cf9aaad Mon Sep 17 00:00:00 2001 From: Gavin <94215019+Gavin-Niederman@users.noreply.github.com> Date: Sat, 10 Feb 2024 20:20:32 -0800 Subject: [PATCH 25/96] docs: update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8f0d3e9..f7e7b45f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ Before releasing: ### Fixed +- Fix error handling and error type variats in ADI bindings + ### Changed - Re-exported printing macros from `pros::io`. (#82) From 940f8891bc9c7a9ab322ede0964ddad7a4f411a6 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 11 Feb 2024 04:32:41 -0800 Subject: [PATCH 26/96] chore: format --- packages/pros/src/devices/adi/gyro.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros/src/devices/adi/gyro.rs index 8a65ef5e..b720dbe6 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros/src/devices/adi/gyro.rs @@ -32,9 +32,7 @@ impl AdiGyro { /// Reset the current gyro angle to zero degrees. pub fn zero(&mut self) -> Result<(), AdiError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_gyro_reset(self.raw) - }); + bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_gyro_reset(self.raw) }); Ok(()) } } From ac6b962df25ab37ceeb8fffe129ced2d978d168f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 20:48:23 -0600 Subject: [PATCH 27/96] refactor: analog ADI --- packages/pros/src/devices/adi/analog.rs | 88 +++++++++++++++---- packages/pros/src/devices/adi/digital.rs | 5 +- packages/pros/src/devices/adi/encoder.rs | 4 +- packages/pros/src/devices/adi/gyro.rs | 28 +++--- packages/pros/src/devices/adi/linetracker.rs | 78 ++++++++++++++++ packages/pros/src/devices/adi/mod.rs | 16 ++-- packages/pros/src/devices/adi/motor.rs | 19 +++- .../pros/src/devices/adi/potentiometer.rs | 4 +- packages/pros/src/devices/adi/solenoid.rs | 13 +-- packages/pros/src/devices/adi/switch.rs | 17 ++-- packages/pros/src/devices/adi/ultrasonic.rs | 15 +++- packages/pros/src/lib.rs | 2 +- 12 files changed, 229 insertions(+), 60 deletions(-) create mode 100644 packages/pros/src/devices/adi/linetracker.rs diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros/src/devices/adi/analog.rs index 9d877077..a5ceec3c 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros/src/devices/adi/analog.rs @@ -1,4 +1,12 @@ //! Analog input and output ADI devices. +//! +//! # Overview +//! +//! Unlike digital ADI devices which can only report a "high" or "low" state, analog +//! ADI devices may report a wide range of values spanning 0-5 volts. These analog +//! voltages readings are then converted into a digital values using the internal +//! Analog-to-Digital Converter (ADC) in the V5 brain. The brain measures analog input +//! using 12-bit values ranging from 0 (0V) to 4095 (5V). use pros_sys::PROS_ERR; @@ -7,7 +15,6 @@ use crate::error::bail_on; /// Generic analog input ADI device. #[derive(Debug, Eq, PartialEq)] -/// Generic analog input ADI device. pub struct AdiAnalogIn { port: AdiPort, } @@ -42,6 +49,8 @@ impl AdiAnalogIn { /// Reads an analog input channel and returns the 12-bit value. /// + /// # Sensor Compatibility + /// /// The value returned is undefined if the analog pin has been switched to a different mode. /// The meaning of the returned value varies depending on the sensor attached. pub fn value(&self) -> Result { @@ -50,14 +59,24 @@ impl AdiAnalogIn { })) } + /// Reads an analog input channel and returns the calculated voltage input (0-5V). + /// + /// # Sensor Compatibility + /// + /// The value returned is undefined if the analog pin has been switched to a different mode. + /// The meaning of the returned value varies depending on the sensor attached. + pub fn voltage(&self) -> Result { + Ok(self.value()? as f64 / 4095.0 * 5.0) + } + /// Reads the calibrated value of an analog input channel. /// - /// The calibrate function must be run first on that channel. + /// The [`Self::calibrate`] function must be run first on that channel. /// /// This function is inappropriate for sensor values intended for integration, /// as round-off error can accumulate causing drift over time. - /// Use value_calbrated_hr instead. - pub fn value_calibrated(&self) -> Result { + /// Use [`Self::calibrated_value_hr`] instead. + pub fn calibrated_value(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read_calibrated( self.port.internal_expander_index(), @@ -66,7 +85,18 @@ impl AdiAnalogIn { })) } - /// Reads the calibrated value of an analog input channel 1-8 with enhanced precision. + /// Reads the calibrated volt of an analog input channel. + /// + /// The calibrate function must be run first on that channel. + /// + /// This function is inappropriate for sensor values intended for integration, + /// as round-off error can accumulate causing drift over time. + /// Use [`Self::calibrated_voltage_hr`] instead. + pub fn calibrated_voltage(&self) -> Result { + Ok(self.calibrated_value()? as f64 / 4095.0 * 5.0) + } + + /// Reads the calibrated value of an analog input channel with enhanced precision. /// /// The calibrate function must be run first. /// @@ -74,13 +104,13 @@ impl AdiAnalogIn { /// to reduce drift due to round-off, and should not be used on a sensor such as a /// line tracker or potentiometer. /// - /// The value returned actually has 16 bits of “precision”, + /// The value returned actually has 16 bits of "precision", /// even though the ADC only reads 12 bits, /// so that errors induced by the average value being /// between two values come out in the wash when integrated over time. /// /// Think of the value as the true value times 16. - pub fn value_calibrated_hr(&self) -> Result { + pub fn calibrated_value_hr(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read_calibrated_HR( self.port.internal_expander_index(), @@ -88,6 +118,26 @@ impl AdiAnalogIn { ) })) } + + /// Reads the calibrated voltage of an analog input channel with enhanced precision. + /// + /// The calibrate function must be run first. + /// + /// # Use + /// + /// This is intended for integrated sensor values such as gyros and accelerometers + /// to reduce drift due to round-off, and should not be used on a sensor such as a + /// line tracker or potentiometer. + /// + /// The value returned actually has 16 bits of "precision", + /// even though the ADC only reads 12 bits, + /// so that errors induced by the average value being + /// between two values come out in the wash when integrated over time. + /// + /// Think of the value as the true value times 16. + pub fn calibrated_voltage_hr(&self) -> Result { + Ok(self.calibrated_value_hr()? as f64 / 4095.0 * 5.0) + } } impl AdiDevice for AdiAnalogIn { @@ -106,8 +156,8 @@ impl AdiDevice for AdiAnalogIn { } } -#[derive(Debug, Eq, PartialEq)] /// Generic analog output ADI device. +#[derive(Debug, Eq, PartialEq)] pub struct AdiAnalogOut { port: AdiPort, } @@ -119,13 +169,21 @@ impl AdiAnalogOut { } /// Sets the output for the Analog Output from 0 (0V) to 4095 (5V). - pub fn set_value(&mut self, value: i32) -> Result { - Ok(unsafe { - bail_on! { - PROS_ERR, - pros_sys::ext_adi_port_set_value(self.port.internal_expander_index(), self.port.index(), value) - } - }) + pub fn set_value(&mut self, value: i32) -> Result<(), AdiError> { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_value( + self.port.internal_expander_index(), + self.port.index(), + value, + ) + }); + + Ok(()) + } + + /// Sets the output for the Analog Output from 0V to (5V). + pub fn set_voltage(&mut self, value: f64) -> Result<(), AdiError> { + self.set_value((value / 5.0 * 4095.0) as i32) } } diff --git a/packages/pros/src/devices/adi/digital.rs b/packages/pros/src/devices/adi/digital.rs index d959079f..d52f5932 100644 --- a/packages/pros/src/devices/adi/digital.rs +++ b/packages/pros/src/devices/adi/digital.rs @@ -25,7 +25,7 @@ pub enum LogicLevel { impl LogicLevel { /// Returns `true` if the level is [`High`]. - pub fn is_high(&self) -> bool { + pub const fn is_high(&self) -> bool { match self { Self::High => true, Self::Low => false, @@ -33,7 +33,7 @@ impl LogicLevel { } /// Returns `true` if the level is [`Low`]. - pub fn is_low(&self) -> bool { + pub const fn is_low(&self) -> bool { !self.is_high() } } @@ -103,7 +103,6 @@ impl AdiDevice for AdiDigitalIn { /// Generic digital output ADI device. #[derive(Debug, Eq, PartialEq)] -/// Generic digital output ADI device. pub struct AdiDigitalOut { port: AdiPort, } diff --git a/packages/pros/src/devices/adi/encoder.rs b/packages/pros/src/devices/adi/encoder.rs index e4752532..e9f0816a 100644 --- a/packages/pros/src/devices/adi/encoder.rs +++ b/packages/pros/src/devices/adi/encoder.rs @@ -5,9 +5,9 @@ use pros_sys::{ext_adi_encoder_t, PROS_ERR}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; -#[derive(Debug, Eq, PartialEq)] /// ADI encoder device. /// Requires two adi ports. +#[derive(Debug, Eq, PartialEq)] pub struct AdiEncoder { raw: ext_adi_encoder_t, port_top: AdiPort, @@ -49,7 +49,7 @@ impl AdiEncoder { } /// Gets the number of ticks recorded by the encoder. - pub fn value(&self) -> Result { + pub fn position(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::adi_encoder_get(self.raw) })) diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros/src/devices/adi/gyro.rs index bc48caa7..9ef00108 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros/src/devices/adi/gyro.rs @@ -1,12 +1,20 @@ //! ADI gyro device. +use core::time::Duration; + use pros_sys::{ext_adi_gyro_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; -#[derive(Debug, Eq, PartialEq)] +/// The time it takes to calibrate an [`AdiGyro`]. +/// +/// The theoretical calibration time is 1024ms, but in practice this seemed to be the +/// actual time that it takes. +pub const GYRO_CALIBRATION_TIME: Duration = Duration::from_millis(1300); + /// ADI gyro device. +#[derive(Debug, Eq, PartialEq)] pub struct AdiGyro { raw: ext_adi_gyro_t, port: AdiPort, @@ -14,6 +22,9 @@ pub struct AdiGyro { impl AdiGyro { /// Create a new gyro from an [`AdiPort`]. + /// + /// If the given port has not previously been configured as a gyro, then this + /// function blocks for a 1300ms calibration period. pub fn new(port: AdiPort, multiplier: f64) -> Result { let raw = bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_gyro_init(port.internal_expander_index(), port.index(), multiplier) @@ -22,20 +33,17 @@ impl AdiGyro { Ok(Self { raw, port }) } - /// Gets the current gyro angle in tenths of a degree. Unless a multiplier is applied to the gyro, the return value will be a whole number representing the number of degrees of rotation times 10. + /// Gets the yaw angle of the gyroscope in degrees. /// - /// There are 360 degrees in a circle, thus the gyro will return 3600 for one whole rotation. - pub fn value(&self) -> Result { - Ok(bail_on!(PROS_ERR_F, unsafe { - pros_sys::ext_adi_gyro_get(self.raw) - })) + /// Unless a multiplier is applied to the gyro, the return value will be a whole + /// number representing the number of degrees of rotation. + pub fn angle(&self) -> Result { + Ok(bail_on!(PROS_ERR_F, unsafe { pros_sys::ext_adi_gyro_get(self.raw) }) / 10.0) } /// Reset the current gyro angle to zero degrees. pub fn zero(&mut self) -> Result<(), AdiError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_gyro_reset(self.raw) - }); + bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_gyro_reset(self.raw) }); Ok(()) } } diff --git a/packages/pros/src/devices/adi/linetracker.rs b/packages/pros/src/devices/adi/linetracker.rs new file mode 100644 index 00000000..48ba2251 --- /dev/null +++ b/packages/pros/src/devices/adi/linetracker.rs @@ -0,0 +1,78 @@ +//! ADI Line Tracker +//! +//! Line trackers read the difference between a black line and a white surface. They can +//! be used to follow a marked path on the ground. +//! +//! # Overview +//! +//! A line tracker consists of an analog infrared light sensor and an infrared LED. +//! It works by illuminating a surface with infrared light; the sensor then picks up +//! the reflected infrared radiation and, based on its intensity, determines the +//! reflectivity of the surface in question. White surfaces will reflect more light +//! than dark surfaces, resulting in their appearing brighter to the sensor. This +//! allows the sensor to detect a dark line on a white background, or a white line on +//! a dark background. +//! +//! # Hardware +//! +//! The Line Tracking Sensor is an analog sensor, and it internally measures values in the +//! range of 0 to 4095 from 0-5V. Darker objects reflect less light, and are indicated by +//! higher numbers. Lighter objects reflect more light, and are indicated by lower numbers. +//! +//! For best results when using the Line Tracking Sensors, it is best to mount the sensors +//! between 1/8 and 1/4 of an inch away from the surface it is measuring. It is also important +//! to keep lighting in the room consistent, so sensors' readings remain accurate. + +use pros_sys::PROS_ERR; + +use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; +use crate::error::bail_on; + +/// Analog line tracker device. +#[derive(Debug, Eq, PartialEq)] +pub struct AdiLineTracker { + port: AdiPort, +} + +impl AdiLineTracker { + /// Create a line tracker on an ADI port. + pub const fn new(port: AdiPort) -> Self { + Self { port } + } + + /// Get the reflectivity factor measured by the sensor. + /// + /// This is returned as a value ranging from [0.0, 1.0]. + pub fn reflectivity(&self) -> Result { + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index()) + }) as f64 + / 4095.0) + } + + /// Get the raw reflectivity factor of the sensor. + /// + /// This is a raw 12-bit value from [0, 4095] representing the voltage level from + /// 0-5V measured by the V5 brain's ADC. + pub fn raw_reflectivity(&self) -> Result { + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index()) + })) + } +} + +impl AdiDevice for AdiLineTracker { + type PortIndexOutput = u8; + + fn port_index(&self) -> Self::PortIndexOutput { + self.port.index() + } + + fn expander_port_index(&self) -> Option { + self.port.expander_index() + } + + fn device_type(&self) -> AdiDeviceType { + AdiDeviceType::AnalogIn + } +} diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros/src/devices/adi/mod.rs index d6fc8f11..5c845b1f 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros/src/devices/adi/mod.rs @@ -11,16 +11,18 @@ pub mod digital; pub mod encoder; pub mod gyro; +pub mod linetracker; pub mod motor; pub mod potentiometer; pub mod solenoid; -pub mod ultrasonic; pub mod switch; +pub mod ultrasonic; -pub use analog::{AdiAnalogIn, AdiAnalogOut}; +pub use analog::AdiAnalogIn; pub use digital::{AdiDigitalIn, AdiDigitalOut}; pub use encoder::AdiEncoder; pub use gyro::AdiGyro; +pub use linetracker::AdiLineTracker; pub use motor::AdiMotor; pub use potentiometer::AdiPotentiometer; pub use solenoid::AdiSolenoid; @@ -116,17 +118,15 @@ pub enum AdiDeviceType { /// Generic digital output. DigitalOut = pros_sys::adi::E_ADI_DIGITAL_OUT, - /// Cortex era gyro. + /// Cortex-era gyro. LegacyGyro = pros_sys::adi::E_ADI_LEGACY_GYRO, - - /// Cortex era servo motor. + /// Cortex-era servo motor. LegacyServo = pros_sys::adi::E_ADI_LEGACY_SERVO, /// PWM output. LegacyPwm = pros_sys::adi::E_ADI_LEGACY_PWM, - - /// Cortex era encoder. + /// Cortex-era encoder. LegacyEncoder = pros_sys::E_ADI_LEGACY_ENCODER, - /// Cortex era ultrasonic sensor. + /// Cortex-era ultrasonic sensor. LegacyUltrasonic = pros_sys::E_ADI_LEGACY_ULTRASONIC, } diff --git a/packages/pros/src/devices/adi/motor.rs b/packages/pros/src/devices/adi/motor.rs index bdb52490..9eb20fd8 100644 --- a/packages/pros/src/devices/adi/motor.rs +++ b/packages/pros/src/devices/adi/motor.rs @@ -17,8 +17,13 @@ impl AdiMotor { Self { port } } + /// Sets the PWM output of the given motor as an f32 from [-1.0, 1.0]. + pub fn set_output(&mut self, value: f32) -> Result<(), AdiError> { + self.set_raw_output((value * 127.0) as i8) + } + /// Sets the PWM output of the given motor as an i8 from [-127, 127]. - pub fn set_value(&mut self, value: i8) -> Result<(), AdiError> { + pub fn set_raw_output(&mut self, value: i8) -> Result<(), AdiError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_motor_set( self.port.internal_expander_index(), @@ -26,14 +31,20 @@ impl AdiMotor { value, ) }); + Ok(()) } - /// Returns the last set PWM output of the motor on the given port. - pub fn value(&self) -> Result { + /// Returns the last set PWM output of the motor on the given port as an f32 from [-1.0, 1.0]. + pub fn output(&self) -> Result { + Ok(self.raw_output()? as f32 / 127.0) + } + + /// Returns the last set PWM output of the motor on the given port as an i8 from [-127, 127]. + pub fn raw_output(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_motor_get(self.port.internal_expander_index(), self.port.index()) - })) + }) as i8) } /// Stops the given motor. diff --git a/packages/pros/src/devices/adi/potentiometer.rs b/packages/pros/src/devices/adi/potentiometer.rs index 8cc66a7a..433d1677 100644 --- a/packages/pros/src/devices/adi/potentiometer.rs +++ b/packages/pros/src/devices/adi/potentiometer.rs @@ -36,7 +36,7 @@ impl AdiPotentiometer { self.potentiometer_type } - /// Gets the current potentiometer angle in tenths of a degree. + /// Gets the current potentiometer angle in degrees. /// /// The original potentiometer rotates 250 degrees /// thus returning an angle between 0-250 degrees. @@ -45,7 +45,7 @@ impl AdiPotentiometer { pub fn angle(&self) -> Result { Ok(bail_on!(PROS_ERR_F, unsafe { pros_sys::ext_adi_potentiometer_get_angle(self.raw) - })) + }) / 10.0) } } diff --git a/packages/pros/src/devices/adi/solenoid.rs b/packages/pros/src/devices/adi/solenoid.rs index de969f65..32b21b61 100644 --- a/packages/pros/src/devices/adi/solenoid.rs +++ b/packages/pros/src/devices/adi/solenoid.rs @@ -14,8 +14,11 @@ pub struct AdiSolenoid { impl AdiSolenoid { /// Create an AdiSolenoid. - pub fn new(port: AdiPort) -> Self { - Self { port, level: LogicLevel::Low } + pub const fn new(port: AdiPort) -> Self { + Self { + port, + level: LogicLevel::Low, + } } /// Sets the digital logic level of the solenoid. [`LogicLevel::Low`] will close the solenoid, @@ -35,17 +38,17 @@ impl AdiSolenoid { } /// Returns the current [`LogicLevel`] of the solenoid's digital output state. - pub fn level(&self) -> LogicLevel { + pub const fn level(&self) -> LogicLevel { self.level } /// Returns `true` if the solenoid is open. - pub fn is_open(&self) -> LogicLevel { + pub const fn is_open(&self) -> LogicLevel { self.level } /// Returns `true` if the solenoid is closed. - pub fn is_closed(&self) -> LogicLevel { + pub const fn is_closed(&self) -> LogicLevel { self.level } diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros/src/devices/adi/switch.rs index c5101ff1..5de703a4 100644 --- a/packages/pros/src/devices/adi/switch.rs +++ b/packages/pros/src/devices/adi/switch.rs @@ -2,7 +2,7 @@ use pros_sys::PROS_ERR; -use super::{AdiDevice, AdiDeviceType, AdiDigitalIn, AdiError, AdiPort, digital::LogicLevel}; +use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiDigitalIn, AdiError, AdiPort}; use crate::error::bail_on; /// Generic digital input ADI device. @@ -32,9 +32,9 @@ impl AdiSwitch { /// Returrns `true` if the switch is currently being pressed. /// /// This is equivalent shorthand to calling `Self::level().is_high()`. - pub fn is_pressed(&self) -> Result { - Ok(self.level()?.is_high()) - } + pub fn is_pressed(&self) -> Result { + Ok(self.level()?.is_high()) + } /// Returns `true` if the switch has been pressed again since the last time this /// function was called. @@ -50,10 +50,13 @@ impl AdiSwitch { /// use-case for this function is to call inside opcontrol to detect new button /// presses, and not in any other tasks. pub fn was_pressed(&mut self) -> Result { - Ok(bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_digital_get_new_press(self.port.internal_expander_index(), self.port.index()) + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_digital_get_new_press( + self.port.internal_expander_index(), + self.port.index(), + ) }) != 0) - } + } } impl From for AdiSwitch { diff --git a/packages/pros/src/devices/adi/ultrasonic.rs b/packages/pros/src/devices/adi/ultrasonic.rs index d85cb54c..a0a0b3b4 100644 --- a/packages/pros/src/devices/adi/ultrasonic.rs +++ b/packages/pros/src/devices/adi/ultrasonic.rs @@ -39,10 +39,19 @@ impl AdiUltrasonic { }) } - /// Get the distance of a surface to the ultrasonic sensor's mounting point in centimeters. + /// Get the distance of a surface to the ultrasonic sensor's mounting point + /// in millimeters. /// - /// Round and fluffy objects can cause inaccurate values to be returned. - pub fn distance(&self) -> Result { + /// Round and/or fluffy objects can cause inaccurate values to be returned. + pub fn distance(&self) -> Result { + Ok(self.raw_distance()? as f64 / 10.0) + } + + /// Get the raw distance reading of the ultrasonic sensor. This value is returned + /// in 10^-4 * meters, or ten-thousanths of a meter. + /// + /// Round and/or fluffy objects can cause inaccurate values to be returned. + pub fn raw_distance(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_ultrasonic_get(self.raw) })) diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 3d9b0f10..44fafeb5 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -377,7 +377,7 @@ pub mod prelude { color::Rgb, devices::{ adi::{ - analog::{AdiAnalogIn, AdiAnalogOut}, + analog::AdiAnalogIn, digital::{AdiDigitalIn, AdiDigitalOut}, encoder::AdiEncoder, gyro::AdiGyro, From e82cf122fa7bec7bfcfacc66ff8d192068a82360 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 20:51:22 -0600 Subject: [PATCH 28/96] chore: remove smart-leds-trait --- packages/pros/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 63fcd1fa..702142b2 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -29,7 +29,6 @@ no_std_io = { version = "0.6.0", features = ["alloc"] } futures = { version = "0.3.28", default-features = false, features = ["alloc"] } async-task = { version = "4.5.0", default-features = false } waker-fn = "1.1.1" -smart-leds-trait = { version = "0.3.0", optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] dlmalloc = { version = "0.2.4", features = ["global"] } From 000b6df258f21fe5f09da15d1bb4ac3e808fe969 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 21:10:55 -0600 Subject: [PATCH 29/96] chore: fmt --- packages/pros/src/devices/adi/analog.rs | 41 ++++++----------------- packages/pros/src/devices/adi/solenoid.rs | 4 +-- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros/src/devices/adi/analog.rs index a5ceec3c..97454195 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros/src/devices/adi/analog.rs @@ -61,6 +61,11 @@ impl AdiAnalogIn { /// Reads an analog input channel and returns the calculated voltage input (0-5V). /// + /// # Precision + /// + /// This function has a precision of `5.0/4095.0` volts, as ADC reports 12-bit voltage data + /// on a scale of 0-4095. + /// /// # Sensor Compatibility /// /// The value returned is undefined if the analog pin has been switched to a different mode. @@ -85,17 +90,6 @@ impl AdiAnalogIn { })) } - /// Reads the calibrated volt of an analog input channel. - /// - /// The calibrate function must be run first on that channel. - /// - /// This function is inappropriate for sensor values intended for integration, - /// as round-off error can accumulate causing drift over time. - /// Use [`Self::calibrated_voltage_hr`] instead. - pub fn calibrated_voltage(&self) -> Result { - Ok(self.calibrated_value()? as f64 / 4095.0 * 5.0) - } - /// Reads the calibrated value of an analog input channel with enhanced precision. /// /// The calibrate function must be run first. @@ -118,26 +112,6 @@ impl AdiAnalogIn { ) })) } - - /// Reads the calibrated voltage of an analog input channel with enhanced precision. - /// - /// The calibrate function must be run first. - /// - /// # Use - /// - /// This is intended for integrated sensor values such as gyros and accelerometers - /// to reduce drift due to round-off, and should not be used on a sensor such as a - /// line tracker or potentiometer. - /// - /// The value returned actually has 16 bits of "precision", - /// even though the ADC only reads 12 bits, - /// so that errors induced by the average value being - /// between two values come out in the wash when integrated over time. - /// - /// Think of the value as the true value times 16. - pub fn calibrated_voltage_hr(&self) -> Result { - Ok(self.calibrated_value_hr()? as f64 / 4095.0 * 5.0) - } } impl AdiDevice for AdiAnalogIn { @@ -182,6 +156,11 @@ impl AdiAnalogOut { } /// Sets the output for the Analog Output from 0V to (5V). + /// + /// # Precision + /// + /// This function has a precision of `5.0/4095.0` volts, as ADC reports 12-bit voltage data + /// on a scale of 0-4095. pub fn set_voltage(&mut self, value: f64) -> Result<(), AdiError> { self.set_value((value / 5.0 * 4095.0) as i32) } diff --git a/packages/pros/src/devices/adi/solenoid.rs b/packages/pros/src/devices/adi/solenoid.rs index 32b21b61..1447aa63 100644 --- a/packages/pros/src/devices/adi/solenoid.rs +++ b/packages/pros/src/devices/adi/solenoid.rs @@ -38,12 +38,12 @@ impl AdiSolenoid { } /// Returns the current [`LogicLevel`] of the solenoid's digital output state. - pub const fn level(&self) -> LogicLevel { + pub const fn level(&self) -> LogicLevel { self.level } /// Returns `true` if the solenoid is open. - pub const fn is_open(&self) -> LogicLevel { + pub const fn is_open(&self) -> LogicLevel { self.level } From e2197445bbf9d6236507b159e7172344678a31a9 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 21:25:06 -0600 Subject: [PATCH 30/96] refactor: `is_low` --- packages/pros/src/devices/adi/digital.rs | 5 ++++- packages/pros/src/devices/adi/gyro.rs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/pros/src/devices/adi/digital.rs b/packages/pros/src/devices/adi/digital.rs index d52f5932..4d36630c 100644 --- a/packages/pros/src/devices/adi/digital.rs +++ b/packages/pros/src/devices/adi/digital.rs @@ -34,7 +34,10 @@ impl LogicLevel { /// Returns `true` if the level is [`Low`]. pub const fn is_low(&self) -> bool { - !self.is_high() + match self { + Self::High => false, + Self::Low => true, + } } } diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros/src/devices/adi/gyro.rs index 586c4ad7..9ef00108 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros/src/devices/adi/gyro.rs @@ -1,6 +1,7 @@ //! ADI gyro device. use core::time::Duration; + use pros_sys::{ext_adi_gyro_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; From f250621ff52aadfc2d8e07befa142d8bfc4e3c5f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 21:49:21 -0600 Subject: [PATCH 31/96] refactor: use u16 for analog return data --- packages/pros/src/devices/adi/analog.rs | 18 +++++++++--------- packages/pros/src/devices/adi/linetracker.rs | 4 ++-- packages/pros/src/devices/adi/ultrasonic.rs | 15 +++------------ 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros/src/devices/adi/analog.rs index 97454195..3dd67f33 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros/src/devices/adi/analog.rs @@ -53,10 +53,10 @@ impl AdiAnalogIn { /// /// The value returned is undefined if the analog pin has been switched to a different mode. /// The meaning of the returned value varies depending on the sensor attached. - pub fn value(&self) -> Result { + pub fn value(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index()) - })) + }) as u16) } /// Reads an analog input channel and returns the calculated voltage input (0-5V). @@ -81,13 +81,13 @@ impl AdiAnalogIn { /// This function is inappropriate for sensor values intended for integration, /// as round-off error can accumulate causing drift over time. /// Use [`Self::calibrated_value_hr`] instead. - pub fn calibrated_value(&self) -> Result { + pub fn calibrated_value(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read_calibrated( self.port.internal_expander_index(), self.port.index(), ) - })) + }) as u16) } /// Reads the calibrated value of an analog input channel with enhanced precision. @@ -104,13 +104,13 @@ impl AdiAnalogIn { /// between two values come out in the wash when integrated over time. /// /// Think of the value as the true value times 16. - pub fn calibrated_value_hr(&self) -> Result { + pub fn calibrated_value_hr(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read_calibrated_HR( self.port.internal_expander_index(), self.port.index(), ) - })) + }) as i16) } } @@ -143,12 +143,12 @@ impl AdiAnalogOut { } /// Sets the output for the Analog Output from 0 (0V) to 4095 (5V). - pub fn set_value(&mut self, value: i32) -> Result<(), AdiError> { + pub fn set_value(&mut self, value: u16) -> Result<(), AdiError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_port_set_value( self.port.internal_expander_index(), self.port.index(), - value, + value as i32, ) }); @@ -162,7 +162,7 @@ impl AdiAnalogOut { /// This function has a precision of `5.0/4095.0` volts, as ADC reports 12-bit voltage data /// on a scale of 0-4095. pub fn set_voltage(&mut self, value: f64) -> Result<(), AdiError> { - self.set_value((value / 5.0 * 4095.0) as i32) + self.set_value((value / 5.0 * 4095.0) as u16) } } diff --git a/packages/pros/src/devices/adi/linetracker.rs b/packages/pros/src/devices/adi/linetracker.rs index 48ba2251..4ba4b884 100644 --- a/packages/pros/src/devices/adi/linetracker.rs +++ b/packages/pros/src/devices/adi/linetracker.rs @@ -54,10 +54,10 @@ impl AdiLineTracker { /// /// This is a raw 12-bit value from [0, 4095] representing the voltage level from /// 0-5V measured by the V5 brain's ADC. - pub fn raw_reflectivity(&self) -> Result { + pub fn raw_reflectivity(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index()) - })) + }) as u16) } } diff --git a/packages/pros/src/devices/adi/ultrasonic.rs b/packages/pros/src/devices/adi/ultrasonic.rs index a0a0b3b4..f8710cfb 100644 --- a/packages/pros/src/devices/adi/ultrasonic.rs +++ b/packages/pros/src/devices/adi/ultrasonic.rs @@ -39,22 +39,13 @@ impl AdiUltrasonic { }) } - /// Get the distance of a surface to the ultrasonic sensor's mounting point - /// in millimeters. + /// Get the distance reading of the ultrasonic sensor in centimeters. /// /// Round and/or fluffy objects can cause inaccurate values to be returned. - pub fn distance(&self) -> Result { - Ok(self.raw_distance()? as f64 / 10.0) - } - - /// Get the raw distance reading of the ultrasonic sensor. This value is returned - /// in 10^-4 * meters, or ten-thousanths of a meter. - /// - /// Round and/or fluffy objects can cause inaccurate values to be returned. - pub fn raw_distance(&self) -> Result { + pub fn distance(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_ultrasonic_get(self.raw) - })) + }) as u16) } } From 3fbeae5e5f853cc5af22c2f1b03763a875248b7f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 21:59:08 -0600 Subject: [PATCH 32/96] fix: return `calibrated_value` as an i16 --- packages/pros/src/devices/adi/analog.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros/src/devices/adi/analog.rs index 3dd67f33..e2318748 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros/src/devices/adi/analog.rs @@ -81,13 +81,13 @@ impl AdiAnalogIn { /// This function is inappropriate for sensor values intended for integration, /// as round-off error can accumulate causing drift over time. /// Use [`Self::calibrated_value_hr`] instead. - pub fn calibrated_value(&self) -> Result { + pub fn calibrated_value(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read_calibrated( self.port.internal_expander_index(), self.port.index(), ) - }) as u16) + }) as i16) } /// Reads the calibrated value of an analog input channel with enhanced precision. From ec23d6e1bf4747c9aa95763728151d833bac6d12 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 22:35:55 -0600 Subject: [PATCH 33/96] Update CHANGELOG.md --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7e7b45f..09229dce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ Before releasing: - Screen drawing API. (#81) - Added screen field to `Peripherals` and `DynamicPeripherals::take_screen` method. (#81) +- Added `AdiSolenoid`, a wrapper over `AdiDigitalOut` for actuating SMC pneumatic solenoids. (#61) +- Added `AdiSwitch`, another `AdiDigitalOut` wrapper that abstracts bumper switches and limit switches. (#61) +- Added `AdiLineTracker` for abstracting the EDR line tracker sensor. ### Fixed @@ -42,6 +45,15 @@ Before releasing: - The VEXOS target has been updated to improve file size and floating point operation speed. (#81) - `Peripherals::new()` is no longer const (**Breaking Change) (#81) - Updated panic handler to print to the brain display as well as over serial (#81) +- Refactors digital and analog ADI input/output. (**Breaking Change**) (#61) + - Adds LogicLevel rather than bools for controlling digital devices. + - Adds 0-5V voltage getters and setters for analog ADI. + - Changed analog getters and setters to use `u16` data. +- Changed `AdiPotentiometer` to return degrees rather than tenth degrees (**Breaking Change**) (#61). + - Renamed `AdiPotentiometer::value` to `AdiPotentiometer::angle`. +- Refactors `AdiMotor` to match the smart motor APIs, having output/raw output getters/setters. +- Renamed `AdiUltrasonic::value` to `AdiUltrasonic::distance` (**Breaking Change**) (#61). +- Renamed `AdiEncoder::value` to `AdiEncoder::position` (**Breaking Change**) (#61). ### Removed @@ -50,6 +62,7 @@ Before releasing: - Re-exported printing macros from `pros::io`. (#82) - Applied several lints to improve code quality. (#70) - Removed the confusingly named `write`, `ewrite`, `writeln`, and `ewriteln` macros. (**Breaking Change**) (#82) +- Removed AdiDigitalIn::new_press, instead swapping it for AdiSwitch::was_pressed. (**Breaking Change**) (#61) ## [0.7.0] From 4f219ef6ccbd1269c6963ea2a5e0e42751ec75a8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 22:38:45 -0600 Subject: [PATCH 34/96] refactor: rename `calibrated_value_hr` to `high_precision_calibrated_value` --- packages/pros/src/devices/adi/analog.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros/src/devices/adi/analog.rs index e2318748..5db2a8f2 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros/src/devices/adi/analog.rs @@ -104,7 +104,7 @@ impl AdiAnalogIn { /// between two values come out in the wash when integrated over time. /// /// Think of the value as the true value times 16. - pub fn calibrated_value_hr(&self) -> Result { + pub fn high_precision_calibrated_value(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read_calibrated_HR( self.port.internal_expander_index(), From 5a5da880f1f326e03de7e53bd670ff68888f2108 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 23:38:56 -0600 Subject: [PATCH 35/96] fix: docs, AnalogOut prelude --- packages/pros/src/devices/adi/analog.rs | 2 +- packages/pros/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros/src/devices/adi/analog.rs index 5db2a8f2..61ef4428 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros/src/devices/adi/analog.rs @@ -80,7 +80,7 @@ impl AdiAnalogIn { /// /// This function is inappropriate for sensor values intended for integration, /// as round-off error can accumulate causing drift over time. - /// Use [`Self::calibrated_value_hr`] instead. + /// Use [`Self::high_precision_calibrated_value`] instead. pub fn calibrated_value(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_analog_read_calibrated( diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 110ad6d3..53f1c306 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -377,7 +377,7 @@ pub mod prelude { color::Rgb, devices::{ adi::{ - analog::AdiAnalogIn, + analog::{AdiAnalogIn, AdiAnalogOut}, digital::{AdiDigitalIn, AdiDigitalOut}, encoder::AdiEncoder, gyro::AdiGyro, From d223905e3bb9f9a072c689e4c47466a01513d881 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 11 Feb 2024 23:41:15 -0600 Subject: [PATCH 36/96] docs: add missing docs for adi ports --- packages/pros/src/devices/smart/expander.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs index 105e16d1..8fc3f8c6 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros/src/devices/smart/expander.rs @@ -10,14 +10,23 @@ use crate::devices::adi::AdiPort; /// be partially moved out of this struct to create devices. #[derive(Debug, Eq, PartialEq)] pub struct AdiExpander { + /// ADI port A on the expander. pub adi_a: AdiPort, + /// ADI port B on the expander. pub adi_b: AdiPort, + /// ADI Port C on the expander. pub adi_c: AdiPort, + /// ADI Port D on the expander. pub adi_d: AdiPort, + /// ADI Port E on the expander. pub adi_e: AdiPort, + /// ADI Port F on the expander. pub adi_f: AdiPort, + /// ADI Port G on the expander. pub adi_g: AdiPort, + /// ADI Port H on the expander. pub adi_h: AdiPort, + port: SmartPort, } From 5fdf09206d33828ec32db5ed32f8fe8de5f0be73 Mon Sep 17 00:00:00 2001 From: Gavin <94215019+Gavin-Niederman@users.noreply.github.com> Date: Sun, 11 Feb 2024 22:12:22 -0800 Subject: [PATCH 37/96] docs: add ADI expander module docs --- packages/pros/src/devices/smart/expander.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs index 8fc3f8c6..d794a5f7 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros/src/devices/smart/expander.rs @@ -1,3 +1,9 @@ +//! ADI expander module support. +//! +//! The ADI expander API is similar to that of [`Peripherals`]. +//! A main difference between the two is that ADI expanders can be created safely without returning an option. +//! This is because they require a [`SmartPort`] to be created which can only be created without either peripherals struct unsafely. + use super::{SmartDevice, SmartDeviceType, SmartPort}; use crate::devices::adi::AdiPort; From 17aac44fa737d66560aa328997d1322def4c3037 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 12 Feb 2024 06:18:31 -0800 Subject: [PATCH 38/96] chore: format --- packages/pros/src/devices/smart/expander.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros/src/devices/smart/expander.rs index d794a5f7..3ea2ef3a 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros/src/devices/smart/expander.rs @@ -1,4 +1,4 @@ -//! ADI expander module support. +//! ADI expander module support. //! //! The ADI expander API is similar to that of [`Peripherals`]. //! A main difference between the two is that ADI expanders can be created safely without returning an option. From fa53d848409f10bacd46f5a1914332edb9c97dbf Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:47:31 -0600 Subject: [PATCH 39/96] refactor: fix config setters, actually wrap base devices --- packages/pros/src/devices/adi/analog.rs | 66 ++++---------------- packages/pros/src/devices/adi/digital.rs | 24 +++++-- packages/pros/src/devices/adi/gyro.rs | 2 +- packages/pros/src/devices/adi/linetracker.rs | 26 +++----- packages/pros/src/devices/adi/mod.rs | 13 +++- packages/pros/src/devices/adi/motor.rs | 2 +- packages/pros/src/devices/adi/pwm.rs | 58 +++++++++++++++++ packages/pros/src/devices/adi/solenoid.rs | 42 +++++-------- packages/pros/src/devices/adi/switch.rs | 36 +++++------ packages/pros/src/lib.rs | 3 +- 10 files changed, 146 insertions(+), 126 deletions(-) create mode 100644 packages/pros/src/devices/adi/pwm.rs diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros/src/devices/adi/analog.rs index 61ef4428..3107dd8b 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros/src/devices/adi/analog.rs @@ -1,4 +1,4 @@ -//! Analog input and output ADI devices. +//! ADI Analog Interfaces //! //! # Overview //! @@ -21,8 +21,16 @@ pub struct AdiAnalogIn { impl AdiAnalogIn { /// Create a analog input from an ADI port. - pub const fn new(port: AdiPort) -> Self { - Self { port } + pub fn new(port: AdiPort) -> Result { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_config( + port.internal_expander_index(), + port.index(), + pros_sys::E_ADI_ANALOG_IN, + ) + }); + + Ok(Self { port }) } /// Calibrates the analog sensor on the specified channel. @@ -129,55 +137,3 @@ impl AdiDevice for AdiAnalogIn { AdiDeviceType::AnalogIn } } - -/// Generic analog output ADI device. -#[derive(Debug, Eq, PartialEq)] -pub struct AdiAnalogOut { - port: AdiPort, -} - -impl AdiAnalogOut { - /// Create a analog output from an [`AdiPort`]. - pub const fn new(port: AdiPort) -> Self { - Self { port } - } - - /// Sets the output for the Analog Output from 0 (0V) to 4095 (5V). - pub fn set_value(&mut self, value: u16) -> Result<(), AdiError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_port_set_value( - self.port.internal_expander_index(), - self.port.index(), - value as i32, - ) - }); - - Ok(()) - } - - /// Sets the output for the Analog Output from 0V to (5V). - /// - /// # Precision - /// - /// This function has a precision of `5.0/4095.0` volts, as ADC reports 12-bit voltage data - /// on a scale of 0-4095. - pub fn set_voltage(&mut self, value: f64) -> Result<(), AdiError> { - self.set_value((value / 5.0 * 4095.0) as u16) - } -} - -impl AdiDevice for AdiAnalogOut { - type PortIndexOutput = u8; - - fn port_index(&self) -> Self::PortIndexOutput { - self.port.index() - } - - fn expander_port_index(&self) -> Option { - self.port.expander_index() - } - - fn device_type(&self) -> AdiDeviceType { - AdiDeviceType::AnalogOut - } -} diff --git a/packages/pros/src/devices/adi/digital.rs b/packages/pros/src/devices/adi/digital.rs index 4d36630c..e695a4ce 100644 --- a/packages/pros/src/devices/adi/digital.rs +++ b/packages/pros/src/devices/adi/digital.rs @@ -61,8 +61,16 @@ pub struct AdiDigitalIn { impl AdiDigitalIn { /// Create a digital input from an ADI port. - pub const fn new(port: AdiPort) -> Self { - Self { port } + pub fn new(port: AdiPort) -> Result { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_config( + port.internal_expander_index(), + port.index(), + pros_sys::E_ADI_DIGITAL_IN, + ) + }); + + Ok(Self { port }) } /// Gets the current logic level of a digital input pin. @@ -112,8 +120,16 @@ pub struct AdiDigitalOut { impl AdiDigitalOut { /// Create a digital output from an [`AdiPort`]. - pub const fn new(port: AdiPort) -> Self { - Self { port } + pub fn new(port: AdiPort) -> Result { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_config( + port.internal_expander_index(), + port.index(), + pros_sys::E_ADI_DIGITAL_OUT, + ) + }); + + Ok(Self { port }) } /// Sets the digital logic level (high or low) of a pin. diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros/src/devices/adi/gyro.rs index 9ef00108..02281f3b 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros/src/devices/adi/gyro.rs @@ -17,7 +17,7 @@ pub const GYRO_CALIBRATION_TIME: Duration = Duration::from_millis(1300); #[derive(Debug, Eq, PartialEq)] pub struct AdiGyro { raw: ext_adi_gyro_t, - port: AdiPort, + pub(crate) port: AdiPort, } impl AdiGyro { diff --git a/packages/pros/src/devices/adi/linetracker.rs b/packages/pros/src/devices/adi/linetracker.rs index 4ba4b884..200f1975 100644 --- a/packages/pros/src/devices/adi/linetracker.rs +++ b/packages/pros/src/devices/adi/linetracker.rs @@ -23,31 +23,27 @@ //! between 1/8 and 1/4 of an inch away from the surface it is measuring. It is also important //! to keep lighting in the room consistent, so sensors' readings remain accurate. -use pros_sys::PROS_ERR; - -use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use super::{AdiAnalogIn, AdiDevice, AdiDeviceType, AdiError, AdiPort}; /// Analog line tracker device. #[derive(Debug, Eq, PartialEq)] pub struct AdiLineTracker { - port: AdiPort, + analog_in: AdiAnalogIn, } impl AdiLineTracker { /// Create a line tracker on an ADI port. - pub const fn new(port: AdiPort) -> Self { - Self { port } + pub fn new(port: AdiPort) -> Result { + Ok(Self { + analog_in: AdiAnalogIn::new(port)?, + }) } /// Get the reflectivity factor measured by the sensor. /// /// This is returned as a value ranging from [0.0, 1.0]. pub fn reflectivity(&self) -> Result { - Ok(bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index()) - }) as f64 - / 4095.0) + Ok(self.analog_in.value()? as f64 / 4095.0) } /// Get the raw reflectivity factor of the sensor. @@ -55,9 +51,7 @@ impl AdiLineTracker { /// This is a raw 12-bit value from [0, 4095] representing the voltage level from /// 0-5V measured by the V5 brain's ADC. pub fn raw_reflectivity(&self) -> Result { - Ok(bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index()) - }) as u16) + self.analog_in.value() } } @@ -65,11 +59,11 @@ impl AdiDevice for AdiLineTracker { type PortIndexOutput = u8; fn port_index(&self) -> Self::PortIndexOutput { - self.port.index() + self.analog_in.port_index() } fn expander_port_index(&self) -> Option { - self.port.expander_index() + self.analog_in.expander_port_index() } fn device_type(&self) -> AdiDeviceType { diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros/src/devices/adi/mod.rs index 5c845b1f..f934eada 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros/src/devices/adi/mod.rs @@ -8,6 +8,7 @@ use crate::error::{bail_on, map_errno, PortError}; //TODO: much more in depth module documentation for device modules as well as this module. pub mod analog; pub mod digital; +pub mod pwm; pub mod encoder; pub mod gyro; @@ -111,21 +112,31 @@ pub trait AdiDevice { pub enum AdiDeviceType { /// Generic analog input. AnalogIn = pros_sys::adi::E_ADI_ANALOG_IN, + /// Generic analog output. + /// + /// This doesn't actually emit analog signals from the ADI pins; it's + /// just PWM output. AnalogOut = pros_sys::adi::E_ADI_ANALOG_OUT, + /// Generic digital input. DigitalIn = pros_sys::adi::E_ADI_DIGITAL_IN, + /// Generic digital output. DigitalOut = pros_sys::adi::E_ADI_DIGITAL_OUT, - /// Cortex-era gyro. + /// Cortex-era yaw-rate gyroscope. LegacyGyro = pros_sys::adi::E_ADI_LEGACY_GYRO, + /// Cortex-era servo motor. LegacyServo = pros_sys::adi::E_ADI_LEGACY_SERVO, + /// PWM output. LegacyPwm = pros_sys::adi::E_ADI_LEGACY_PWM, + /// Cortex-era encoder. LegacyEncoder = pros_sys::E_ADI_LEGACY_ENCODER, + /// Cortex-era ultrasonic sensor. LegacyUltrasonic = pros_sys::E_ADI_LEGACY_ULTRASONIC, } diff --git a/packages/pros/src/devices/adi/motor.rs b/packages/pros/src/devices/adi/motor.rs index 9eb20fd8..3abd256e 100644 --- a/packages/pros/src/devices/adi/motor.rs +++ b/packages/pros/src/devices/adi/motor.rs @@ -8,7 +8,7 @@ use crate::error::bail_on; #[derive(Debug, Eq, PartialEq)] /// Cortex era motor device. pub struct AdiMotor { - port: AdiPort, + pub(crate) port: AdiPort, } impl AdiMotor { diff --git a/packages/pros/src/devices/adi/pwm.rs b/packages/pros/src/devices/adi/pwm.rs new file mode 100644 index 00000000..2da33ad6 --- /dev/null +++ b/packages/pros/src/devices/adi/pwm.rs @@ -0,0 +1,58 @@ +//! ADI Pulse-width modulation (PWM). + +use pros_sys::PROS_ERR; + +use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; +use crate::error::bail_on; + +/// Generic PWM output ADI device. +#[derive(Debug, Eq, PartialEq)] +pub struct AdiPwmOut { + port: AdiPort, +} + +impl AdiPwmOut { + /// Create a pwm output from an [`AdiPort`]. + pub fn new(port: AdiPort) -> Result { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_config( + port.internal_expander_index(), + port.index(), + pros_sys::E_ADI_ANALOG_OUT, + ) + }); + + Ok(Self { port }) + } + + /// Sets the PWM output from 0 (0V) to 4095 (5V). + pub fn set_value(&mut self, value: u8) -> Result<(), AdiError> { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_value( + self.port.internal_expander_index(), + self.port.index(), + value as i32, + ) + }); + + Ok(()) + } +} + +impl AdiDevice for AdiPwmOut { + type PortIndexOutput = u8; + + fn port_index(&self) -> Self::PortIndexOutput { + self.port.index() + } + + fn expander_port_index(&self) -> Option { + self.port.expander_index() + } + + fn device_type(&self) -> AdiDeviceType { + // This could be either AnalogOut or LegacyPwm, they + // have seemingly equivalent behavior. + AdiDeviceType::AnalogOut + } +} diff --git a/packages/pros/src/devices/adi/solenoid.rs b/packages/pros/src/devices/adi/solenoid.rs index 1447aa63..139d084c 100644 --- a/packages/pros/src/devices/adi/solenoid.rs +++ b/packages/pros/src/devices/adi/solenoid.rs @@ -1,39 +1,29 @@ //! ADI Solenoid Pneumatic Control -use pros_sys::PROS_ERR; - -use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiDigitalOut, AdiError, AdiPort}; /// Digital pneumatic solenoid valve. #[derive(Debug, Eq, PartialEq)] pub struct AdiSolenoid { - port: AdiPort, + digital_out: AdiDigitalOut, level: LogicLevel, } impl AdiSolenoid { /// Create an AdiSolenoid. - pub const fn new(port: AdiPort) -> Self { - Self { - port, + pub fn new(port: AdiPort) -> Result { + Ok(Self { + digital_out: AdiDigitalOut::new(port)?, level: LogicLevel::Low, - } + }) } /// Sets the digital logic level of the solenoid. [`LogicLevel::Low`] will close the solenoid, /// and [`LogicLevel::High`] will open it. pub fn set_level(&mut self, level: LogicLevel) -> Result<(), AdiError> { + self.digital_out.set_level(level)?; self.level = level; - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_digital_write( - self.port.internal_expander_index(), - self.port.index(), - level.is_high(), - ) - }); - Ok(()) } @@ -43,18 +33,18 @@ impl AdiSolenoid { } /// Returns `true` if the solenoid is open. - pub const fn is_open(&self) -> LogicLevel { - self.level + pub const fn is_open(&self) -> bool { + self.level.is_high() } /// Returns `true` if the solenoid is closed. - pub const fn is_closed(&self) -> LogicLevel { - self.level + pub const fn is_closed(&self) -> bool { + self.level.is_low() } /// Open the solenoid, allowing air pressure through the "open" valve. pub fn open(&mut self) -> Result<(), AdiError> { - self.set_level(LogicLevel::High) + self.digital_out.set_level(LogicLevel::High) } /// Close the solenoid. @@ -64,12 +54,12 @@ impl AdiSolenoid { /// - On double-acting solenoids (e.g. SYJ3120-SMO-M3-F), this will block air pressure through /// the "open" valve and allow air pressure into the "close" valve. pub fn close(&mut self) -> Result<(), AdiError> { - self.set_level(LogicLevel::Low) + self.digital_out.set_level(LogicLevel::Low) } /// Toggle the solenoid's state between open and closed. pub fn toggle(&mut self) -> Result<(), AdiError> { - self.set_level(!self.level) + self.digital_out.set_level(!self.level) } } @@ -77,11 +67,11 @@ impl AdiDevice for AdiSolenoid { type PortIndexOutput = u8; fn port_index(&self) -> Self::PortIndexOutput { - self.port.index() + self.digital_out.port_index() } fn expander_port_index(&self) -> Option { - self.port.expander_index() + self.digital_out.expander_port_index() } fn device_type(&self) -> AdiDeviceType { diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros/src/devices/adi/switch.rs index 5de703a4..781909df 100644 --- a/packages/pros/src/devices/adi/switch.rs +++ b/packages/pros/src/devices/adi/switch.rs @@ -8,32 +8,27 @@ use crate::error::bail_on; /// Generic digital input ADI device. #[derive(Debug, Eq, PartialEq)] pub struct AdiSwitch { - port: AdiPort, + digital_in: AdiDigitalIn, } impl AdiSwitch { - /// Create a digital input from an ADI port. - pub const fn new(port: AdiPort) -> Self { - Self { port } + /// Create a digital switch from an ADI port. + pub fn new(port: AdiPort) -> Result { + Ok(Self { + digital_in: AdiDigitalIn::new(port)?, + }) } /// Gets the current logic level of a digital switch. pub fn level(&self) -> Result { - let value = bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_digital_read(self.port.internal_expander_index(), self.port.index()) - }) != 0; - - Ok(match value { - true => LogicLevel::High, - false => LogicLevel::Low, - }) + self.digital_in.level() } /// Returrns `true` if the switch is currently being pressed. /// /// This is equivalent shorthand to calling `Self::level().is_high()`. pub fn is_pressed(&self) -> Result { - Ok(self.level()?.is_high()) + self.digital_in.is_high() } /// Returns `true` if the switch has been pressed again since the last time this @@ -52,18 +47,17 @@ impl AdiSwitch { pub fn was_pressed(&mut self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_digital_get_new_press( - self.port.internal_expander_index(), - self.port.index(), + self.digital_in.expander_port_index() + .unwrap_or(pros_sys::adi::INTERNAL_ADI_PORT as u8), + self.digital_in.port_index(), ) }) != 0) } } impl From for AdiSwitch { - fn from(device: AdiDigitalIn) -> Self { - Self { - port: unsafe { AdiPort::new(device.port_index(), device.expander_port_index()) }, - } + fn from(digital_in: AdiDigitalIn) -> Self { + Self { digital_in } } } @@ -71,11 +65,11 @@ impl AdiDevice for AdiSwitch { type PortIndexOutput = u8; fn port_index(&self) -> Self::PortIndexOutput { - self.port.index() + self.digital_in.port_index() } fn expander_port_index(&self) -> Option { - self.port.expander_index() + self.digital_in.expander_port_index() } fn device_type(&self) -> AdiDeviceType { diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 53f1c306..f634fd10 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -377,12 +377,13 @@ pub mod prelude { color::Rgb, devices::{ adi::{ - analog::{AdiAnalogIn, AdiAnalogOut}, + analog::AdiAnalogIn, digital::{AdiDigitalIn, AdiDigitalOut}, encoder::AdiEncoder, gyro::AdiGyro, motor::AdiMotor, potentiometer::{AdiPotentiometer, AdiPotentiometerType}, + pwm::AdiPwmOut, solenoid::AdiSolenoid, ultrasonic::AdiUltrasonic, AdiDevice, AdiPort, From c5e4212605259555db10a3587b0c13e647ba5bc8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:49:57 -0600 Subject: [PATCH 40/96] docs: typo --- packages/pros/src/devices/adi/switch.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros/src/devices/adi/switch.rs index 781909df..e691b30e 100644 --- a/packages/pros/src/devices/adi/switch.rs +++ b/packages/pros/src/devices/adi/switch.rs @@ -24,7 +24,7 @@ impl AdiSwitch { self.digital_in.level() } - /// Returrns `true` if the switch is currently being pressed. + /// Returns `true` if the switch is currently being pressed. /// /// This is equivalent shorthand to calling `Self::level().is_high()`. pub fn is_pressed(&self) -> Result { @@ -47,7 +47,8 @@ impl AdiSwitch { pub fn was_pressed(&mut self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_digital_get_new_press( - self.digital_in.expander_port_index() + self.digital_in + .expander_port_index() .unwrap_or(pros_sys::adi::INTERNAL_ADI_PORT as u8), self.digital_in.port_index(), ) From a03ce3f62e8dfb4ffabb6f70529b829e132b1d65 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Mon, 12 Feb 2024 22:02:44 -0600 Subject: [PATCH 41/96] remove leftover pub(crate) --- packages/pros/src/devices/adi/gyro.rs | 2 +- packages/pros/src/devices/adi/motor.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros/src/devices/adi/gyro.rs index 02281f3b..9ef00108 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros/src/devices/adi/gyro.rs @@ -17,7 +17,7 @@ pub const GYRO_CALIBRATION_TIME: Duration = Duration::from_millis(1300); #[derive(Debug, Eq, PartialEq)] pub struct AdiGyro { raw: ext_adi_gyro_t, - pub(crate) port: AdiPort, + port: AdiPort, } impl AdiGyro { diff --git a/packages/pros/src/devices/adi/motor.rs b/packages/pros/src/devices/adi/motor.rs index 3abd256e..9eb20fd8 100644 --- a/packages/pros/src/devices/adi/motor.rs +++ b/packages/pros/src/devices/adi/motor.rs @@ -8,7 +8,7 @@ use crate::error::bail_on; #[derive(Debug, Eq, PartialEq)] /// Cortex era motor device. pub struct AdiMotor { - pub(crate) port: AdiPort, + port: AdiPort, } impl AdiMotor { From 9df9b5d99ab3baa712127d43b4f9b7a51967dc34 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:13:10 -0600 Subject: [PATCH 42/96] remove device conversions for now --- packages/pros/src/devices/adi/switch.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros/src/devices/adi/switch.rs index e691b30e..3ea1dbf7 100644 --- a/packages/pros/src/devices/adi/switch.rs +++ b/packages/pros/src/devices/adi/switch.rs @@ -56,12 +56,6 @@ impl AdiSwitch { } } -impl From for AdiSwitch { - fn from(digital_in: AdiDigitalIn) -> Self { - Self { digital_in } - } -} - impl AdiDevice for AdiSwitch { type PortIndexOutput = u8; From dadb8db9786b10306bb9ca27fd58452d2dd49acb Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:34:23 -0600 Subject: [PATCH 43/96] refactor: revert wrapper change --- packages/pros/src/devices/adi/linetracker.rs | 32 +++++++++---- packages/pros/src/devices/adi/solenoid.rs | 44 ++++++++++++------ packages/pros/src/devices/adi/switch.rs | 47 ++++++++++++++------ 3 files changed, 87 insertions(+), 36 deletions(-) diff --git a/packages/pros/src/devices/adi/linetracker.rs b/packages/pros/src/devices/adi/linetracker.rs index 200f1975..3f677779 100644 --- a/packages/pros/src/devices/adi/linetracker.rs +++ b/packages/pros/src/devices/adi/linetracker.rs @@ -23,27 +23,39 @@ //! between 1/8 and 1/4 of an inch away from the surface it is measuring. It is also important //! to keep lighting in the room consistent, so sensors' readings remain accurate. -use super::{AdiAnalogIn, AdiDevice, AdiDeviceType, AdiError, AdiPort}; +use pros_sys::PROS_ERR; + +use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; +use crate::error::bail_on; /// Analog line tracker device. #[derive(Debug, Eq, PartialEq)] pub struct AdiLineTracker { - analog_in: AdiAnalogIn, + port: AdiPort, } impl AdiLineTracker { /// Create a line tracker on an ADI port. pub fn new(port: AdiPort) -> Result { - Ok(Self { - analog_in: AdiAnalogIn::new(port)?, - }) + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_config( + port.internal_expander_index(), + port.index(), + pros_sys::E_ADI_ANALOG_IN, + ) + }); + + Ok(Self { port }) } /// Get the reflectivity factor measured by the sensor. /// /// This is returned as a value ranging from [0.0, 1.0]. pub fn reflectivity(&self) -> Result { - Ok(self.analog_in.value()? as f64 / 4095.0) + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index()) + }) as f64 + / 4095.0) } /// Get the raw reflectivity factor of the sensor. @@ -51,7 +63,9 @@ impl AdiLineTracker { /// This is a raw 12-bit value from [0, 4095] representing the voltage level from /// 0-5V measured by the V5 brain's ADC. pub fn raw_reflectivity(&self) -> Result { - self.analog_in.value() + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_analog_read(self.port.internal_expander_index(), self.port.index()) + }) as u16) } } @@ -59,11 +73,11 @@ impl AdiDevice for AdiLineTracker { type PortIndexOutput = u8; fn port_index(&self) -> Self::PortIndexOutput { - self.analog_in.port_index() + self.port.index() } fn expander_port_index(&self) -> Option { - self.analog_in.expander_port_index() + self.port.expander_index() } fn device_type(&self) -> AdiDeviceType { diff --git a/packages/pros/src/devices/adi/solenoid.rs b/packages/pros/src/devices/adi/solenoid.rs index 139d084c..d6152a51 100644 --- a/packages/pros/src/devices/adi/solenoid.rs +++ b/packages/pros/src/devices/adi/solenoid.rs @@ -1,19 +1,30 @@ //! ADI Solenoid Pneumatic Control -use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiDigitalOut, AdiError, AdiPort}; +use pros_sys::PROS_ERR; + +use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiError, AdiPort}; +use crate::error::bail_on; /// Digital pneumatic solenoid valve. #[derive(Debug, Eq, PartialEq)] pub struct AdiSolenoid { - digital_out: AdiDigitalOut, + port: AdiPort, level: LogicLevel, } impl AdiSolenoid { /// Create an AdiSolenoid. pub fn new(port: AdiPort) -> Result { + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_config( + port.internal_expander_index(), + port.index(), + pros_sys::E_ADI_DIGITAL_OUT, + ) + }); + Ok(Self { - digital_out: AdiDigitalOut::new(port)?, + port, level: LogicLevel::Low, }) } @@ -21,9 +32,16 @@ impl AdiSolenoid { /// Sets the digital logic level of the solenoid. [`LogicLevel::Low`] will close the solenoid, /// and [`LogicLevel::High`] will open it. pub fn set_level(&mut self, level: LogicLevel) -> Result<(), AdiError> { - self.digital_out.set_level(level)?; self.level = level; + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_digital_write( + self.port.internal_expander_index(), + self.port.index(), + level.is_high(), + ) + }); + Ok(()) } @@ -33,18 +51,18 @@ impl AdiSolenoid { } /// Returns `true` if the solenoid is open. - pub const fn is_open(&self) -> bool { - self.level.is_high() + pub const fn is_open(&self) -> LogicLevel { + self.level } /// Returns `true` if the solenoid is closed. - pub const fn is_closed(&self) -> bool { - self.level.is_low() + pub const fn is_closed(&self) -> LogicLevel { + self.level } /// Open the solenoid, allowing air pressure through the "open" valve. pub fn open(&mut self) -> Result<(), AdiError> { - self.digital_out.set_level(LogicLevel::High) + self.set_level(LogicLevel::High) } /// Close the solenoid. @@ -54,12 +72,12 @@ impl AdiSolenoid { /// - On double-acting solenoids (e.g. SYJ3120-SMO-M3-F), this will block air pressure through /// the "open" valve and allow air pressure into the "close" valve. pub fn close(&mut self) -> Result<(), AdiError> { - self.digital_out.set_level(LogicLevel::Low) + self.set_level(LogicLevel::Low) } /// Toggle the solenoid's state between open and closed. pub fn toggle(&mut self) -> Result<(), AdiError> { - self.digital_out.set_level(!self.level) + self.set_level(!self.level) } } @@ -67,11 +85,11 @@ impl AdiDevice for AdiSolenoid { type PortIndexOutput = u8; fn port_index(&self) -> Self::PortIndexOutput { - self.digital_out.port_index() + self.port.index() } fn expander_port_index(&self) -> Option { - self.digital_out.expander_port_index() + self.port.expander_index() } fn device_type(&self) -> AdiDeviceType { diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros/src/devices/adi/switch.rs index 3ea1dbf7..15d824ac 100644 --- a/packages/pros/src/devices/adi/switch.rs +++ b/packages/pros/src/devices/adi/switch.rs @@ -8,27 +8,40 @@ use crate::error::bail_on; /// Generic digital input ADI device. #[derive(Debug, Eq, PartialEq)] pub struct AdiSwitch { - digital_in: AdiDigitalIn, + port: AdiPort, } impl AdiSwitch { - /// Create a digital switch from an ADI port. + /// Create a digital input from an ADI port. pub fn new(port: AdiPort) -> Result { - Ok(Self { - digital_in: AdiDigitalIn::new(port)?, - }) + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_port_set_config( + port.internal_expander_index(), + port.index(), + pros_sys::E_ADI_DIGITAL_IN, + ) + }); + + Ok(Self { port }) } /// Gets the current logic level of a digital switch. pub fn level(&self) -> Result { - self.digital_in.level() + let value = bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_digital_read(self.port.internal_expander_index(), self.port.index()) + }) != 0; + + Ok(match value { + true => LogicLevel::High, + false => LogicLevel::Low, + }) } - /// Returns `true` if the switch is currently being pressed. + /// Returrns `true` if the switch is currently being pressed. /// /// This is equivalent shorthand to calling `Self::level().is_high()`. pub fn is_pressed(&self) -> Result { - self.digital_in.is_high() + Ok(self.level()?.is_high()) } /// Returns `true` if the switch has been pressed again since the last time this @@ -47,24 +60,30 @@ impl AdiSwitch { pub fn was_pressed(&mut self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_digital_get_new_press( - self.digital_in - .expander_port_index() - .unwrap_or(pros_sys::adi::INTERNAL_ADI_PORT as u8), - self.digital_in.port_index(), + self.port.internal_expander_index(), + self.port.index(), ) }) != 0) } } +impl From for AdiSwitch { + fn from(device: AdiDigitalIn) -> Self { + Self { + port: unsafe { AdiPort::new(device.port_index(), device.expander_port_index()) }, + } + } +} + impl AdiDevice for AdiSwitch { type PortIndexOutput = u8; fn port_index(&self) -> Self::PortIndexOutput { - self.digital_in.port_index() + self.port.index() } fn expander_port_index(&self) -> Option { - self.digital_in.expander_port_index() + self.port.expander_index() } fn device_type(&self) -> AdiDeviceType { From 3f6ac079841a843c75c8c819b1d9648e736e6579 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:37:35 -0600 Subject: [PATCH 44/96] docs: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09229dce..acaeac1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ Before releasing: - Refactors `AdiMotor` to match the smart motor APIs, having output/raw output getters/setters. - Renamed `AdiUltrasonic::value` to `AdiUltrasonic::distance` (**Breaking Change**) (#61). - Renamed `AdiEncoder::value` to `AdiEncoder::position` (**Breaking Change**) (#61). +- Repurposed `AdiAnalogOut` as `AdiPwmOut` to correct match port output. (**Breaking Change**) (#90). ### Removed From 292df31b8c1bebb5461045419279636c2d143633 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Wed, 14 Feb 2024 07:38:27 -0600 Subject: [PATCH 45/96] refactor: PWM Output --- packages/pros/src/devices/adi/mod.rs | 16 ++++++++++------ packages/pros/src/devices/adi/pwm.rs | 11 ++++++----- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros/src/devices/adi/mod.rs index f934eada..6eff690a 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros/src/devices/adi/mod.rs @@ -113,11 +113,11 @@ pub enum AdiDeviceType { /// Generic analog input. AnalogIn = pros_sys::adi::E_ADI_ANALOG_IN, - /// Generic analog output. + /// Generic PWM output. /// - /// This doesn't actually emit analog signals from the ADI pins; it's - /// just PWM output. - AnalogOut = pros_sys::adi::E_ADI_ANALOG_OUT, + /// This is actually equivalent `pros_sys::adi::E_ADI_ANALOG_OUT`, which is a misnomer. + /// "Analog Out" in reality outputs an 8-bit PWM value. + PwmOut = pros_sys::adi::E_ADI_ANALOG_OUT, /// Generic digital input. DigitalIn = pros_sys::adi::E_ADI_DIGITAL_IN, @@ -131,7 +131,11 @@ pub enum AdiDeviceType { /// Cortex-era servo motor. LegacyServo = pros_sys::adi::E_ADI_LEGACY_SERVO, - /// PWM output. + /// MC29 Controller Output + /// + /// This differs from [`Self::PwmOut`] in that it is specifically designed for controlling + /// legacy ADI motors. Rather than taking a u8 for output, it takes a i8 allowing negative + /// values to be sent for controlling motors in reverse with a nicer API. LegacyPwm = pros_sys::adi::E_ADI_LEGACY_PWM, /// Cortex-era encoder. @@ -149,7 +153,7 @@ impl TryFrom for AdiDeviceType { match value { pros_sys::E_ADI_ANALOG_IN => Ok(AdiDeviceType::AnalogIn), - pros_sys::E_ADI_ANALOG_OUT => Ok(AdiDeviceType::AnalogOut), + pros_sys::E_ADI_ANALOG_OUT => Ok(AdiDeviceType::PwmOut), pros_sys::E_ADI_DIGITAL_IN => Ok(AdiDeviceType::DigitalIn), pros_sys::E_ADI_DIGITAL_OUT => Ok(AdiDeviceType::DigitalOut), diff --git a/packages/pros/src/devices/adi/pwm.rs b/packages/pros/src/devices/adi/pwm.rs index 2da33ad6..d1556533 100644 --- a/packages/pros/src/devices/adi/pwm.rs +++ b/packages/pros/src/devices/adi/pwm.rs @@ -25,8 +25,11 @@ impl AdiPwmOut { Ok(Self { port }) } - /// Sets the PWM output from 0 (0V) to 4095 (5V). - pub fn set_value(&mut self, value: u8) -> Result<(), AdiError> { + /// Sets the PWM output width. + /// + /// This value is sent over 16ms periods with pulse widths ranging from roughly + /// 0.94mS to 2.03mS. + pub fn set_output(&mut self, value: u8) -> Result<(), AdiError> { bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_port_set_value( self.port.internal_expander_index(), @@ -51,8 +54,6 @@ impl AdiDevice for AdiPwmOut { } fn device_type(&self) -> AdiDeviceType { - // This could be either AnalogOut or LegacyPwm, they - // have seemingly equivalent behavior. - AdiDeviceType::AnalogOut + AdiDeviceType::PwmOut } } From fcfc612ba8f5526f2c92a8a2734a5df77299a1b4 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Wed, 14 Feb 2024 21:54:14 -0800 Subject: [PATCH 46/96] fix: avoid overflowing multiplications in draw_buffer --- packages/pros/src/devices/screen.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/pros/src/devices/screen.rs b/packages/pros/src/devices/screen.rs index 34413e7e..776b2837 100644 --- a/packages/pros/src/devices/screen.rs +++ b/packages/pros/src/devices/screen.rs @@ -459,7 +459,8 @@ impl Screen { .into_iter() .map(|i| i.into_rgb().into()) .collect::>(); - let expected_size = ((x1 - x0) * (y1 - y0)) as usize; + // Convert the coordinates to u32 to avoid overflows when multiplying. + let expected_size = ((x1 - x0) as u32 * (y1 - y0) as u32) as usize; if raw_buf.len() != expected_size { return Err(ScreenError::CopyBufferWrongSize { buffer_size: raw_buf.len(), From 478f85533e7d6f0757e46e78531afc2559eed11b Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Wed, 14 Feb 2024 21:58:01 -0800 Subject: [PATCH 47/96] docs: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 121a965b..2220f5e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -92,6 +92,7 @@ Before releasing: - Fixed Missing ERRNO and ADI config variants in pros-sys (#55) - Fixed incorrect error handling with `InertialSensor::status`. (#65) - `Controller::status` now handles errors by returning `Result`. (**Breaking Change**) (#74) +- Fixed a multiplication overflow in `screen::draw_buffer`. (#92) ### Changed From 1ac7a3ded48745bcb082654ce50a7c7daade28fe Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Wed, 14 Feb 2024 22:02:00 -0800 Subject: [PATCH 48/96] revert: take fix out of changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2220f5e8..121a965b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -92,7 +92,6 @@ Before releasing: - Fixed Missing ERRNO and ADI config variants in pros-sys (#55) - Fixed incorrect error handling with `InertialSensor::status`. (#65) - `Controller::status` now handles errors by returning `Result`. (**Breaking Change**) (#74) -- Fixed a multiplication overflow in `screen::draw_buffer`. (#92) ### Changed From ef31c62415472d7f2f8768a2543db1dcd479ca2a Mon Sep 17 00:00:00 2001 From: Johan Novak Date: Tue, 27 Feb 2024 21:43:56 -0800 Subject: [PATCH 49/96] fix: AsyncRobot shouldn't only run opcontrol --- packages/pros/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 50acce59..8f501810 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -209,7 +209,7 @@ macro_rules! __gen_async_exports { #[doc(hidden)] #[no_mangle] extern "C" fn autonomous() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe { + $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::auto(unsafe { ROBOT .as_mut() .expect("Expected initialize to run before auto") @@ -220,7 +220,7 @@ macro_rules! __gen_async_exports { #[doc(hidden)] #[no_mangle] extern "C" fn disabled() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe { + $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::disabled(unsafe { ROBOT .as_mut() .expect("Expected initialize to run before disabled") @@ -231,7 +231,7 @@ macro_rules! __gen_async_exports { #[doc(hidden)] #[no_mangle] extern "C" fn competition_initialize() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe { + $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::comp_init(unsafe { ROBOT .as_mut() .expect("Expected initialize to run before comp_init") From 5fd6360530c107807be34a1ed4911621c796adb2 Mon Sep 17 00:00:00 2001 From: Johan Novak Date: Tue, 27 Feb 2024 21:44:43 -0800 Subject: [PATCH 50/96] chore: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 121a965b..ca82973d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Before releasing: ### Fixed - Fix error handling and error type variats in ADI bindings +- Fix `AsynRobot` only running opcontrol ### Changed From 162e3c46158aa5fa7d27b8c7717008a14ca67f6a Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 29 Feb 2024 20:58:14 -0600 Subject: [PATCH 51/96] fix: handle EADDRINUSE --- packages/pros/src/error.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/pros/src/error.rs b/packages/pros/src/error.rs index c619f01d..4d0dd7bb 100644 --- a/packages/pros/src/error.rs +++ b/packages/pros/src/error.rs @@ -97,9 +97,12 @@ pub enum PortError { PortOutOfRange, /// The specified port couldn't be configured as the specified type. PortCannotBeConfigured, + /// The specified port is already being used or is mismatched. + AlreadyInUse, } map_errno!(PortError { ENXIO => Self::PortOutOfRange, ENODEV => Self::PortCannotBeConfigured, + EADDRINUSE => Self::AlreadyInUse, }); From d62e6678c32f2811709bd030e67c38ab540dd649 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:02:42 -0600 Subject: [PATCH 52/96] docs: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca82973d..b8693765 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ Before releasing: - Fix error handling and error type variats in ADI bindings - Fix `AsynRobot` only running opcontrol +- Properly handle `EADDRINUSE` return for smart port errors (**Breaking Change**) (#97) ### Changed From 4263c049e4e04b8df76e61e33c129411a6cdd3e0 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:17:58 -0600 Subject: [PATCH 53/96] refactor: move device constants into associated impl --- packages/pros/src/devices/adi/gyro.rs | 12 ++++---- packages/pros/src/devices/screen.rs | 34 ++++++++++++---------- packages/pros/src/devices/smart/imu.rs | 17 ++++++----- packages/pros/src/devices/smart/optical.rs | 21 ++++++------- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros/src/devices/adi/gyro.rs index 9ef00108..632a6c47 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros/src/devices/adi/gyro.rs @@ -7,12 +7,6 @@ use pros_sys::{ext_adi_gyro_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; use crate::error::bail_on; -/// The time it takes to calibrate an [`AdiGyro`]. -/// -/// The theoretical calibration time is 1024ms, but in practice this seemed to be the -/// actual time that it takes. -pub const GYRO_CALIBRATION_TIME: Duration = Duration::from_millis(1300); - /// ADI gyro device. #[derive(Debug, Eq, PartialEq)] pub struct AdiGyro { @@ -21,6 +15,12 @@ pub struct AdiGyro { } impl AdiGyro { + /// The time it takes to calibrate an [`AdiGyro`]. + /// + /// The theoretical calibration time is 1024ms, but in practice this seemed to be the + /// actual time that it takes. + pub const CALIBRATION_TIME: Duration = Duration::from_millis(1300); + /// Create a new gyro from an [`AdiPort`]. /// /// If the given port has not previously been configured as a gyro, then this diff --git a/packages/pros/src/devices/screen.rs b/packages/pros/src/devices/screen.rs index 776b2837..4346392e 100644 --- a/packages/pros/src/devices/screen.rs +++ b/packages/pros/src/devices/screen.rs @@ -20,22 +20,12 @@ pub struct Screen { current_line: i16, } -/// The maximum number of lines that can be visible on the screen at once. -pub const SCREEN_MAX_VISIBLE_LINES: usize = 12; -/// The height of a single line of text on the screen. -pub const SCREEN_LINE_HEIGHT: i16 = 20; - -/// The horizontal resolution of the display. -pub const SCREEN_HORIZONTAL_RESOLUTION: i16 = 480; -/// The vertical resolution of the writable part of the display. -pub const SCREEN_VERTICAL_RESOLUTION: i16 = 240; - impl core::fmt::Write for Screen { fn write_str(&mut self, text: &str) -> core::fmt::Result { for character in text.chars() { if character == '\n' { - if self.current_line > (SCREEN_MAX_VISIBLE_LINES as i16 - 2) { - self.scroll(0, SCREEN_LINE_HEIGHT) + if self.current_line > (Self::MAX_VISIBLE_LINES as i16 - 2) { + self.scroll(0, Self::LINE_HEIGHT) .map_err(|_| core::fmt::Error)?; } else { self.current_line += 1; @@ -344,6 +334,18 @@ impl From for pros_sys::last_touch_e_t { } impl Screen { + /// The maximum number of lines that can be visible on the screen at once. + pub const MAX_VISIBLE_LINES: usize = 12; + + /// The height of a single line of text on the screen. + pub const LINE_HEIGHT: i16 = 20; + + /// The horizontal resolution of the display. + pub const HORIZONTAL_RESOLUTION: i16 = 480; + + /// The vertical resolution of the writable part of the display. + pub const VERTICAL_RESOLUTION: i16 = 240; + /// Create a new screen. /// /// # Safety @@ -488,8 +490,8 @@ impl Screen { let error_box_rect = Rect::new( ERROR_BOX_MARGIN, ERROR_BOX_MARGIN, - SCREEN_HORIZONTAL_RESOLUTION - ERROR_BOX_MARGIN, - SCREEN_VERTICAL_RESOLUTION - ERROR_BOX_MARGIN, + Self::HORIZONTAL_RESOLUTION - ERROR_BOX_MARGIN, + Self::VERTICAL_RESOLUTION - ERROR_BOX_MARGIN, ); self.fill(&error_box_rect, Rgb::RED)?; @@ -509,7 +511,7 @@ impl Screen { buffer.as_str(), TextPosition::Point( ERROR_BOX_MARGIN + ERROR_BOX_PADDING, - ERROR_BOX_MARGIN + ERROR_BOX_PADDING + (line * SCREEN_LINE_HEIGHT), + ERROR_BOX_MARGIN + ERROR_BOX_PADDING + (line * Self::LINE_HEIGHT), ), TextFormat::Small, ), @@ -526,7 +528,7 @@ impl Screen { buffer.as_str(), TextPosition::Point( ERROR_BOX_MARGIN + ERROR_BOX_PADDING, - ERROR_BOX_MARGIN + ERROR_BOX_PADDING + (line * SCREEN_LINE_HEIGHT), + ERROR_BOX_MARGIN + ERROR_BOX_PADDING + (line * Self::LINE_HEIGHT), ), TextFormat::Small, ), diff --git a/packages/pros/src/devices/smart/imu.rs b/packages/pros/src/devices/smart/imu.rs index 0b6b4f9c..519d5a75 100644 --- a/packages/pros/src/devices/smart/imu.rs +++ b/packages/pros/src/devices/smart/imu.rs @@ -15,11 +15,6 @@ use crate::{ time::Instant, }; -/// The timeout for the IMU to calibrate. -pub const IMU_RESET_TIMEOUT: Duration = Duration::from_secs(3); -/// The minimum data rate that you can set an IMU to. -pub const IMU_MIN_DATA_RATE: Duration = Duration::from_millis(5); - /// Represents a smart port configured as a V5 inertial sensor (IMU) #[derive(Debug, Eq, PartialEq)] pub struct InertialSensor { @@ -27,6 +22,12 @@ pub struct InertialSensor { } impl InertialSensor { + /// The timeout for the IMU to calibrate. + pub const CALIBRATION_TIMEOUT: Duration = Duration::from_secs(3); + + /// The minimum data rate that you can set an IMU to. + pub const MIN_DATA_RATE: Duration = Duration::from_millis(5); + /// Create a new inertial sensor from a smart port index. pub const fn new(port: SmartPort) -> Self { Self { port } @@ -237,10 +238,10 @@ impl InertialSensor { /// Sets the update rate of the IMU. /// - /// This duration must be above [`IMU_MIN_DATA_RATE`] (5 milliseconds). + /// This duration must be above [`Self::MIN_DATA_RATE`] (5 milliseconds). pub fn set_data_rate(&mut self, data_rate: Duration) -> Result<(), InertialError> { unsafe { - let rate_ms = if data_rate > IMU_MIN_DATA_RATE { + let rate_ms = if data_rate > Self::MIN_DATA_RATE { if let Ok(rate) = u32::try_from(data_rate.as_millis()) { rate } else { @@ -431,7 +432,7 @@ impl core::future::Future for InertialCalibrateFuture { if !is_calibrating { return Poll::Ready(Ok(())); - } else if timestamp.elapsed() > IMU_RESET_TIMEOUT { + } else if timestamp.elapsed() > InertialSensor::CALIBRATION_TIMEOUT { return Poll::Ready(Err(InertialError::CalibrationTimedOut)); } diff --git a/packages/pros/src/devices/smart/optical.rs b/packages/pros/src/devices/smart/optical.rs index c80d9387..fe700ab6 100644 --- a/packages/pros/src/devices/smart/optical.rs +++ b/packages/pros/src/devices/smart/optical.rs @@ -8,14 +8,6 @@ use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; use crate::error::{bail_on, map_errno, PortError}; -/// The smallest integration time you can set on an optical sensor. -pub const MIN_INTEGRATION_TIME: Duration = Duration::from_millis(3); -/// The largest integration time you can set on an optical sensor. -pub const MAX_INTEGRATION_TIME: Duration = Duration::from_millis(712); - -/// The maximum value for the LED PWM. -pub const MAX_LED_PWM: u8 = 100; - /// Represents a smart port configured as a V5 optical sensor #[derive(Debug, Eq, PartialEq)] pub struct OpticalSensor { @@ -24,6 +16,15 @@ pub struct OpticalSensor { } impl OpticalSensor { + /// The smallest integration time you can set on an optical sensor. + pub const MIN_INTEGRATION_TIME: Duration = Duration::from_millis(3); + + /// The largest integration time you can set on an optical sensor. + pub const MAX_INTEGRATION_TIME: Duration = Duration::from_millis(712); + + /// The maximum value for the LED PWM. + pub const MAX_LED_PWM: u8 = 100; + /// Creates a new inertial sensor from a smart port index. /// /// Gesture detection features can be optionally enabled, allowing the use of [`Self::last_gesture_direction()`] and [`Self::last_gesture_direction()`]. @@ -54,7 +55,7 @@ impl OpticalSensor { /// Sets the pwm value of the White LED. Valid values are in the range `0` `100`. pub fn set_led_pwm(&mut self, value: u8) -> Result<(), OpticalError> { - if value > MAX_LED_PWM { + if value > Self::MAX_LED_PWM { return Err(OpticalError::InvalidLedPwm); } unsafe { @@ -86,7 +87,7 @@ impl OpticalSensor { /// https://www.vexforum.com/t/v5-optical-sensor-refresh-rate/109632/9 for /// more information. pub fn set_integration_time(&mut self, time: Duration) -> Result<(), OpticalError> { - if time < MIN_INTEGRATION_TIME || time > MAX_INTEGRATION_TIME { + if time < Self::MIN_INTEGRATION_TIME || time > Self::MAX_INTEGRATION_TIME { return Err(OpticalError::InvalidIntegrationTime); } From 38ecca9caf018cefc08d2254cc989d5181b19521 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:20:05 -0600 Subject: [PATCH 54/96] docs: changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca82973d..57b7d21e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,8 @@ Before releasing: - Renamed `AdiUltrasonic::value` to `AdiUltrasonic::distance` (**Breaking Change**) (#61). - Renamed `AdiEncoder::value` to `AdiEncoder::position` (**Breaking Change**) (#61). - Repurposed `AdiAnalogOut` as `AdiPwmOut` to correct match port output. (**Breaking Change**) (#90). +- Moved most device-related constants into their associated struct `impl` (**Breaking Change**) (#98). +- Renamed IMU_RESET_TIMEOUT to `InertialSensor::CALIBRATION_TIMEOUT` (**Breaking Change**) (#98). ### Removed From d6844889572cac3ac8d1ee7f545d0d12680601c5 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 4 Feb 2024 02:00:41 -0800 Subject: [PATCH 55/96] refactor: split pros-rs into multiple smaller subcrates --- packages/pros-async/Cargo.toml | 14 + .../src/async_runtime/executor.rs | 2 +- .../src/async_runtime/mod.rs | 0 .../src/async_runtime/reactor.rs | 0 packages/pros-async/src/lib.rs | 182 ++++++++ packages/pros-core/Cargo.toml | 17 + .../{pros => pros-core}/src/competition.rs | 2 +- packages/{pros => pros-core}/src/error.rs | 11 +- .../print_impl.rs => pros-core/src/io/mod.rs} | 18 +- packages/pros-core/src/lib.rs | 9 + packages/pros-core/src/pros_alloc/mod.rs | 4 + .../src/pros_alloc/vexos.rs} | 0 .../src/pros_alloc/wasm.rs} | 5 - packages/{pros => pros-core}/src/time.rs | 0 packages/pros-devices/Cargo.toml | 15 + .../src}/adi/analog.rs | 2 +- .../src}/adi/digital.rs | 2 +- .../src}/adi/encoder.rs | 2 +- .../devices => pros-devices/src}/adi/gyro.rs | 2 +- .../src}/adi/linetracker.rs | 2 +- .../devices => pros-devices/src}/adi/mod.rs | 5 +- .../devices => pros-devices/src}/adi/motor.rs | 2 +- .../src}/adi/potentiometer.rs | 2 +- .../devices => pros-devices/src}/adi/pwm.rs | 0 .../src}/adi/solenoid.rs | 2 +- .../src}/adi/switch.rs | 2 +- .../src}/adi/ultrasonic.rs | 2 +- .../devices => pros-devices/src}/battery.rs | 3 +- packages/{pros => pros-devices}/src/color.rs | 0 .../src}/controller.rs | 3 +- .../mod.rs => pros-devices/src/lib.rs} | 7 + .../src}/peripherals.rs | 2 +- .../devices => pros-devices/src}/position.rs | 0 .../devices => pros-devices/src}/screen.rs | 8 +- .../src}/smart/distance.rs | 2 +- .../src}/smart/expander.rs | 2 +- .../devices => pros-devices/src}/smart/gps.rs | 2 +- .../devices => pros-devices/src}/smart/imu.rs | 10 +- .../src}/smart/link.rs | 4 +- .../devices => pros-devices/src}/smart/mod.rs | 3 +- .../src}/smart/motor.rs | 8 +- .../src}/smart/optical.rs | 2 +- .../src}/smart/rotation.rs | 6 +- .../src}/smart/vision.rs | 6 +- packages/{pros => pros-devices}/src/usd.rs | 0 packages/pros-math/Cargo.toml | 9 + packages/pros-math/src/lib.rs | 4 + packages/{pros => pros-math}/src/pid.rs | 0 packages/pros-panic/Cargo.toml | 17 + .../src/panic.rs => pros-panic/src/lib.rs} | 19 +- packages/pros-sync/Cargo.toml | 15 + packages/pros-sync/src/lib.rs | 143 +++++++ packages/{pros => pros-sync}/src/sync.rs | 2 +- .../{pros => pros-sync}/src/task/local.rs | 0 packages/{pros => pros-sync}/src/task/mod.rs | 42 +- packages/pros/Cargo.toml | 32 +- packages/pros/examples/basic.rs | 2 +- packages/pros/src/feedforward.rs | 59 --- packages/pros/src/io/mod.rs | 7 - packages/pros/src/lib.rs | 397 +++--------------- 60 files changed, 588 insertions(+), 532 deletions(-) create mode 100644 packages/pros-async/Cargo.toml rename packages/{pros => pros-async}/src/async_runtime/executor.rs (98%) rename packages/{pros => pros-async}/src/async_runtime/mod.rs (100%) rename packages/{pros => pros-async}/src/async_runtime/reactor.rs (100%) create mode 100644 packages/pros-async/src/lib.rs create mode 100644 packages/pros-core/Cargo.toml rename packages/{pros => pros-core}/src/competition.rs (99%) rename packages/{pros => pros-core}/src/error.rs (93%) rename packages/{pros/src/io/print_impl.rs => pros-core/src/io/mod.rs} (92%) create mode 100644 packages/pros-core/src/lib.rs create mode 100644 packages/pros-core/src/pros_alloc/mod.rs rename packages/{pros/src/vexos_env.rs => pros-core/src/pros_alloc/vexos.rs} (100%) rename packages/{pros/src/wasm_env.rs => pros-core/src/pros_alloc/wasm.rs} (91%) rename packages/{pros => pros-core}/src/time.rs (100%) create mode 100644 packages/pros-devices/Cargo.toml rename packages/{pros/src/devices => pros-devices/src}/adi/analog.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/adi/digital.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/adi/encoder.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/adi/gyro.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/adi/linetracker.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/adi/mod.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/adi/motor.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/adi/potentiometer.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/adi/pwm.rs (100%) rename packages/{pros/src/devices => pros-devices/src}/adi/solenoid.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/adi/switch.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/adi/ultrasonic.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/battery.rs (96%) rename packages/{pros => pros-devices}/src/color.rs (100%) rename packages/{pros/src/devices => pros-devices/src}/controller.rs (99%) rename packages/{pros/src/devices/mod.rs => pros-devices/src/lib.rs} (91%) rename packages/{pros/src/devices => pros-devices/src}/peripherals.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/position.rs (100%) rename packages/{pros/src/devices => pros-devices/src}/screen.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/smart/distance.rs (97%) rename packages/{pros/src/devices => pros-devices/src}/smart/expander.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/smart/gps.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/smart/imu.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/smart/link.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/smart/mod.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/smart/motor.rs (98%) rename packages/{pros/src/devices => pros-devices/src}/smart/optical.rs (99%) rename packages/{pros/src/devices => pros-devices/src}/smart/rotation.rs (97%) rename packages/{pros/src/devices => pros-devices/src}/smart/vision.rs (98%) rename packages/{pros => pros-devices}/src/usd.rs (100%) create mode 100644 packages/pros-math/Cargo.toml create mode 100644 packages/pros-math/src/lib.rs rename packages/{pros => pros-math}/src/pid.rs (100%) create mode 100644 packages/pros-panic/Cargo.toml rename packages/{pros/src/panic.rs => pros-panic/src/lib.rs} (68%) create mode 100644 packages/pros-sync/Cargo.toml create mode 100644 packages/pros-sync/src/lib.rs rename packages/{pros => pros-sync}/src/sync.rs (99%) rename packages/{pros => pros-sync}/src/task/local.rs (100%) rename packages/{pros => pros-sync}/src/task/mod.rs (90%) delete mode 100644 packages/pros/src/feedforward.rs delete mode 100644 packages/pros/src/io/mod.rs diff --git a/packages/pros-async/Cargo.toml b/packages/pros-async/Cargo.toml new file mode 100644 index 00000000..7e5d3e73 --- /dev/null +++ b/packages/pros-async/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "pros-async" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +futures = { version = "0.3.28", default-features = false, features = ["alloc"] } +async-task = { version = "4.5.0", default-features = false } +pros-core = { version = "0.1.0", path = "../pros-core" } +waker-fn = "1.1.1" +pros-sys = { version = "0.6.0", path = "../pros-sys" } +pros-sync = { version = "0.1.0", path = "../pros-sync" } diff --git a/packages/pros/src/async_runtime/executor.rs b/packages/pros-async/src/async_runtime/executor.rs similarity index 98% rename from packages/pros/src/async_runtime/executor.rs rename to packages/pros-async/src/async_runtime/executor.rs index 24cfef37..8db68da6 100644 --- a/packages/pros/src/async_runtime/executor.rs +++ b/packages/pros-async/src/async_runtime/executor.rs @@ -9,10 +9,10 @@ use core::{ }; use async_task::{Runnable, Task}; +use pros_sync::{os_task_local, task::delay}; use waker_fn::waker_fn; use super::reactor::Reactor; -use crate::{os_task_local, task::delay}; os_task_local! { pub(crate) static EXECUTOR: Executor = Executor::new(); diff --git a/packages/pros/src/async_runtime/mod.rs b/packages/pros-async/src/async_runtime/mod.rs similarity index 100% rename from packages/pros/src/async_runtime/mod.rs rename to packages/pros-async/src/async_runtime/mod.rs diff --git a/packages/pros/src/async_runtime/reactor.rs b/packages/pros-async/src/async_runtime/reactor.rs similarity index 100% rename from packages/pros/src/async_runtime/reactor.rs rename to packages/pros-async/src/async_runtime/reactor.rs diff --git a/packages/pros-async/src/lib.rs b/packages/pros-async/src/lib.rs new file mode 100644 index 00000000..a65e47cd --- /dev/null +++ b/packages/pros-async/src/lib.rs @@ -0,0 +1,182 @@ +#![no_std] +#![feature(negative_impls)] +extern crate alloc; + +pub mod async_runtime; + +use core::{future::Future, task::Poll}; + +use async_runtime::executor::EXECUTOR; +use pros_core::error::Result; + +/// A future that will complete after the given duration. +/// Sleep futures that are closer to completion are prioritized to improve accuracy. +#[derive(Debug)] +pub struct SleepFuture { + target_millis: u32, +} +impl Future for SleepFuture { + type Output = (); + + fn poll( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll { + if self.target_millis < unsafe { pros_sys::millis() } { + Poll::Ready(()) + } else { + EXECUTOR.with(|e| { + e.reactor + .borrow_mut() + .sleepers + .push(cx.waker().clone(), self.target_millis) + }); + Poll::Pending + } + } +} + +/// Returns a future that will complete after the given duration. +pub fn sleep(duration: core::time::Duration) -> SleepFuture { + SleepFuture { + target_millis: unsafe { pros_sys::millis() + duration.as_millis() as u32 }, + } +} + +/// A trait for robot code that spins up the pros-rs async executor. +/// This is the preferred trait to run robot code. +pub trait AsyncRobot { + /// Runs during the operator control period. + /// This function may be called more than once. + /// For that reason, do not use [`Peripherals::take`](prelude::Peripherals::take) in this function. + fn opcontrol(&mut self) -> impl Future { + async { Ok(()) } + } + /// Runs during the autonomous period. + fn auto(&mut self) -> impl Future { + async { Ok(()) } + } + /// Runs continuously during the disabled period. + fn disabled(&mut self) -> impl Future { + async { Ok(()) } + } + /// Runs once when the competition system is initialized. + fn comp_init(&mut self) -> impl Future { + async { Ok(()) } + } +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __gen_async_exports { + ($rbt:ty) => { + pub static mut ROBOT: Option<$rbt> = None; + + #[doc(hidden)] + #[no_mangle] + extern "C" fn opcontrol() { + $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe { + ROBOT + .as_mut() + .expect("Expected initialize to run before opcontrol") + })) + .unwrap(); + } + + #[doc(hidden)] + #[no_mangle] + extern "C" fn autonomous() { + $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::auto(unsafe { + ROBOT + .as_mut() + .expect("Expected initialize to run before auto") + })) + .unwrap(); + } + + #[doc(hidden)] + #[no_mangle] + extern "C" fn disabled() { + $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::disabled(unsafe { + ROBOT + .as_mut() + .expect("Expected initialize to run before disabled") + })) + .unwrap(); + } + + #[doc(hidden)] + #[no_mangle] + extern "C" fn competition_initialize() { + $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::comp_init(unsafe { + ROBOT + .as_mut() + .expect("Expected initialize to run before comp_init") + })) + .unwrap(); + } + }; +} + +/// Allows your async robot code to be executed by the pros kernel. +/// If your robot struct implements Default then you can just supply this macro with its type. +/// If not, you can supply an expression that returns your robot type to initialize your robot struct. +/// The code that runs to create your robot struct will run in the initialize function in PROS. +/// +/// Example of using the macro with a struct that implements Default: +/// ```rust +/// use pros::prelude::*; +/// #[derive(Default)] +/// struct ExampleRobot; +/// #[async_trait] +/// impl AsyncRobot for ExampleRobot { +/// asnyc fn opcontrol(&mut self) -> pros::Result { +/// println!("Hello, world!"); +/// Ok(()) +/// } +/// } +/// async_robot!(ExampleRobot); +/// ``` +/// +/// Example of using the macro with a struct that does not implement Default: +/// ```rust +/// use pros::prelude::*; +/// struct ExampleRobot { +/// x: i32, +/// } +/// #[async_trait] +/// impl AsyncRobot for ExampleRobot { +/// async fn opcontrol(&mut self) -> pros::Result { +/// println!("Hello, world! {}", self.x); +/// Ok(()) +/// } +/// } +/// impl ExampleRobot { +/// pub fn new() -> Self { +/// Self { x: 5 } +/// } +/// } +/// async_robot!(ExampleRobot, ExampleRobot::new()); +#[macro_export] +macro_rules! async_robot { + ($rbt:ty) => { + $crate::__gen_async_exports!($rbt); + + #[no_mangle] + extern "C" fn initialize() { + unsafe { + ROBOT = Some(Default::default()); + } + } + }; + ($rbt:ty, $init:expr) => { + $crate::__gen_async_exports!($rbt); + + #[no_mangle] + extern "C" fn initialize() { + unsafe { + ROBOT = Some($init); + } + } + }; +} diff --git a/packages/pros-core/Cargo.toml b/packages/pros-core/Cargo.toml new file mode 100644 index 00000000..712f7e04 --- /dev/null +++ b/packages/pros-core/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "pros-core" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +pros-sys = { version = "0.6.0", path = "../pros-sys" } +no_std_io = { version = "0.6.0", features = ["alloc"] } +snafu = { version = "0.8.0", default-features = false, features = [ + "rust_1_61", + "unstable-core-error", +] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +dlmalloc = { version = "0.2.4", features = ["global"] } diff --git a/packages/pros/src/competition.rs b/packages/pros-core/src/competition.rs similarity index 99% rename from packages/pros/src/competition.rs rename to packages/pros-core/src/competition.rs index 7c006d1e..089b830b 100644 --- a/packages/pros/src/competition.rs +++ b/packages/pros-core/src/competition.rs @@ -1,5 +1,5 @@ //! Utilities for getting what state of the competition the robot is in. -//! + use pros_sys::misc::{COMPETITION_AUTONOMOUS, COMPETITION_CONNECTED, COMPETITION_DISABLED}; // TODO: change this to use PROS' internal version once we switch to PROS 4. diff --git a/packages/pros/src/error.rs b/packages/pros-core/src/error.rs similarity index 93% rename from packages/pros/src/error.rs rename to packages/pros-core/src/error.rs index 4d0dd7bb..2cf9065d 100644 --- a/packages/pros/src/error.rs +++ b/packages/pros-core/src/error.rs @@ -5,7 +5,10 @@ //! //! Most of the contents of this file are not public. -pub(crate) fn take_errno() -> i32 { +/// A result type that makes returning errors easier. +pub type Result = core::result::Result>; + +pub fn take_errno() -> i32 { let err = unsafe { *pros_sys::__errno() }; if err != 0 { unsafe { *pros_sys::__errno() = 0 }; @@ -24,6 +27,7 @@ pub(crate) fn take_errno() -> i32 { /// inherit PortError; /// } /// ``` +#[macro_export] macro_rules! map_errno { { $err_ty:ty { $($errno:pat => $err:expr),*$(,)? } @@ -49,9 +53,9 @@ macro_rules! map_errno { } } } -pub(crate) use map_errno; /// If errno has an error, return early. +#[macro_export] macro_rules! bail_errno { () => {{ let errno = $crate::error::take_errno(); @@ -62,10 +66,10 @@ macro_rules! bail_errno { } }}; } -pub(crate) use bail_errno; /// Checks if the value is equal to the error state, and if it is, /// uses the value of errno to create an error and return early. +#[macro_export] macro_rules! bail_on { ($err_state:expr, $val:expr) => {{ let val = $val; @@ -79,7 +83,6 @@ macro_rules! bail_on { val }}; } -pub(crate) use bail_on; use snafu::Snafu; /// A trait for converting an errno value into an error type. diff --git a/packages/pros/src/io/print_impl.rs b/packages/pros-core/src/io/mod.rs similarity index 92% rename from packages/pros/src/io/print_impl.rs rename to packages/pros-core/src/io/mod.rs index 6932b9f6..5ac209e4 100644 --- a/packages/pros/src/io/print_impl.rs +++ b/packages/pros-core/src/io/mod.rs @@ -1,3 +1,5 @@ +//! Std-like I/O macros and types for use in pros. +//! //! Implements `println!`, `eprintln!` and `dbg!` on top of the `pros_sys` crate without requiring //! the use of an allocator. (Modified version of `libc_print` crate) //! @@ -9,7 +11,7 @@ //! Exactly as you'd use `println!`, `eprintln!` and `dbg!`. //! //! ```rust -//! # use pros::io::print_impl::*; +//! # use pros::io::*; //! // Use the default ``-prefixed macros: //! # fn test1() //! # { @@ -24,7 +26,7 @@ //! Or you can import aliases to `std` names: //! //! ```rust -//! use pros::io::print_impl::{println, eprintln, dbg}; +//! use pros::io::{println, eprintln, dbg}; //! //! # fn test2() //! # { @@ -36,6 +38,10 @@ //! # } //! ``` +pub use no_std_io::io::*; + +pub use crate::{dbg, eprint, eprintln, print, println}; + // libc_print is licensed under the MIT License: // Copyright (c) 2023 Matt Mastracci and contributors @@ -135,7 +141,7 @@ macro_rules! println { { #[allow(unused_must_use)] { - let mut stm = $crate::io::print_impl::__SerialWriter::new(false); + let mut stm = $crate::io::__SerialWriter::new(false); stm.write_fmt(format_args!($($arg)*)); stm.write_nl(); } @@ -155,7 +161,7 @@ macro_rules! print { { #[allow(unused_must_use)] { - let mut stm = $crate::io::print_impl::__SerialWriter::new(false); + let mut stm = $crate::io::__SerialWriter::new(false); stm.write_fmt(format_args!($($arg)*)); } } @@ -175,7 +181,7 @@ macro_rules! eprintln { { #[allow(unused_must_use)] { - let mut stm = $crate::io::print_impl::__SerialWriter::new(true); + let mut stm = $crate::io::__SerialWriter::new(true); stm.write_fmt(format_args!($($arg)*)); stm.write_nl(); } @@ -195,7 +201,7 @@ macro_rules! eprint { { #[allow(unused_must_use)] { - let mut stm = $crate::io::print_impl::__SerialWriter::new(true); + let mut stm = $crate::io::__SerialWriter::new(true); stm.write_fmt(format_args!($($arg)*)); } } diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs new file mode 100644 index 00000000..b61ed55d --- /dev/null +++ b/packages/pros-core/src/lib.rs @@ -0,0 +1,9 @@ +#![no_std] +#![feature(error_in_core)] +extern crate alloc; + +pub mod pros_alloc; +pub mod error; +pub mod io; +pub mod time; +pub mod competition; diff --git a/packages/pros-core/src/pros_alloc/mod.rs b/packages/pros-core/src/pros_alloc/mod.rs new file mode 100644 index 00000000..7eed7108 --- /dev/null +++ b/packages/pros-core/src/pros_alloc/mod.rs @@ -0,0 +1,4 @@ +#[cfg(target_os = "vexos")] +mod vexos; +#[cfg(target_arch = "wasm32")] +mod wasm; diff --git a/packages/pros/src/vexos_env.rs b/packages/pros-core/src/pros_alloc/vexos.rs similarity index 100% rename from packages/pros/src/vexos_env.rs rename to packages/pros-core/src/pros_alloc/vexos.rs diff --git a/packages/pros/src/wasm_env.rs b/packages/pros-core/src/pros_alloc/wasm.rs similarity index 91% rename from packages/pros/src/wasm_env.rs rename to packages/pros-core/src/pros_alloc/wasm.rs index e9a48d59..5fabbe9f 100644 --- a/packages/pros/src/wasm_env.rs +++ b/packages/pros-core/src/pros_alloc/wasm.rs @@ -12,11 +12,6 @@ use dlmalloc::GlobalDlmalloc; // no multithreading in wasm static mut LAYOUTS: BTreeMap<*mut u8, Layout> = BTreeMap::new(); -extern "C" { - /// Prints a backtrace to the debug console - pub fn sim_log_backtrace(); -} - #[no_mangle] extern "C" fn wasm_memalign(alignment: usize, size: usize) -> *mut u8 { if size == 0 { diff --git a/packages/pros/src/time.rs b/packages/pros-core/src/time.rs similarity index 100% rename from packages/pros/src/time.rs rename to packages/pros-core/src/time.rs diff --git a/packages/pros-devices/Cargo.toml b/packages/pros-devices/Cargo.toml new file mode 100644 index 00000000..c9819c33 --- /dev/null +++ b/packages/pros-devices/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "pros-devices" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +pros-core = { verion = "0.1.0", path = "../pros-core" } +pros-sys = { path = "../pros-sys", version = "0.6.0", features = ["xapi"] } +snafu = { version = "0.8.0", default-features = false, features = [ + "rust_1_61", + "unstable-core-error", +] } +no_std_io = { version = "0.6.0", features = ["alloc"] } diff --git a/packages/pros/src/devices/adi/analog.rs b/packages/pros-devices/src/adi/analog.rs similarity index 99% rename from packages/pros/src/devices/adi/analog.rs rename to packages/pros-devices/src/adi/analog.rs index 3107dd8b..104bbd05 100644 --- a/packages/pros/src/devices/adi/analog.rs +++ b/packages/pros-devices/src/adi/analog.rs @@ -11,7 +11,7 @@ use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; /// Generic analog input ADI device. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/devices/adi/digital.rs b/packages/pros-devices/src/adi/digital.rs similarity index 99% rename from packages/pros/src/devices/adi/digital.rs rename to packages/pros-devices/src/adi/digital.rs index e695a4ce..bf33bcb7 100644 --- a/packages/pros/src/devices/adi/digital.rs +++ b/packages/pros-devices/src/adi/digital.rs @@ -3,7 +3,7 @@ use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; /// Represents the logic level of a digital pin. /// diff --git a/packages/pros/src/devices/adi/encoder.rs b/packages/pros-devices/src/adi/encoder.rs similarity index 98% rename from packages/pros/src/devices/adi/encoder.rs rename to packages/pros-devices/src/adi/encoder.rs index e9f0816a..aa3520eb 100644 --- a/packages/pros/src/devices/adi/encoder.rs +++ b/packages/pros-devices/src/adi/encoder.rs @@ -3,7 +3,7 @@ use pros_sys::{ext_adi_encoder_t, PROS_ERR}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; /// ADI encoder device. /// Requires two adi ports. diff --git a/packages/pros/src/devices/adi/gyro.rs b/packages/pros-devices/src/adi/gyro.rs similarity index 98% rename from packages/pros/src/devices/adi/gyro.rs rename to packages/pros-devices/src/adi/gyro.rs index 632a6c47..d7cae9a5 100644 --- a/packages/pros/src/devices/adi/gyro.rs +++ b/packages/pros-devices/src/adi/gyro.rs @@ -5,7 +5,7 @@ use core::time::Duration; use pros_sys::{ext_adi_gyro_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; /// ADI gyro device. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/devices/adi/linetracker.rs b/packages/pros-devices/src/adi/linetracker.rs similarity index 99% rename from packages/pros/src/devices/adi/linetracker.rs rename to packages/pros-devices/src/adi/linetracker.rs index 3f677779..4a80cdf3 100644 --- a/packages/pros/src/devices/adi/linetracker.rs +++ b/packages/pros-devices/src/adi/linetracker.rs @@ -26,7 +26,7 @@ use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; /// Analog line tracker device. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/devices/adi/mod.rs b/packages/pros-devices/src/adi/mod.rs similarity index 98% rename from packages/pros/src/devices/adi/mod.rs rename to packages/pros-devices/src/adi/mod.rs index 6eff690a..527e2861 100644 --- a/packages/pros/src/devices/adi/mod.rs +++ b/packages/pros-devices/src/adi/mod.rs @@ -1,10 +1,9 @@ //! ADI (Triport) devices on the Vex V5. -use pros_sys::{adi_port_config_e_t, E_ADI_ERR, PROS_ERR}; +use pros_core::{bail_on, map_errno, error::PortError}; +use pros_sys::{adi_port_config_e_t, PROS_ERR, E_ADI_ERR,}; use snafu::Snafu; -use crate::error::{bail_on, map_errno, PortError}; - //TODO: much more in depth module documentation for device modules as well as this module. pub mod analog; pub mod digital; diff --git a/packages/pros/src/devices/adi/motor.rs b/packages/pros-devices/src/adi/motor.rs similarity index 98% rename from packages/pros/src/devices/adi/motor.rs rename to packages/pros-devices/src/adi/motor.rs index 9eb20fd8..ba1ba842 100644 --- a/packages/pros/src/devices/adi/motor.rs +++ b/packages/pros-devices/src/adi/motor.rs @@ -3,7 +3,7 @@ use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; #[derive(Debug, Eq, PartialEq)] /// Cortex era motor device. diff --git a/packages/pros/src/devices/adi/potentiometer.rs b/packages/pros-devices/src/adi/potentiometer.rs similarity index 98% rename from packages/pros/src/devices/adi/potentiometer.rs rename to packages/pros-devices/src/adi/potentiometer.rs index 433d1677..ee0caa13 100644 --- a/packages/pros/src/devices/adi/potentiometer.rs +++ b/packages/pros-devices/src/adi/potentiometer.rs @@ -3,7 +3,7 @@ use pros_sys::{adi_potentiometer_type_e_t, ext_adi_potentiometer_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; #[derive(Debug, Eq, PartialEq)] /// Analog potentiometer ADI device. diff --git a/packages/pros/src/devices/adi/pwm.rs b/packages/pros-devices/src/adi/pwm.rs similarity index 100% rename from packages/pros/src/devices/adi/pwm.rs rename to packages/pros-devices/src/adi/pwm.rs diff --git a/packages/pros/src/devices/adi/solenoid.rs b/packages/pros-devices/src/adi/solenoid.rs similarity index 99% rename from packages/pros/src/devices/adi/solenoid.rs rename to packages/pros-devices/src/adi/solenoid.rs index d6152a51..0856959d 100644 --- a/packages/pros/src/devices/adi/solenoid.rs +++ b/packages/pros-devices/src/adi/solenoid.rs @@ -3,7 +3,7 @@ use pros_sys::PROS_ERR; use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; /// Digital pneumatic solenoid valve. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/devices/adi/switch.rs b/packages/pros-devices/src/adi/switch.rs similarity index 99% rename from packages/pros/src/devices/adi/switch.rs rename to packages/pros-devices/src/adi/switch.rs index 15d824ac..d8e198fa 100644 --- a/packages/pros/src/devices/adi/switch.rs +++ b/packages/pros-devices/src/adi/switch.rs @@ -3,7 +3,7 @@ use pros_sys::PROS_ERR; use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiDigitalIn, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; /// Generic digital input ADI device. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/devices/adi/ultrasonic.rs b/packages/pros-devices/src/adi/ultrasonic.rs similarity index 98% rename from packages/pros/src/devices/adi/ultrasonic.rs rename to packages/pros-devices/src/adi/ultrasonic.rs index f8710cfb..27b74e2a 100644 --- a/packages/pros/src/devices/adi/ultrasonic.rs +++ b/packages/pros-devices/src/adi/ultrasonic.rs @@ -3,7 +3,7 @@ use pros_sys::{ext_adi_ultrasonic_t, PROS_ERR}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; #[derive(Debug, Eq, PartialEq)] /// Adi ultrasonic sensor. diff --git a/packages/pros/src/devices/battery.rs b/packages/pros-devices/src/battery.rs similarity index 96% rename from packages/pros/src/devices/battery.rs rename to packages/pros-devices/src/battery.rs index f209bcef..ebb02ce4 100644 --- a/packages/pros/src/devices/battery.rs +++ b/packages/pros-devices/src/battery.rs @@ -1,10 +1,9 @@ //! Utilites for getting information about the robot's battery. +use pros_core::{bail_on, map_errno}; use pros_sys::{PROS_ERR, PROS_ERR_F}; use snafu::Snafu; -use crate::error::{bail_on, map_errno}; - /// Get the robot's battery capacity. pub fn capacity() -> Result { Ok(bail_on!(PROS_ERR_F, unsafe { diff --git a/packages/pros/src/color.rs b/packages/pros-devices/src/color.rs similarity index 100% rename from packages/pros/src/color.rs rename to packages/pros-devices/src/color.rs diff --git a/packages/pros/src/devices/controller.rs b/packages/pros-devices/src/controller.rs similarity index 99% rename from packages/pros/src/devices/controller.rs rename to packages/pros-devices/src/controller.rs index f3c946de..ba06b0b8 100644 --- a/packages/pros/src/devices/controller.rs +++ b/packages/pros-devices/src/controller.rs @@ -5,11 +5,10 @@ use alloc::{ffi::CString, vec::Vec}; +use pros_core::{bail_on, map_errno}; use pros_sys::{controller_id_e_t, PROS_ERR}; use snafu::Snafu; -use crate::error::{bail_on, map_errno}; - /// Holds whether or not the buttons on the controller are pressed or not #[derive(Default, Debug, Clone, Copy, Eq, PartialEq)] pub struct Buttons { diff --git a/packages/pros/src/devices/mod.rs b/packages/pros-devices/src/lib.rs similarity index 91% rename from packages/pros/src/devices/mod.rs rename to packages/pros-devices/src/lib.rs index 700a576f..ed852c77 100644 --- a/packages/pros/src/devices/mod.rs +++ b/packages/pros-devices/src/lib.rs @@ -17,6 +17,9 @@ //! battery. //! - [`devices::controller`] provides types for interacting with the V5 controller. +#![no_std] +extern crate alloc; + pub mod adi; pub mod smart; @@ -25,6 +28,10 @@ pub mod controller; pub mod peripherals; pub mod position; pub mod screen; +pub mod usd; + +//TODO: find a better place to put this +pub mod color; pub use controller::Controller; pub use position::Position; diff --git a/packages/pros/src/devices/peripherals.rs b/packages/pros-devices/src/peripherals.rs similarity index 99% rename from packages/pros/src/devices/peripherals.rs rename to packages/pros-devices/src/peripherals.rs index 8029845b..8d9733f6 100644 --- a/packages/pros/src/devices/peripherals.rs +++ b/packages/pros-devices/src/peripherals.rs @@ -24,7 +24,7 @@ use core::sync::atomic::AtomicBool; -use crate::devices::{adi::AdiPort, screen::Screen, smart::SmartPort}; +use crate::{adi::AdiPort, screen::Screen, smart::SmartPort}; static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false); diff --git a/packages/pros/src/devices/position.rs b/packages/pros-devices/src/position.rs similarity index 100% rename from packages/pros/src/devices/position.rs rename to packages/pros-devices/src/position.rs diff --git a/packages/pros/src/devices/screen.rs b/packages/pros-devices/src/screen.rs similarity index 99% rename from packages/pros/src/devices/screen.rs rename to packages/pros-devices/src/screen.rs index 4346392e..29b069d9 100644 --- a/packages/pros/src/devices/screen.rs +++ b/packages/pros-devices/src/screen.rs @@ -5,13 +5,11 @@ use alloc::{ffi::CString, string::String, vec::Vec}; +use pros_core::{bail_on, map_errno}; use pros_sys::PROS_ERR; use snafu::Snafu; -use crate::{ - color::{IntoRgb, Rgb}, - error::{bail_on, map_errno}, -}; +use crate::color::{IntoRgb, Rgb}; #[derive(Debug, Eq, PartialEq)] /// Represents the physical display on the V5 Brain. @@ -482,7 +480,7 @@ impl Screen { /// /// This function is internally used by the pros-rs panic handler for displaying /// panic messages graphically before exiting. - pub(crate) fn draw_error(&mut self, msg: &str) -> Result<(), ScreenError> { + pub fn draw_error(&mut self, msg: &str) -> Result<(), ScreenError> { const ERROR_BOX_MARGIN: i16 = 16; const ERROR_BOX_PADDING: i16 = 16; const LINE_MAX_WIDTH: usize = 52; diff --git a/packages/pros/src/devices/smart/distance.rs b/packages/pros-devices/src/smart/distance.rs similarity index 97% rename from packages/pros/src/devices/smart/distance.rs rename to packages/pros-devices/src/smart/distance.rs index c81f606c..6cebcf52 100644 --- a/packages/pros/src/devices/smart/distance.rs +++ b/packages/pros-devices/src/smart/distance.rs @@ -7,7 +7,7 @@ use core::ffi::c_double; use pros_sys::PROS_ERR; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::error::{bail_on, PortError}; +use pros_core::{bail_on, error::PortError}; /// A physical distance sensor plugged into a port. /// Distance sensors can only keep track of one object at a time. diff --git a/packages/pros/src/devices/smart/expander.rs b/packages/pros-devices/src/smart/expander.rs similarity index 98% rename from packages/pros/src/devices/smart/expander.rs rename to packages/pros-devices/src/smart/expander.rs index 3ea2ef3a..df4d26dc 100644 --- a/packages/pros/src/devices/smart/expander.rs +++ b/packages/pros-devices/src/smart/expander.rs @@ -5,7 +5,7 @@ //! This is because they require a [`SmartPort`] to be created which can only be created without either peripherals struct unsafely. use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::devices::adi::AdiPort; +use crate::adi::AdiPort; /// Represents an ADI expander module plugged into a smart port. /// diff --git a/packages/pros/src/devices/smart/gps.rs b/packages/pros-devices/src/smart/gps.rs similarity index 98% rename from packages/pros/src/devices/smart/gps.rs rename to packages/pros-devices/src/smart/gps.rs index 3f3dd2fd..a00cb18d 100644 --- a/packages/pros/src/devices/smart/gps.rs +++ b/packages/pros-devices/src/smart/gps.rs @@ -7,7 +7,7 @@ use pros_sys::{PROS_ERR, PROS_ERR_F}; use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::error::{bail_on, map_errno, PortError}; +use pros_core::{bail_on, map_errno, error::PortError}; //TODO: Figure out what all the units are #[derive(Default, Debug, Clone, Copy, PartialEq)] diff --git a/packages/pros/src/devices/smart/imu.rs b/packages/pros-devices/src/smart/imu.rs similarity index 99% rename from packages/pros/src/devices/smart/imu.rs rename to packages/pros-devices/src/smart/imu.rs index 519d5a75..fb3b367d 100644 --- a/packages/pros/src/devices/smart/imu.rs +++ b/packages/pros-devices/src/smart/imu.rs @@ -6,14 +6,16 @@ use core::{ time::Duration, }; +use pros_core::{ + bail_on, + error::{take_errno, FromErrno, PortError}, + map_errno, + time::Instant, +}; use pros_sys::{PROS_ERR, PROS_ERR_F}; use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::{ - error::{bail_on, map_errno, take_errno, FromErrno, PortError}, - time::Instant, -}; /// Represents a smart port configured as a V5 inertial sensor (IMU) #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/devices/smart/link.rs b/packages/pros-devices/src/smart/link.rs similarity index 98% rename from packages/pros/src/devices/smart/link.rs rename to packages/pros-devices/src/smart/link.rs index 8ea262a9..1a34003c 100644 --- a/packages/pros/src/devices/smart/link.rs +++ b/packages/pros-devices/src/smart/link.rs @@ -7,11 +7,11 @@ use alloc::{ffi::CString, string::String}; use core::ffi::CStr; use no_std_io::io; +use pros_core::{bail_errno, bail_on, map_errno, error::{ FromErrno, PortError }}; use pros_sys::{link_receive, link_transmit, E_LINK_RECEIVER, E_LINK_TRANSMITTER}; use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::error::{bail_errno, bail_on, map_errno, FromErrno, PortError}; /// Types that implement Link can be used to send data to another robot over VEXLink. pub trait Link: SmartDevice { @@ -148,7 +148,7 @@ impl TxLink { match unsafe { link_transmit(self.port.index(), buf.as_ptr().cast(), buf.len() as _) } { PROS_ERR_U32 => { - let errno = crate::error::take_errno(); + let errno = pros_core::error::take_errno(); Err(FromErrno::from_errno(errno) .unwrap_or_else(|| panic!("Unknown errno code {errno}"))) } diff --git a/packages/pros/src/devices/smart/mod.rs b/packages/pros-devices/src/smart/mod.rs similarity index 99% rename from packages/pros/src/devices/smart/mod.rs rename to packages/pros-devices/src/smart/mod.rs index 772c1ebe..eb591769 100644 --- a/packages/pros/src/devices/smart/mod.rs +++ b/packages/pros-devices/src/smart/mod.rs @@ -37,11 +37,10 @@ pub use imu::InertialSensor; pub use link::{Link, RxLink, TxLink}; pub use motor::Motor; pub use optical::OpticalSensor; +use pros_core::{bail_on, error::PortError}; pub use rotation::RotationSensor; pub use vision::VisionSensor; -use crate::{error::bail_on, prelude::PortError}; - /// Defines common functionality shared by all smart port devices. pub trait SmartDevice { /// Get the index of the [`SmartPort`] this device is registered on. diff --git a/packages/pros/src/devices/smart/motor.rs b/packages/pros-devices/src/smart/motor.rs similarity index 98% rename from packages/pros/src/devices/smart/motor.rs rename to packages/pros-devices/src/smart/motor.rs index f5bb9959..8eb8421e 100644 --- a/packages/pros/src/devices/smart/motor.rs +++ b/packages/pros-devices/src/smart/motor.rs @@ -21,14 +21,12 @@ //! } //! ``` +use pros_core::{bail_on, map_errno, error::PortError}; use pros_sys::{PROS_ERR, PROS_ERR_F}; use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::{ - devices::Position, - error::{bail_on, map_errno, PortError}, -}; +use crate::Position; /// The basic motor struct. #[derive(Debug, Eq, PartialEq)] @@ -348,7 +346,7 @@ pub struct MotorStoppedFuture<'a> { } impl<'a> core::future::Future for MotorStoppedFuture<'a> { - type Output = crate::Result; + type Output = pros_core::error::Result; fn poll( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, diff --git a/packages/pros/src/devices/smart/optical.rs b/packages/pros-devices/src/smart/optical.rs similarity index 99% rename from packages/pros/src/devices/smart/optical.rs rename to packages/pros-devices/src/smart/optical.rs index fe700ab6..4ed513ef 100644 --- a/packages/pros/src/devices/smart/optical.rs +++ b/packages/pros-devices/src/smart/optical.rs @@ -6,7 +6,7 @@ use pros_sys::{OPT_GESTURE_ERR, PROS_ERR, PROS_ERR_F}; use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::error::{bail_on, map_errno, PortError}; +use pros_core::{bail_on, map_errno, error::PortError}; /// Represents a smart port configured as a V5 optical sensor #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/devices/smart/rotation.rs b/packages/pros-devices/src/smart/rotation.rs similarity index 97% rename from packages/pros/src/devices/smart/rotation.rs rename to packages/pros-devices/src/smart/rotation.rs index 0be6e772..2988af2a 100644 --- a/packages/pros/src/devices/smart/rotation.rs +++ b/packages/pros-devices/src/smart/rotation.rs @@ -2,13 +2,11 @@ //! //! Rotation sensors operate on the same [`Position`] type as motors to measure rotation. +use pros_core::{bail_on, error::PortError}; use pros_sys::PROS_ERR; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::{ - devices::position::Position, - error::{bail_on, PortError}, -}; +use crate::position::Position; /// A physical rotation sensor plugged into a port. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/devices/smart/vision.rs b/packages/pros-devices/src/smart/vision.rs similarity index 98% rename from packages/pros/src/devices/smart/vision.rs rename to packages/pros-devices/src/smart/vision.rs index f37b8e82..eed7f5b0 100644 --- a/packages/pros/src/devices/smart/vision.rs +++ b/packages/pros-devices/src/smart/vision.rs @@ -5,14 +5,12 @@ extern crate alloc; use alloc::vec::Vec; +use pros_core::{bail_errno, bail_on, map_errno, error::PortError}; use pros_sys::{PROS_ERR, VISION_OBJECT_ERR_SIG}; use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use crate::{ - color::Rgb, - error::{bail_errno, bail_on, map_errno, PortError}, -}; +use crate::color::Rgb; /// Represents a vision sensor plugged into the vex. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/src/usd.rs b/packages/pros-devices/src/usd.rs similarity index 100% rename from packages/pros/src/usd.rs rename to packages/pros-devices/src/usd.rs diff --git a/packages/pros-math/Cargo.toml b/packages/pros-math/Cargo.toml new file mode 100644 index 00000000..a51e24af --- /dev/null +++ b/packages/pros-math/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "pros-math" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +pros-sys = { version = "0.6.0", path = "../pros-sys" } diff --git a/packages/pros-math/src/lib.rs b/packages/pros-math/src/lib.rs new file mode 100644 index 00000000..4e86cbb6 --- /dev/null +++ b/packages/pros-math/src/lib.rs @@ -0,0 +1,4 @@ +#![no_std] +extern crate alloc; + +pub mod pid; diff --git a/packages/pros/src/pid.rs b/packages/pros-math/src/pid.rs similarity index 100% rename from packages/pros/src/pid.rs rename to packages/pros-math/src/pid.rs diff --git a/packages/pros-panic/Cargo.toml b/packages/pros-panic/Cargo.toml new file mode 100644 index 00000000..0e09c218 --- /dev/null +++ b/packages/pros-panic/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "pros-panic" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +pros-core = { version = "0.1.0", path = "../pros-core" } +pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } +pros-sys = { version = "0.6.0", path = "../pros-sys" } +pros-sync = { version = "0.1.0", path = "../pros-sync" } + +[features] +default = ["display_panics"] + +display_panics = ["dep:pros-devices"] diff --git a/packages/pros/src/panic.rs b/packages/pros-panic/src/lib.rs similarity index 68% rename from packages/pros/src/panic.rs rename to packages/pros-panic/src/lib.rs index ebfb9bd4..46f8e350 100644 --- a/packages/pros/src/panic.rs +++ b/packages/pros-panic/src/lib.rs @@ -1,11 +1,17 @@ -//! Panic Handler -//! -//! This module contains the internal `#[panic_handler]` used by pros-rs for -//! dealing with unrecoverable program errors. +#![no_std] +extern crate alloc; use alloc::format; +use pros_core::eprintln; +use pros_sync::task; -use crate::{devices::screen::Screen, io::eprintln, task}; +#[cfg(feature = "display_panics")] +use pros_devices::Screen; + +extern "C" { + /// Prints a backtrace to the debug console + pub fn sim_log_backtrace(); +} #[panic_handler] /// The panic handler for pros-rs. @@ -21,12 +27,13 @@ pub fn panic(info: &core::panic::PanicInfo<'_>) -> ! { eprintln!("{msg}"); unsafe { + #[cfg(feature = "display_panics")] Screen::new().draw_error(&msg).unwrap_or_else(|err| { eprintln!("Failed to draw error message to screen: {err}"); }); #[cfg(target_arch = "wasm32")] - crate::wasm_env::sim_log_backtrace(); + sim_log_backtrace(); pros_sys::exit(1); } diff --git a/packages/pros-sync/Cargo.toml b/packages/pros-sync/Cargo.toml new file mode 100644 index 00000000..578fdfc2 --- /dev/null +++ b/packages/pros-sync/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "pros-sync" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +pros-core = { version = "0.1.0", path = "../pros-core" } +pros-sys = { version = "0.6.0", path = "../pros-sys" } +snafu = { version = "0.8.0", default-features = false, features = [ + "rust_1_61", + "unstable-core-error", +] } +spin = "0.9.8" diff --git a/packages/pros-sync/src/lib.rs b/packages/pros-sync/src/lib.rs new file mode 100644 index 00000000..f98beb0f --- /dev/null +++ b/packages/pros-sync/src/lib.rs @@ -0,0 +1,143 @@ +#![no_std] +extern crate alloc; + +pub mod sync; +pub mod task; + +use pros_core::error::Result; + +/// A trait for robot code that runs without the async executor spun up. +/// This trait isn't recommended. See [`AsyncRobot`] for the preferred trait to run robot code. +pub trait SyncRobot { + /// Runs during the operator control period. + /// This function may be called more than once. + /// For that reason, do not use [`Peripherals::take`](prelude::Peripherals::take) in this function. + fn opcontrol(&mut self) -> Result { + Ok(()) + } + /// Runs during the autonomous period. + fn auto(&mut self) -> Result { + Ok(()) + } + /// Runs continuously during the disabled period. + fn disabled(&mut self) -> Result { + Ok(()) + } + /// Runs once when the competition system is initialized. + fn comp_init(&mut self) -> Result { + Ok(()) + } +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __gen_sync_exports { + ($rbt:ty) => { + pub static mut ROBOT: Option<$rbt> = None; + + #[doc(hidden)] + #[no_mangle] + extern "C" fn opcontrol() { + <$rbt as $crate::SyncRobot>::opcontrol(unsafe { + ROBOT + .as_mut() + .expect("Expected initialize to run before opcontrol") + }) + .unwrap(); + } + + #[doc(hidden)] + #[no_mangle] + extern "C" fn autonomous() { + <$rbt as $crate::SyncRobot>::auto(unsafe { + ROBOT + .as_mut() + .expect("Expected initialize to run before opcontrol") + }) + .unwrap(); + } + + #[doc(hidden)] + #[no_mangle] + extern "C" fn disabled() { + <$rbt as $crate::SyncRobot>::disabled(unsafe { + ROBOT + .as_mut() + .expect("Expected initialize to run before opcontrol") + }) + .unwrap(); + } + + #[doc(hidden)] + #[no_mangle] + extern "C" fn competition_initialize() { + <$rbt as $crate::SyncRobot>::comp_init(unsafe { + ROBOT + .as_mut() + .expect("Expected initialize to run before opcontrol") + }) + .unwrap(); + } + }; +} + +/// Allows your sync robot code to be executed by the pros kernel. +/// If your robot struct implements Default then you can just supply this macro with its type. +/// If not, you can supply an expression that returns your robot type to initialize your robot struct. +/// The code that runs to create your robot struct will run in the initialize function in PROS. +/// +/// Example of using the macro with a struct that implements Default: +/// ```rust +/// use pros::prelude::*; +/// #[derive(Default)] +/// struct ExampleRobot; +/// impl SyncRobot for ExampleRobot { +/// asnyc fn opcontrol(&mut self) -> pros::Result { +/// println!("Hello, world!"); +/// Ok(()) +/// } +/// } +/// sync_robot!(ExampleRobot); +/// ``` +/// +/// Example of using the macro with a struct that does not implement Default: +/// ```rust +/// use pros::prelude::*; +/// struct ExampleRobot { +/// x: i32, +/// } +/// impl SyncRobot for ExampleRobot { +/// async fn opcontrol(&mut self) -> pros::Result { +/// println!("Hello, world! {}", self.x); +/// Ok(()) +/// } +/// } +/// impl ExampleRobot { +/// pub fn new() -> Self { +/// Self { x: 5 } +/// } +/// } +/// sync_robot!(ExampleRobot, ExampleRobot::new()); +#[macro_export] +macro_rules! sync_robot { + ($rbt:ty) => { + $crate::__gen_sync_exports!($rbt); + + #[no_mangle] + extern "C" fn initialize() { + unsafe { + ROBOT = Some(Default::default()); + } + } + }; + ($rbt:ty, $init:expr) => { + $crate::__gen_sync_exports!($rbt); + + #[no_mangle] + extern "C" fn initialize() { + unsafe { + ROBOT = Some($init); + } + } + }; +} diff --git a/packages/pros/src/sync.rs b/packages/pros-sync/src/sync.rs similarity index 99% rename from packages/pros/src/sync.rs rename to packages/pros-sync/src/sync.rs index 7233996e..62afec98 100644 --- a/packages/pros/src/sync.rs +++ b/packages/pros-sync/src/sync.rs @@ -4,7 +4,7 @@ use core::{cell::UnsafeCell, fmt::Debug, mem}; -use crate::error::take_errno; +use pros_core::error::take_errno; /// The basic mutex type. /// Mutexes are used to share variables between tasks safely. diff --git a/packages/pros/src/task/local.rs b/packages/pros-sync/src/task/local.rs similarity index 100% rename from packages/pros/src/task/local.rs rename to packages/pros-sync/src/task/local.rs diff --git a/packages/pros/src/task/mod.rs b/packages/pros-sync/src/task/mod.rs similarity index 90% rename from packages/pros/src/task/mod.rs rename to packages/pros-sync/src/task/mod.rs index b815d868..df11ec25 100644 --- a/packages/pros/src/task/mod.rs +++ b/packages/pros-sync/src/task/mod.rs @@ -23,15 +23,11 @@ use alloc::{ boxed::Box, string::{String, ToString}, }; -use core::{ffi::CStr, future::Future, hash::Hash, str::Utf8Error, task::Poll, time::Duration}; +use core::{ffi::CStr, hash::Hash, str::Utf8Error, time::Duration}; +use pros_core::{bail_on, map_errno}; use snafu::Snafu; -use crate::{ - async_runtime::executor::EXECUTOR, - error::{bail_on, map_errno}, -}; - /// Creates a task to be run 'asynchronously' (More information at the [FreeRTOS docs](https://www.freertos.org/taskandcr.html)). /// Takes in a closure that can move variables if needed. /// If your task has a loop it is advised to use [`sleep(duration)`](sleep) so that the task does not take up necessary system resources. @@ -335,40 +331,6 @@ impl Interval { } } -/// A future that will complete after the given duration. -/// Sleep futures that are closer to completion are prioritized to improve accuracy. -#[derive(Debug)] -pub struct SleepFuture { - target_millis: u32, -} -impl Future for SleepFuture { - type Output = (); - - fn poll( - self: core::pin::Pin<&mut Self>, - cx: &mut core::task::Context<'_>, - ) -> core::task::Poll { - if self.target_millis < unsafe { pros_sys::millis() } { - Poll::Ready(()) - } else { - EXECUTOR.with(|e| { - e.reactor - .borrow_mut() - .sleepers - .push(cx.waker().clone(), self.target_millis) - }); - Poll::Pending - } - } -} - -/// Returns a future that will complete after the given duration. -pub fn sleep(duration: core::time::Duration) -> SleepFuture { - SleepFuture { - target_millis: unsafe { pros_sys::millis() + duration.as_millis() as u32 }, - } -} - /// Returns the task the function was called from. pub fn current() -> TaskHandle { unsafe { diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 702142b2..50d1a550 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -18,17 +18,23 @@ rust-version = "1.75.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -lazy_static = { version = "1.4.0", features = ["spin_no_std"] } -spin = "0.9.8" -pros-sys = { version = "0.6", path = "../pros-sys", features = ["xapi"] } -snafu = { version = "0.8.0", default-features = false, features = [ - "rust_1_61", - "unstable-core-error", -] } -no_std_io = { version = "0.6.0", features = ["alloc"] } -futures = { version = "0.3.28", default-features = false, features = ["alloc"] } -async-task = { version = "4.5.0", default-features = false } -waker-fn = "1.1.1" +pros-sync = { version = "0.1.0", path = "../pros-sync", optional = true } +pros-async = { version = "0.1.0", path = "../pros-async", optional = true } +pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } +pros-math = { version = "0.1.0", path = "../pros-math", optional = true } +pros-panic = { version = "0.1.0", path = "../pros-panic", optional = true } +pros-core = { version = "0.1.0", path = "../pros-core", optional = true } -[target.'cfg(target_arch = "wasm32")'.dependencies] -dlmalloc = { version = "0.2.4", features = ["global"] } +[features] +default = ["async", "devices", "math", "panic", "display_panics", "core"] + +core = ["dep:pros-core"] + +async = ["dep:pros-async"] +sync = ["dep:pros-sync"] + +devices = ["dep:pros-devices"] +math = ["dep:pros-math"] + +panic = ["dep:pros-panic"] +display_panics = ["pros-panic/display_panics"] diff --git a/packages/pros/examples/basic.rs b/packages/pros/examples/basic.rs index 78837a04..e1e120a3 100644 --- a/packages/pros/examples/basic.rs +++ b/packages/pros/examples/basic.rs @@ -7,7 +7,7 @@ use pros::prelude::*; pub struct Robot; impl AsyncRobot for Robot { - async fn opcontrol(&mut self) -> pros::Result { + async fn opcontrol(&mut self) -> Result { println!("basic example"); Ok(()) diff --git a/packages/pros/src/feedforward.rs b/packages/pros/src/feedforward.rs deleted file mode 100644 index 8639b963..00000000 --- a/packages/pros/src/feedforward.rs +++ /dev/null @@ -1,59 +0,0 @@ -/// Feedforward controller for motor control. -/// -/// This controller is used to apply feedforward control to achieve desired motor behavior -/// based on velocity and acceleration. -#[derive(Debug, Clone)] -pub struct FeedforwardMotorController { - /// Feedforward constant for static friction compensation. - pub ks: f32, - /// Feedforward constant for velocity compensation. - pub kv: f32, - /// Feedforward constant for acceleration compensation. - pub ka: f32, - /// Feedforward constant for the target acceleration. - pub target_acceleration: f32, - /// Target. - pub target: f32, -} - -impl FeedforwardMotorController { - /// Creates a new [`FeedforwardMotorController`] with the given constants and target. - /// - /// # Arguments - /// - /// * `ks` - Feedforward constant for static friction compensation. - /// * `kv` - Feedforward constant for velocity compensation. - /// * `ka` - Feedforward constant for acceleration compensation. - /// * `target_acceleration` - Feedforward constant for the target acceleration. - /// - /// # Returns - /// - /// A new [`FeedforwardMotorController`]. - pub fn new(ks: f32, kv: f32, ka: f32, target_acceleration: f32) -> Self { - Self { - ks, - kv, - ka, - } - } - - /// Updates the feedforward controller to calculate the control output. - /// - /// # Arguments - /// - /// * `target_acceleration` - The target_acceleration of the system. - /// * `target` - Target. - /// - /// # Returns - /// - /// The control output to apply to the motor. - pub fn update(&self, target: f32, target_acceleration: f32) -> f32 { - // Calculate the feedforward component based on velocity and acceleration - let v = self.ks * target.signum() + self.kv * target + self.ka * target_acceleration; - - // The output is the feedforward controller (V) - let output = v; - - output - } -} diff --git a/packages/pros/src/io/mod.rs b/packages/pros/src/io/mod.rs deleted file mode 100644 index 58db33a1..00000000 --- a/packages/pros/src/io/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! Helpers for terminal I/O functionality. - -pub mod print_impl; - -pub use no_std_io::io::*; - -pub use crate::{dbg, eprint, eprintln, print, println}; diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 8f501810..c29bba4b 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -62,354 +62,71 @@ clippy::missing_const_for_fn )] -extern crate alloc; - -pub mod async_runtime; -pub mod devices; -pub mod error; -pub mod pid; -pub mod sync; -#[macro_use] -pub mod task; -pub mod panic; - -#[doc(hidden)] -pub use pros_sys as __pros_sys; -#[cfg(target_os = "vexos")] -mod vexos_env; -#[cfg(target_arch = "wasm32")] -mod wasm_env; -#[macro_use] -pub mod competition; -pub mod color; -pub mod io; -pub mod time; -pub mod usd; - -use core::future::Future; - -/// A result type that makes returning errors easier. -pub type Result = core::result::Result>; - -/// A trait for robot code that spins up the pros-rs async executor. -/// This is the preferred trait to run robot code. -pub trait AsyncRobot { - /// Runs during the operator control period. - /// This function may be called more than once. - /// For that reason, do not use [`Peripherals::take`](prelude::Peripherals::take) in this function. - fn opcontrol(&mut self) -> impl Future { - async { Ok(()) } - } - /// Runs during the autonomous period. - fn auto(&mut self) -> impl Future { - async { Ok(()) } - } - /// Runs continuously during the disabled period. - fn disabled(&mut self) -> impl Future { - async { Ok(()) } - } - /// Runs once when the competition system is initialized. - fn comp_init(&mut self) -> impl Future { - async { Ok(()) } - } -} - -/// A trait for robot code that runs without the async executor spun up. -/// This trait isn't recommended. See [`AsyncRobot`] for the preferred trait to run robot code. -pub trait SyncRobot { - /// Runs during the operator control period. - /// This function may be called more than once. - /// For that reason, do not use [`Peripherals::take`](prelude::Peripherals::take) in this function. - fn opcontrol(&mut self) -> Result { - Ok(()) - } - /// Runs during the autonomous period. - fn auto(&mut self) -> Result { - Ok(()) - } - /// Runs continuously during the disabled period. - fn disabled(&mut self) -> Result { - Ok(()) - } - /// Runs once when the competition system is initialized. - fn comp_init(&mut self) -> Result { - Ok(()) - } -} - -#[doc(hidden)] -#[macro_export] -macro_rules! __gen_sync_exports { - ($rbt:ty) => { - pub static mut ROBOT: Option<$rbt> = None; - - #[doc(hidden)] - #[no_mangle] - extern "C" fn opcontrol() { - <$rbt as $crate::SyncRobot>::opcontrol(unsafe { - ROBOT - .as_mut() - .expect("Expected initialize to run before opcontrol") - }) - .unwrap(); - } - - #[doc(hidden)] - #[no_mangle] - extern "C" fn autonomous() { - <$rbt as $crate::SyncRobot>::auto(unsafe { - ROBOT - .as_mut() - .expect("Expected initialize to run before opcontrol") - }) - .unwrap(); - } - - #[doc(hidden)] - #[no_mangle] - extern "C" fn disabled() { - <$rbt as $crate::SyncRobot>::disabled(unsafe { - ROBOT - .as_mut() - .expect("Expected initialize to run before opcontrol") - }) - .unwrap(); - } - - #[doc(hidden)] - #[no_mangle] - extern "C" fn competition_initialize() { - <$rbt as $crate::SyncRobot>::comp_init(unsafe { - ROBOT - .as_mut() - .expect("Expected initialize to run before opcontrol") - }) - .unwrap(); - } - }; -} - -#[doc(hidden)] -#[macro_export] -macro_rules! __gen_async_exports { - ($rbt:ty) => { - pub static mut ROBOT: Option<$rbt> = None; - - #[doc(hidden)] - #[no_mangle] - extern "C" fn opcontrol() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe { - ROBOT - .as_mut() - .expect("Expected initialize to run before opcontrol") - })) - .unwrap(); - } - - #[doc(hidden)] - #[no_mangle] - extern "C" fn autonomous() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::auto(unsafe { - ROBOT - .as_mut() - .expect("Expected initialize to run before auto") - })) - .unwrap(); - } - - #[doc(hidden)] - #[no_mangle] - extern "C" fn disabled() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::disabled(unsafe { - ROBOT - .as_mut() - .expect("Expected initialize to run before disabled") - })) - .unwrap(); - } - - #[doc(hidden)] - #[no_mangle] - extern "C" fn competition_initialize() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::comp_init(unsafe { - ROBOT - .as_mut() - .expect("Expected initialize to run before comp_init") - })) - .unwrap(); - } - }; -} - -/// Allows your async robot code to be executed by the pros kernel. -/// If your robot struct implements Default then you can just supply this macro with its type. -/// If not, you can supply an expression that returns your robot type to initialize your robot struct. -/// The code that runs to create your robot struct will run in the initialize function in PROS. -/// -/// Example of using the macro with a struct that implements Default: -/// ```rust -/// use pros::prelude::*; -/// #[derive(Default)] -/// struct ExampleRobot; -/// #[async_trait] -/// impl AsyncRobot for ExampleRobot { -/// asnyc fn opcontrol(&mut self) -> pros::Result { -/// println!("Hello, world!"); -/// Ok(()) -/// } -/// } -/// async_robot!(ExampleRobot); -/// ``` -/// -/// Example of using the macro with a struct that does not implement Default: -/// ```rust -/// use pros::prelude::*; -/// struct ExampleRobot { -/// x: i32, -/// } -/// #[async_trait] -/// impl AsyncRobot for ExampleRobot { -/// async fn opcontrol(&mut self) -> pros::Result { -/// println!("Hello, world! {}", self.x); -/// Ok(()) -/// } -/// } -/// impl ExampleRobot { -/// pub fn new() -> Self { -/// Self { x: 5 } -/// } -/// } -/// async_robot!(ExampleRobot, ExampleRobot::new()); -#[macro_export] -macro_rules! async_robot { - ($rbt:ty) => { - $crate::__gen_async_exports!($rbt); - - #[no_mangle] - extern "C" fn initialize() { - unsafe { - ROBOT = Some(Default::default()); - } - } - }; - ($rbt:ty, $init:expr) => { - $crate::__gen_async_exports!($rbt); - - #[no_mangle] - extern "C" fn initialize() { - unsafe { - ROBOT = Some($init); - } - } - }; -} - -/// Allows your sync robot code to be executed by the pros kernel. -/// If your robot struct implements Default then you can just supply this macro with its type. -/// If not, you can supply an expression that returns your robot type to initialize your robot struct. -/// The code that runs to create your robot struct will run in the initialize function in PROS. -/// -/// Example of using the macro with a struct that implements Default: -/// ```rust -/// use pros::prelude::*; -/// #[derive(Default)] -/// struct ExampleRobot; -/// impl SyncRobot for ExampleRobot { -/// asnyc fn opcontrol(&mut self) -> pros::Result { -/// println!("Hello, world!"); -/// Ok(()) -/// } -/// } -/// sync_robot!(ExampleRobot); -/// ``` -/// -/// Example of using the macro with a struct that does not implement Default: -/// ```rust -/// use pros::prelude::*; -/// struct ExampleRobot { -/// x: i32, -/// } -/// impl SyncRobot for ExampleRobot { -/// async fn opcontrol(&mut self) -> pros::Result { -/// println!("Hello, world! {}", self.x); -/// Ok(()) -/// } -/// } -/// impl ExampleRobot { -/// pub fn new() -> Self { -/// Self { x: 5 } -/// } -/// } -/// sync_robot!(ExampleRobot, ExampleRobot::new()); -#[macro_export] -macro_rules! sync_robot { - ($rbt:ty) => { - $crate::__gen_sync_exports!($rbt); - - #[no_mangle] - extern "C" fn initialize() { - unsafe { - ROBOT = Some(Default::default()); - } - } - }; - ($rbt:ty, $init:expr) => { - $crate::__gen_sync_exports!($rbt); - - #[no_mangle] - extern "C" fn initialize() { - unsafe { - ROBOT = Some($init); - } - } - }; -} +#[cfg(all(feature = "async", feature = "sync"))] +compile_error!("The `async` and `sync` features are mutually exclusive."); + +#[cfg(all(not(feature = "async"), not(feature = "sync")))] +compile_error!("You must enable either the `async` or `sync` feature in order to make a robot."); + +#[cfg(feature = "async")] +pub use pros_async; +#[cfg(feature = "core")] +pub use pros_core; +#[cfg(feature = "devices")] +pub use pros_devices; +#[cfg(feature = "sync")] +pub use pros_sync; +#[cfg(feature = "math")] +pub use pros_math; +#[cfg(feature = "panic")] +pub use pros_panic; /// Commonly used features of pros-rs. /// This module is meant to be glob imported. pub mod prelude { - // Import Box from alloc so that it can be used in async_trait! - pub use alloc::boxed::Box; - - pub use crate::{ - async_robot, - async_runtime::*, + #[cfg(feature = "async")] + pub use pros_async::{async_robot, async_runtime::*, sleep, AsyncRobot}; + #[cfg(feature = "core")] + pub use pros_core::{ + dbg, eprint, eprintln, + error::{PortError, Result}, + io::{BufRead, Read, Seek, Write}, + print, println, + }; + #[cfg(feature = "devices")] + pub use pros_devices::{ + adi::{ + analog::AdiAnalogIn, + digital::{AdiDigitalIn, AdiDigitalOut}, + encoder::AdiEncoder, + gyro::AdiGyro, + motor::AdiMotor, + potentiometer::{AdiPotentiometer, AdiPotentiometerType}, + pwm::AdiPwmOut, + solenoid::AdiSolenoid, + ultrasonic::AdiUltrasonic, + AdiDevice, AdiPort, + }, color::Rgb, - devices::{ - adi::{ - analog::AdiAnalogIn, - digital::{AdiDigitalIn, AdiDigitalOut}, - encoder::AdiEncoder, - gyro::AdiGyro, - motor::AdiMotor, - potentiometer::{AdiPotentiometer, AdiPotentiometerType}, - pwm::AdiPwmOut, - solenoid::AdiSolenoid, - ultrasonic::AdiUltrasonic, - AdiDevice, AdiPort, - }, - peripherals::{DynamicPeripherals, Peripherals}, position::Position, screen::{Circle, Line, Rect, Screen, Text, TextFormat, TextPosition, TouchState}, - smart::{ - distance::DistanceSensor, - expander::AdiExpander, - gps::GpsSensor, - imu::InertialSensor, - link::{Link, RxLink, TxLink}, - motor::{BrakeMode, Gearset, Motor}, - optical::OpticalSensor, - rotation::RotationSensor, - vision::VisionSensor, - SmartDevice, SmartPort, - }, + smart::{ + distance::DistanceSensor, + expander::AdiExpander, + gps::GpsSensor, + imu::InertialSensor, + link::{Link, RxLink, TxLink}, + motor::{BrakeMode, Gearset, Motor}, + optical::OpticalSensor, + rotation::RotationSensor, + vision::VisionSensor, + SmartDevice, SmartPort, }, - error::PortError, - io::{dbg, eprintln, print, println, BufRead, Read, Seek, Write}, - os_task_local, - pid::*, - sync_robot, + }; + #[cfg(feature = "sync")] + pub use pros_sync::{ + os_task_local, sync_robot, task::{delay, sleep, spawn}, - AsyncRobot, SyncRobot, + SyncRobot, }; } From 92ea621ca5c199c26eb3ba8abc2850123ce86aa2 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 4 Feb 2024 11:40:58 -0800 Subject: [PATCH 56/96] fix: get examples working --- packages/pros-async/src/lib.rs | 2 +- packages/pros-core/src/io/mod.rs | 9 ++++---- packages/pros-core/src/lib.rs | 4 ++-- packages/pros-devices/src/adi/analog.rs | 2 +- packages/pros-devices/src/adi/digital.rs | 2 +- packages/pros-devices/src/adi/encoder.rs | 2 +- packages/pros-devices/src/adi/gyro.rs | 2 +- packages/pros-devices/src/adi/mod.rs | 2 +- packages/pros-devices/src/adi/motor.rs | 2 +- .../pros-devices/src/adi/potentiometer.rs | 2 +- packages/pros-devices/src/adi/ultrasonic.rs | 2 +- packages/pros-devices/src/smart/distance.rs | 2 +- packages/pros-devices/src/smart/gps.rs | 2 +- packages/pros-devices/src/smart/link.rs | 6 ++++- packages/pros-devices/src/smart/motor.rs | 2 +- packages/pros-devices/src/smart/optical.rs | 2 +- packages/pros-devices/src/smart/vision.rs | 2 +- packages/pros-panic/src/lib.rs | 4 ++-- packages/pros-sync/src/lib.rs | 1 + packages/pros/Cargo.toml | 2 +- packages/pros/examples/accessories.rs | 4 +--- packages/pros/examples/adi.rs | 4 ++-- packages/pros/examples/battery.rs | 2 +- packages/pros/examples/dynamic_peripherals.rs | 2 +- packages/pros/examples/imu.rs | 4 ++-- packages/pros/examples/optical.rs | 4 ++-- packages/pros/examples/screen.rs | 2 +- packages/pros/src/lib.rs | 22 +++++++------------ 28 files changed, 47 insertions(+), 51 deletions(-) diff --git a/packages/pros-async/src/lib.rs b/packages/pros-async/src/lib.rs index a65e47cd..f091ffb8 100644 --- a/packages/pros-async/src/lib.rs +++ b/packages/pros-async/src/lib.rs @@ -3,10 +3,10 @@ extern crate alloc; pub mod async_runtime; - use core::{future::Future, task::Poll}; use async_runtime::executor::EXECUTOR; +pub use async_runtime::*; use pros_core::error::Result; /// A future that will complete after the given duration. diff --git a/packages/pros-core/src/io/mod.rs b/packages/pros-core/src/io/mod.rs index 5ac209e4..12166332 100644 --- a/packages/pros-core/src/io/mod.rs +++ b/packages/pros-core/src/io/mod.rs @@ -38,10 +38,6 @@ //! # } //! ``` -pub use no_std_io::io::*; - -pub use crate::{dbg, eprint, eprintln, print, println}; - // libc_print is licensed under the MIT License: // Copyright (c) 2023 Matt Mastracci and contributors @@ -63,10 +59,13 @@ pub use crate::{dbg, eprint, eprintln, print, println}; // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. - #[allow(unused_imports)] use core::{convert::TryFrom, file, line, stringify}; +pub use no_std_io::io::*; + +pub use crate::{dbg, eprint, eprintln, print, println}; + #[doc(hidden)] #[allow(missing_debug_implementations)] pub struct __SerialWriter(i32); diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index b61ed55d..29b52f70 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -2,8 +2,8 @@ #![feature(error_in_core)] extern crate alloc; -pub mod pros_alloc; +pub mod competition; pub mod error; pub mod io; +pub mod pros_alloc; pub mod time; -pub mod competition; diff --git a/packages/pros-devices/src/adi/analog.rs b/packages/pros-devices/src/adi/analog.rs index 104bbd05..1a4a83c9 100644 --- a/packages/pros-devices/src/adi/analog.rs +++ b/packages/pros-devices/src/adi/analog.rs @@ -8,10 +8,10 @@ //! Analog-to-Digital Converter (ADC) in the V5 brain. The brain measures analog input //! using 12-bit values ranging from 0 (0V) to 4095 (5V). +use pros_core::bail_on; use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; /// Generic analog input ADI device. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros-devices/src/adi/digital.rs b/packages/pros-devices/src/adi/digital.rs index bf33bcb7..f1e7c9fa 100644 --- a/packages/pros-devices/src/adi/digital.rs +++ b/packages/pros-devices/src/adi/digital.rs @@ -1,9 +1,9 @@ //! Digital input and output ADI devices +use pros_core::bail_on; use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; /// Represents the logic level of a digital pin. /// diff --git a/packages/pros-devices/src/adi/encoder.rs b/packages/pros-devices/src/adi/encoder.rs index aa3520eb..ee0ae8f9 100644 --- a/packages/pros-devices/src/adi/encoder.rs +++ b/packages/pros-devices/src/adi/encoder.rs @@ -1,9 +1,9 @@ //! ADI encoder device. +use pros_core::bail_on; use pros_sys::{ext_adi_encoder_t, PROS_ERR}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; /// ADI encoder device. /// Requires two adi ports. diff --git a/packages/pros-devices/src/adi/gyro.rs b/packages/pros-devices/src/adi/gyro.rs index d7cae9a5..617007e6 100644 --- a/packages/pros-devices/src/adi/gyro.rs +++ b/packages/pros-devices/src/adi/gyro.rs @@ -2,10 +2,10 @@ use core::time::Duration; +use pros_core::bail_on; use pros_sys::{ext_adi_gyro_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; /// ADI gyro device. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros-devices/src/adi/mod.rs b/packages/pros-devices/src/adi/mod.rs index 527e2861..6c814eb6 100644 --- a/packages/pros-devices/src/adi/mod.rs +++ b/packages/pros-devices/src/adi/mod.rs @@ -1,6 +1,6 @@ //! ADI (Triport) devices on the Vex V5. -use pros_core::{bail_on, map_errno, error::PortError}; +use pros_core::{bail_on, error::PortError, map_errno}; use pros_sys::{adi_port_config_e_t, PROS_ERR, E_ADI_ERR,}; use snafu::Snafu; diff --git a/packages/pros-devices/src/adi/motor.rs b/packages/pros-devices/src/adi/motor.rs index ba1ba842..bda8d5df 100644 --- a/packages/pros-devices/src/adi/motor.rs +++ b/packages/pros-devices/src/adi/motor.rs @@ -1,9 +1,9 @@ //! ADI motor device. +use pros_core::bail_on; use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; #[derive(Debug, Eq, PartialEq)] /// Cortex era motor device. diff --git a/packages/pros-devices/src/adi/potentiometer.rs b/packages/pros-devices/src/adi/potentiometer.rs index ee0caa13..80f6375a 100644 --- a/packages/pros-devices/src/adi/potentiometer.rs +++ b/packages/pros-devices/src/adi/potentiometer.rs @@ -1,9 +1,9 @@ //! ADI Potentiometer device. +use pros_core::bail_on; use pros_sys::{adi_potentiometer_type_e_t, ext_adi_potentiometer_t, PROS_ERR, PROS_ERR_F}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; #[derive(Debug, Eq, PartialEq)] /// Analog potentiometer ADI device. diff --git a/packages/pros-devices/src/adi/ultrasonic.rs b/packages/pros-devices/src/adi/ultrasonic.rs index 27b74e2a..098a867a 100644 --- a/packages/pros-devices/src/adi/ultrasonic.rs +++ b/packages/pros-devices/src/adi/ultrasonic.rs @@ -1,9 +1,9 @@ //! ADI ultrasonic sensor. +use pros_core::bail_on; use pros_sys::{ext_adi_ultrasonic_t, PROS_ERR}; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; #[derive(Debug, Eq, PartialEq)] /// Adi ultrasonic sensor. diff --git a/packages/pros-devices/src/smart/distance.rs b/packages/pros-devices/src/smart/distance.rs index 6cebcf52..37f55703 100644 --- a/packages/pros-devices/src/smart/distance.rs +++ b/packages/pros-devices/src/smart/distance.rs @@ -4,10 +4,10 @@ use core::ffi::c_double; +use pros_core::{bail_on, error::PortError}; use pros_sys::PROS_ERR; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use pros_core::{bail_on, error::PortError}; /// A physical distance sensor plugged into a port. /// Distance sensors can only keep track of one object at a time. diff --git a/packages/pros-devices/src/smart/gps.rs b/packages/pros-devices/src/smart/gps.rs index a00cb18d..16e561b0 100644 --- a/packages/pros-devices/src/smart/gps.rs +++ b/packages/pros-devices/src/smart/gps.rs @@ -3,11 +3,11 @@ //! A notable differenc between this API and that of PROS //! is that [`GpsSensor::status`] returns acceleration along with other status data. +use pros_core::{bail_on, error::PortError, map_errno}; use pros_sys::{PROS_ERR, PROS_ERR_F}; use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use pros_core::{bail_on, map_errno, error::PortError}; //TODO: Figure out what all the units are #[derive(Default, Debug, Clone, Copy, PartialEq)] diff --git a/packages/pros-devices/src/smart/link.rs b/packages/pros-devices/src/smart/link.rs index 1a34003c..ddcebdf7 100644 --- a/packages/pros-devices/src/smart/link.rs +++ b/packages/pros-devices/src/smart/link.rs @@ -7,7 +7,11 @@ use alloc::{ffi::CString, string::String}; use core::ffi::CStr; use no_std_io::io; -use pros_core::{bail_errno, bail_on, map_errno, error::{ FromErrno, PortError }}; +use pros_core::{ + bail_errno, bail_on, + error::{FromErrno, PortError}, + map_errno, +}; use pros_sys::{link_receive, link_transmit, E_LINK_RECEIVER, E_LINK_TRANSMITTER}; use snafu::Snafu; diff --git a/packages/pros-devices/src/smart/motor.rs b/packages/pros-devices/src/smart/motor.rs index 8eb8421e..5b8efaf3 100644 --- a/packages/pros-devices/src/smart/motor.rs +++ b/packages/pros-devices/src/smart/motor.rs @@ -21,7 +21,7 @@ //! } //! ``` -use pros_core::{bail_on, map_errno, error::PortError}; +use pros_core::{bail_on, error::PortError, map_errno}; use pros_sys::{PROS_ERR, PROS_ERR_F}; use snafu::Snafu; diff --git a/packages/pros-devices/src/smart/optical.rs b/packages/pros-devices/src/smart/optical.rs index 4ed513ef..464e3b7b 100644 --- a/packages/pros-devices/src/smart/optical.rs +++ b/packages/pros-devices/src/smart/optical.rs @@ -2,11 +2,11 @@ use core::time::Duration; +use pros_core::{bail_on, error::PortError, map_errno}; use pros_sys::{OPT_GESTURE_ERR, PROS_ERR, PROS_ERR_F}; use snafu::Snafu; use super::{SmartDevice, SmartDeviceType, SmartPort}; -use pros_core::{bail_on, map_errno, error::PortError}; /// Represents a smart port configured as a V5 optical sensor #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros-devices/src/smart/vision.rs b/packages/pros-devices/src/smart/vision.rs index eed7f5b0..ad27ce5e 100644 --- a/packages/pros-devices/src/smart/vision.rs +++ b/packages/pros-devices/src/smart/vision.rs @@ -5,7 +5,7 @@ extern crate alloc; use alloc::vec::Vec; -use pros_core::{bail_errno, bail_on, map_errno, error::PortError}; +use pros_core::{bail_errno, bail_on, error::PortError, map_errno}; use pros_sys::{PROS_ERR, VISION_OBJECT_ERR_SIG}; use snafu::Snafu; diff --git a/packages/pros-panic/src/lib.rs b/packages/pros-panic/src/lib.rs index 46f8e350..6b3b6adf 100644 --- a/packages/pros-panic/src/lib.rs +++ b/packages/pros-panic/src/lib.rs @@ -2,11 +2,11 @@ extern crate alloc; use alloc::format; -use pros_core::eprintln; -use pros_sync::task; +use pros_core::eprintln; #[cfg(feature = "display_panics")] use pros_devices::Screen; +use pros_sync::task; extern "C" { /// Prints a backtrace to the debug console diff --git a/packages/pros-sync/src/lib.rs b/packages/pros-sync/src/lib.rs index f98beb0f..621f1c3d 100644 --- a/packages/pros-sync/src/lib.rs +++ b/packages/pros-sync/src/lib.rs @@ -5,6 +5,7 @@ pub mod sync; pub mod task; use pros_core::error::Result; +pub use sync::*; /// A trait for robot code that runs without the async executor spun up. /// This trait isn't recommended. See [`AsyncRobot`] for the preferred trait to run robot code. diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 50d1a550..470150a8 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -26,7 +26,7 @@ pros-panic = { version = "0.1.0", path = "../pros-panic", optional = true } pros-core = { version = "0.1.0", path = "../pros-core", optional = true } [features] -default = ["async", "devices", "math", "panic", "display_panics", "core"] +default = ["async", "sync", "devices", "math", "panic", "display_panics", "core"] core = ["dep:pros-core"] diff --git a/packages/pros/examples/accessories.rs b/packages/pros/examples/accessories.rs index b2e74b96..119934b9 100644 --- a/packages/pros/examples/accessories.rs +++ b/packages/pros/examples/accessories.rs @@ -7,14 +7,12 @@ use alloc::sync::Arc; use core::time::Duration; use pros::{ - color::Rgb, devices::{ smart::vision::{LedMode, VisionZeroPoint}, Controller, }, prelude::*, sync::Mutex, - task::delay, }; struct ExampleRobot { @@ -33,7 +31,7 @@ impl ExampleRobot { } impl AsyncRobot for ExampleRobot { - async fn opcontrol(&mut self) -> pros::Result { + async fn opcontrol(&mut self) -> Result { let handle = pros::async_runtime::spawn(async { for _ in 0..5 { println!("Hello from async!"); diff --git a/packages/pros/examples/adi.rs b/packages/pros/examples/adi.rs index aa0d4fa4..1425a42e 100644 --- a/packages/pros/examples/adi.rs +++ b/packages/pros/examples/adi.rs @@ -21,7 +21,7 @@ impl ExampleRobot { } impl AsyncRobot for ExampleRobot { - async fn opcontrol(&mut self) -> pros::Result { + async fn opcontrol(&mut self) -> Result { self.gyro.zero()?; self.encoder.zero()?; @@ -29,7 +29,7 @@ impl AsyncRobot for ExampleRobot { println!("Encoder value: {:?}", self.encoder.value()); println!("Ultrasonic value: {:?}", self.ultrasonic.value()); - pros::task::delay(Duration::from_millis(10)); + delay(Duration::from_millis(10)); } } } diff --git a/packages/pros/examples/battery.rs b/packages/pros/examples/battery.rs index 679e1079..e0384393 100644 --- a/packages/pros/examples/battery.rs +++ b/packages/pros/examples/battery.rs @@ -7,7 +7,7 @@ use pros::{devices::battery, prelude::*}; pub struct Robot; impl AsyncRobot for Robot { - async fn opcontrol(&mut self) -> pros::Result { + async fn opcontrol(&mut self) -> Result { if battery::capacity()? < 20.0 { println!("Battery is low!"); } else if battery::temperature()? > 999.0 { diff --git a/packages/pros/examples/dynamic_peripherals.rs b/packages/pros/examples/dynamic_peripherals.rs index 205ecea1..4b4c321a 100644 --- a/packages/pros/examples/dynamic_peripherals.rs +++ b/packages/pros/examples/dynamic_peripherals.rs @@ -14,7 +14,7 @@ impl Robot { } } impl AsyncRobot for Robot { - async fn opcontrol(&mut self) -> pros::Result { + async fn opcontrol(&mut self) -> Result { let motor = Motor::new( self.peripherals.take_smart_port(10).unwrap(), BrakeMode::Brake, diff --git a/packages/pros/examples/imu.rs b/packages/pros/examples/imu.rs index 214c2e84..20440fd9 100644 --- a/packages/pros/examples/imu.rs +++ b/packages/pros/examples/imu.rs @@ -17,7 +17,7 @@ impl Robot { } impl AsyncRobot for Robot { - async fn opcontrol(&mut self) -> pros::Result { + async fn opcontrol(&mut self) -> Result { self.imu.calibrate().await?; loop { @@ -28,7 +28,7 @@ impl AsyncRobot for Robot { euler.pitch, euler.roll, euler.yaw ); - pros::task::delay(Duration::from_secs(1)); + delay(Duration::from_secs(1)); } } } diff --git a/packages/pros/examples/optical.rs b/packages/pros/examples/optical.rs index 5766fdc9..d237553d 100644 --- a/packages/pros/examples/optical.rs +++ b/packages/pros/examples/optical.rs @@ -17,7 +17,7 @@ impl Robot { } impl SyncRobot for Robot { - fn opcontrol(&mut self) -> pros::Result { + fn opcontrol(&mut self) -> Result { loop { println!( "-----\nHue: {}\nSaturation: {}\nBrightess: {}\nLast Gesture Direction: {:?}\n-----\n", @@ -27,7 +27,7 @@ impl SyncRobot for Robot { self.optical.last_gesture_direction()? ); - pros::task::delay(Duration::from_millis(10)); + delay(Duration::from_millis(10)); } } } diff --git a/packages/pros/examples/screen.rs b/packages/pros/examples/screen.rs index 04d692f4..d6daa3e2 100644 --- a/packages/pros/examples/screen.rs +++ b/packages/pros/examples/screen.rs @@ -18,7 +18,7 @@ impl Robot { } impl AsyncRobot for Robot { - async fn opcontrol(&mut self) -> pros::Result { + async fn opcontrol(&mut self) -> Result { self.screen.fill(&Rect::new(0, 0, 20, 20), Rgb::RED)?; self.screen.stroke(&Circle::new(25, 25, 20), Rgb::BLUE)?; diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index c29bba4b..e697d83f 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -62,24 +62,18 @@ clippy::missing_const_for_fn )] -#[cfg(all(feature = "async", feature = "sync"))] -compile_error!("The `async` and `sync` features are mutually exclusive."); - -#[cfg(all(not(feature = "async"), not(feature = "sync")))] -compile_error!("You must enable either the `async` or `sync` feature in order to make a robot."); - #[cfg(feature = "async")] -pub use pros_async; +pub use pros_async as async_runtime; #[cfg(feature = "core")] -pub use pros_core; +pub use pros_core as core; #[cfg(feature = "devices")] -pub use pros_devices; -#[cfg(feature = "sync")] -pub use pros_sync; +pub use pros_devices as devices; #[cfg(feature = "math")] -pub use pros_math; +pub use pros_math as math; #[cfg(feature = "panic")] -pub use pros_panic; +pub use pros_panic as panic; +#[cfg(feature = "sync")] +pub use pros_sync as sync; /// Commonly used features of pros-rs. /// This module is meant to be glob imported. @@ -126,7 +120,7 @@ pub mod prelude { #[cfg(feature = "sync")] pub use pros_sync::{ os_task_local, sync_robot, - task::{delay, sleep, spawn}, + task::{delay, spawn}, SyncRobot, }; } From 8f659187156a09436f4452b78f5a5601afa4da78 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 4 Feb 2024 11:53:37 -0800 Subject: [PATCH 57/96] docs: update changelog --- CHANGELOG.md | 2 +- packages/pros-devices/src/adi/gyro.rs | 4 +++- packages/pros-devices/src/smart/imu.rs | 4 ++-- packages/pros-math/Cargo.toml | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39b3feab..d32f513c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,6 @@ Before releasing: - Added feedforward motor controllers (#80) - Lightly document all APIs with missing documentation. (#70) - Added `Debug`, `Copy`, and `Clone` derives for common structs (#70) - - Screen drawing API. (#81) - Added screen field to `Peripherals` and `DynamicPeripherals::take_screen` method. (#81) - Added `AdiSolenoid`, a wrapper over `AdiDigitalOut` for actuating SMC pneumatic solenoids. (#61) @@ -59,6 +58,7 @@ Before releasing: - Repurposed `AdiAnalogOut` as `AdiPwmOut` to correct match port output. (**Breaking Change**) (#90). - Moved most device-related constants into their associated struct `impl` (**Breaking Change**) (#98). - Renamed IMU_RESET_TIMEOUT to `InertialSensor::CALIBRATION_TIMEOUT` (**Breaking Change**) (#98). +- Split the `pros` crate into several smaller subcrates. (#86) (**Breaking Change**) ### Removed diff --git a/packages/pros-devices/src/adi/gyro.rs b/packages/pros-devices/src/adi/gyro.rs index 617007e6..bc6eb156 100644 --- a/packages/pros-devices/src/adi/gyro.rs +++ b/packages/pros-devices/src/adi/gyro.rs @@ -43,7 +43,9 @@ impl AdiGyro { /// Reset the current gyro angle to zero degrees. pub fn zero(&mut self) -> Result<(), AdiError> { - bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_gyro_reset(self.raw) }); + bail_on!(PROS_ERR, unsafe { + pros_sys::ext_adi_gyro_reset(self.raw) + }); Ok(()) } } diff --git a/packages/pros-devices/src/smart/imu.rs b/packages/pros-devices/src/smart/imu.rs index fb3b367d..2ec5223e 100644 --- a/packages/pros-devices/src/smart/imu.rs +++ b/packages/pros-devices/src/smart/imu.rs @@ -413,8 +413,8 @@ impl core::future::Future for InertialCalibrateFuture { Self::Calibrate(port) => match unsafe { pros_sys::imu_reset(port) } { PROS_ERR => { let errno = take_errno(); - return Poll::Ready(Err(InertialError::from_errno(errno) - .unwrap_or_else(|| panic!("Unknown errno code {errno}")))); + Poll::Ready(Err(InertialError::from_errno(errno) + .unwrap_or_else(|| panic!("Unknown errno code {errno}")))) } _ => { *self = Self::Waiting(port, Instant::now()); diff --git a/packages/pros-math/Cargo.toml b/packages/pros-math/Cargo.toml index a51e24af..e0d17465 100644 --- a/packages/pros-math/Cargo.toml +++ b/packages/pros-math/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" [dependencies] pros-sys = { version = "0.6.0", path = "../pros-sys" } +pros-core = { version = "0.1.0", path = "../pros-core" } From 9a7f04c2983d9c3c326dd52d68fbdf174d78df06 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 4 Feb 2024 12:03:47 -0800 Subject: [PATCH 58/96] chore: format --- packages/pros-devices/src/adi/gyro.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/pros-devices/src/adi/gyro.rs b/packages/pros-devices/src/adi/gyro.rs index bc6eb156..617007e6 100644 --- a/packages/pros-devices/src/adi/gyro.rs +++ b/packages/pros-devices/src/adi/gyro.rs @@ -43,9 +43,7 @@ impl AdiGyro { /// Reset the current gyro angle to zero degrees. pub fn zero(&mut self) -> Result<(), AdiError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::ext_adi_gyro_reset(self.raw) - }); + bail_on!(PROS_ERR, unsafe { pros_sys::ext_adi_gyro_reset(self.raw) }); Ok(()) } } From 494cdbbe2133817e327b302afc5d9e59d3aa0b4a Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 4 Feb 2024 14:10:36 -0800 Subject: [PATCH 59/96] docs: add basic module level documentation --- packages/pros-async/src/async_runtime/mod.rs | 1 - packages/pros-async/src/lib.rs | 12 ++++++++++++ packages/pros-core/src/error.rs | 1 + packages/pros-core/src/lib.rs | 18 ++++++++++++++++++ packages/pros-core/src/pros_alloc/mod.rs | 2 ++ packages/pros-devices/src/lib.rs | 8 ++++++++ packages/pros-panic/src/lib.rs | 14 +++++++++++++- packages/pros-sync/src/lib.rs | 13 +++++++++++++ packages/pros-sync/src/task/mod.rs | 2 +- packages/pros/src/lib.rs | 13 +++---------- 10 files changed, 71 insertions(+), 13 deletions(-) diff --git a/packages/pros-async/src/async_runtime/mod.rs b/packages/pros-async/src/async_runtime/mod.rs index 2fec27f4..acb1e545 100644 --- a/packages/pros-async/src/async_runtime/mod.rs +++ b/packages/pros-async/src/async_runtime/mod.rs @@ -18,7 +18,6 @@ pub fn spawn(future: impl Future + 'static) -> Task { /// Blocks the current task untill a return value can be extracted from the provided future. /// Does not poll all futures to completion. -/// If you want to complete all futures, use the [`complete_all`] function. pub fn block_on(future: F) -> F::Output { executor::EXECUTOR.with(|e| e.block_on(spawn(future))) } diff --git a/packages/pros-async/src/lib.rs b/packages/pros-async/src/lib.rs index f091ffb8..eae8e512 100644 --- a/packages/pros-async/src/lib.rs +++ b/packages/pros-async/src/lib.rs @@ -1,5 +1,17 @@ +//! Tiny async runtime and robot traits for `pros-rs`. +//! The async executor supports spawning tasks and blocking on futures. +//! It has a reactor to improve the performance of some futures. + #![no_std] #![feature(negative_impls)] +#![warn( + missing_docs, + rust_2018_idioms, + missing_debug_implementations, + unsafe_op_in_unsafe_fn, + clippy::missing_const_for_fn +)] + extern crate alloc; pub mod async_runtime; diff --git a/packages/pros-core/src/error.rs b/packages/pros-core/src/error.rs index 2cf9065d..f129cede 100644 --- a/packages/pros-core/src/error.rs +++ b/packages/pros-core/src/error.rs @@ -8,6 +8,7 @@ /// A result type that makes returning errors easier. pub type Result = core::result::Result>; +/// Gets the value of errno and sets errno to 0. pub fn take_errno() -> i32 { let err = unsafe { *pros_sys::__errno() }; if err != 0 { diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index 29b52f70..52d6bc5d 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -1,5 +1,23 @@ +//! Low level core functionality for [`pros-rs`](https://crates.io/crates/pros). +//! The core crate is used in all other crates in the pros-rs ecosystem. +//! +//! Included in this crate: +//! - Global allocator: [`pros_alloc`] +//! - Competition state checking: [`competition`] +//! - Errno handling: [`error`] +//! - Serial terminal printing: [`io`] +//! - No-std [`Instant`](time::Instant)s: [`time`] + #![no_std] #![feature(error_in_core)] +#![warn( + missing_docs, + rust_2018_idioms, + missing_debug_implementations, + unsafe_op_in_unsafe_fn, + clippy::missing_const_for_fn +)] + extern crate alloc; pub mod competition; diff --git a/packages/pros-core/src/pros_alloc/mod.rs b/packages/pros-core/src/pros_alloc/mod.rs index 7eed7108..bd4c949c 100644 --- a/packages/pros-core/src/pros_alloc/mod.rs +++ b/packages/pros-core/src/pros_alloc/mod.rs @@ -1,3 +1,5 @@ +//! Simple allocator using the VEX libc allocation functions in vexos and jemalloc in the sim. + #[cfg(target_os = "vexos")] mod vexos; #[cfg(target_arch = "wasm32")] diff --git a/packages/pros-devices/src/lib.rs b/packages/pros-devices/src/lib.rs index ed852c77..9debf368 100644 --- a/packages/pros-devices/src/lib.rs +++ b/packages/pros-devices/src/lib.rs @@ -18,6 +18,14 @@ //! - [`devices::controller`] provides types for interacting with the V5 controller. #![no_std] +#![warn( + missing_docs, + rust_2018_idioms, + missing_debug_implementations, + unsafe_op_in_unsafe_fn, + clippy::missing_const_for_fn +)] + extern crate alloc; pub mod adi; diff --git a/packages/pros-panic/src/lib.rs b/packages/pros-panic/src/lib.rs index 6b3b6adf..f3608b2d 100644 --- a/packages/pros-panic/src/lib.rs +++ b/packages/pros-panic/src/lib.rs @@ -1,4 +1,15 @@ +//! Panic handler implementation for [`pros-rs`](https://crates.io/crates/pros-rs). +//! Supports printing a backtrace when running in the simulator. +//! If the `display_panics` feature is enabled, it will also display the panic message on the V5 Brain display. + #![no_std] +#![warn( + missing_docs, + rust_2018_idioms, + missing_debug_implementations, + unsafe_op_in_unsafe_fn, + clippy::missing_const_for_fn +)] extern crate alloc; use alloc::format; @@ -8,9 +19,10 @@ use pros_core::eprintln; use pros_devices::Screen; use pros_sync::task; +#[cfg(target_arch = "wasm32")] extern "C" { /// Prints a backtrace to the debug console - pub fn sim_log_backtrace(); + fn sim_log_backtrace(); } #[panic_handler] diff --git a/packages/pros-sync/src/lib.rs b/packages/pros-sync/src/lib.rs index 621f1c3d..1028bf56 100644 --- a/packages/pros-sync/src/lib.rs +++ b/packages/pros-sync/src/lib.rs @@ -1,4 +1,17 @@ +//! Synchronization primitives and FreeRTOS task management for [`pros-rs`]. +//! +//! The synchronization types are modeled after the standard library. +//! For more information on the task api, see the [`task`] module. + #![no_std] +#![warn( + missing_docs, + rust_2018_idioms, + missing_debug_implementations, + unsafe_op_in_unsafe_fn, + clippy::missing_const_for_fn +)] + extern crate alloc; pub mod sync; diff --git a/packages/pros-sync/src/task/mod.rs b/packages/pros-sync/src/task/mod.rs index df11ec25..d705037a 100644 --- a/packages/pros-sync/src/task/mod.rs +++ b/packages/pros-sync/src/task/mod.rs @@ -295,7 +295,7 @@ map_errno! { /// /// This function will block the entire task, preventing concurrent /// execution of async code. When in an async context, it is recommended -/// to use [`sleep`] instead. +/// to use the `sleep` function in [`pros_async`](https://crates.io/crates/pros-async) instead. pub fn delay(duration: Duration) { unsafe { pros_sys::delay(duration.as_millis() as u32) } } diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index e697d83f..ba55a1b0 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -28,6 +28,7 @@ //! loop { //! // Do something //! sleep(Duration::from_millis(20)).await; +//! } //! } //! } //! async_robot!(Robot); @@ -44,23 +45,15 @@ //! loop { //! // Do something //! delay(Duration::from_millis(20)); +//! } //! } //! } //! sync_robot!(Robot); //! ``` //! //! You may have noticed the `#[derive(Default)]` attribute on these Robot structs. -//! If you want to learn why, look at the docs for [`async_robot`] or [`sync_robot`]. - -#![feature(error_in_core, negative_impls)] +//! If you want to learn why, look at the docs for [`pros_async::async_robot`] or [`pros_sync::sync_robot`]. #![no_std] -#![warn( - missing_docs, - rust_2018_idioms, - missing_debug_implementations, - unsafe_op_in_unsafe_fn, - clippy::missing_const_for_fn -)] #[cfg(feature = "async")] pub use pros_async as async_runtime; From 519d4069afe64e5f0011af9f528b6cc4fbe71b6c Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 4 Feb 2024 16:11:57 -0800 Subject: [PATCH 60/96] fix: broken pros-devices manifest --- packages/pros-devices/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros-devices/Cargo.toml b/packages/pros-devices/Cargo.toml index c9819c33..c919df49 100644 --- a/packages/pros-devices/Cargo.toml +++ b/packages/pros-devices/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -pros-core = { verion = "0.1.0", path = "../pros-core" } +pros-core = { version = "0.1.0", path = "../pros-core" } pros-sys = { path = "../pros-sys", version = "0.6.0", features = ["xapi"] } snafu = { version = "0.8.0", default-features = false, features = [ "rust_1_61", From 1c208f06c88f378feea5f494c579f4c544e421b7 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 4 Feb 2024 16:38:50 -0800 Subject: [PATCH 61/96] docs: fix most documentation warnings --- packages/pros-async/src/lib.rs | 2 +- packages/pros-devices/src/adi/mod.rs | 4 +- packages/pros-devices/src/color.rs | 14 +++--- packages/pros-devices/src/lib.rs | 8 ++-- packages/pros-devices/src/peripherals.rs | 2 +- packages/pros-devices/src/screen.rs | 2 +- packages/pros-devices/src/smart/imu.rs | 2 +- packages/pros-devices/src/smart/mod.rs | 4 +- packages/pros-devices/src/smart/motor.rs | 6 +-- packages/pros-devices/src/smart/optical.rs | 8 ++-- packages/pros-sync/src/lib.rs | 4 +- packages/pros-sync/src/task/mod.rs | 4 +- packages/pros-sys/src/apix.rs | 50 +++++++++++----------- packages/pros-sys/src/motor.rs | 2 +- packages/pros-sys/src/rtos.rs | 14 +++--- packages/pros-sys/src/vision.rs | 16 +++---- 16 files changed, 69 insertions(+), 73 deletions(-) diff --git a/packages/pros-async/src/lib.rs b/packages/pros-async/src/lib.rs index eae8e512..bc561d5c 100644 --- a/packages/pros-async/src/lib.rs +++ b/packages/pros-async/src/lib.rs @@ -60,7 +60,7 @@ pub fn sleep(duration: core::time::Duration) -> SleepFuture { pub trait AsyncRobot { /// Runs during the operator control period. /// This function may be called more than once. - /// For that reason, do not use [`Peripherals::take`](prelude::Peripherals::take) in this function. + /// For that reason, do not use `Peripherals::take`in this function. fn opcontrol(&mut self) -> impl Future { async { Ok(()) } } diff --git a/packages/pros-devices/src/adi/mod.rs b/packages/pros-devices/src/adi/mod.rs index 6c814eb6..5834ca26 100644 --- a/packages/pros-devices/src/adi/mod.rs +++ b/packages/pros-devices/src/adi/mod.rs @@ -49,7 +49,7 @@ impl AdiPort { /// /// Creating new `AdiPort`s is inherently unsafe due to the possibility of constructing /// more than one device on the same port index allowing multiple mutable references to - /// the same hardware device. Prefer using [`Peripherals`] to register devices if possible. + /// the same hardware device. Prefer using [`crate::peripherals::Peripherals`] to register devices if possible. pub const unsafe fn new(index: u8, expander_index: Option) -> Self { Self { index, @@ -101,7 +101,7 @@ pub trait AdiDevice { /// Ports are indexed starting from 1. fn expander_port_index(&self) -> Option; - /// Get the variant of [`SmartDeviceType`] that this device is associated with. + /// Get the variant of [`AdiDeviceType`] that this device is associated with. fn device_type(&self) -> AdiDeviceType; } diff --git a/packages/pros-devices/src/color.rs b/packages/pros-devices/src/color.rs index c4e1e140..94b3a276 100644 --- a/packages/pros-devices/src/color.rs +++ b/packages/pros-devices/src/color.rs @@ -304,19 +304,19 @@ impl Rgb { pub const YELLOW: Rgb = Rgb::from_raw(pros_sys::COLOR_YELLOW); /// #9ACD32 color constant. pub const YELLOW_GREEN: Rgb = Rgb::from_raw(pros_sys::COLOR_YELLOW_GREEN); - /// Alias to [`COLOR_DARK_GREY`]. + /// Alias to [`Self::SLATE_GRAY`]. pub const DARK_GREY: Rgb = Rgb::from_raw(pros_sys::COLOR_DARK_GREY); - /// Alias tp [`COLOR_DARK_SLATE_GREY`]. + /// Alias to [`Self::DARK_SLATE_GRAY`]. pub const DARK_SLATE_GREY: Rgb = Rgb::from_raw(pros_sys::COLOR_DARK_SLATE_GREY); - /// Alias to [`COLOR_DIM_GREY`]. + /// Alias to [`Self::DIM_GRAY`]. pub const DIM_GREY: Rgb = Rgb::from_raw(pros_sys::COLOR_DIM_GREY); - /// Alias to [`COLOR_GREY`]. + /// Alias to [`Self::GRAY`]. pub const GREY: Rgb = Rgb::from_raw(pros_sys::COLOR_GREY); - /// Alias to [`COLOR_LIGHT_GREY`]. + /// Alias to [`Self::LIGHT_GRAY`]. pub const LIGHT_GREY: Rgb = Rgb::from_raw(pros_sys::COLOR_LIGHT_GREY); - /// Alias to [`COLOR_LIGHT_SLATE_GREY`]. + /// Alias to [`Self::LIGHT_SLATE_GRAY`]. pub const LIGHT_SLATE_GREY: Rgb = Rgb::from_raw(pros_sys::COLOR_LIGHT_SLATE_GREY); - /// Alias to [`COLOR_SLATE_GREY`]. + /// Alias to [`Self::SLATE_GREY`]. pub const SLATE_GREY: Rgb = Rgb::from_raw(pros_sys::COLOR_SLATE_GREY); const BITMASK: u32 = 0b11111111; diff --git a/packages/pros-devices/src/lib.rs b/packages/pros-devices/src/lib.rs index 9debf368..63aba64a 100644 --- a/packages/pros-devices/src/lib.rs +++ b/packages/pros-devices/src/lib.rs @@ -11,11 +11,11 @@ //! //! # Organization //! -//! - [`devices::smart`] contains abstractions and types for smart port connected devices. -//! - [`devices::adi`] contains abstractions for three wire ADI connected devices. -//! - [`devices::battery`] provides functions for getting information about the currently connected +//! - [`smart`] contains abstractions and types for smart port connected devices. +//! - [`adi`] contains abstractions for three wire ADI connected devices. +//! - [`battery`] provides functions for getting information about the currently connected //! battery. -//! - [`devices::controller`] provides types for interacting with the V5 controller. +//! - [`controller`] provides types for interacting with the V5 controller. #![no_std] #![warn( diff --git a/packages/pros-devices/src/peripherals.rs b/packages/pros-devices/src/peripherals.rs index 8d9733f6..f99c769d 100644 --- a/packages/pros-devices/src/peripherals.rs +++ b/packages/pros-devices/src/peripherals.rs @@ -208,7 +208,7 @@ impl DynamicPeripherals { Some(unsafe { SmartPort::new(port_index as u8 + 1) }) } - /// Creates an [`AdiSlot`] only if one has not been created on the given slot before. + /// Creates an [`AdiPort`] only if one has not been created on the given slot before. /// /// # Panics /// diff --git a/packages/pros-devices/src/screen.rs b/packages/pros-devices/src/screen.rs index 29b069d9..b89ae6c5 100644 --- a/packages/pros-devices/src/screen.rs +++ b/packages/pros-devices/src/screen.rs @@ -350,7 +350,7 @@ impl Screen { /// /// Creating new `Screen`s is inherently unsafe due to the possibility of constructing /// more than one screen at once allowing multiple mutable references to the same - /// hardware device. Prefer using [`Peripherals`] to register devices if possible. + /// hardware device. Prefer using [`crate::peripherals::Peripherals`] to register devices if possible. pub unsafe fn new() -> Self { Self { current_line: 0, diff --git a/packages/pros-devices/src/smart/imu.rs b/packages/pros-devices/src/smart/imu.rs index 2ec5223e..b60c5ba6 100644 --- a/packages/pros-devices/src/smart/imu.rs +++ b/packages/pros-devices/src/smart/imu.rs @@ -48,7 +48,7 @@ impl InertialSensor { /// Calibrate IMU asynchronously. /// - /// Returns an [`InertialCalibrationFuture`] that is be polled until the IMU status flag reports the sensor as + /// Returns an [`InertialCalibrateFuture`] that is be polled until the IMU status flag reports the sensor as /// no longer calibrating. /// There a 3 second timeout that will return [`InertialError::CalibrationTimedOut`] if the timeout is exceeded. pub fn calibrate(&mut self) -> InertialCalibrateFuture { diff --git a/packages/pros-devices/src/smart/mod.rs b/packages/pros-devices/src/smart/mod.rs index eb591769..158a2ae6 100644 --- a/packages/pros-devices/src/smart/mod.rs +++ b/packages/pros-devices/src/smart/mod.rs @@ -13,7 +13,7 @@ //! //! Most devices can be created with a `new` function that generally takes a port number along with other //! device-specific parameters. All sensors are thread safe, however sensors can only be safely constructed -//! using the [`Peripherals`] API. +//! using the [`crate::peripherals`] API. //! //! In cases where PROS gives the option of a blocking or non-blocking API, //! the blocking API is used for a synchronous method and the non-blocking API is used to create a future. @@ -108,7 +108,7 @@ impl SmartPort { /// Creating new `SmartPort`s is inherently unsafe due to the possibility of constructing /// more than one device on the same port index allowing multiple mutable references to /// the same hardware device. This violates rust's borrow checked guarantees. Prefer using - /// [`Peripherals`] to register devices if possible. + /// [`crate::peripherals::Peripherals`] to register devices if possible. /// /// # Examples /// diff --git a/packages/pros-devices/src/smart/motor.rs b/packages/pros-devices/src/smart/motor.rs index 5b8efaf3..b6310001 100644 --- a/packages/pros-devices/src/smart/motor.rs +++ b/packages/pros-devices/src/smart/motor.rs @@ -1,10 +1,6 @@ //! Motors and gearsets. //! -//! The motor API is similar to that of [`sensors`](crate::sensors). -//! Multiple motors can be created on the same port and they are thread safe. -//! -//! Motors can be created with the [`Motor::new`] function. -//! Once created they can be controlled with one three functions: +//! Once created motors can be controlled with one three functions: //! [`Motor::set_output`], [`Motor::set_raw_output`], and [`Motor::set_voltage`]. //! [`Motor::set_output`] takes in a f32 from -1 to 1 for ease of use with [`Controller`](crate::controller::Controller)s. //! [`Motor::set_raw_output`] takes in an i8 from -127 to 127. diff --git a/packages/pros-devices/src/smart/optical.rs b/packages/pros-devices/src/smart/optical.rs index 464e3b7b..d529887d 100644 --- a/packages/pros-devices/src/smart/optical.rs +++ b/packages/pros-devices/src/smart/optical.rs @@ -84,7 +84,7 @@ impl OpticalSensor { /// due to less available light being read by the sensor. /// /// Time value must be a [`Duration`] between 3 and 712 milliseconds. See - /// https://www.vexforum.com/t/v5-optical-sensor-refresh-rate/109632/9 for + /// for /// more information. pub fn set_integration_time(&mut self, time: Duration) -> Result<(), OpticalError> { if time < Self::MIN_INTEGRATION_TIME || time > Self::MAX_INTEGRATION_TIME { @@ -189,7 +189,7 @@ impl OpticalSensor { /// Get the most recent gesture data from the sensor. Gestures will be cleared after 500mS. /// - /// Will return [`OpticalError::GestureDetectionNotEnabled`] if the sensor is not + /// Will return [`OpticalError::GestureDetectionDisabled`] if the sensor is not /// confgured to detect gestures. pub fn last_gesture_direction(&self) -> Result { if !self.gesture_detection_enabled { @@ -201,7 +201,7 @@ impl OpticalSensor { /// Get the most recent raw gesture data from the sensor. /// - /// Will return [`OpticalError::GestureDetectionNotEnabled`] if the sensor is not + /// Will return [`OpticalError::GestureDetectionDisabled`] if the sensor is not /// confgured to detect gestures. pub fn last_gesture_raw(&self) -> Result { if !self.gesture_detection_enabled { @@ -352,7 +352,7 @@ pub enum OpticalError { /// Integration time must be between 3 and 712 milliseconds. /// - /// See https://www.vexforum.com/t/v5-optical-sensor-refresh-rate/109632/9 for more information. + /// See for more information. InvalidIntegrationTime, /// Gesture detection is not enabled for this sensor. diff --git a/packages/pros-sync/src/lib.rs b/packages/pros-sync/src/lib.rs index 1028bf56..c8c96603 100644 --- a/packages/pros-sync/src/lib.rs +++ b/packages/pros-sync/src/lib.rs @@ -21,11 +21,11 @@ use pros_core::error::Result; pub use sync::*; /// A trait for robot code that runs without the async executor spun up. -/// This trait isn't recommended. See [`AsyncRobot`] for the preferred trait to run robot code. +/// This trait isn't recommended. See `AsyncRobot` in [pros-async](https://crates.io/crates/pros-async) for the preferred trait to run robot code. pub trait SyncRobot { /// Runs during the operator control period. /// This function may be called more than once. - /// For that reason, do not use [`Peripherals::take`](prelude::Peripherals::take) in this function. + /// For that reason, do not use `Peripherals::take` in this function. fn opcontrol(&mut self) -> Result { Ok(()) } diff --git a/packages/pros-sync/src/task/mod.rs b/packages/pros-sync/src/task/mod.rs index d705037a..61395519 100644 --- a/packages/pros-sync/src/task/mod.rs +++ b/packages/pros-sync/src/task/mod.rs @@ -30,7 +30,7 @@ use snafu::Snafu; /// Creates a task to be run 'asynchronously' (More information at the [FreeRTOS docs](https://www.freertos.org/taskandcr.html)). /// Takes in a closure that can move variables if needed. -/// If your task has a loop it is advised to use [`sleep(duration)`](sleep) so that the task does not take up necessary system resources. +/// If your task has a loop it is advised to use [`delay`] so that the task does not take up necessary system resources. /// Tasks should be long-living; starting many tasks can be slow and is usually not necessary. pub fn spawn(f: F) -> TaskHandle where @@ -201,7 +201,7 @@ pub enum TaskState { Running, /// The task is currently yielding but may run in the future Ready, - /// The task is blocked. For example, it may be [`sleep`]ing or waiting on a mutex. + /// The task is blocked. For example, it may be [`delay`]ing or waiting on a mutex. /// Tasks that are in this state will usually return to the task queue after a set timeout. Blocked, /// The task is suspended. For example, it may be waiting on a mutex or semaphore. diff --git a/packages/pros-sys/src/apix.rs b/packages/pros-sys/src/apix.rs index f155daf4..ff5daa95 100644 --- a/packages/pros-sys/src/apix.rs +++ b/packages/pros-sys/src/apix.rs @@ -32,7 +32,7 @@ identifier. When used with serctl, the extra argument must be the little endian representation of the stream identifier (e.g. "sout" -> 0x74756f73) -Visit https://pros.cs.purdue.edu/v5/tutorials/topical/filesystem.html#serial +Visit to learn more. */ pub const SERCTL_ACTIVATE: u32 = 10; @@ -43,7 +43,7 @@ identifier. When used with serctl, the extra argument must be the little endian representation of the stream identifier (e.g. "sout" -> 0x74756f73) -Visit https://pros.cs.purdue.edu/v5/tutorials/topical/filesystem.html#serial +Visit to learn more. */ pub const SERCTL_DEACTIVATE: u32 = 11; @@ -53,7 +53,7 @@ Action macro to pass into fdctl that enables blocking writes for the file The extra argument is not used with this action, provide any value (e.g. NULL) instead -Visit https://pros.cs.purdue.edu/v5/tutorials/topical/filesystem.html#serial +Visit to learn more. */ pub const SERCTL_BLKWRITE: u32 = 12; @@ -63,7 +63,7 @@ Action macro to pass into fdctl that makes writes non-blocking for the file The extra argument is not used with this action, provide any value (e.g. NULL) instead -Visit https://pros.cs.purdue.edu/v5/tutorials/topical/filesystem.html#serial +Visit to learn more. */ pub const SERCTL_NOBLKWRITE: u32 = 13; @@ -74,7 +74,7 @@ capabilities The extra argument is not used with this action, provide any value (e.g. NULL) instead -Visit https://pros.cs.purdue.edu/v5/tutorials/topical/filesystem.html#serial +Visit to learn more. */ pub const SERCTL_ENABLE_COBS: u32 = 14; @@ -85,7 +85,7 @@ capabilities The extra argument is not used with this action, provide any value (e.g. NULL) instead -Visit https://pros.cs.purdue.edu/v5/tutorials/topical/filesystem.html#serial +Visit to learn more. */ pub const SERCTL_DISABLE_COBS: u32 = 15; @@ -117,7 +117,7 @@ extern "C" { Unblocks a task in the Blocked state (e.g. waiting for a delay, on a semaphore, etc.). - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#abort_delay for + See for details. */ pub fn task_abort_delay(task: task_t) -> bool; @@ -148,7 +148,7 @@ extern "C" { Creates a recursive mutex which can be locked recursively by the owner. See - https://pros.cs.purdue.edu/v5/extended/multitasking.html#recursive_mutexes + for details. \return A newly created recursive mutex. @@ -158,7 +158,7 @@ extern "C" { Takes a recursive mutex. See - https://pros.cs.purdue.edu/v5/extended/multitasking.html#recursive_mutexes + for details. \param mutex @@ -173,7 +173,7 @@ extern "C" { Gives a recursive mutex. See - https://pros.cs.purdue.edu/v5/extended/multitasking.html#recursive_mutexes + for details. \param mutex @@ -185,7 +185,7 @@ extern "C" { /** Returns a handle to the current owner of a mutex. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#extra for + See for details. \param mutex @@ -198,7 +198,7 @@ extern "C" { /** Creates a counting sempahore. - See https://pros.cs.purdue.edu/v5/tutorials/multitasking.html#semaphores for + See for details. \param max_count @@ -213,7 +213,7 @@ extern "C" { /** Deletes a semaphore (or binary semaphore) - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#semaphores for + See for details. \param sem @@ -224,7 +224,7 @@ extern "C" { Creates a binary semaphore. See - https://pros.cs.purdue.edu/v5/extended/multitasking#.htmlbinary_semaphores + for details. \return A newly created semaphore. @@ -234,7 +234,7 @@ extern "C" { Waits for the semaphore's value to be greater than 0. If the value is already greater than 0, this function immediately returns. - See https://pros.cs.purdue.edu/v5/tutorials/multitasking.html#semaphores for + See for details. \param sem @@ -252,7 +252,7 @@ extern "C" { /** Increments a semaphore's value. - See https://pros.cs.purdue.edu/v5/tutorials/multitasking.html#semaphores for + See for details. \param sem @@ -266,7 +266,7 @@ extern "C" { /** Returns the current value of the semaphore. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#extra for + See for details. \param sem @@ -279,7 +279,7 @@ extern "C" { /** Creates a queue. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#queues for + See for details. \param length @@ -295,7 +295,7 @@ extern "C" { Posts an item to the front of a queue. The item is queued by copy, not by reference. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#queues for + See for details. \param queue @@ -314,7 +314,7 @@ extern "C" { Posts an item to the end of a queue. The item is queued by copy, not by reference. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#queues for + See for details. \param queue @@ -332,7 +332,7 @@ extern "C" { /** Receive an item from a queue without removing the item from the queue. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#queues for + See for details. \param queue @@ -349,7 +349,7 @@ extern "C" { /** Receive an item from the queue. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#queues for + See for details. \param queue @@ -368,7 +368,7 @@ extern "C" { /** Return the number of messages stored in a queue. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#queues for + See for details. \param queue @@ -380,7 +380,7 @@ extern "C" { /** Return the number of spaces left in a queue. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#queues for + See for details. \param queue @@ -392,7 +392,7 @@ extern "C" { /** Delete a queue. - See https://pros.cs.purdue.edu/v5/extended/multitasking.html#queues for + See for details. \param queue diff --git a/packages/pros-sys/src/motor.rs b/packages/pros-sys/src/motor.rs index 0b2b0f0e..b893904b 100644 --- a/packages/pros-sys/src/motor.rs +++ b/packages/pros-sys/src/motor.rs @@ -449,7 +449,7 @@ extern "C" { \param port The V5 port number from 1-21 - \param[in] timestamp + \param\[in] timestamp A pointer to a time in milliseconds for which the encoder count will be returned. If NULL, the timestamp at which the encoder count was read will not be supplied diff --git a/packages/pros-sys/src/rtos.rs b/packages/pros-sys/src/rtos.rs index 402da0e5..480bd1c7 100644 --- a/packages/pros-sys/src/rtos.rs +++ b/packages/pros-sys/src/rtos.rs @@ -173,7 +173,7 @@ extern "C" { pub fn task_get_current() -> task_t; /** Sends a simple notification to task and increments the notification counter. - See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + See for details. \param task @@ -184,7 +184,7 @@ extern "C" { /** Utilizes task notifications to wait until specified task is complete and deleted, then continues to execute the program. Analogous to std::thread::join in C++. - See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + See for details. \param task @@ -196,7 +196,7 @@ extern "C" { retrieve the value of the notification in the target task before modifying the notification value. - See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + See for details. \param task @@ -222,7 +222,7 @@ extern "C" { ) -> u32; /** Waits for a notification to be nonzero. - See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + See for details. \param clear_on_exit @@ -237,7 +237,7 @@ extern "C" { pub fn task_notify_take(clear_on_exit: bool, timeout: u32) -> u32; /** Clears the notification for a task. - See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for + See for details. \param task @@ -247,7 +247,7 @@ extern "C" { pub fn task_notify_clear(task: task_t) -> bool; /** Creates a mutex. - See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + See for details. \return A handle to a newly created mutex. If an error occurred, NULL will be @@ -256,7 +256,7 @@ extern "C" { /** Takes and locks a mutex, waiting for up to a certain number of milliseconds before timing out. - See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes + See for details. \param mutex diff --git a/packages/pros-sys/src/vision.rs b/packages/pros-sys/src/vision.rs index 0c29c265..a3272d5d 100644 --- a/packages/pros-sys/src/vision.rs +++ b/packages/pros-sys/src/vision.rs @@ -213,7 +213,7 @@ extern "C" { ) -> vision_object_s_t; /** Gets the exposure parameter of the Vision Sensor. See - https://pros.cs.purdue.edu/v5/tutorials/topical/vision.html#exposure-setting + for more details. This function uses the following values of errno when an error state is @@ -224,7 +224,7 @@ extern "C" { \param port The V5 port number from 1-21 - \return The current exposure setting from [0,150], PROS_ERR if an error + \return The current exposure setting from \[0,150], PROS_ERR if an error occurred */ pub fn vision_get_exposure(port: u8) -> i32; @@ -283,7 +283,7 @@ extern "C" { (0 is the largest item, 1 is the second largest, etc.) \param object_count The number of objects to read - \param[out] object_arr + \param\[out] object_arr A pointer to copy the objects into \return The number of object signatures copied. This number will be less than @@ -317,7 +317,7 @@ extern "C" { (0 is the largest item, 1 is the second largest, etc.) \param signature The signature ID [1-7] for which objects will be returned. - \param[out] object_arr + \param\[out] object_arr A pointer to copy the objects into \return The number of object signatures copied. This number will be less than @@ -351,7 +351,7 @@ extern "C" { (0 is the largest item, 1 is the second largest, etc.) \param color_code The vision_color_code_t for which objects will be returned - \param[out] object_arr + \param\[out] object_arr A pointer to copy the objects into \return The number of object signatures copied. This number will be less than @@ -388,7 +388,7 @@ extern "C" { The V5 port number from 1-21 \param signature_id The signature id to store into - \param[in] signature_ptr + \param\[in] signature_ptr A pointer to the signature to save \return 1 if no errors occurred, PROS_ERR otherwise @@ -418,7 +418,7 @@ extern "C" { pub fn vision_set_auto_white_balance(port: u8, enable: u8) -> i32; /** Sets the exposure parameter of the Vision Sensor. See - https://pros.cs.purdue.edu/v5/tutorials/topical/vision.html#exposure-setting + for more details. This function uses the following values of errno when an error state is @@ -429,7 +429,7 @@ extern "C" { \param port The V5 port number from 1-21 \param percent - The new exposure setting from [0,150] + The new exposure setting from \[0,150] \return 1 if the operation was successful or PROS_ERR if the operation failed, setting errno. From a9d579a846137d16c9a436fa1ace02afe18c8ce5 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 5 Feb 2024 14:27:31 -0800 Subject: [PATCH 62/96] refactor: remove useless async_runtime module --- packages/pros-async/src/async_runtime/mod.rs | 23 ------------------- .../src/{async_runtime => }/executor.rs | 0 packages/pros-async/src/lib.rs | 22 +++++++++++++++--- .../src/{async_runtime => }/reactor.rs | 0 packages/pros/src/lib.rs | 3 +-- 5 files changed, 20 insertions(+), 28 deletions(-) delete mode 100644 packages/pros-async/src/async_runtime/mod.rs rename packages/pros-async/src/{async_runtime => }/executor.rs (100%) rename packages/pros-async/src/{async_runtime => }/reactor.rs (100%) diff --git a/packages/pros-async/src/async_runtime/mod.rs b/packages/pros-async/src/async_runtime/mod.rs deleted file mode 100644 index acb1e545..00000000 --- a/packages/pros-async/src/async_runtime/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! A tiny async runtime. -//! -//! This runtime can be used outside of the main task, but it is reccomended to only use either -//! real FreeRTOS tasks or this async runtime. - -use core::future::Future; - -use async_task::Task; - -pub(crate) mod executor; -pub(crate) mod reactor; - -/// Runs a future in the background without having to await it -/// To get the the return value you can await a task. -pub fn spawn(future: impl Future + 'static) -> Task { - executor::EXECUTOR.with(|e| e.spawn(future)) -} - -/// Blocks the current task untill a return value can be extracted from the provided future. -/// Does not poll all futures to completion. -pub fn block_on(future: F) -> F::Output { - executor::EXECUTOR.with(|e| e.block_on(spawn(future))) -} diff --git a/packages/pros-async/src/async_runtime/executor.rs b/packages/pros-async/src/executor.rs similarity index 100% rename from packages/pros-async/src/async_runtime/executor.rs rename to packages/pros-async/src/executor.rs diff --git a/packages/pros-async/src/lib.rs b/packages/pros-async/src/lib.rs index bc561d5c..24d6bbcd 100644 --- a/packages/pros-async/src/lib.rs +++ b/packages/pros-async/src/lib.rs @@ -1,6 +1,8 @@ //! Tiny async runtime and robot traits for `pros-rs`. //! The async executor supports spawning tasks and blocking on futures. //! It has a reactor to improve the performance of some futures. +//! It is recommended to use the `AsyncRobot` trait to run robot code. +//! FreeRTOS tasks can still be used, but it is recommended to use only async tasks for performance. #![no_std] #![feature(negative_impls)] @@ -14,13 +16,27 @@ extern crate alloc; -pub mod async_runtime; use core::{future::Future, task::Poll}; -use async_runtime::executor::EXECUTOR; -pub use async_runtime::*; +use async_task::Task; +use executor::EXECUTOR; use pros_core::error::Result; +mod executor; +mod reactor; + +/// Runs a future in the background without having to await it +/// To get the the return value you can await a task. +pub fn spawn(future: impl Future + 'static) -> Task { + executor::EXECUTOR.with(|e| e.spawn(future)) +} + +/// Blocks the current task untill a return value can be extracted from the provided future. +/// Does not poll all futures to completion. +pub fn block_on(future: F) -> F::Output { + executor::EXECUTOR.with(|e| e.block_on(spawn(future))) +} + /// A future that will complete after the given duration. /// Sleep futures that are closer to completion are prioritized to improve accuracy. #[derive(Debug)] diff --git a/packages/pros-async/src/async_runtime/reactor.rs b/packages/pros-async/src/reactor.rs similarity index 100% rename from packages/pros-async/src/async_runtime/reactor.rs rename to packages/pros-async/src/reactor.rs diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index ba55a1b0..934e704e 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -72,7 +72,7 @@ pub use pros_sync as sync; /// This module is meant to be glob imported. pub mod prelude { #[cfg(feature = "async")] - pub use pros_async::{async_robot, async_runtime::*, sleep, AsyncRobot}; + pub use pros_async::{async_robot, spawn, block_on, sleep, AsyncRobot}; #[cfg(feature = "core")] pub use pros_core::{ dbg, eprint, eprintln, @@ -113,7 +113,6 @@ pub mod prelude { #[cfg(feature = "sync")] pub use pros_sync::{ os_task_local, sync_robot, - task::{delay, spawn}, SyncRobot, }; } From b9c7ba50a8e495b9e0ce9f0b044c15c2b61908eb Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 00:28:32 -0800 Subject: [PATCH 63/96] refactor: move FreeRTOS tasks into pros-core --- packages/pros-async/src/executor.rs | 2 +- packages/pros-async/src/lib.rs | 8 +- packages/pros-core/Cargo.toml | 1 + packages/pros-core/src/lib.rs | 2 + packages/{pros-sync => pros-core}/src/sync.rs | 2 +- .../src/task/local.rs | 0 .../{pros-sync => pros-core}/src/task/mod.rs | 3 +- packages/pros-panic/Cargo.toml | 1 - packages/pros-panic/src/lib.rs | 75 ++++++++++++++++++- packages/pros-sync/Cargo.toml | 1 - packages/pros-sync/src/lib.rs | 6 -- packages/pros/examples/accessories.rs | 4 +- packages/pros/src/lib.rs | 8 +- 13 files changed, 87 insertions(+), 26 deletions(-) rename packages/{pros-sync => pros-core}/src/sync.rs (99%) rename packages/{pros-sync => pros-core}/src/task/local.rs (100%) rename packages/{pros-sync => pros-core}/src/task/mod.rs (99%) diff --git a/packages/pros-async/src/executor.rs b/packages/pros-async/src/executor.rs index 8db68da6..5628263b 100644 --- a/packages/pros-async/src/executor.rs +++ b/packages/pros-async/src/executor.rs @@ -9,7 +9,7 @@ use core::{ }; use async_task::{Runnable, Task}; -use pros_sync::{os_task_local, task::delay}; +use pros_core::{os_task_local, task::delay}; use waker_fn::waker_fn; use super::reactor::Reactor; diff --git a/packages/pros-async/src/lib.rs b/packages/pros-async/src/lib.rs index 24d6bbcd..25b5cf5b 100644 --- a/packages/pros-async/src/lib.rs +++ b/packages/pros-async/src/lib.rs @@ -103,7 +103,7 @@ macro_rules! __gen_async_exports { #[doc(hidden)] #[no_mangle] extern "C" fn opcontrol() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe { + $crate::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe { ROBOT .as_mut() .expect("Expected initialize to run before opcontrol") @@ -114,7 +114,7 @@ macro_rules! __gen_async_exports { #[doc(hidden)] #[no_mangle] extern "C" fn autonomous() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::auto(unsafe { + $crate::block_on(<$rbt as $crate::AsyncRobot>::auto(unsafe { ROBOT .as_mut() .expect("Expected initialize to run before auto") @@ -125,7 +125,7 @@ macro_rules! __gen_async_exports { #[doc(hidden)] #[no_mangle] extern "C" fn disabled() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::disabled(unsafe { + $crate::block_on(<$rbt as $crate::AsyncRobot>::disabled(unsafe { ROBOT .as_mut() .expect("Expected initialize to run before disabled") @@ -136,7 +136,7 @@ macro_rules! __gen_async_exports { #[doc(hidden)] #[no_mangle] extern "C" fn competition_initialize() { - $crate::async_runtime::block_on(<$rbt as $crate::AsyncRobot>::comp_init(unsafe { + $crate::block_on(<$rbt as $crate::AsyncRobot>::comp_init(unsafe { ROBOT .as_mut() .expect("Expected initialize to run before comp_init") diff --git a/packages/pros-core/Cargo.toml b/packages/pros-core/Cargo.toml index 712f7e04..0e974784 100644 --- a/packages/pros-core/Cargo.toml +++ b/packages/pros-core/Cargo.toml @@ -12,6 +12,7 @@ snafu = { version = "0.8.0", default-features = false, features = [ "rust_1_61", "unstable-core-error", ] } +spin = "0.9.8" [target.'cfg(target_arch = "wasm32")'.dependencies] dlmalloc = { version = "0.2.4", features = ["global"] } diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index 52d6bc5d..106242d5 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -24,4 +24,6 @@ pub mod competition; pub mod error; pub mod io; pub mod pros_alloc; +pub mod sync; +pub mod task; pub mod time; diff --git a/packages/pros-sync/src/sync.rs b/packages/pros-core/src/sync.rs similarity index 99% rename from packages/pros-sync/src/sync.rs rename to packages/pros-core/src/sync.rs index 62afec98..7233996e 100644 --- a/packages/pros-sync/src/sync.rs +++ b/packages/pros-core/src/sync.rs @@ -4,7 +4,7 @@ use core::{cell::UnsafeCell, fmt::Debug, mem}; -use pros_core::error::take_errno; +use crate::error::take_errno; /// The basic mutex type. /// Mutexes are used to share variables between tasks safely. diff --git a/packages/pros-sync/src/task/local.rs b/packages/pros-core/src/task/local.rs similarity index 100% rename from packages/pros-sync/src/task/local.rs rename to packages/pros-core/src/task/local.rs diff --git a/packages/pros-sync/src/task/mod.rs b/packages/pros-core/src/task/mod.rs similarity index 99% rename from packages/pros-sync/src/task/mod.rs rename to packages/pros-core/src/task/mod.rs index 61395519..7c40d103 100644 --- a/packages/pros-sync/src/task/mod.rs +++ b/packages/pros-core/src/task/mod.rs @@ -25,9 +25,10 @@ use alloc::{ }; use core::{ffi::CStr, hash::Hash, str::Utf8Error, time::Duration}; -use pros_core::{bail_on, map_errno}; use snafu::Snafu; +use crate::{bail_on, map_errno}; + /// Creates a task to be run 'asynchronously' (More information at the [FreeRTOS docs](https://www.freertos.org/taskandcr.html)). /// Takes in a closure that can move variables if needed. /// If your task has a loop it is advised to use [`delay`] so that the task does not take up necessary system resources. diff --git a/packages/pros-panic/Cargo.toml b/packages/pros-panic/Cargo.toml index 0e09c218..17a77f75 100644 --- a/packages/pros-panic/Cargo.toml +++ b/packages/pros-panic/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" pros-core = { version = "0.1.0", path = "../pros-core" } pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } pros-sys = { version = "0.6.0", path = "../pros-sys" } -pros-sync = { version = "0.1.0", path = "../pros-sync" } [features] default = ["display_panics"] diff --git a/packages/pros-panic/src/lib.rs b/packages/pros-panic/src/lib.rs index f3608b2d..22c74750 100644 --- a/packages/pros-panic/src/lib.rs +++ b/packages/pros-panic/src/lib.rs @@ -12,12 +12,11 @@ )] extern crate alloc; -use alloc::format; +use alloc::{format, string::String}; use pros_core::eprintln; #[cfg(feature = "display_panics")] use pros_devices::Screen; -use pros_sync::task; #[cfg(target_arch = "wasm32")] extern "C" { @@ -25,10 +24,78 @@ extern "C" { fn sim_log_backtrace(); } +/// Draw an error box to the screen. +/// +/// This function is internally used by the pros-rs panic handler for displaying +/// panic messages graphically before exiting. +#[cfg(feature = "display_panics")] +fn draw_error( + screen: &mut pros_devices::screen::Screen, + msg: &str, +) -> Result<(), pros_devices::screen::ScreenError> { + const ERROR_BOX_MARGIN: i16 = 16; + const ERROR_BOX_PADDING: i16 = 16; + const LINE_MAX_WIDTH: usize = 52; + + let error_box_rect = pros_devices::screen::Rect::new( + ERROR_BOX_MARGIN, + ERROR_BOX_MARGIN, + pros_devices::screen::SCREEN_HORIZONTAL_RESOLUTION - ERROR_BOX_MARGIN, + pros_devices::screen::SCREEN_VERTICAL_RESOLUTION - ERROR_BOX_MARGIN, + ); + + screen.fill(&error_box_rect, pros_devices::color::Rgb::RED)?; + screen.stroke(&error_box_rect, pros_devices::color::Rgb::WHITE)?; + + let mut buffer = String::new(); + let mut line: i16 = 0; + + for (i, character) in msg.char_indices() { + if !character.is_ascii_control() { + buffer.push(character); + } + + if character == '\n' || ((buffer.len() % LINE_MAX_WIDTH == 0) && (i > 0)) { + screen.fill( + &pros_devices::screen::Text::new( + buffer.as_str(), + pros_devices::screen::TextPosition::Point( + ERROR_BOX_MARGIN + ERROR_BOX_PADDING, + ERROR_BOX_MARGIN + + ERROR_BOX_PADDING + + (line * pros_devices::screen::SCREEN_LINE_HEIGHT), + ), + pros_devices::screen::TextFormat::Small, + ), + pros_devices::color::Rgb::WHITE, + )?; + + line += 1; + buffer.clear(); + } + } + + screen.fill( + &pros_devices::screen::Text::new( + buffer.as_str(), + pros_devices::screen::TextPosition::Point( + ERROR_BOX_MARGIN + ERROR_BOX_PADDING, + ERROR_BOX_MARGIN + + ERROR_BOX_PADDING + + (line * pros_devices::screen::SCREEN_LINE_HEIGHT), + ), + pros_devices::screen::TextFormat::Small, + ), + pros_devices::color::Rgb::WHITE, + )?; + + Ok(()) +} + #[panic_handler] /// The panic handler for pros-rs. pub fn panic(info: &core::panic::PanicInfo<'_>) -> ! { - let current_task = task::current(); + let current_task = pros_core::task::current(); let task_name = current_task.name().unwrap_or_else(|_| "".into()); @@ -40,7 +107,7 @@ pub fn panic(info: &core::panic::PanicInfo<'_>) -> ! { unsafe { #[cfg(feature = "display_panics")] - Screen::new().draw_error(&msg).unwrap_or_else(|err| { + draw_error(&mut Screen::new(), &msg).unwrap_or_else(|err| { eprintln!("Failed to draw error message to screen: {err}"); }); diff --git a/packages/pros-sync/Cargo.toml b/packages/pros-sync/Cargo.toml index 578fdfc2..14e25b0f 100644 --- a/packages/pros-sync/Cargo.toml +++ b/packages/pros-sync/Cargo.toml @@ -12,4 +12,3 @@ snafu = { version = "0.8.0", default-features = false, features = [ "rust_1_61", "unstable-core-error", ] } -spin = "0.9.8" diff --git a/packages/pros-sync/src/lib.rs b/packages/pros-sync/src/lib.rs index c8c96603..ea384803 100644 --- a/packages/pros-sync/src/lib.rs +++ b/packages/pros-sync/src/lib.rs @@ -12,13 +12,7 @@ clippy::missing_const_for_fn )] -extern crate alloc; - -pub mod sync; -pub mod task; - use pros_core::error::Result; -pub use sync::*; /// A trait for robot code that runs without the async executor spun up. /// This trait isn't recommended. See `AsyncRobot` in [pros-async](https://crates.io/crates/pros-async) for the preferred trait to run robot code. diff --git a/packages/pros/examples/accessories.rs b/packages/pros/examples/accessories.rs index 119934b9..729bf1e6 100644 --- a/packages/pros/examples/accessories.rs +++ b/packages/pros/examples/accessories.rs @@ -12,7 +12,7 @@ use pros::{ Controller, }, prelude::*, - sync::Mutex, + core::sync::Mutex, }; struct ExampleRobot { @@ -50,7 +50,7 @@ impl AsyncRobot for ExampleRobot { self.vision.set_led(LedMode::On(Rgb::new(0, 0, 255))); // Spawn a new task that will print whether or not the motor is stopped constantly. - spawn({ + pros_core::task::spawn({ let motor = Arc::clone(&self.motor); // Obtain a shared reference to our motor to safely share between tasks. move || loop { diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 934e704e..b9e2ca00 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -72,13 +72,14 @@ pub use pros_sync as sync; /// This module is meant to be glob imported. pub mod prelude { #[cfg(feature = "async")] - pub use pros_async::{async_robot, spawn, block_on, sleep, AsyncRobot}; + pub use pros_async::{async_robot, block_on, sleep, spawn, AsyncRobot}; #[cfg(feature = "core")] pub use pros_core::{ dbg, eprint, eprintln, error::{PortError, Result}, io::{BufRead, Read, Seek, Write}, print, println, + task::delay, }; #[cfg(feature = "devices")] pub use pros_devices::{ @@ -111,8 +112,5 @@ pub mod prelude { }, }; #[cfg(feature = "sync")] - pub use pros_sync::{ - os_task_local, sync_robot, - SyncRobot, - }; + pub use pros_sync::{sync_robot, SyncRobot}; } From 4788caf2fe38b0fed9808af4752c6a3e3847cc57 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 00:31:46 -0800 Subject: [PATCH 64/96] =?UTF-8?q?chore:=20format=20(=E2=80=A2=E1=B7=84?= =?UTF-8?q?=E2=8C=93=E2=80=A2=E1=B7=85=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/pros/examples/accessories.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros/examples/accessories.rs b/packages/pros/examples/accessories.rs index 729bf1e6..fb19faba 100644 --- a/packages/pros/examples/accessories.rs +++ b/packages/pros/examples/accessories.rs @@ -7,12 +7,12 @@ use alloc::sync::Arc; use core::time::Duration; use pros::{ + core::sync::Mutex, devices::{ smart::vision::{LedMode, VisionZeroPoint}, Controller, }, prelude::*, - core::sync::Mutex, }; struct ExampleRobot { From 42e589c2ca539602a804b2baa0041707062cd61e Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 13:44:54 -0800 Subject: [PATCH 65/96] fix: remove pros-math package for now --- packages/pros-math/Cargo.toml | 10 ------ packages/pros-math/src/lib.rs | 4 --- packages/pros-math/src/pid.rs | 67 ----------------------------------- packages/pros/Cargo.toml | 4 +-- 4 files changed, 1 insertion(+), 84 deletions(-) delete mode 100644 packages/pros-math/Cargo.toml delete mode 100644 packages/pros-math/src/lib.rs delete mode 100644 packages/pros-math/src/pid.rs diff --git a/packages/pros-math/Cargo.toml b/packages/pros-math/Cargo.toml deleted file mode 100644 index e0d17465..00000000 --- a/packages/pros-math/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "pros-math" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -pros-sys = { version = "0.6.0", path = "../pros-sys" } -pros-core = { version = "0.1.0", path = "../pros-core" } diff --git a/packages/pros-math/src/lib.rs b/packages/pros-math/src/lib.rs deleted file mode 100644 index 4e86cbb6..00000000 --- a/packages/pros-math/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![no_std] -extern crate alloc; - -pub mod pid; diff --git a/packages/pros-math/src/pid.rs b/packages/pros-math/src/pid.rs deleted file mode 100644 index 4d8b37fe..00000000 --- a/packages/pros-math/src/pid.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! PID controllers. -//! -//! PID controllers are first created with [`PidController::new`] -//! and then can be utilized by calling [`PidController::update`] repeatedly. - -/// A proportional–integral–derivative controller. -/// -/// This controller is used to smoothly move motors to a certain point, -/// and allows for feedback-based power adjustments. This is desirable -/// over just setting the motor power, as it can be tuned to make the -/// motor stop in exactly the right position without overshooting. -#[derive(Debug, Clone, Copy)] -pub struct PidController { - /// Proportional constant. This is multiplied by the error to get the - /// proportional component of the output. - pub kp: f32, - /// Integral constant. This accounts for the past values of the error. - pub ki: f32, - /// Derivative constant. This allows you to change the motor behavior - /// based on the rate of change of the error (predicting future values). - pub kd: f32, - - last_time: i32, - last_position: f32, - i: f32, -} - -impl PidController { - /// Create a new PID controller with the given constants. - pub const fn new(kp: f32, ki: f32, kd: f32) -> Self { - Self { - kp, - ki, - kd, - last_time: 0, - last_position: 0.0, - i: 0.0, - } - } - - /// Update the PID controller with the current setpoint and position. - pub fn update(&mut self, setpoint: f32, position: f32) -> f32 { - let time = unsafe { pros_sys::clock() }; - let mut delta_time = (time - self.last_time) as f32 / pros_sys::CLOCKS_PER_SEC as f32; - if delta_time == 0.0 { - delta_time += 0.001; - } - let error = setpoint - position; - - self.i += error * delta_time; - - let p = self.kp * error; - let i = self.ki * self.i; - - let mut d = (position - self.last_position) / delta_time; - if d.is_nan() { - d = 0.0 - } - - let output = p + i + d; - - self.last_position = position; - self.last_time = time; - - output - } -} diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 470150a8..4cbf07f0 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -21,12 +21,11 @@ rust-version = "1.75.0" pros-sync = { version = "0.1.0", path = "../pros-sync", optional = true } pros-async = { version = "0.1.0", path = "../pros-async", optional = true } pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } -pros-math = { version = "0.1.0", path = "../pros-math", optional = true } pros-panic = { version = "0.1.0", path = "../pros-panic", optional = true } pros-core = { version = "0.1.0", path = "../pros-core", optional = true } [features] -default = ["async", "sync", "devices", "math", "panic", "display_panics", "core"] +default = ["async", "sync", "devices", "panic", "display_panics", "core"] core = ["dep:pros-core"] @@ -34,7 +33,6 @@ async = ["dep:pros-async"] sync = ["dep:pros-sync"] devices = ["dep:pros-devices"] -math = ["dep:pros-math"] panic = ["dep:pros-panic"] display_panics = ["pros-panic/display_panics"] From 644b2dfa202c1a544f88ef81839173d43099671f Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 14:06:22 -0800 Subject: [PATCH 66/96] fix(docs): update pros-core docs --- packages/pros-core/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index 106242d5..18417d2b 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -7,6 +7,8 @@ //! - Errno handling: [`error`] //! - Serial terminal printing: [`io`] //! - No-std [`Instant`](time::Instant)s: [`time`] +//! - Synchronization primitives: [`sync`] +//! - FreeRTOS task management: [`task`] #![no_std] #![feature(error_in_core)] From 19bc0eb7c2e515452224893b6c473a81495ce01c Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 19:07:42 -0800 Subject: [PATCH 67/96] refactor: put lints in workspace instead of per crate --- Cargo.toml | 8 ++++++++ packages/pros-async/Cargo.toml | 5 +++-- packages/pros-async/src/lib.rs | 7 ------- packages/pros-core/Cargo.toml | 3 +++ packages/pros-core/src/lib.rs | 7 ------- packages/pros-devices/Cargo.toml | 3 +++ packages/pros-devices/src/lib.rs | 7 ------- packages/pros-panic/Cargo.toml | 3 +++ packages/pros-panic/src/lib.rs | 8 +------- packages/pros-sync/Cargo.toml | 8 +++----- packages/pros-sync/src/lib.rs | 7 ------- packages/pros/Cargo.toml | 3 +++ 12 files changed, 27 insertions(+), 42 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 225effa9..322f9564 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,11 @@ [workspace] members = ["packages/*"] resolver = "2" + +[workspace.lints.rust] +rust_2018_idioms = "warn" +missing_docs = "warn" +unsafe_op_in_unsafe_fn = "warn" + +[workspace.lints.clippy] +missing_const_for_fn = "warn" diff --git a/packages/pros-async/Cargo.toml b/packages/pros-async/Cargo.toml index 7e5d3e73..f0c1c941 100644 --- a/packages/pros-async/Cargo.toml +++ b/packages/pros-async/Cargo.toml @@ -6,9 +6,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -futures = { version = "0.3.28", default-features = false, features = ["alloc"] } async-task = { version = "4.5.0", default-features = false } pros-core = { version = "0.1.0", path = "../pros-core" } waker-fn = "1.1.1" pros-sys = { version = "0.6.0", path = "../pros-sys" } -pros-sync = { version = "0.1.0", path = "../pros-sync" } + +[lints] +workspace = true diff --git a/packages/pros-async/src/lib.rs b/packages/pros-async/src/lib.rs index 25b5cf5b..6d1beb30 100644 --- a/packages/pros-async/src/lib.rs +++ b/packages/pros-async/src/lib.rs @@ -6,13 +6,6 @@ #![no_std] #![feature(negative_impls)] -#![warn( - missing_docs, - rust_2018_idioms, - missing_debug_implementations, - unsafe_op_in_unsafe_fn, - clippy::missing_const_for_fn -)] extern crate alloc; diff --git a/packages/pros-core/Cargo.toml b/packages/pros-core/Cargo.toml index 0e974784..8b728b22 100644 --- a/packages/pros-core/Cargo.toml +++ b/packages/pros-core/Cargo.toml @@ -16,3 +16,6 @@ spin = "0.9.8" [target.'cfg(target_arch = "wasm32")'.dependencies] dlmalloc = { version = "0.2.4", features = ["global"] } + +[lints] +workspace = true diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index 18417d2b..fded44ec 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -12,13 +12,6 @@ #![no_std] #![feature(error_in_core)] -#![warn( - missing_docs, - rust_2018_idioms, - missing_debug_implementations, - unsafe_op_in_unsafe_fn, - clippy::missing_const_for_fn -)] extern crate alloc; diff --git a/packages/pros-devices/Cargo.toml b/packages/pros-devices/Cargo.toml index c919df49..6c58f2f2 100644 --- a/packages/pros-devices/Cargo.toml +++ b/packages/pros-devices/Cargo.toml @@ -13,3 +13,6 @@ snafu = { version = "0.8.0", default-features = false, features = [ "unstable-core-error", ] } no_std_io = { version = "0.6.0", features = ["alloc"] } + +[lints] +workspace = true diff --git a/packages/pros-devices/src/lib.rs b/packages/pros-devices/src/lib.rs index 63aba64a..0a56b96a 100644 --- a/packages/pros-devices/src/lib.rs +++ b/packages/pros-devices/src/lib.rs @@ -18,13 +18,6 @@ //! - [`controller`] provides types for interacting with the V5 controller. #![no_std] -#![warn( - missing_docs, - rust_2018_idioms, - missing_debug_implementations, - unsafe_op_in_unsafe_fn, - clippy::missing_const_for_fn -)] extern crate alloc; diff --git a/packages/pros-panic/Cargo.toml b/packages/pros-panic/Cargo.toml index 17a77f75..54234af7 100644 --- a/packages/pros-panic/Cargo.toml +++ b/packages/pros-panic/Cargo.toml @@ -14,3 +14,6 @@ pros-sys = { version = "0.6.0", path = "../pros-sys" } default = ["display_panics"] display_panics = ["dep:pros-devices"] + +[lints] +workspace = true diff --git a/packages/pros-panic/src/lib.rs b/packages/pros-panic/src/lib.rs index 22c74750..aefae6e3 100644 --- a/packages/pros-panic/src/lib.rs +++ b/packages/pros-panic/src/lib.rs @@ -3,13 +3,7 @@ //! If the `display_panics` feature is enabled, it will also display the panic message on the V5 Brain display. #![no_std] -#![warn( - missing_docs, - rust_2018_idioms, - missing_debug_implementations, - unsafe_op_in_unsafe_fn, - clippy::missing_const_for_fn -)] + extern crate alloc; use alloc::{format, string::String}; diff --git a/packages/pros-sync/Cargo.toml b/packages/pros-sync/Cargo.toml index 14e25b0f..1df90f53 100644 --- a/packages/pros-sync/Cargo.toml +++ b/packages/pros-sync/Cargo.toml @@ -7,8 +7,6 @@ edition = "2021" [dependencies] pros-core = { version = "0.1.0", path = "../pros-core" } -pros-sys = { version = "0.6.0", path = "../pros-sys" } -snafu = { version = "0.8.0", default-features = false, features = [ - "rust_1_61", - "unstable-core-error", -] } + +[lints] +workspace = true diff --git a/packages/pros-sync/src/lib.rs b/packages/pros-sync/src/lib.rs index ea384803..10834c21 100644 --- a/packages/pros-sync/src/lib.rs +++ b/packages/pros-sync/src/lib.rs @@ -4,13 +4,6 @@ //! For more information on the task api, see the [`task`] module. #![no_std] -#![warn( - missing_docs, - rust_2018_idioms, - missing_debug_implementations, - unsafe_op_in_unsafe_fn, - clippy::missing_const_for_fn -)] use pros_core::error::Result; diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 4cbf07f0..caaff233 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -36,3 +36,6 @@ devices = ["dep:pros-devices"] panic = ["dep:pros-panic"] display_panics = ["pros-panic/display_panics"] + +[lints] +workspace = true From 0ac520f4611a34cb05b69492bbc67c1d78fe9b82 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 19:21:38 -0800 Subject: [PATCH 68/96] refactor: move competition module into pros_devices --- packages/pros-core/src/lib.rs | 1 - packages/{pros-core => pros-devices}/src/competition.rs | 0 packages/pros-devices/src/lib.rs | 1 + 3 files changed, 1 insertion(+), 1 deletion(-) rename packages/{pros-core => pros-devices}/src/competition.rs (100%) diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index fded44ec..37322e9b 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -15,7 +15,6 @@ extern crate alloc; -pub mod competition; pub mod error; pub mod io; pub mod pros_alloc; diff --git a/packages/pros-core/src/competition.rs b/packages/pros-devices/src/competition.rs similarity index 100% rename from packages/pros-core/src/competition.rs rename to packages/pros-devices/src/competition.rs diff --git a/packages/pros-devices/src/lib.rs b/packages/pros-devices/src/lib.rs index 0a56b96a..06169c96 100644 --- a/packages/pros-devices/src/lib.rs +++ b/packages/pros-devices/src/lib.rs @@ -25,6 +25,7 @@ pub mod adi; pub mod smart; pub mod battery; +pub mod competition; pub mod controller; pub mod peripherals; pub mod position; From 5d6dabaf91dadea7c3a5f9b7b375ee2f8a1e96ed Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 10 Feb 2024 19:26:44 -0800 Subject: [PATCH 69/96] docs(pros-sync): update outdated module docs --- packages/pros-sync/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/pros-sync/src/lib.rs b/packages/pros-sync/src/lib.rs index 10834c21..6f7df18a 100644 --- a/packages/pros-sync/src/lib.rs +++ b/packages/pros-sync/src/lib.rs @@ -1,7 +1,4 @@ -//! Synchronization primitives and FreeRTOS task management for [`pros-rs`]. -//! -//! The synchronization types are modeled after the standard library. -//! For more information on the task api, see the [`task`] module. +//! Synchronous robot code trait for [pros-rs](https://crates.io/crates/pros). #![no_std] From 2c29b6535bf8b2a2385fccad66eae4cd2f256339 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 11 Feb 2024 05:29:12 -0800 Subject: [PATCH 70/96] chore: format --- packages/pros-devices/src/adi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros-devices/src/adi/mod.rs b/packages/pros-devices/src/adi/mod.rs index 5834ca26..d3853f64 100644 --- a/packages/pros-devices/src/adi/mod.rs +++ b/packages/pros-devices/src/adi/mod.rs @@ -1,7 +1,7 @@ //! ADI (Triport) devices on the Vex V5. use pros_core::{bail_on, error::PortError, map_errno}; -use pros_sys::{adi_port_config_e_t, PROS_ERR, E_ADI_ERR,}; +use pros_sys::{adi_port_config_e_t, E_ADI_ERR, PROS_ERR}; use snafu::Snafu; //TODO: much more in depth module documentation for device modules as well as this module. From e65faf95f7f46060bc6cecdedf2deb6534978f91 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 11 Feb 2024 23:39:32 -0800 Subject: [PATCH 71/96] docs: fix ADI examples --- packages/pros-devices/src/adi/linetracker.rs | 2 +- packages/pros-devices/src/adi/solenoid.rs | 2 +- packages/pros-devices/src/adi/switch.rs | 2 +- packages/pros/Cargo.toml | 3 --- packages/pros/examples/adi.rs | 4 ++-- packages/pros/examples/adi_expander.rs | 8 ++++---- packages/pros/src/lib.rs | 5 +++-- 7 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/pros-devices/src/adi/linetracker.rs b/packages/pros-devices/src/adi/linetracker.rs index 4a80cdf3..02068600 100644 --- a/packages/pros-devices/src/adi/linetracker.rs +++ b/packages/pros-devices/src/adi/linetracker.rs @@ -23,10 +23,10 @@ //! between 1/8 and 1/4 of an inch away from the surface it is measuring. It is also important //! to keep lighting in the room consistent, so sensors' readings remain accurate. +use pros_core::bail_on; use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; /// Analog line tracker device. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros-devices/src/adi/solenoid.rs b/packages/pros-devices/src/adi/solenoid.rs index 0856959d..e7fffea5 100644 --- a/packages/pros-devices/src/adi/solenoid.rs +++ b/packages/pros-devices/src/adi/solenoid.rs @@ -1,9 +1,9 @@ //! ADI Solenoid Pneumatic Control +use pros_core::bail_on; use pros_sys::PROS_ERR; use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; /// Digital pneumatic solenoid valve. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros-devices/src/adi/switch.rs b/packages/pros-devices/src/adi/switch.rs index d8e198fa..7cf972eb 100644 --- a/packages/pros-devices/src/adi/switch.rs +++ b/packages/pros-devices/src/adi/switch.rs @@ -1,9 +1,9 @@ //! ADI Digital Switch +use pros_core::bail_on; use pros_sys::PROS_ERR; use super::{digital::LogicLevel, AdiDevice, AdiDeviceType, AdiDigitalIn, AdiError, AdiPort}; -use pros_core::bail_on; /// Generic digital input ADI device. #[derive(Debug, Eq, PartialEq)] diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index caaff233..4cbf07f0 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -36,6 +36,3 @@ devices = ["dep:pros-devices"] panic = ["dep:pros-panic"] display_panics = ["pros-panic/display_panics"] - -[lints] -workspace = true diff --git a/packages/pros/examples/adi.rs b/packages/pros/examples/adi.rs index 1425a42e..10e83c16 100644 --- a/packages/pros/examples/adi.rs +++ b/packages/pros/examples/adi.rs @@ -26,8 +26,8 @@ impl AsyncRobot for ExampleRobot { self.encoder.zero()?; loop { - println!("Encoder value: {:?}", self.encoder.value()); - println!("Ultrasonic value: {:?}", self.ultrasonic.value()); + println!("Encoder position: {:?}", self.encoder.position()); + println!("Ultrasonic distance: {:?}", self.ultrasonic.distance()); delay(Duration::from_millis(10)); } diff --git a/packages/pros/examples/adi_expander.rs b/packages/pros/examples/adi_expander.rs index 2672451b..efd6eee1 100644 --- a/packages/pros/examples/adi_expander.rs +++ b/packages/pros/examples/adi_expander.rs @@ -15,18 +15,18 @@ impl Robot { Self { // Create an encoder on the expander's A and B ports. - encoder: AdiEncoder::new((expander.adi_a, expander.adi_b), false), + encoder: AdiEncoder::new((expander.adi_a, expander.adi_b), false).unwrap(), } } } impl AsyncRobot for Robot { - async fn opcontrol(&mut self) -> pros::Result { + async fn opcontrol(&mut self) -> Result { // Read from the encoder every second. loop { - println!("Encoder value: {}", self.encoder.value()?); + println!("Encoder position: {}", self.encoder.position()?); - pros::task::delay(Duration::from_secs(1)); + delay(Duration::from_secs(1)); } } } diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index b9e2ca00..5dc3a091 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -96,8 +96,9 @@ pub mod prelude { AdiDevice, AdiPort, }, color::Rgb, - position::Position, - screen::{Circle, Line, Rect, Screen, Text, TextFormat, TextPosition, TouchState}, + peripherals::{DynamicPeripherals, Peripherals}, + position::Position, + screen::{Circle, Line, Rect, Screen, Text, TextFormat, TextPosition, TouchState}, smart::{ distance::DistanceSensor, expander::AdiExpander, From 14ea5953872f776313928c99148d466f6b962240 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 12 Feb 2024 18:06:59 -0800 Subject: [PATCH 72/96] docs: improve changelog entry --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d32f513c..02a728ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,12 @@ Before releasing: - Moved most device-related constants into their associated struct `impl` (**Breaking Change**) (#98). - Renamed IMU_RESET_TIMEOUT to `InertialSensor::CALIBRATION_TIMEOUT` (**Breaking Change**) (#98). - Split the `pros` crate into several smaller subcrates. (#86) (**Breaking Change**) +- Changed the `pros` crate into a metapackage without any code of it's own. (**Breaking Change**) (#86) +- Split the `pros` crate into several smaller subcrates. (**Breaking Change**) (#86) + - Added the `pros-async` crate with the async executor and robot trait. + - Added the `pros-sync` crate for the sync robot trait. + - Added the `pros-core` crate with basic abstractions over `pros-sys` needed to compile a program to the brain. + - Added the `pros-panic` crate for the panic handler implementation. ### Removed From aee2f96d043037e394b0f98e95e787cef4b92275 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Wed, 14 Feb 2024 13:19:06 -0800 Subject: [PATCH 73/96] fix: update ADI pwm module imports --- packages/pros-devices/src/adi/pwm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros-devices/src/adi/pwm.rs b/packages/pros-devices/src/adi/pwm.rs index d1556533..06933e4b 100644 --- a/packages/pros-devices/src/adi/pwm.rs +++ b/packages/pros-devices/src/adi/pwm.rs @@ -3,7 +3,7 @@ use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use crate::error::bail_on; +use pros_core::bail_on; /// Generic PWM output ADI device. #[derive(Debug, Eq, PartialEq)] From 7e0f67655bf839990b6852675d831325dd65d0ff Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Wed, 14 Feb 2024 13:20:14 -0800 Subject: [PATCH 74/96] chore: format --- packages/pros-devices/src/adi/pwm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros-devices/src/adi/pwm.rs b/packages/pros-devices/src/adi/pwm.rs index 06933e4b..411869d1 100644 --- a/packages/pros-devices/src/adi/pwm.rs +++ b/packages/pros-devices/src/adi/pwm.rs @@ -1,9 +1,9 @@ //! ADI Pulse-width modulation (PWM). +use pros_core::bail_on; use pros_sys::PROS_ERR; use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort}; -use pros_core::bail_on; /// Generic PWM output ADI device. #[derive(Debug, Eq, PartialEq)] From 2abfea08d9b1f40274fdec29a1375e2286913186 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sun, 18 Feb 2024 20:50:24 -0800 Subject: [PATCH 75/96] docs: improve links in docs --- packages/pros-devices/src/adi/mod.rs | 2 +- packages/pros-devices/src/lib.rs | 4 +--- packages/pros-devices/src/screen.rs | 2 +- packages/pros-devices/src/smart/mod.rs | 4 ++-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/pros-devices/src/adi/mod.rs b/packages/pros-devices/src/adi/mod.rs index d3853f64..9012d496 100644 --- a/packages/pros-devices/src/adi/mod.rs +++ b/packages/pros-devices/src/adi/mod.rs @@ -49,7 +49,7 @@ impl AdiPort { /// /// Creating new `AdiPort`s is inherently unsafe due to the possibility of constructing /// more than one device on the same port index allowing multiple mutable references to - /// the same hardware device. Prefer using [`crate::peripherals::Peripherals`] to register devices if possible. + /// the same hardware device. Prefer using [`Peripherals`](crate::peripherals::Peripherals) to register devices if possible. pub const unsafe fn new(index: u8, expander_index: Option) -> Self { Self { index, diff --git a/packages/pros-devices/src/lib.rs b/packages/pros-devices/src/lib.rs index 06169c96..f4c7dfe0 100644 --- a/packages/pros-devices/src/lib.rs +++ b/packages/pros-devices/src/lib.rs @@ -25,6 +25,7 @@ pub mod adi; pub mod smart; pub mod battery; +pub mod color; pub mod competition; pub mod controller; pub mod peripherals; @@ -32,9 +33,6 @@ pub mod position; pub mod screen; pub mod usd; -//TODO: find a better place to put this -pub mod color; - pub use controller::Controller; pub use position::Position; pub use screen::Screen; diff --git a/packages/pros-devices/src/screen.rs b/packages/pros-devices/src/screen.rs index b89ae6c5..f90a7548 100644 --- a/packages/pros-devices/src/screen.rs +++ b/packages/pros-devices/src/screen.rs @@ -350,7 +350,7 @@ impl Screen { /// /// Creating new `Screen`s is inherently unsafe due to the possibility of constructing /// more than one screen at once allowing multiple mutable references to the same - /// hardware device. Prefer using [`crate::peripherals::Peripherals`] to register devices if possible. + /// hardware device. Prefer using [`Peripherals`](crate::peripherals::Peripherals) to register devices if possible. pub unsafe fn new() -> Self { Self { current_line: 0, diff --git a/packages/pros-devices/src/smart/mod.rs b/packages/pros-devices/src/smart/mod.rs index 158a2ae6..e45ae7cf 100644 --- a/packages/pros-devices/src/smart/mod.rs +++ b/packages/pros-devices/src/smart/mod.rs @@ -13,7 +13,7 @@ //! //! Most devices can be created with a `new` function that generally takes a port number along with other //! device-specific parameters. All sensors are thread safe, however sensors can only be safely constructed -//! using the [`crate::peripherals`] API. +//! using the [`peripherals`](crate::peripherals) API. //! //! In cases where PROS gives the option of a blocking or non-blocking API, //! the blocking API is used for a synchronous method and the non-blocking API is used to create a future. @@ -108,7 +108,7 @@ impl SmartPort { /// Creating new `SmartPort`s is inherently unsafe due to the possibility of constructing /// more than one device on the same port index allowing multiple mutable references to /// the same hardware device. This violates rust's borrow checked guarantees. Prefer using - /// [`crate::peripherals::Peripherals`] to register devices if possible. + /// [`Peripherals`](crate::peripherals::Peripherals) to register devices if possible. /// /// # Examples /// From 9aacd2c0a7e78988cd26d21d9d7d7fd98cefb85a Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Thu, 22 Feb 2024 23:18:03 -0800 Subject: [PATCH 76/96] feat: pros now depends on and exports pros-sys --- packages/pros/Cargo.toml | 1 + packages/pros/src/lib.rs | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 4cbf07f0..1e9a0a82 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -23,6 +23,7 @@ pros-async = { version = "0.1.0", path = "../pros-async", optional = true } pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } pros-panic = { version = "0.1.0", path = "../pros-panic", optional = true } pros-core = { version = "0.1.0", path = "../pros-core", optional = true } +pros-sys = { version = "0.7.0", path = "../pros-sys" } [features] default = ["async", "sync", "devices", "panic", "display_panics", "core"] diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 5dc3a091..305564d2 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -61,12 +61,11 @@ pub use pros_async as async_runtime; pub use pros_core as core; #[cfg(feature = "devices")] pub use pros_devices as devices; -#[cfg(feature = "math")] -pub use pros_math as math; #[cfg(feature = "panic")] pub use pros_panic as panic; #[cfg(feature = "sync")] pub use pros_sync as sync; +pub use pros_sys as sys; /// Commonly used features of pros-rs. /// This module is meant to be glob imported. From 579a44b1b9d4a6f9f564048c9141823c75fc1caa Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Thu, 22 Feb 2024 23:21:32 -0800 Subject: [PATCH 77/96] fix: use a real version of pros-sys --- packages/pros/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 1e9a0a82..9b195253 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -23,7 +23,7 @@ pros-async = { version = "0.1.0", path = "../pros-async", optional = true } pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } pros-panic = { version = "0.1.0", path = "../pros-panic", optional = true } pros-core = { version = "0.1.0", path = "../pros-core", optional = true } -pros-sys = { version = "0.7.0", path = "../pros-sys" } +pros-sys = { version = "0.6.0", path = "../pros-sys" } [features] default = ["async", "sync", "devices", "panic", "display_panics", "core"] From f6d1ae588f4222769cc285489699ec587d818a60 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Fri, 23 Feb 2024 14:09:31 -0800 Subject: [PATCH 78/96] docs: fix grammar issues and repetition --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02a728ed..4f656acf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,12 +59,12 @@ Before releasing: - Moved most device-related constants into their associated struct `impl` (**Breaking Change**) (#98). - Renamed IMU_RESET_TIMEOUT to `InertialSensor::CALIBRATION_TIMEOUT` (**Breaking Change**) (#98). - Split the `pros` crate into several smaller subcrates. (#86) (**Breaking Change**) -- Changed the `pros` crate into a metapackage without any code of it's own. (**Breaking Change**) (#86) +- Changed the `pros` crate into a metapackage without any code of its own. (**Breaking Change**) (#86) - Split the `pros` crate into several smaller subcrates. (**Breaking Change**) (#86) - - Added the `pros-async` crate with the async executor and robot trait. - - Added the `pros-sync` crate for the sync robot trait. - - Added the `pros-core` crate with basic abstractions over `pros-sys` needed to compile a program to the brain. - - Added the `pros-panic` crate for the panic handler implementation. + - `pros-async` with the async executor and robot trait. + - `pros-sync` for the sync robot trait. + - `pros-core` with basic abstractions over `pros-sys` needed to compile a program to the brain. + - `pros-panic` for the panic handler implementation. ### Removed From 0951065aa7b22b5aada7b637fc23637d1cf12c34 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 24 Feb 2024 02:05:46 -0800 Subject: [PATCH 79/96] docs: remove duplicate changelog entry --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f656acf..a046dece 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,10 +58,10 @@ Before releasing: - Repurposed `AdiAnalogOut` as `AdiPwmOut` to correct match port output. (**Breaking Change**) (#90). - Moved most device-related constants into their associated struct `impl` (**Breaking Change**) (#98). - Renamed IMU_RESET_TIMEOUT to `InertialSensor::CALIBRATION_TIMEOUT` (**Breaking Change**) (#98). -- Split the `pros` crate into several smaller subcrates. (#86) (**Breaking Change**) -- Changed the `pros` crate into a metapackage without any code of its own. (**Breaking Change**) (#86) -- Split the `pros` crate into several smaller subcrates. (**Breaking Change**) (#86) +- Repurposed the `pros` crate as a metapackage without any code of its own. (**Breaking Change**) (#86) +- Split the pros-rs into several small subcrates. (**Breaking Change**) (#86) - `pros-async` with the async executor and robot trait. + - `pros-devices` for device bindings. - `pros-sync` for the sync robot trait. - `pros-core` with basic abstractions over `pros-sys` needed to compile a program to the brain. - `pros-panic` for the panic handler implementation. From d545b2edf5db091d23b44a4cd79804f7a76a1092 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 24 Feb 2024 02:48:04 -0800 Subject: [PATCH 80/96] feat: create pros-math crate and bring back pid and feedforward controllers --- packages/pros-math/Cargo.toml | 11 +++++ packages/pros-math/src/feedforward.rs | 65 +++++++++++++++++++++++++ packages/pros-math/src/lib.rs | 7 +++ packages/pros-math/src/pid.rs | 68 +++++++++++++++++++++++++++ packages/pros/Cargo.toml | 5 +- packages/pros/src/lib.rs | 5 ++ 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 packages/pros-math/Cargo.toml create mode 100644 packages/pros-math/src/feedforward.rs create mode 100644 packages/pros-math/src/lib.rs create mode 100644 packages/pros-math/src/pid.rs diff --git a/packages/pros-math/Cargo.toml b/packages/pros-math/Cargo.toml new file mode 100644 index 00000000..279a41d8 --- /dev/null +++ b/packages/pros-math/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "pros-math" +version = "0.1.0" +edition = "2021" + +[dependencies] +num = { version = "0.4.1", default-features = false } +pros-core = { version = "0.1.0", path = "../pros-core" } + +[lints] +workspace = true diff --git a/packages/pros-math/src/feedforward.rs b/packages/pros-math/src/feedforward.rs new file mode 100644 index 00000000..c8e8b3c9 --- /dev/null +++ b/packages/pros-math/src/feedforward.rs @@ -0,0 +1,65 @@ +//! Simple feedforward controller for motors. +//! Computes the voltage to maintain an idealized DC motor in a certain state. +//! Uses this feedforward model: V = Kₛ sign(ω) + Kᵥ ω + Kₐ α + +/// Feedforward controller for motor control. +/// +/// This controller is used to apply feedforward control to achieve desired motor behavior +/// based on velocity and acceleration. +#[derive(Debug, Clone)] +pub struct MotorFeedforwardController { + /// Feedforward constant for static friction compensation. + pub ks: f32, + /// Feedforward constant for velocity compensation. + pub kv: f32, + /// Feedforward constant for acceleration compensation. + pub ka: f32, + /// Feedforward constant for the target acceleration. + pub target_acceleration: f32, + /// Target. + pub target: f32, +} + +impl MotorFeedforwardController { + /// Creates a new [`FeedforwardMotorController`] with the given constants and target. + /// + /// # Arguments + /// + /// * `ks` - Feedforward constant for static friction compensation. + /// * `kv` - Feedforward constant for velocity compensation. + /// * `ka` - Feedforward constant for acceleration compensation. + /// * `target_acceleration` - Feedforward constant for the target acceleration. + /// + /// # Returns + /// + /// A new [`FeedforwardMotorController`]. + pub fn new(ks: f32, kv: f32, ka: f32, target_acceleration: f32) -> Self { + Self { + ks, + kv, + ka, + target_acceleration, + target: 0.0, + } + } + + /// Calculates the control output. + /// + /// # Arguments + /// + /// * `target_acceleration` - The target_acceleration of the system. + /// * `target` - Target. + /// + /// # Returns + /// + /// The control output to apply to the motor. + pub fn calculate(&self, target: f32, target_acceleration: f32) -> f32 { + // Calculate the feedforward component based on velocity and acceleration + let v = self.ks * num::signum(target) + self.kv * target + self.ka * target_acceleration; + + // The output is the feedforward controller (V) + let output = v; + + output + } +} diff --git a/packages/pros-math/src/lib.rs b/packages/pros-math/src/lib.rs new file mode 100644 index 00000000..c64c24dd --- /dev/null +++ b/packages/pros-math/src/lib.rs @@ -0,0 +1,7 @@ +//! Common mathematical formulas and models implemented for [`pros-rs`](https://crates.io/crates/pros). +//! + +#![no_std] + +pub mod pid; +pub mod feedforward; diff --git a/packages/pros-math/src/pid.rs b/packages/pros-math/src/pid.rs new file mode 100644 index 00000000..74a8e40f --- /dev/null +++ b/packages/pros-math/src/pid.rs @@ -0,0 +1,68 @@ +//! PID controllers. +//! +//! PID controllers are first created with [`PidController::new`] +//! and then can be utilized by calling [`PidController::update`] repeatedly. + +use core::time::Duration; + +/// A proportional–integral–derivative controller. +/// +/// This controller is used to smoothly move motors to a certain point, +/// and allows for feedback-based power adjustments. This is desirable +/// over just setting the motor power, as it can be tuned to make the +/// motor stop in exactly the right position without overshooting. +#[derive(Debug, Clone, Copy)] +pub struct PidController { + /// Proportional constant. This is multiplied by the error to get the + /// proportional component of the output. + pub kp: f32, + /// Integral constant. This accounts for the past values of the error. + pub ki: f32, + /// Derivative constant. This allows you to change the motor behavior + /// based on the rate of change of the error (predicting future values). + pub kd: f32, + + last_time: pros_core::time::Instant, + last_position: f32, + i: f32, +} + +impl PidController { + /// Create a new PID controller with the given constants. + pub fn new(kp: f32, ki: f32, kd: f32) -> Self { + Self { + kp, + ki, + kd, + last_time: pros_core::time::Instant::now(), + last_position: 0.0, + i: 0.0, + } + } + + /// Update the PID controller with the current setpoint and position. + pub fn update(&mut self, setpoint: f32, position: f32) -> f32 { + let mut delta_time = self.last_time.elapsed(); + if delta_time.is_zero() { + delta_time += Duration::from_micros(1); + } + let error = setpoint - position; + + self.i += error * delta_time.as_secs_f32(); + + let p = self.kp * error; + let i = self.ki * self.i; + + let mut d = (position - self.last_position) / delta_time.as_secs_f32(); + if d.is_nan() { + d = 0.0 + } + + let output = p + i + d; + + self.last_position = position; + self.last_time = pros_core::time::Instant::now(); + + output + } +} diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 9b195253..20252fa6 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -23,10 +23,11 @@ pros-async = { version = "0.1.0", path = "../pros-async", optional = true } pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } pros-panic = { version = "0.1.0", path = "../pros-panic", optional = true } pros-core = { version = "0.1.0", path = "../pros-core", optional = true } +pros-math = { version = "0.1.0", path = "../pros-math", optional = true } pros-sys = { version = "0.6.0", path = "../pros-sys" } [features] -default = ["async", "sync", "devices", "panic", "display_panics", "core"] +default = ["async", "sync", "devices", "panic", "display_panics", "core", "math"] core = ["dep:pros-core"] @@ -35,5 +36,7 @@ sync = ["dep:pros-sync"] devices = ["dep:pros-devices"] +math = ["dep:pros-math"] + panic = ["dep:pros-panic"] display_panics = ["pros-panic/display_panics"] diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 305564d2..60237ca0 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -65,6 +65,9 @@ pub use pros_devices as devices; pub use pros_panic as panic; #[cfg(feature = "sync")] pub use pros_sync as sync; +#[cfg(feature = "math")] +pub use pros_math as math; + pub use pros_sys as sys; /// Commonly used features of pros-rs. @@ -113,4 +116,6 @@ pub mod prelude { }; #[cfg(feature = "sync")] pub use pros_sync::{sync_robot, SyncRobot}; + #[cfg(feature = "math")] + pub use pros_math::{feedforward::MotorFeedforwardController, pid::PidController}; } From 8041103e901e201e6e4a11bec100f8fffa59c299 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 24 Feb 2024 02:48:52 -0800 Subject: [PATCH 81/96] docs: update added crates in changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a046dece..448f0843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ Before releasing: - `pros-devices` for device bindings. - `pros-sync` for the sync robot trait. - `pros-core` with basic abstractions over `pros-sys` needed to compile a program to the brain. + - `pros-math` with commonly used controllers and other mathematical models. - `pros-panic` for the panic handler implementation. ### Removed From 2fedca0dcad307a617e735a6db81d8fd0453cf2e Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 24 Feb 2024 02:50:36 -0800 Subject: [PATCH 82/96] chore: formatting --- packages/pros-math/src/lib.rs | 3 +-- packages/pros/src/lib.rs | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/pros-math/src/lib.rs b/packages/pros-math/src/lib.rs index c64c24dd..49c5474c 100644 --- a/packages/pros-math/src/lib.rs +++ b/packages/pros-math/src/lib.rs @@ -1,7 +1,6 @@ //! Common mathematical formulas and models implemented for [`pros-rs`](https://crates.io/crates/pros). -//! #![no_std] -pub mod pid; pub mod feedforward; +pub mod pid; diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index 60237ca0..7e24f127 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -61,13 +61,12 @@ pub use pros_async as async_runtime; pub use pros_core as core; #[cfg(feature = "devices")] pub use pros_devices as devices; +#[cfg(feature = "math")] +pub use pros_math as math; #[cfg(feature = "panic")] pub use pros_panic as panic; #[cfg(feature = "sync")] pub use pros_sync as sync; -#[cfg(feature = "math")] -pub use pros_math as math; - pub use pros_sys as sys; /// Commonly used features of pros-rs. @@ -114,8 +113,8 @@ pub mod prelude { SmartDevice, SmartPort, }, }; - #[cfg(feature = "sync")] - pub use pros_sync::{sync_robot, SyncRobot}; #[cfg(feature = "math")] pub use pros_math::{feedforward::MotorFeedforwardController, pid::PidController}; + #[cfg(feature = "sync")] + pub use pros_sync::{sync_robot, SyncRobot}; } From 99c803b2dc554064b159655175db20cabcd9215f Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 26 Feb 2024 18:45:25 -0800 Subject: [PATCH 83/96] refactor: rename pros_alloc module to allocator --- packages/pros-core/src/{pros_alloc => allocator}/mod.rs | 0 packages/pros-core/src/{pros_alloc => allocator}/vexos.rs | 0 packages/pros-core/src/{pros_alloc => allocator}/wasm.rs | 0 packages/pros-core/src/lib.rs | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) rename packages/pros-core/src/{pros_alloc => allocator}/mod.rs (100%) rename packages/pros-core/src/{pros_alloc => allocator}/vexos.rs (100%) rename packages/pros-core/src/{pros_alloc => allocator}/wasm.rs (100%) diff --git a/packages/pros-core/src/pros_alloc/mod.rs b/packages/pros-core/src/allocator/mod.rs similarity index 100% rename from packages/pros-core/src/pros_alloc/mod.rs rename to packages/pros-core/src/allocator/mod.rs diff --git a/packages/pros-core/src/pros_alloc/vexos.rs b/packages/pros-core/src/allocator/vexos.rs similarity index 100% rename from packages/pros-core/src/pros_alloc/vexos.rs rename to packages/pros-core/src/allocator/vexos.rs diff --git a/packages/pros-core/src/pros_alloc/wasm.rs b/packages/pros-core/src/allocator/wasm.rs similarity index 100% rename from packages/pros-core/src/pros_alloc/wasm.rs rename to packages/pros-core/src/allocator/wasm.rs diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index 37322e9b..042db8cc 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -17,7 +17,7 @@ extern crate alloc; pub mod error; pub mod io; -pub mod pros_alloc; +pub mod allocator; pub mod sync; pub mod task; pub mod time; From 1c54299603c566b6a2a384dda94b66d365574469 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Mon, 26 Feb 2024 18:51:53 -0800 Subject: [PATCH 84/96] chore: format --- packages/pros-core/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index 042db8cc..dc868f74 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -15,9 +15,9 @@ extern crate alloc; +pub mod allocator; pub mod error; pub mod io; -pub mod allocator; pub mod sync; pub mod task; pub mod time; From fd5bc09cddc2d74d9fad72e5c70be9182031b4df Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Fri, 1 Mar 2024 06:36:34 -0800 Subject: [PATCH 85/96] refactor: disable `sync` feature by default --- packages/pros/Cargo.toml | 2 +- packages/pros/examples/optical.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 20252fa6..e7968736 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -27,7 +27,7 @@ pros-math = { version = "0.1.0", path = "../pros-math", optional = true } pros-sys = { version = "0.6.0", path = "../pros-sys" } [features] -default = ["async", "sync", "devices", "panic", "display_panics", "core", "math"] +default = ["async", "devices", "panic", "display_panics", "core", "math"] core = ["dep:pros-core"] diff --git a/packages/pros/examples/optical.rs b/packages/pros/examples/optical.rs index d237553d..296abd6e 100644 --- a/packages/pros/examples/optical.rs +++ b/packages/pros/examples/optical.rs @@ -16,8 +16,8 @@ impl Robot { } } -impl SyncRobot for Robot { - fn opcontrol(&mut self) -> Result { +impl AsyncRobot for Robot { + async fn opcontrol(&mut self) -> Result { loop { println!( "-----\nHue: {}\nSaturation: {}\nBrightess: {}\nLast Gesture Direction: {:?}\n-----\n", @@ -32,4 +32,4 @@ impl SyncRobot for Robot { } } -sync_robot!(Robot, Robot::new(Peripherals::take().unwrap())); +async_robot!(Robot, Robot::new(Peripherals::take().unwrap())); From be01cda723e55b5ed174fa4ffa1e44c6d7aa11f4 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Fri, 1 Mar 2024 12:24:12 -0800 Subject: [PATCH 86/96] fix: use associated screen constants in panic handler --- packages/pros-panic/src/lib.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/pros-panic/src/lib.rs b/packages/pros-panic/src/lib.rs index aefae6e3..220725db 100644 --- a/packages/pros-panic/src/lib.rs +++ b/packages/pros-panic/src/lib.rs @@ -34,8 +34,8 @@ fn draw_error( let error_box_rect = pros_devices::screen::Rect::new( ERROR_BOX_MARGIN, ERROR_BOX_MARGIN, - pros_devices::screen::SCREEN_HORIZONTAL_RESOLUTION - ERROR_BOX_MARGIN, - pros_devices::screen::SCREEN_VERTICAL_RESOLUTION - ERROR_BOX_MARGIN, + Screen::HORIZONTAL_RESOLUTION - ERROR_BOX_MARGIN, + Screen::VERTICAL_RESOLUTION - ERROR_BOX_MARGIN, ); screen.fill(&error_box_rect, pros_devices::color::Rgb::RED)?; @@ -55,9 +55,7 @@ fn draw_error( buffer.as_str(), pros_devices::screen::TextPosition::Point( ERROR_BOX_MARGIN + ERROR_BOX_PADDING, - ERROR_BOX_MARGIN - + ERROR_BOX_PADDING - + (line * pros_devices::screen::SCREEN_LINE_HEIGHT), + ERROR_BOX_MARGIN + ERROR_BOX_PADDING + (line * Screen::LINE_HEIGHT), ), pros_devices::screen::TextFormat::Small, ), @@ -74,9 +72,7 @@ fn draw_error( buffer.as_str(), pros_devices::screen::TextPosition::Point( ERROR_BOX_MARGIN + ERROR_BOX_PADDING, - ERROR_BOX_MARGIN - + ERROR_BOX_PADDING - + (line * pros_devices::screen::SCREEN_LINE_HEIGHT), + ERROR_BOX_MARGIN + ERROR_BOX_PADDING + (line * Screen::LINE_HEIGHT), ), pros_devices::screen::TextFormat::Small, ), From 923af4ae76e322d4902a7a0e47ebe134c5e6d9e7 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 2 Mar 2024 01:57:47 -0800 Subject: [PATCH 87/96] chore: bump versions and update changelog --- CHANGELOG.md | 13 ++++++++++++- packages/pros-async/Cargo.toml | 2 +- packages/pros-core/Cargo.toml | 2 +- packages/pros-devices/Cargo.toml | 2 +- packages/pros-panic/Cargo.toml | 2 +- packages/pros-sys/Cargo.toml | 2 +- packages/pros/Cargo.toml | 4 ++-- 7 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 448f0843..7e6b0afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,16 @@ Before releasing: ## [Unreleased] +### Added + +### Fixed + +### Changed + +### Removed + +## [0.8.0] + ### Added - Added feedforward motor controllers (#80) - Lightly document all APIs with missing documentation. (#70) @@ -178,8 +188,9 @@ Before releasing: ### Removed -[unreleased]: https://github.com/pros-rs/pros-rs/compare/v0.7.0...HEAD +[unreleased]: https://github.com/pros-rs/pros-rs/compare/v0.8.0...HEAD [0.4.0]: https://github.com/pros-rs/pros-rs/releases/tag/v0.4.0 [0.5.0]: https://github.com/pros-rs/pros-rs/compare/v0.4.0...v0.5.0 [0.6.0]: https://github.com/pros-rs/pros-rs/compare/v0.5.0...v0.6.0 [0.7.0]: https://github.com/pros-rs/pros-rs/compare/v0.6.0...v0.7.0 +[0.8.0]: https://github.com/pros-rs/pros-rs/compare/v0.7.0...v0.8.0 diff --git a/packages/pros-async/Cargo.toml b/packages/pros-async/Cargo.toml index f0c1c941..cdff9b30 100644 --- a/packages/pros-async/Cargo.toml +++ b/packages/pros-async/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" async-task = { version = "4.5.0", default-features = false } pros-core = { version = "0.1.0", path = "../pros-core" } waker-fn = "1.1.1" -pros-sys = { version = "0.6.0", path = "../pros-sys" } +pros-sys = { version = "0.7.0", path = "../pros-sys" } [lints] workspace = true diff --git a/packages/pros-core/Cargo.toml b/packages/pros-core/Cargo.toml index 8b728b22..60fc43d1 100644 --- a/packages/pros-core/Cargo.toml +++ b/packages/pros-core/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -pros-sys = { version = "0.6.0", path = "../pros-sys" } +pros-sys = { version = "0.7.0", path = "../pros-sys" } no_std_io = { version = "0.6.0", features = ["alloc"] } snafu = { version = "0.8.0", default-features = false, features = [ "rust_1_61", diff --git a/packages/pros-devices/Cargo.toml b/packages/pros-devices/Cargo.toml index 6c58f2f2..17a62012 100644 --- a/packages/pros-devices/Cargo.toml +++ b/packages/pros-devices/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] pros-core = { version = "0.1.0", path = "../pros-core" } -pros-sys = { path = "../pros-sys", version = "0.6.0", features = ["xapi"] } +pros-sys = { path = "../pros-sys", version = "0.7.0", features = ["xapi"] } snafu = { version = "0.8.0", default-features = false, features = [ "rust_1_61", "unstable-core-error", diff --git a/packages/pros-panic/Cargo.toml b/packages/pros-panic/Cargo.toml index 54234af7..0314c46c 100644 --- a/packages/pros-panic/Cargo.toml +++ b/packages/pros-panic/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] pros-core = { version = "0.1.0", path = "../pros-core" } pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } -pros-sys = { version = "0.6.0", path = "../pros-sys" } +pros-sys = { version = "0.7.0", path = "../pros-sys" } [features] default = ["display_panics"] diff --git a/packages/pros-sys/Cargo.toml b/packages/pros-sys/Cargo.toml index d9912b00..145824f7 100644 --- a/packages/pros-sys/Cargo.toml +++ b/packages/pros-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pros-sys" -version = "0.6.0" +version = "0.7.0" edition = "2021" description = "EFI for the PROS rust bindings" keywords = ["PROS", "Robotics", "bindings"] diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index e7968736..2df5fa64 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pros" -version = "0.7.0" +version = "0.8.0" edition = "2021" description = "Rust bindings for PROS" keywords = ["PROS", "Robotics", "bindings"] @@ -24,7 +24,7 @@ pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true } pros-panic = { version = "0.1.0", path = "../pros-panic", optional = true } pros-core = { version = "0.1.0", path = "../pros-core", optional = true } pros-math = { version = "0.1.0", path = "../pros-math", optional = true } -pros-sys = { version = "0.6.0", path = "../pros-sys" } +pros-sys = { version = "0.7.0", path = "../pros-sys" } [features] default = ["async", "devices", "panic", "display_panics", "core", "math"] From b666c7b7f37a4b5e28419b7c38339049e7428f8c Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 2 Mar 2024 02:49:22 -0800 Subject: [PATCH 88/96] docs: add readme and liscence to all new crates --- packages/pros-async/Cargo.toml | 2 ++ packages/pros-async/README.md | 6 ++++++ packages/pros-core/Cargo.toml | 2 ++ packages/pros-core/README.md | 11 +++++++++++ packages/pros-devices/Cargo.toml | 2 ++ packages/pros-devices/README.md | 15 +++++++++++++++ packages/pros-math/Cargo.toml | 2 ++ packages/pros-math/src/README.md | 3 +++ packages/pros-panic/Cargo.toml | 2 ++ packages/pros-panic/README.md | 5 +++++ packages/pros-sync/Cargo.toml | 2 ++ packages/pros-sync/README.md | 1 + 12 files changed, 53 insertions(+) create mode 100644 packages/pros-async/README.md create mode 100644 packages/pros-core/README.md create mode 100644 packages/pros-devices/README.md create mode 100644 packages/pros-math/src/README.md create mode 100644 packages/pros-panic/README.md create mode 100644 packages/pros-sync/README.md diff --git a/packages/pros-async/Cargo.toml b/packages/pros-async/Cargo.toml index cdff9b30..5f88a77b 100644 --- a/packages/pros-async/Cargo.toml +++ b/packages/pros-async/Cargo.toml @@ -2,6 +2,8 @@ name = "pros-async" version = "0.1.0" edition = "2021" +license = "MIT" +description = "A simple async executor for pros-rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-async/README.md b/packages/pros-async/README.md new file mode 100644 index 00000000..abc23d78 --- /dev/null +++ b/packages/pros-async/README.md @@ -0,0 +1,6 @@ +# pros-async + +Tiny async runtime and robot traits for `pros-rs`. +The async executor supports spawning tasks and blocking on futures. +It has a reactor to improve the performance of some futures. +FreeRTOS tasks can still be used, but it is recommended to use only async tasks for performance. diff --git a/packages/pros-core/Cargo.toml b/packages/pros-core/Cargo.toml index 60fc43d1..4430d545 100644 --- a/packages/pros-core/Cargo.toml +++ b/packages/pros-core/Cargo.toml @@ -2,6 +2,8 @@ name = "pros-core" version = "0.1.0" edition = "2021" +license = "MIT" +description = "Core functionality for pros-rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-core/README.md b/packages/pros-core/README.md new file mode 100644 index 00000000..cd2a7a3b --- /dev/null +++ b/packages/pros-core/README.md @@ -0,0 +1,11 @@ +# pros-core +Low level core functionality for [`pros-rs`](https://crates.io/crates/pros). +The core crate is used in all other crates in the pros-rs ecosystem. +Included in this crate: +- Global allocator +- Competition state checking +- Errno handling +- Serial terminal printing +- No-std `Instant`s +- Synchronization primitives +- FreeRTOS task management diff --git a/packages/pros-devices/Cargo.toml b/packages/pros-devices/Cargo.toml index 17a62012..9919ac9f 100644 --- a/packages/pros-devices/Cargo.toml +++ b/packages/pros-devices/Cargo.toml @@ -2,6 +2,8 @@ name = "pros-devices" version = "0.1.0" edition = "2021" +license = "MIT" +description = "High level device for pros-rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-devices/README.md b/packages/pros-devices/README.md new file mode 100644 index 00000000..6054c421 --- /dev/null +++ b/packages/pros-devices/README.md @@ -0,0 +1,15 @@ +This module provides functionality for accessing hardware annected to the V5 brain. + +# Overview + +The V5 brain features 21 RJ9 4p4c connector ports (known as "Smart ts")for communicating with +newer V5 peripherals, as well as six 3-wire ports with log-to-digitalconversion capability for +compatibility with legacy cortex devices. This module provides access both smart devices and +ADI devices. + +# Organization + +- `smart` contains abstractions and types for smart port connected ices. +- `adi` contains abstractions for three wire ADI connected devices. +- `battery` provides functions for getting information about the battery. +- `controller` provides types for interacting with the V5 controller. diff --git a/packages/pros-math/Cargo.toml b/packages/pros-math/Cargo.toml index 279a41d8..c9ec93ad 100644 --- a/packages/pros-math/Cargo.toml +++ b/packages/pros-math/Cargo.toml @@ -2,6 +2,8 @@ name = "pros-math" version = "0.1.0" edition = "2021" +license = "MIT" +description = "Commonly used mathematical formulas for pros-rs" [dependencies] num = { version = "0.4.1", default-features = false } diff --git a/packages/pros-math/src/README.md b/packages/pros-math/src/README.md new file mode 100644 index 00000000..ea2cda52 --- /dev/null +++ b/packages/pros-math/src/README.md @@ -0,0 +1,3 @@ +# pros-math + +Common mathematical formulas and models implemented for [`pros-rs`](https://crates.io/crates/pros). diff --git a/packages/pros-panic/Cargo.toml b/packages/pros-panic/Cargo.toml index 0314c46c..f74e5478 100644 --- a/packages/pros-panic/Cargo.toml +++ b/packages/pros-panic/Cargo.toml @@ -2,6 +2,8 @@ name = "pros-panic" version = "0.1.0" edition = "2021" +license = "MIT" +description = "Panic handler for pros-rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-panic/README.md b/packages/pros-panic/README.md new file mode 100644 index 00000000..9b485e8a --- /dev/null +++ b/packages/pros-panic/README.md @@ -0,0 +1,5 @@ +# pros-panic + +Panic handler implementation for [`pros-rs`](https://crates.io/crates/pros-rs). +Supports printing a backtrace when running in the simulator. +If the `display_panics` feature is enabled, it will also display the panic message on the V5 Brain display. diff --git a/packages/pros-sync/Cargo.toml b/packages/pros-sync/Cargo.toml index 1df90f53..45eee70e 100644 --- a/packages/pros-sync/Cargo.toml +++ b/packages/pros-sync/Cargo.toml @@ -2,6 +2,8 @@ name = "pros-sync" version = "0.1.0" edition = "2021" +license = "MIT" +description = "`SyncRobot` trait and macro for pros-rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-sync/README.md b/packages/pros-sync/README.md new file mode 100644 index 00000000..e1804501 --- /dev/null +++ b/packages/pros-sync/README.md @@ -0,0 +1 @@ +Synchronous robot code trait for [pros-rs](https://crates.io/crates/pros). From 96d16535f484369a2b9b0da49daeb58ac9cb8f04 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 2 Mar 2024 02:54:04 -0800 Subject: [PATCH 89/96] docs: add keywords and categories to new crates --- packages/pros-async/Cargo.toml | 6 ++++++ packages/pros-core/Cargo.toml | 6 ++++++ packages/pros-devices/Cargo.toml | 6 ++++++ packages/pros-math/Cargo.toml | 5 +++++ packages/pros-panic/Cargo.toml | 5 +++++ packages/pros-sync/Cargo.toml | 5 +++++ 6 files changed, 33 insertions(+) diff --git a/packages/pros-async/Cargo.toml b/packages/pros-async/Cargo.toml index 5f88a77b..e5292c76 100644 --- a/packages/pros-async/Cargo.toml +++ b/packages/pros-async/Cargo.toml @@ -4,6 +4,12 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "A simple async executor for pros-rs" +keywords = ["PROS", "Robotics", "bindings", "async"] +categories = [ + "no-std", + "science::robotics", + "Asynchronous" +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-core/Cargo.toml b/packages/pros-core/Cargo.toml index 4430d545..fe7407b1 100644 --- a/packages/pros-core/Cargo.toml +++ b/packages/pros-core/Cargo.toml @@ -4,6 +4,12 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "Core functionality for pros-rs" +keywords = ["PROS", "Robotics", "bindings"] +categories = [ + "api-bindings", + "no-std", + "science::robotics", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-devices/Cargo.toml b/packages/pros-devices/Cargo.toml index 9919ac9f..b9b23a29 100644 --- a/packages/pros-devices/Cargo.toml +++ b/packages/pros-devices/Cargo.toml @@ -4,6 +4,12 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "High level device for pros-rs" +keywords = ["PROS", "Robotics", "bindings"] +categories = [ + "api-bindings", + "no-std", + "science::robotics", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-math/Cargo.toml b/packages/pros-math/Cargo.toml index c9ec93ad..64b70cb8 100644 --- a/packages/pros-math/Cargo.toml +++ b/packages/pros-math/Cargo.toml @@ -4,6 +4,11 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "Commonly used mathematical formulas for pros-rs" +keywords = ["PROS", "Robotics"] +categories = [ + "no-std", + "science::robotics", +] [dependencies] num = { version = "0.4.1", default-features = false } diff --git a/packages/pros-panic/Cargo.toml b/packages/pros-panic/Cargo.toml index f74e5478..174b085e 100644 --- a/packages/pros-panic/Cargo.toml +++ b/packages/pros-panic/Cargo.toml @@ -4,6 +4,11 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "Panic handler for pros-rs" +keywords = ["PROS", "Robotics"] +categories = [ + "no-std", + "science::robotics", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-sync/Cargo.toml b/packages/pros-sync/Cargo.toml index 45eee70e..176ac926 100644 --- a/packages/pros-sync/Cargo.toml +++ b/packages/pros-sync/Cargo.toml @@ -4,6 +4,11 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "`SyncRobot` trait and macro for pros-rs" +keywords = ["PROS", "Robotics"] +categories = [ + "no-std", + "science::robotics", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 14f6a46cc4e5f484315896e8fe45cd68feb2c041 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 2 Mar 2024 02:56:09 -0800 Subject: [PATCH 90/96] docs: add authors to new crates --- packages/pros-async/Cargo.toml | 6 ++++++ packages/pros-core/Cargo.toml | 6 ++++++ packages/pros-devices/Cargo.toml | 6 ++++++ packages/pros-math/Cargo.toml | 6 ++++++ packages/pros-panic/Cargo.toml | 6 ++++++ packages/pros-sync/Cargo.toml | 6 ++++++ 6 files changed, 36 insertions(+) diff --git a/packages/pros-async/Cargo.toml b/packages/pros-async/Cargo.toml index e5292c76..6f5f7c60 100644 --- a/packages/pros-async/Cargo.toml +++ b/packages/pros-async/Cargo.toml @@ -10,6 +10,12 @@ categories = [ "science::robotics", "Asynchronous" ] +repository = "https://github.com/gavin-niederman/pros-rs" +authors = [ + "pros-rs", + "Gavin Niederman ", + "doinkythederp ", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-core/Cargo.toml b/packages/pros-core/Cargo.toml index fe7407b1..8c8178d2 100644 --- a/packages/pros-core/Cargo.toml +++ b/packages/pros-core/Cargo.toml @@ -10,6 +10,12 @@ categories = [ "no-std", "science::robotics", ] +repository = "https://github.com/gavin-niederman/pros-rs" +authors = [ + "pros-rs", + "Gavin Niederman ", + "doinkythederp ", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-devices/Cargo.toml b/packages/pros-devices/Cargo.toml index b9b23a29..dcd81671 100644 --- a/packages/pros-devices/Cargo.toml +++ b/packages/pros-devices/Cargo.toml @@ -10,6 +10,12 @@ categories = [ "no-std", "science::robotics", ] +repository = "https://github.com/gavin-niederman/pros-rs" +authors = [ + "pros-rs", + "Gavin Niederman ", + "doinkythederp ", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-math/Cargo.toml b/packages/pros-math/Cargo.toml index 64b70cb8..64c5d8f2 100644 --- a/packages/pros-math/Cargo.toml +++ b/packages/pros-math/Cargo.toml @@ -9,6 +9,12 @@ categories = [ "no-std", "science::robotics", ] +repository = "https://github.com/gavin-niederman/pros-rs" +authors = [ + "pros-rs", + "Gavin Niederman ", + "doinkythederp ", +] [dependencies] num = { version = "0.4.1", default-features = false } diff --git a/packages/pros-panic/Cargo.toml b/packages/pros-panic/Cargo.toml index 174b085e..96cd07ef 100644 --- a/packages/pros-panic/Cargo.toml +++ b/packages/pros-panic/Cargo.toml @@ -9,6 +9,12 @@ categories = [ "no-std", "science::robotics", ] +repository = "https://github.com/gavin-niederman/pros-rs" +authors = [ + "pros-rs", + "Gavin Niederman ", + "doinkythederp ", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/pros-sync/Cargo.toml b/packages/pros-sync/Cargo.toml index 176ac926..358193de 100644 --- a/packages/pros-sync/Cargo.toml +++ b/packages/pros-sync/Cargo.toml @@ -9,6 +9,12 @@ categories = [ "no-std", "science::robotics", ] +repository = "https://github.com/gavin-niederman/pros-rs" +authors = [ + "pros-rs", + "Gavin Niederman ", + "doinkythederp ", +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From c3222e94968c68f8dcf35602c04bcfc4fd59ec3b Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 2 Mar 2024 03:06:56 -0800 Subject: [PATCH 91/96] docs: update pros-devices readme --- packages/pros-devices/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/pros-devices/README.md b/packages/pros-devices/README.md index 6054c421..6c0f5042 100644 --- a/packages/pros-devices/README.md +++ b/packages/pros-devices/README.md @@ -1,4 +1,6 @@ -This module provides functionality for accessing hardware annected to the V5 brain. +# pros-devices + +functionality for accessing hardware connected to the V5 brain. # Overview From 89354609944228e9a5c2a5ded89ed60963f91e89 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 2 Mar 2024 03:08:04 -0800 Subject: [PATCH 92/96] docs: update pros-sync readme --- packages/pros-sync/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/pros-sync/README.md b/packages/pros-sync/README.md index e1804501..e65db59a 100644 --- a/packages/pros-sync/README.md +++ b/packages/pros-sync/README.md @@ -1 +1,3 @@ +# pros-sync + Synchronous robot code trait for [pros-rs](https://crates.io/crates/pros). From 691a58547351a1129d50e71209c461701a254ffb Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Sat, 2 Mar 2024 03:11:39 -0800 Subject: [PATCH 93/96] fix: move pros-math readme into crate directory --- packages/pros-math/{src => }/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/pros-math/{src => }/README.md (100%) diff --git a/packages/pros-math/src/README.md b/packages/pros-math/README.md similarity index 100% rename from packages/pros-math/src/README.md rename to packages/pros-math/README.md From 9acac8df811e65965504c64203ed133714787b74 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Tue, 5 Mar 2024 20:30:44 -0800 Subject: [PATCH 94/96] docs: correct grammar errors --- packages/pros-devices/README.md | 11 ++++------- packages/pros-devices/src/lib.rs | 13 +++++-------- packages/pros-sys/README.md | 4 ++-- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/packages/pros-devices/README.md b/packages/pros-devices/README.md index 6c0f5042..b5e924ee 100644 --- a/packages/pros-devices/README.md +++ b/packages/pros-devices/README.md @@ -1,15 +1,12 @@ # pros-devices -functionality for accessing hardware connected to the V5 brain. +Functionality for accessing hardware connected to the V5 brain. -# Overview +## Overview -The V5 brain features 21 RJ9 4p4c connector ports (known as "Smart ts")for communicating with -newer V5 peripherals, as well as six 3-wire ports with log-to-digitalconversion capability for -compatibility with legacy cortex devices. This module provides access both smart devices and -ADI devices. +The V5 brain features 21 RJ9 4p4c connector ports (known as "Smart ports") for communicating with newer V5 peripherals, as well as six 3-wire ports with log-to-digital conversion capability for compatibility with legacy Cortex devices. This module provides access to both smart devices and ADI devices. -# Organization +## Organization - `smart` contains abstractions and types for smart port connected ices. - `adi` contains abstractions for three wire ADI connected devices. diff --git a/packages/pros-devices/src/lib.rs b/packages/pros-devices/src/lib.rs index f4c7dfe0..d3e19f4e 100644 --- a/packages/pros-devices/src/lib.rs +++ b/packages/pros-devices/src/lib.rs @@ -1,15 +1,12 @@ -//! Devices +//! # pros-devices //! -//! This module provides functionality for accessing hardware and devices connected to the V5 brain. +//! Functionality for accessing hardware connected to the V5 brain. //! -//! # Overview +//! ## Overview //! -//! The V5 brain features 21 RJ9 4p4c connector ports (known as "Smart Ports") for communicating with -//! newer V5 peripherals, as well as six 3-wire ports with analog-to-digital conversion capability for -//! compatibility with legacy cortex devices. This module provides access for both smart devices and -//! ADI devices. +//! The V5 brain features 21 RJ9 4p4c connector ports (known as "Smart ports") for communicating with newer V5 peripherals, as well as six 3-wire ports with log-to-digital conversion capability for compatibility with legacy Cortex devices. This module provides access to both smart devices and ADI devices. //! -//! # Organization +//! ## Organization //! //! - [`smart`] contains abstractions and types for smart port connected devices. //! - [`adi`] contains abstractions for three wire ADI connected devices. diff --git a/packages/pros-sys/README.md b/packages/pros-sys/README.md index 2623d9de..9182522b 100644 --- a/packages/pros-sys/README.md +++ b/packages/pros-sys/README.md @@ -1,7 +1,7 @@ # Pros-sys - EFI for Rust PROS bindings, used in [pros-rs](https://crates.io/crates/pros) +EFI for Rust PROS bindings, used in [pros-rs](https://crates.io/crates/pros) ## This project is still very early in development - Make sure to check out the todo list [(TODO.md)](../TODO.md) +Make sure to check out the todo list [(TODO.md)](../TODO.md) From ce8ed54a027c06a440d27da0a0108d3c4c94512f Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Tue, 5 Mar 2024 20:37:22 -0800 Subject: [PATCH 95/96] docs: add vex and v5 to crate keywords --- packages/pros-async/Cargo.toml | 2 +- packages/pros-core/Cargo.toml | 2 +- packages/pros-devices/Cargo.toml | 2 +- packages/pros-math/Cargo.toml | 3 ++- packages/pros-panic/Cargo.toml | 2 +- packages/pros-sync/Cargo.toml | 2 +- packages/pros-sys/Cargo.toml | 2 +- packages/pros/Cargo.toml | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/pros-async/Cargo.toml b/packages/pros-async/Cargo.toml index 6f5f7c60..498b9af2 100644 --- a/packages/pros-async/Cargo.toml +++ b/packages/pros-async/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "A simple async executor for pros-rs" -keywords = ["PROS", "Robotics", "bindings", "async"] +keywords = ["PROS", "Robotics", "bindings", "async", "vex", "v5"] categories = [ "no-std", "science::robotics", diff --git a/packages/pros-core/Cargo.toml b/packages/pros-core/Cargo.toml index 8c8178d2..ed6c827a 100644 --- a/packages/pros-core/Cargo.toml +++ b/packages/pros-core/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "Core functionality for pros-rs" -keywords = ["PROS", "Robotics", "bindings"] +keywords = ["PROS", "Robotics", "bindings", "vex", "v5"] categories = [ "api-bindings", "no-std", diff --git a/packages/pros-devices/Cargo.toml b/packages/pros-devices/Cargo.toml index dcd81671..6d49ac81 100644 --- a/packages/pros-devices/Cargo.toml +++ b/packages/pros-devices/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "High level device for pros-rs" -keywords = ["PROS", "Robotics", "bindings"] +keywords = ["PROS", "Robotics", "bindings", "vex", "v5"] categories = [ "api-bindings", "no-std", diff --git a/packages/pros-math/Cargo.toml b/packages/pros-math/Cargo.toml index 64c5d8f2..e2a39aca 100644 --- a/packages/pros-math/Cargo.toml +++ b/packages/pros-math/Cargo.toml @@ -4,10 +4,11 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "Commonly used mathematical formulas for pros-rs" -keywords = ["PROS", "Robotics"] +keywords = ["PROS", "Robotics", "vex", "v5"] categories = [ "no-std", "science::robotics", + "Mathematics", ] repository = "https://github.com/gavin-niederman/pros-rs" authors = [ diff --git a/packages/pros-panic/Cargo.toml b/packages/pros-panic/Cargo.toml index 96cd07ef..39237284 100644 --- a/packages/pros-panic/Cargo.toml +++ b/packages/pros-panic/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "Panic handler for pros-rs" -keywords = ["PROS", "Robotics"] +keywords = ["PROS", "Robotics", "vex", "v5"] categories = [ "no-std", "science::robotics", diff --git a/packages/pros-sync/Cargo.toml b/packages/pros-sync/Cargo.toml index 358193de..e30b4f0b 100644 --- a/packages/pros-sync/Cargo.toml +++ b/packages/pros-sync/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" license = "MIT" description = "`SyncRobot` trait and macro for pros-rs" -keywords = ["PROS", "Robotics"] +keywords = ["PROS", "Robotics", "vex", "v5"] categories = [ "no-std", "science::robotics", diff --git a/packages/pros-sys/Cargo.toml b/packages/pros-sys/Cargo.toml index 145824f7..682b1784 100644 --- a/packages/pros-sys/Cargo.toml +++ b/packages/pros-sys/Cargo.toml @@ -3,7 +3,7 @@ name = "pros-sys" version = "0.7.0" edition = "2021" description = "EFI for the PROS rust bindings" -keywords = ["PROS", "Robotics", "bindings"] +keywords = ["PROS", "Robotics", "bindings", "vex", "v5"] categories = [ "api-bindings", "development-tools::ffi", diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 2df5fa64..4740916b 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -3,7 +3,7 @@ name = "pros" version = "0.8.0" edition = "2021" description = "Rust bindings for PROS" -keywords = ["PROS", "Robotics", "bindings"] +keywords = ["PROS", "Robotics", "bindings", "vex", "v5"] categories = ["os", "api-bindings", "no-std", "science::robotics"] license = "MIT" repository = "https://github.com/pros-rs/pros-rs" From dc115463c5931443423c5ccd5a45a20280f8c169 Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Tue, 5 Mar 2024 20:43:43 -0800 Subject: [PATCH 96/96] fix: remove competition state checking from pros-core docs --- packages/pros-core/README.md | 1 - packages/pros-core/src/lib.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/pros-core/README.md b/packages/pros-core/README.md index cd2a7a3b..fd26132c 100644 --- a/packages/pros-core/README.md +++ b/packages/pros-core/README.md @@ -3,7 +3,6 @@ Low level core functionality for [`pros-rs`](https://crates.io/crates/pros). The core crate is used in all other crates in the pros-rs ecosystem. Included in this crate: - Global allocator -- Competition state checking - Errno handling - Serial terminal printing - No-std `Instant`s diff --git a/packages/pros-core/src/lib.rs b/packages/pros-core/src/lib.rs index dc868f74..67838b74 100644 --- a/packages/pros-core/src/lib.rs +++ b/packages/pros-core/src/lib.rs @@ -3,7 +3,6 @@ //! //! Included in this crate: //! - Global allocator: [`pros_alloc`] -//! - Competition state checking: [`competition`] //! - Errno handling: [`error`] //! - Serial terminal printing: [`io`] //! - No-std [`Instant`](time::Instant)s: [`time`]