From e7b61e584c062a516d37378dfc11555b25c8d5ec Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sun, 21 Jan 2024 11:58:10 -0600 Subject: [PATCH 1/5] feat: add `object_size` method to distance sensor --- CHANGELOG.md | 1 + packages/pros/src/devices/smart/distance.rs | 33 +++++++++++++-------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5424dc3d..c2510a2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ Before releasing: - All ADI device bindings (#55) - `LocalKey` now has `Cell`/`RefCell`-specific methods for setting and taking values. (#42) - `Peripherals` and `DynamicPeripherals` structs to ensure that you have only registered one device on a given smart or ADI port. (#53) +- `object_size` method on `DistanceSensor` for getting a guess at an object's relative size. ### Fixed diff --git a/packages/pros/src/devices/smart/distance.rs b/packages/pros/src/devices/smart/distance.rs index 66e1661f..55fec9a7 100644 --- a/packages/pros/src/devices/smart/distance.rs +++ b/packages/pros/src/devices/smart/distance.rs @@ -24,30 +24,37 @@ impl DistanceSensor { /// Returns the distance to the object the sensor detects in millimeters. pub fn distance(&self) -> Result { - Ok(unsafe { bail_on!(PROS_ERR, pros_sys::distance_get(self.port.index())) as u32 }) + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::distance_get(self.port.index()) + }) as u32) } /// returns the velocity of the object the sensor detects in m/s pub fn object_velocity(&self) -> Result { // all VEX Distance Sensor functions return PROS_ERR on failure even though // some return floating point values (not PROS_ERR_F) - Ok(unsafe { - bail_on!( - PROS_ERR as c_double, - pros_sys::distance_get_object_velocity(self.port.index()) - ) - }) + Ok(bail_on!(PROS_ERR as c_double, unsafe { + pros_sys::distance_get_object_velocity(self.port.index()) + })) + } + + /// Get the current guess at relative object size. + /// + /// This is a value that has a range of 0 to 400. + /// A 18" x 30" grey card will return a value of approximately 75 + /// in typical room lighting. + pub fn object_size(&self) -> Result { + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::distance_get_object_size(self.port.index()) + }) as u32) } /// Returns the confidence in the distance measurement from 0% to 100%. pub fn distance_confidence(&self) -> Result { // 0 -> 63 - let confidence = unsafe { - bail_on!( - PROS_ERR, - pros_sys::distance_get_confidence(self.port.index()) - ) - } as f32; + let confidence = bail_on!(PROS_ERR, unsafe { + pros_sys::distance_get_confidence(self.port.index()) + }) as f32; Ok(confidence * 100.0 / 63.0) } } From 250c228cdd31ce987ca9c43d8db1c5b52287486d Mon Sep 17 00:00:00 2001 From: Gavin-Niederman Date: Wed, 31 Jan 2024 13:09:23 -0800 Subject: [PATCH 2/5] fast forward --- CHANGELOG.md | 20 +- packages/pros-sys/Cargo.toml | 2 +- packages/pros-sys/src/lib.rs | 7 +- packages/pros/Cargo.toml | 5 +- packages/pros/src/devices/controller.rs | 169 +++++++++----- packages/pros/src/devices/smart/imu.rs | 156 +++++-------- packages/pros/src/{io.rs => io/mod.rs} | 3 +- packages/pros/src/io/print_impl.rs | 294 ++++++++++++++++++++++++ packages/pros/src/lib.rs | 13 +- 9 files changed, 504 insertions(+), 165 deletions(-) rename packages/pros/src/{io.rs => io/mod.rs} (68%) create mode 100644 packages/pros/src/io/print_impl.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index c2510a2a..619fbb56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,18 @@ Before releasing: ### Added +- `object_size` method on `DistanceSensor` for getting a guess at an object's relative size. + +### Fixed + +### Changed + +### Removed + +## [0.7.0] + +### Added + - `SmartPort` struct for device access. (#34) - `SmartDevice` trait for common functionality across smart port devices. (#34) - Methods to get a device's port number as well as determine if the device is plugged in or not. (#34) @@ -36,7 +48,6 @@ Before releasing: - All ADI device bindings (#55) - `LocalKey` now has `Cell`/`RefCell`-specific methods for setting and taking values. (#42) - `Peripherals` and `DynamicPeripherals` structs to ensure that you have only registered one device on a given smart or ADI port. (#53) -- `object_size` method on `DistanceSensor` for getting a guess at an object's relative size. ### Fixed @@ -44,12 +55,15 @@ Before releasing: - Fixed error handling in IMU sensor bindings. (#37) - Fixed errors in doctests and examples throughout the crate. (#37) - 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) ### Changed - Overhauled the `competition` module with more straightforward getters for competition state. (#38) (**Breaking Change**) - LLEMU-related macros have been prefixed with `llemu_` (e.g. `llemu_println`). (**Breaking Change**) (#30) - Added `Debug`, `Copy`, and `Clone` derives for common structs (#37) +- Renamed `InertialSensor::is_calibrating` to `InertialSensor::calibrating`. (**Breaking Change**) (#65) - Battery API functions now return `Result<_, BatteryError>`. (**Breaking Change**) (#62) - Renamed `battery::get_capacity` to `battery::capacity`, `battery::get_current` -> `battery::current`, `battery::get_temperature` -> `battery::temperature`, `battery::get_voltage` -> `battery::voltage`. (**Breaking Change**) (#62) @@ -57,6 +71,7 @@ Before releasing: - Removed several broken bindings in `pros_sys` relating to competition state. (#38) (**Breaking Change**) - `LocalKey` no longer implements `set` for non-`Cell`/`RefCell` stored values. (**Breaking change**) (#42) +- Removed the now-redundant `InertialStatus::error` function. (**Breaking Change**) (#65) ## [0.6.0] - 2024-01-14 @@ -117,7 +132,8 @@ Before releasing: ### Removed -[unreleased]: https://github.com/pros-rs/pros-rs/compare/v0.6.0...HEAD +[unreleased]: https://github.com/pros-rs/pros-rs/compare/v0.7.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 diff --git a/packages/pros-sys/Cargo.toml b/packages/pros-sys/Cargo.toml index f8266912..d9912b00 100644 --- a/packages/pros-sys/Cargo.toml +++ b/packages/pros-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pros-sys" -version = "0.5.0" +version = "0.6.0" edition = "2021" description = "EFI for the PROS rust bindings" keywords = ["PROS", "Robotics", "bindings"] diff --git a/packages/pros-sys/src/lib.rs b/packages/pros-sys/src/lib.rs index d80658fe..9d7b55ac 100644 --- a/packages/pros-sys/src/lib.rs +++ b/packages/pros-sys/src/lib.rs @@ -22,7 +22,7 @@ pub mod rotation; pub mod rtos; pub mod vision; -use core::ffi::c_char; +use core::ffi::{c_char, c_int, c_void}; pub use adi::*; pub use colors::*; @@ -48,11 +48,12 @@ pub const CLOCKS_PER_SEC: u32 = 1000; extern "C" { #[cfg(not(target_arch = "wasm32"))] - pub fn memalign(alignment: usize, size: usize) -> *mut core::ffi::c_void; + pub fn memalign(alignment: usize, size: usize) -> *mut c_void; #[cfg(not(target_arch = "wasm32"))] - pub fn free(ptr: *mut core::ffi::c_void); + pub fn free(ptr: *mut c_void); pub fn __errno() -> *mut i32; pub fn clock() -> i32; pub fn puts(s: *const c_char) -> i32; pub fn exit(code: i32) -> !; + pub fn write(fd: c_int, buf: *const c_void, count: usize) -> isize; } diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index 6249bc21..a9bbfda7 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pros" -version = "0.7.0-pre.1" +version = "0.7.0" edition = "2021" description = "Rust bindings for PROS" keywords = ["PROS", "Robotics", "bindings"] @@ -20,7 +20,7 @@ rust-version = "1.75.0" [dependencies] lazy_static = { version = "1.4.0", features = ["spin_no_std"] } spin = "0.9.8" -pros-sys = { version = "0.5", path = "../pros-sys", features = ["xapi"] } +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", @@ -31,7 +31,6 @@ slab = { version = "0.4.9", default-features = false } 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" [target.'cfg(target_arch = "wasm32")'.dependencies] dlmalloc = { version = "0.2.4", features = ["global"] } diff --git a/packages/pros/src/devices/controller.rs b/packages/pros/src/devices/controller.rs index d5ad0857..310f75c6 100644 --- a/packages/pros/src/devices/controller.rs +++ b/packages/pros/src/devices/controller.rs @@ -135,31 +135,43 @@ impl Controller { } /// Gets the current state of the controller in its entirety. - pub fn state(&self) -> ControllerState { - ControllerState { + pub fn state(&self) -> Result { + Ok(ControllerState { joysticks: unsafe { Joysticks { left: Joystick { - x: pros_sys::controller_get_analog( - self.id(), - pros_sys::E_CONTROLLER_ANALOG_LEFT_X, + x: bail_on!( + PROS_ERR, + pros_sys::controller_get_analog( + self.id(), + pros_sys::E_CONTROLLER_ANALOG_LEFT_X, + ) ) as f32 / 127.0, - y: pros_sys::controller_get_analog( - self.id(), - pros_sys::E_CONTROLLER_ANALOG_LEFT_Y, + y: bail_on!( + PROS_ERR, + pros_sys::controller_get_analog( + self.id(), + pros_sys::E_CONTROLLER_ANALOG_LEFT_Y, + ) ) as f32 / 127.0, }, right: Joystick { - x: pros_sys::controller_get_analog( - self.id(), - pros_sys::E_CONTROLLER_ANALOG_RIGHT_X, + x: bail_on!( + PROS_ERR, + pros_sys::controller_get_analog( + self.id(), + pros_sys::E_CONTROLLER_ANALOG_RIGHT_X, + ) ) as f32 / 127.0, - y: pros_sys::controller_get_analog( - self.id(), - pros_sys::E_CONTROLLER_ANALOG_RIGHT_Y, + y: bail_on!( + PROS_ERR, + pros_sys::controller_get_analog( + self.id(), + pros_sys::E_CONTROLLER_ANALOG_RIGHT_Y, + ) ) as f32 / 127.0, }, @@ -167,72 +179,118 @@ impl Controller { }, buttons: unsafe { Buttons { - a: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_A, + a: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_A, + ) ) == 1, - b: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_B, + b: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_B, + ) ) == 1, - x: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_X, + x: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_X, + ) ) == 1, - y: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_Y, + y: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_Y, + ) ) == 1, - up: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_UP, + up: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_UP, + ) ) == 1, - down: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_DOWN, + down: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_DOWN, + ) ) == 1, - left: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_LEFT, + left: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_LEFT, + ) ) == 1, - right: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_RIGHT, + right: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_RIGHT, + ) ) == 1, - left_trigger_1: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_L1, + left_trigger_1: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_L1, + ) ) == 1, - left_trigger_2: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_L2, + left_trigger_2: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_L2, + ) ) == 1, - right_trigger_1: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_R1, + right_trigger_1: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_R1, + ) ) == 1, - right_trigger_2: pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_R2, + right_trigger_2: bail_on!( + PROS_ERR, + pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_R2, + ) ) == 1, } }, - } + }) } /// Gets the state of a specific button on the controller. - pub fn button(&self, button: ControllerButton) -> bool { - unsafe { pros_sys::controller_get_digital(self.id(), button as u32) == 1 } + pub fn button(&self, button: ControllerButton) -> Result { + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::controller_get_digital(self.id(), button as pros_sys::controller_digital_e_t) + }) == 1) } /// Gets the state of a specific joystick axis on the controller. - pub fn joystick_axis(&self, axis: JoystickAxis) -> f32 { - unsafe { pros_sys::controller_get_analog(self.id(), axis as u32) as f32 / 127.0 } + pub fn joystick_axis(&self, axis: JoystickAxis) -> Result { + Ok(bail_on!(PROS_ERR, unsafe { + pros_sys::controller_get_analog(self.id(), axis as pros_sys::controller_analog_e_t) + }) as f32 + / 127.0) } } #[derive(Debug, Snafu)] pub enum ControllerError { + #[snafu(display( + "A controller ID other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER was given." + ))] + InvalidControllerId, + #[snafu(display("Another resource is already using the controller"))] ConcurrentAccess, } @@ -240,5 +298,6 @@ pub enum ControllerError { map_errno! { ControllerError { EACCES => Self::ConcurrentAccess, + EINVAL => Self::InvalidControllerId, } } diff --git a/packages/pros/src/devices/smart/imu.rs b/packages/pros/src/devices/smart/imu.rs index e2c6c66f..6f44192d 100644 --- a/packages/pros/src/devices/smart/imu.rs +++ b/packages/pros/src/devices/smart/imu.rs @@ -33,9 +33,9 @@ impl InertialSensor { /// This takes approximately 2 seconds, and is blocking until the IMU status flag is set properly. /// There is additionally a 3 second timeout that will return [`InertialError::CalibrationTimedOut`] if the timeout is exceeded. pub fn calibrate_blocking(&mut self) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_reset_blocking(self.port.index())); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_reset_blocking(self.port.index()) + }); Ok(()) } @@ -49,7 +49,7 @@ impl InertialSensor { } /// Check if the Intertial Sensor is currently calibrating. - pub fn is_calibrating(&mut self) -> Result { + pub fn calibrating(&mut self) -> Result { Ok(self.status()?.calibrating()) } @@ -58,12 +58,9 @@ impl InertialSensor { /// This value is theoretically unbounded. Clockwise rotations are represented with positive degree values, /// while counterclockwise rotations are represented with negative ones. pub fn rotation(&self) -> Result { - unsafe { - Ok(bail_on!( - PROS_ERR_F, - pros_sys::imu_get_rotation(self.port.index()) - )) - } + Ok(bail_on!(PROS_ERR_F, unsafe { + pros_sys::imu_get_rotation(self.port.index()) + })) } /// Get the Inertial Sensor’s heading relative to the initial direction of its x-axis. @@ -71,47 +68,35 @@ impl InertialSensor { /// This value is bounded by [0, 360) degrees. Clockwise rotations are represented with positive degree values, /// while counterclockwise rotations are represented with negative ones. pub fn heading(&self) -> Result { - unsafe { - Ok(bail_on!( - PROS_ERR_F, - pros_sys::imu_get_heading(self.port.index()) - )) - } + Ok(bail_on!(PROS_ERR_F, unsafe { + pros_sys::imu_get_heading(self.port.index()) + })) } /// Get the Inertial Sensor’s pitch angle bounded by (-180, 180) degrees. pub fn pitch(&self) -> Result { - unsafe { - Ok(bail_on!( - PROS_ERR_F, - pros_sys::imu_get_pitch(self.port.index()) - )) - } + Ok(bail_on!(PROS_ERR_F, unsafe { + pros_sys::imu_get_pitch(self.port.index()) + })) } /// Get the Inertial Sensor’s roll angle bounded by (-180, 180) degrees. pub fn roll(&self) -> Result { - unsafe { - Ok(bail_on!( - PROS_ERR_F, - pros_sys::imu_get_roll(self.port.index()) - )) - } + Ok(bail_on!(PROS_ERR_F, unsafe { + pros_sys::imu_get_roll(self.port.index()) + })) } /// Get the Inertial Sensor’s yaw angle bounded by (-180, 180) degrees. pub fn yaw(&self) -> Result { - unsafe { - Ok(bail_on!( - PROS_ERR_F, - pros_sys::imu_get_yaw(self.port.index()) - )) - } + Ok(bail_on!(PROS_ERR_F, unsafe { + pros_sys::imu_get_yaw(self.port.index()) + })) } /// Read the inertial sensor's status code. pub fn status(&self) -> Result { - unsafe { Ok(bail_on!(PROS_ERR as _, pros_sys::imu_get_status(self.port.index())).into()) } + unsafe { pros_sys::imu_get_status(self.port.index()).try_into() } } /// Get a quaternion representing the Inertial Sensor’s orientation. @@ -136,57 +121,55 @@ impl InertialSensor { /// Resets the current reading of the Inertial Sensor’s heading to zero. pub fn zero_heading(&mut self) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_tare_heading(self.port.index())); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_tare_heading(self.port.index()) + }); Ok(()) } /// Resets the current reading of the Inertial Sensor’s rotation to zero. pub fn zero_rotation(&mut self) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_tare_rotation(self.port.index())); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_tare_rotation(self.port.index()) + }); Ok(()) } /// Resets the current reading of the Inertial Sensor’s pitch to zero. pub fn zero_pitch(&mut self) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_tare_pitch(self.port.index())); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_tare_pitch(self.port.index()) + }); Ok(()) } /// Resets the current reading of the Inertial Sensor’s roll to zero. pub fn zero_roll(&mut self) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_tare_roll(self.port.index())); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_tare_roll(self.port.index()) + }); Ok(()) } /// Resets the current reading of the Inertial Sensor’s yaw to zero. pub fn zero_yaw(&mut self) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_tare_yaw(self.port.index())); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_tare_yaw(self.port.index()) + }); Ok(()) } /// Reset all 3 euler values of the Inertial Sensor to 0. pub fn zero_euler(&mut self) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_tare_euler(self.port.index())); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_tare_euler(self.port.index()) + }); Ok(()) } /// Resets all 5 values of the Inertial Sensor to 0. pub fn zero(&mut self) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_tare(self.port.index())); - } + bail_on!(PROS_ERR, unsafe { pros_sys::imu_tare(self.port.index()) }); Ok(()) } @@ -194,23 +177,17 @@ impl InertialSensor { /// /// Will default to +/- 180 if target exceeds +/- 180. pub fn set_euler(&mut self, euler: Euler) -> Result<(), InertialError> { - unsafe { - bail_on!( - PROS_ERR, - pros_sys::imu_set_euler(self.port.index(), euler.into()) - ); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_set_euler(self.port.index(), euler.into()) + }); Ok(()) } /// Sets the current reading of the Inertial Sensor’s rotation to target value. pub fn set_rotation(&mut self, rotation: f64) -> Result<(), InertialError> { - unsafe { - bail_on!( - PROS_ERR, - pros_sys::imu_set_rotation(self.port.index(), rotation) - ); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_set_rotation(self.port.index(), rotation) + }); Ok(()) } @@ -218,12 +195,9 @@ impl InertialSensor { /// /// Target will default to 360 if above 360 and default to 0 if below 0. pub fn set_heading(&mut self, heading: f64) -> Result<(), InertialError> { - unsafe { - bail_on!( - PROS_ERR, - pros_sys::imu_set_heading(self.port.index(), heading) - ); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_set_heading(self.port.index(), heading) + }); Ok(()) } @@ -231,9 +205,9 @@ impl InertialSensor { /// /// Will default to +/- 180 if target exceeds +/- 180. pub fn set_pitch(&mut self, pitch: f64) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_set_pitch(self.port.index(), pitch)); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_set_pitch(self.port.index(), pitch) + }); Ok(()) } @@ -241,9 +215,9 @@ impl InertialSensor { /// /// Will default to +/- 180 if target exceeds +/- 180. pub fn set_roll(&mut self, roll: f64) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_set_roll(self.port.index(), roll)); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_set_roll(self.port.index(), roll) + }); Ok(()) } @@ -251,9 +225,9 @@ impl InertialSensor { /// /// Will default to +/- 180 if target exceeds +/- 180. pub fn set_yaw(&mut self, yaw: f64) -> Result<(), InertialError> { - unsafe { - bail_on!(PROS_ERR, pros_sys::imu_set_yaw(self.port.index(), yaw)); - } + bail_on!(PROS_ERR, unsafe { + pros_sys::imu_set_yaw(self.port.index(), yaw) + }); Ok(()) } @@ -404,16 +378,13 @@ impl InertialStatus { pub const fn calibrating(&self) -> bool { self.0 & pros_sys::E_IMU_STATUS_CALIBRATING != 0 } - - /// Determine if an error state was reached when trying to get the IMU's status. - pub const fn error(&self) -> bool { - self.0 & pros_sys::E_IMU_STATUS_ERROR != 0 - } } -impl From for InertialStatus { - fn from(value: pros_sys::imu_status_e_t) -> Self { - Self(value) +impl TryFrom for InertialStatus { + type Error = InertialError; + + fn try_from(value: pros_sys::imu_status_e_t) -> Result { + Ok(Self(bail_on!(pros_sys::E_IMU_STATUS_ERROR, value))) } } @@ -441,9 +412,8 @@ impl core::future::Future for InertialCalibrateFuture { } }, Self::Waiting(port, timestamp) => { - const PROS_ERR_U32: u32 = PROS_ERR as _; let is_calibrating = match unsafe { pros_sys::imu_get_status(port) } { - PROS_ERR_U32 => { + pros_sys::E_IMU_STATUS_ERROR => { let errno = take_errno(); return Poll::Ready(Err(InertialError::from_errno(take_errno()) .unwrap_or_else(|| panic!("Unknown errno code {errno}")))); diff --git a/packages/pros/src/io.rs b/packages/pros/src/io/mod.rs similarity index 68% rename from packages/pros/src/io.rs rename to packages/pros/src/io/mod.rs index bfad2330..855263c8 100644 --- a/packages/pros/src/io.rs +++ b/packages/pros/src/io/mod.rs @@ -1,4 +1,5 @@ //! Helpers for terminal I/O functionality. -pub use libc_print::std_name::*; +pub mod print_impl; + pub use no_std_io::io::*; diff --git a/packages/pros/src/io/print_impl.rs b/packages/pros/src/io/print_impl.rs new file mode 100644 index 00000000..13d04f93 --- /dev/null +++ b/packages/pros/src/io/print_impl.rs @@ -0,0 +1,294 @@ +//! 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) +//! +//! Allows you to use these macros in a #!\[no_std\] context, or in a situation where the +//! traditional Rust streams might not be available (ie: at process shutdown time). +//! +//! [`writeln`] and [`ewriteln`] are provided for cases where you may not wish +//! to pull in the overhead of the formatter code and simply wish to print C-style strings. +//! +//! ## Usage +//! +//! Exactly as you'd use `println!`, `eprintln!` and `dbg!`. +//! +//! ```rust +//! # use pros::io::print_impl::*; +//! // Use the default ``-prefixed macros: +//! # fn test1() +//! # { +//! println!("Hello {}!", "stdout"); +//! eprintln!("Hello {}!", "stderr"); +//! let a = 2; +//! let b = dbg!(a * 2) + 1; +//! assert_eq!(b, 5); +//! # } +//! ``` +//! +//! Or you can import aliases to `std` names: +//! +//! ```rust +//! use pros::io::print_impl::{println, eprintln, dbg}; +//! +//! # fn test2() +//! # { +//! println!("Hello {}!", "stdout"); +//! eprintln!("Hello {}!", "stderr"); +//! let a = 2; +//! let b = dbg!(a * 2) + 1; +//! assert_eq!(b, 5); +//! # } +//! ``` + +// libc_print is licensed under the MIT License: + +// Copyright (c) 2023 Matt Mastracci and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// 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}; + +#[doc(hidden)] +pub struct __SerialWriter(i32); + +impl core::fmt::Write for __SerialWriter { + #[inline] + fn write_str(&mut self, s: &str) -> core::fmt::Result { + __println(self.0, s) + } +} + +impl __SerialWriter { + #[inline] + pub const fn new(err: bool) -> __SerialWriter { + __SerialWriter(if err { 2 } else { 1 }) + } + + #[inline] + pub fn write_fmt(&mut self, args: core::fmt::Arguments) -> core::fmt::Result { + core::fmt::Write::write_fmt(self, args) + } + + #[inline] + pub fn write_str(&mut self, s: &str) -> core::fmt::Result { + __println(self.0, s) + } + + #[inline] + pub fn write_nl(&mut self) -> core::fmt::Result { + __println(self.0, "\n") + } +} + +#[doc(hidden)] +#[inline] +pub fn __println(handle: i32, msg: &str) -> core::fmt::Result { + let msg = msg.as_bytes(); + + let mut written = 0; + while written < msg.len() { + match unsafe { write(handle, &msg[written..]) } { + // Ignore errors + None | Some(0) => break, + Some(res) => written += res, + } + } + + Ok(()) +} + +unsafe fn write(handle: i32, bytes: &[u8]) -> Option { + usize::try_from(unsafe { + pros_sys::write( + handle, + bytes.as_ptr().cast::(), + bytes.len(), + ) + }) + .ok() +} + +/// Macro for printing to the standard output, with a newline. +/// +/// Does not panic on failure to write - instead silently ignores errors. +/// +/// See [`println!`](https://doc.rust-lang.org/std/macro.println.html) for +/// full documentation. +#[macro_export] +macro_rules! println { + () => { $crate::println!("") }; + ($($arg:tt)*) => { + { + #[allow(unused_must_use)] + { + let mut stm = $crate::io::print_impl::__SerialWriter::new(false); + stm.write_fmt(format_args!($($arg)*)); + stm.write_nl(); + } + } + }; +} + +/// Macro for printing to the standard output. +/// +/// Does not panic on failure to write - instead silently ignores errors. +/// +/// See [`print!`](https://doc.rust-lang.org/std/macro.print.html) for +/// full documentation. +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => { + { + #[allow(unused_must_use)] + { + let mut stm = $crate::io::print_impl::__SerialWriter::new(false); + stm.write_fmt(format_args!($($arg)*)); + } + } + }; +} + +/// Macro for printing to the standard error, with a newline. +/// +/// Does not panic on failure to write - instead silently ignores errors. +/// +/// See [`eprintln!`](https://doc.rust-lang.org/std/macro.eprintln.html) for +/// full documentation. +#[macro_export] +macro_rules! eprintln { + () => { $crate::eprintln!("") }; + ($($arg:tt)*) => { + { + #[allow(unused_must_use)] + { + let mut stm = $crate::io::print_impl::__SerialWriter::new(true); + stm.write_fmt(format_args!($($arg)*)); + stm.write_nl(); + } + } + }; +} + +/// Macro for printing to the standard error. +/// +/// Does not panic on failure to write - instead silently ignores errors. +/// +/// See [`eprint!`](https://doc.rust-lang.org/std/macro.eprint.html) for +/// full documentation. +#[macro_export] +macro_rules! eprint { + ($($arg:tt)*) => { + { + #[allow(unused_must_use)] + { + let mut stm = $crate::io::print_impl::__SerialWriter::new(true); + stm.write_fmt(format_args!($($arg)*)); + } + } + }; +} + +/// Macro for printing a static string to the standard output. +/// +/// Does not panic on failure to write - instead silently ignores errors. +#[macro_export] +macro_rules! write { + ($arg:expr) => { + #[allow(unused_must_use)] + { + let mut stm = $crate::io::print_impl::__SerialWriter::new(false); + stm.write_str($arg); + } + }; +} + +/// Macro for printing a static string to the standard error. +/// +/// Does not panic on failure to write - instead silently ignores errors. +#[macro_export] +macro_rules! ewrite { + ($arg:expr) => {{ + #[allow(unused_must_use)] + { + let mut stm = $crate::io::print_impl::__SerialWriter::new(true); + stm.write_str($arg); + } + }}; +} + +/// Macro for printing a static string to the standard output, with a newline. +/// +/// Does not panic on failure to write - instead silently ignores errors. +#[macro_export] +macro_rules! writeln { + ($arg:expr) => { + #[allow(unused_must_use)] + { + let mut stm = $crate::io::print_impl::__SerialWriter::new(false); + stm.write_str($arg); + stm.write_nl(); + } + }; +} + +/// Macro for printing a static string to the standard error, with a newline. +/// +/// Does not panic on failure to write - instead silently ignores errors. +#[macro_export] +macro_rules! ewriteln { + ($arg:expr) => {{ + #[allow(unused_must_use)] + { + let mut stm = $crate::io::print_impl::__SerialWriter::new(true); + stm.write_str($arg); + stm.write_nl(); + } + }}; +} + +/// Prints and returns the value of a given expression for quick and dirty +/// debugging. +/// +/// An example: +/// +/// ```rust +/// let a = 2; +/// let b = dbg!(a * 2) + 1; +/// // ^-- prints: [src/main.rs:2] a * 2 = 4 +/// assert_eq!(b, 5); +/// ``` +/// +/// See [dbg!](https://doc.rust-lang.org/std/macro.dbg.html) for full documentation. +#[macro_export] +macro_rules! dbg { + () => { + $crate::eprintln!("[{}:{}]", $file!(), $line!()) + }; + ($val:expr $(,)?) => { + match $val { + tmp => { + $crate::eprintln!("[{}:{}] {} = {:#?}", file!(), line!(), stringify!($val), &tmp); + tmp + } + } + }; + ($($val:expr),+ $(,)?) => { + ($($crate::dbg!($val)),+,) + }; +} diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index d4f76885..f9b6a4a2 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -83,8 +83,6 @@ pub mod usd; pub type Result = core::result::Result>; -use crate::io::println; - pub trait AsyncRobot { fn opcontrol(&mut self) -> impl Future { async { Ok(()) } @@ -357,10 +355,9 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { // panic message here println!("task '{task_name}' {info}"); - #[cfg(target_arch = "wasm32")] - wasm_env::sim_log_backtrace(); - unsafe { + #[cfg(target_arch = "wasm32")] + wasm_env::sim_log_backtrace(); pros_sys::exit(1); } } @@ -374,6 +371,7 @@ pub mod prelude { pub use crate::{ async_robot, async_runtime::*, + dbg, devices::{ adi::{ analog::{AdiAnalogIn, AdiAnalogOut}, @@ -399,12 +397,13 @@ pub mod prelude { SmartDevice, SmartPort, }, }, + eprint, eprintln, error::PortError, - io::{dbg, eprint, eprintln, print, println, BufRead, Read, Seek, Write}, + io::{BufRead, Read, Seek, Write}, lcd::{buttons::Button, llemu_print, llemu_println, LcdError}, os_task_local, pid::*, - sync_robot, + print, println, sync_robot, task::{delay, sleep, spawn}, AsyncRobot, SyncRobot, }; From 2697da9574c178de98cc0e8eb83d8782485d715f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 2 Mar 2024 23:20:23 -0600 Subject: [PATCH 3/5] Revert "fast forward" This reverts commit 250c228cdd31ce987ca9c43d8db1c5b52287486d. --- CHANGELOG.md | 20 +- packages/pros-sys/Cargo.toml | 2 +- packages/pros-sys/src/lib.rs | 7 +- packages/pros/Cargo.toml | 5 +- packages/pros/src/devices/controller.rs | 169 +++++--------- packages/pros/src/devices/smart/imu.rs | 156 ++++++++----- packages/pros/src/{io/mod.rs => io.rs} | 3 +- packages/pros/src/io/print_impl.rs | 294 ------------------------ packages/pros/src/lib.rs | 13 +- 9 files changed, 165 insertions(+), 504 deletions(-) rename packages/pros/src/{io/mod.rs => io.rs} (68%) delete mode 100644 packages/pros/src/io/print_impl.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 619fbb56..c2510a2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,18 +23,6 @@ Before releasing: ### Added -- `object_size` method on `DistanceSensor` for getting a guess at an object's relative size. - -### Fixed - -### Changed - -### Removed - -## [0.7.0] - -### Added - - `SmartPort` struct for device access. (#34) - `SmartDevice` trait for common functionality across smart port devices. (#34) - Methods to get a device's port number as well as determine if the device is plugged in or not. (#34) @@ -48,6 +36,7 @@ Before releasing: - All ADI device bindings (#55) - `LocalKey` now has `Cell`/`RefCell`-specific methods for setting and taking values. (#42) - `Peripherals` and `DynamicPeripherals` structs to ensure that you have only registered one device on a given smart or ADI port. (#53) +- `object_size` method on `DistanceSensor` for getting a guess at an object's relative size. ### Fixed @@ -55,15 +44,12 @@ Before releasing: - Fixed error handling in IMU sensor bindings. (#37) - Fixed errors in doctests and examples throughout the crate. (#37) - 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) ### Changed - Overhauled the `competition` module with more straightforward getters for competition state. (#38) (**Breaking Change**) - LLEMU-related macros have been prefixed with `llemu_` (e.g. `llemu_println`). (**Breaking Change**) (#30) - Added `Debug`, `Copy`, and `Clone` derives for common structs (#37) -- Renamed `InertialSensor::is_calibrating` to `InertialSensor::calibrating`. (**Breaking Change**) (#65) - Battery API functions now return `Result<_, BatteryError>`. (**Breaking Change**) (#62) - Renamed `battery::get_capacity` to `battery::capacity`, `battery::get_current` -> `battery::current`, `battery::get_temperature` -> `battery::temperature`, `battery::get_voltage` -> `battery::voltage`. (**Breaking Change**) (#62) @@ -71,7 +57,6 @@ Before releasing: - Removed several broken bindings in `pros_sys` relating to competition state. (#38) (**Breaking Change**) - `LocalKey` no longer implements `set` for non-`Cell`/`RefCell` stored values. (**Breaking change**) (#42) -- Removed the now-redundant `InertialStatus::error` function. (**Breaking Change**) (#65) ## [0.6.0] - 2024-01-14 @@ -132,8 +117,7 @@ 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.6.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 diff --git a/packages/pros-sys/Cargo.toml b/packages/pros-sys/Cargo.toml index d9912b00..f8266912 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.5.0" edition = "2021" description = "EFI for the PROS rust bindings" keywords = ["PROS", "Robotics", "bindings"] diff --git a/packages/pros-sys/src/lib.rs b/packages/pros-sys/src/lib.rs index 9d7b55ac..d80658fe 100644 --- a/packages/pros-sys/src/lib.rs +++ b/packages/pros-sys/src/lib.rs @@ -22,7 +22,7 @@ pub mod rotation; pub mod rtos; pub mod vision; -use core::ffi::{c_char, c_int, c_void}; +use core::ffi::c_char; pub use adi::*; pub use colors::*; @@ -48,12 +48,11 @@ pub const CLOCKS_PER_SEC: u32 = 1000; extern "C" { #[cfg(not(target_arch = "wasm32"))] - pub fn memalign(alignment: usize, size: usize) -> *mut c_void; + pub fn memalign(alignment: usize, size: usize) -> *mut core::ffi::c_void; #[cfg(not(target_arch = "wasm32"))] - pub fn free(ptr: *mut c_void); + pub fn free(ptr: *mut core::ffi::c_void); pub fn __errno() -> *mut i32; pub fn clock() -> i32; pub fn puts(s: *const c_char) -> i32; pub fn exit(code: i32) -> !; - pub fn write(fd: c_int, buf: *const c_void, count: usize) -> isize; } diff --git a/packages/pros/Cargo.toml b/packages/pros/Cargo.toml index a9bbfda7..6249bc21 100644 --- a/packages/pros/Cargo.toml +++ b/packages/pros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pros" -version = "0.7.0" +version = "0.7.0-pre.1" edition = "2021" description = "Rust bindings for PROS" keywords = ["PROS", "Robotics", "bindings"] @@ -20,7 +20,7 @@ rust-version = "1.75.0" [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"] } +pros-sys = { version = "0.5", path = "../pros-sys", features = ["xapi"] } snafu = { version = "0.8.0", default-features = false, features = [ "rust_1_61", "unstable-core-error", @@ -31,6 +31,7 @@ slab = { version = "0.4.9", default-features = false } 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" [target.'cfg(target_arch = "wasm32")'.dependencies] dlmalloc = { version = "0.2.4", features = ["global"] } diff --git a/packages/pros/src/devices/controller.rs b/packages/pros/src/devices/controller.rs index 310f75c6..d5ad0857 100644 --- a/packages/pros/src/devices/controller.rs +++ b/packages/pros/src/devices/controller.rs @@ -135,43 +135,31 @@ impl Controller { } /// Gets the current state of the controller in its entirety. - pub fn state(&self) -> Result { - Ok(ControllerState { + pub fn state(&self) -> ControllerState { + ControllerState { joysticks: unsafe { Joysticks { left: Joystick { - x: bail_on!( - PROS_ERR, - pros_sys::controller_get_analog( - self.id(), - pros_sys::E_CONTROLLER_ANALOG_LEFT_X, - ) + x: pros_sys::controller_get_analog( + self.id(), + pros_sys::E_CONTROLLER_ANALOG_LEFT_X, ) as f32 / 127.0, - y: bail_on!( - PROS_ERR, - pros_sys::controller_get_analog( - self.id(), - pros_sys::E_CONTROLLER_ANALOG_LEFT_Y, - ) + y: pros_sys::controller_get_analog( + self.id(), + pros_sys::E_CONTROLLER_ANALOG_LEFT_Y, ) as f32 / 127.0, }, right: Joystick { - x: bail_on!( - PROS_ERR, - pros_sys::controller_get_analog( - self.id(), - pros_sys::E_CONTROLLER_ANALOG_RIGHT_X, - ) + x: pros_sys::controller_get_analog( + self.id(), + pros_sys::E_CONTROLLER_ANALOG_RIGHT_X, ) as f32 / 127.0, - y: bail_on!( - PROS_ERR, - pros_sys::controller_get_analog( - self.id(), - pros_sys::E_CONTROLLER_ANALOG_RIGHT_Y, - ) + y: pros_sys::controller_get_analog( + self.id(), + pros_sys::E_CONTROLLER_ANALOG_RIGHT_Y, ) as f32 / 127.0, }, @@ -179,118 +167,72 @@ impl Controller { }, buttons: unsafe { Buttons { - a: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_A, - ) + a: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_A, ) == 1, - b: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_B, - ) + b: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_B, ) == 1, - x: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_X, - ) + x: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_X, ) == 1, - y: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_Y, - ) + y: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_Y, ) == 1, - up: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_UP, - ) + up: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_UP, ) == 1, - down: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_DOWN, - ) + down: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_DOWN, ) == 1, - left: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_LEFT, - ) + left: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_LEFT, ) == 1, - right: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_RIGHT, - ) + right: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_RIGHT, ) == 1, - left_trigger_1: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_L1, - ) + left_trigger_1: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_L1, ) == 1, - left_trigger_2: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_L2, - ) + left_trigger_2: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_L2, ) == 1, - right_trigger_1: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_R1, - ) + right_trigger_1: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_R1, ) == 1, - right_trigger_2: bail_on!( - PROS_ERR, - pros_sys::controller_get_digital( - self.id(), - pros_sys::E_CONTROLLER_DIGITAL_R2, - ) + right_trigger_2: pros_sys::controller_get_digital( + self.id(), + pros_sys::E_CONTROLLER_DIGITAL_R2, ) == 1, } }, - }) + } } /// Gets the state of a specific button on the controller. - pub fn button(&self, button: ControllerButton) -> Result { - Ok(bail_on!(PROS_ERR, unsafe { - pros_sys::controller_get_digital(self.id(), button as pros_sys::controller_digital_e_t) - }) == 1) + pub fn button(&self, button: ControllerButton) -> bool { + unsafe { pros_sys::controller_get_digital(self.id(), button as u32) == 1 } } /// Gets the state of a specific joystick axis on the controller. - pub fn joystick_axis(&self, axis: JoystickAxis) -> Result { - Ok(bail_on!(PROS_ERR, unsafe { - pros_sys::controller_get_analog(self.id(), axis as pros_sys::controller_analog_e_t) - }) as f32 - / 127.0) + pub fn joystick_axis(&self, axis: JoystickAxis) -> f32 { + unsafe { pros_sys::controller_get_analog(self.id(), axis as u32) as f32 / 127.0 } } } #[derive(Debug, Snafu)] pub enum ControllerError { - #[snafu(display( - "A controller ID other than E_CONTROLLER_MASTER or E_CONTROLLER_PARTNER was given." - ))] - InvalidControllerId, - #[snafu(display("Another resource is already using the controller"))] ConcurrentAccess, } @@ -298,6 +240,5 @@ pub enum ControllerError { map_errno! { ControllerError { EACCES => Self::ConcurrentAccess, - EINVAL => Self::InvalidControllerId, } } diff --git a/packages/pros/src/devices/smart/imu.rs b/packages/pros/src/devices/smart/imu.rs index 6f44192d..e2c6c66f 100644 --- a/packages/pros/src/devices/smart/imu.rs +++ b/packages/pros/src/devices/smart/imu.rs @@ -33,9 +33,9 @@ impl InertialSensor { /// This takes approximately 2 seconds, and is blocking until the IMU status flag is set properly. /// There is additionally a 3 second timeout that will return [`InertialError::CalibrationTimedOut`] if the timeout is exceeded. pub fn calibrate_blocking(&mut self) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_reset_blocking(self.port.index()) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_reset_blocking(self.port.index())); + } Ok(()) } @@ -49,7 +49,7 @@ impl InertialSensor { } /// Check if the Intertial Sensor is currently calibrating. - pub fn calibrating(&mut self) -> Result { + pub fn is_calibrating(&mut self) -> Result { Ok(self.status()?.calibrating()) } @@ -58,9 +58,12 @@ impl InertialSensor { /// This value is theoretically unbounded. Clockwise rotations are represented with positive degree values, /// while counterclockwise rotations are represented with negative ones. pub fn rotation(&self) -> Result { - Ok(bail_on!(PROS_ERR_F, unsafe { - pros_sys::imu_get_rotation(self.port.index()) - })) + unsafe { + Ok(bail_on!( + PROS_ERR_F, + pros_sys::imu_get_rotation(self.port.index()) + )) + } } /// Get the Inertial Sensor’s heading relative to the initial direction of its x-axis. @@ -68,35 +71,47 @@ impl InertialSensor { /// This value is bounded by [0, 360) degrees. Clockwise rotations are represented with positive degree values, /// while counterclockwise rotations are represented with negative ones. pub fn heading(&self) -> Result { - Ok(bail_on!(PROS_ERR_F, unsafe { - pros_sys::imu_get_heading(self.port.index()) - })) + unsafe { + Ok(bail_on!( + PROS_ERR_F, + pros_sys::imu_get_heading(self.port.index()) + )) + } } /// Get the Inertial Sensor’s pitch angle bounded by (-180, 180) degrees. pub fn pitch(&self) -> Result { - Ok(bail_on!(PROS_ERR_F, unsafe { - pros_sys::imu_get_pitch(self.port.index()) - })) + unsafe { + Ok(bail_on!( + PROS_ERR_F, + pros_sys::imu_get_pitch(self.port.index()) + )) + } } /// Get the Inertial Sensor’s roll angle bounded by (-180, 180) degrees. pub fn roll(&self) -> Result { - Ok(bail_on!(PROS_ERR_F, unsafe { - pros_sys::imu_get_roll(self.port.index()) - })) + unsafe { + Ok(bail_on!( + PROS_ERR_F, + pros_sys::imu_get_roll(self.port.index()) + )) + } } /// Get the Inertial Sensor’s yaw angle bounded by (-180, 180) degrees. pub fn yaw(&self) -> Result { - Ok(bail_on!(PROS_ERR_F, unsafe { - pros_sys::imu_get_yaw(self.port.index()) - })) + unsafe { + Ok(bail_on!( + PROS_ERR_F, + pros_sys::imu_get_yaw(self.port.index()) + )) + } } /// Read the inertial sensor's status code. pub fn status(&self) -> Result { - unsafe { pros_sys::imu_get_status(self.port.index()).try_into() } + unsafe { Ok(bail_on!(PROS_ERR as _, pros_sys::imu_get_status(self.port.index())).into()) } } /// Get a quaternion representing the Inertial Sensor’s orientation. @@ -121,55 +136,57 @@ impl InertialSensor { /// Resets the current reading of the Inertial Sensor’s heading to zero. pub fn zero_heading(&mut self) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_tare_heading(self.port.index()) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_tare_heading(self.port.index())); + } Ok(()) } /// Resets the current reading of the Inertial Sensor’s rotation to zero. pub fn zero_rotation(&mut self) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_tare_rotation(self.port.index()) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_tare_rotation(self.port.index())); + } Ok(()) } /// Resets the current reading of the Inertial Sensor’s pitch to zero. pub fn zero_pitch(&mut self) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_tare_pitch(self.port.index()) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_tare_pitch(self.port.index())); + } Ok(()) } /// Resets the current reading of the Inertial Sensor’s roll to zero. pub fn zero_roll(&mut self) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_tare_roll(self.port.index()) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_tare_roll(self.port.index())); + } Ok(()) } /// Resets the current reading of the Inertial Sensor’s yaw to zero. pub fn zero_yaw(&mut self) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_tare_yaw(self.port.index()) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_tare_yaw(self.port.index())); + } Ok(()) } /// Reset all 3 euler values of the Inertial Sensor to 0. pub fn zero_euler(&mut self) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_tare_euler(self.port.index()) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_tare_euler(self.port.index())); + } Ok(()) } /// Resets all 5 values of the Inertial Sensor to 0. pub fn zero(&mut self) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { pros_sys::imu_tare(self.port.index()) }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_tare(self.port.index())); + } Ok(()) } @@ -177,17 +194,23 @@ impl InertialSensor { /// /// Will default to +/- 180 if target exceeds +/- 180. pub fn set_euler(&mut self, euler: Euler) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_set_euler(self.port.index(), euler.into()) - }); + unsafe { + bail_on!( + PROS_ERR, + pros_sys::imu_set_euler(self.port.index(), euler.into()) + ); + } Ok(()) } /// Sets the current reading of the Inertial Sensor’s rotation to target value. pub fn set_rotation(&mut self, rotation: f64) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_set_rotation(self.port.index(), rotation) - }); + unsafe { + bail_on!( + PROS_ERR, + pros_sys::imu_set_rotation(self.port.index(), rotation) + ); + } Ok(()) } @@ -195,9 +218,12 @@ impl InertialSensor { /// /// Target will default to 360 if above 360 and default to 0 if below 0. pub fn set_heading(&mut self, heading: f64) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_set_heading(self.port.index(), heading) - }); + unsafe { + bail_on!( + PROS_ERR, + pros_sys::imu_set_heading(self.port.index(), heading) + ); + } Ok(()) } @@ -205,9 +231,9 @@ impl InertialSensor { /// /// Will default to +/- 180 if target exceeds +/- 180. pub fn set_pitch(&mut self, pitch: f64) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_set_pitch(self.port.index(), pitch) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_set_pitch(self.port.index(), pitch)); + } Ok(()) } @@ -215,9 +241,9 @@ impl InertialSensor { /// /// Will default to +/- 180 if target exceeds +/- 180. pub fn set_roll(&mut self, roll: f64) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_set_roll(self.port.index(), roll) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_set_roll(self.port.index(), roll)); + } Ok(()) } @@ -225,9 +251,9 @@ impl InertialSensor { /// /// Will default to +/- 180 if target exceeds +/- 180. pub fn set_yaw(&mut self, yaw: f64) -> Result<(), InertialError> { - bail_on!(PROS_ERR, unsafe { - pros_sys::imu_set_yaw(self.port.index(), yaw) - }); + unsafe { + bail_on!(PROS_ERR, pros_sys::imu_set_yaw(self.port.index(), yaw)); + } Ok(()) } @@ -378,13 +404,16 @@ impl InertialStatus { pub const fn calibrating(&self) -> bool { self.0 & pros_sys::E_IMU_STATUS_CALIBRATING != 0 } -} -impl TryFrom for InertialStatus { - type Error = InertialError; + /// Determine if an error state was reached when trying to get the IMU's status. + pub const fn error(&self) -> bool { + self.0 & pros_sys::E_IMU_STATUS_ERROR != 0 + } +} - fn try_from(value: pros_sys::imu_status_e_t) -> Result { - Ok(Self(bail_on!(pros_sys::E_IMU_STATUS_ERROR, value))) +impl From for InertialStatus { + fn from(value: pros_sys::imu_status_e_t) -> Self { + Self(value) } } @@ -412,8 +441,9 @@ impl core::future::Future for InertialCalibrateFuture { } }, Self::Waiting(port, timestamp) => { + const PROS_ERR_U32: u32 = PROS_ERR as _; let is_calibrating = match unsafe { pros_sys::imu_get_status(port) } { - pros_sys::E_IMU_STATUS_ERROR => { + PROS_ERR_U32 => { let errno = take_errno(); return Poll::Ready(Err(InertialError::from_errno(take_errno()) .unwrap_or_else(|| panic!("Unknown errno code {errno}")))); diff --git a/packages/pros/src/io/mod.rs b/packages/pros/src/io.rs similarity index 68% rename from packages/pros/src/io/mod.rs rename to packages/pros/src/io.rs index 855263c8..bfad2330 100644 --- a/packages/pros/src/io/mod.rs +++ b/packages/pros/src/io.rs @@ -1,5 +1,4 @@ //! Helpers for terminal I/O functionality. -pub mod print_impl; - +pub use libc_print::std_name::*; pub use no_std_io::io::*; diff --git a/packages/pros/src/io/print_impl.rs b/packages/pros/src/io/print_impl.rs deleted file mode 100644 index 13d04f93..00000000 --- a/packages/pros/src/io/print_impl.rs +++ /dev/null @@ -1,294 +0,0 @@ -//! 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) -//! -//! Allows you to use these macros in a #!\[no_std\] context, or in a situation where the -//! traditional Rust streams might not be available (ie: at process shutdown time). -//! -//! [`writeln`] and [`ewriteln`] are provided for cases where you may not wish -//! to pull in the overhead of the formatter code and simply wish to print C-style strings. -//! -//! ## Usage -//! -//! Exactly as you'd use `println!`, `eprintln!` and `dbg!`. -//! -//! ```rust -//! # use pros::io::print_impl::*; -//! // Use the default ``-prefixed macros: -//! # fn test1() -//! # { -//! println!("Hello {}!", "stdout"); -//! eprintln!("Hello {}!", "stderr"); -//! let a = 2; -//! let b = dbg!(a * 2) + 1; -//! assert_eq!(b, 5); -//! # } -//! ``` -//! -//! Or you can import aliases to `std` names: -//! -//! ```rust -//! use pros::io::print_impl::{println, eprintln, dbg}; -//! -//! # fn test2() -//! # { -//! println!("Hello {}!", "stdout"); -//! eprintln!("Hello {}!", "stderr"); -//! let a = 2; -//! let b = dbg!(a * 2) + 1; -//! assert_eq!(b, 5); -//! # } -//! ``` - -// libc_print is licensed under the MIT License: - -// Copyright (c) 2023 Matt Mastracci and contributors - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// 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}; - -#[doc(hidden)] -pub struct __SerialWriter(i32); - -impl core::fmt::Write for __SerialWriter { - #[inline] - fn write_str(&mut self, s: &str) -> core::fmt::Result { - __println(self.0, s) - } -} - -impl __SerialWriter { - #[inline] - pub const fn new(err: bool) -> __SerialWriter { - __SerialWriter(if err { 2 } else { 1 }) - } - - #[inline] - pub fn write_fmt(&mut self, args: core::fmt::Arguments) -> core::fmt::Result { - core::fmt::Write::write_fmt(self, args) - } - - #[inline] - pub fn write_str(&mut self, s: &str) -> core::fmt::Result { - __println(self.0, s) - } - - #[inline] - pub fn write_nl(&mut self) -> core::fmt::Result { - __println(self.0, "\n") - } -} - -#[doc(hidden)] -#[inline] -pub fn __println(handle: i32, msg: &str) -> core::fmt::Result { - let msg = msg.as_bytes(); - - let mut written = 0; - while written < msg.len() { - match unsafe { write(handle, &msg[written..]) } { - // Ignore errors - None | Some(0) => break, - Some(res) => written += res, - } - } - - Ok(()) -} - -unsafe fn write(handle: i32, bytes: &[u8]) -> Option { - usize::try_from(unsafe { - pros_sys::write( - handle, - bytes.as_ptr().cast::(), - bytes.len(), - ) - }) - .ok() -} - -/// Macro for printing to the standard output, with a newline. -/// -/// Does not panic on failure to write - instead silently ignores errors. -/// -/// See [`println!`](https://doc.rust-lang.org/std/macro.println.html) for -/// full documentation. -#[macro_export] -macro_rules! println { - () => { $crate::println!("") }; - ($($arg:tt)*) => { - { - #[allow(unused_must_use)] - { - let mut stm = $crate::io::print_impl::__SerialWriter::new(false); - stm.write_fmt(format_args!($($arg)*)); - stm.write_nl(); - } - } - }; -} - -/// Macro for printing to the standard output. -/// -/// Does not panic on failure to write - instead silently ignores errors. -/// -/// See [`print!`](https://doc.rust-lang.org/std/macro.print.html) for -/// full documentation. -#[macro_export] -macro_rules! print { - ($($arg:tt)*) => { - { - #[allow(unused_must_use)] - { - let mut stm = $crate::io::print_impl::__SerialWriter::new(false); - stm.write_fmt(format_args!($($arg)*)); - } - } - }; -} - -/// Macro for printing to the standard error, with a newline. -/// -/// Does not panic on failure to write - instead silently ignores errors. -/// -/// See [`eprintln!`](https://doc.rust-lang.org/std/macro.eprintln.html) for -/// full documentation. -#[macro_export] -macro_rules! eprintln { - () => { $crate::eprintln!("") }; - ($($arg:tt)*) => { - { - #[allow(unused_must_use)] - { - let mut stm = $crate::io::print_impl::__SerialWriter::new(true); - stm.write_fmt(format_args!($($arg)*)); - stm.write_nl(); - } - } - }; -} - -/// Macro for printing to the standard error. -/// -/// Does not panic on failure to write - instead silently ignores errors. -/// -/// See [`eprint!`](https://doc.rust-lang.org/std/macro.eprint.html) for -/// full documentation. -#[macro_export] -macro_rules! eprint { - ($($arg:tt)*) => { - { - #[allow(unused_must_use)] - { - let mut stm = $crate::io::print_impl::__SerialWriter::new(true); - stm.write_fmt(format_args!($($arg)*)); - } - } - }; -} - -/// Macro for printing a static string to the standard output. -/// -/// Does not panic on failure to write - instead silently ignores errors. -#[macro_export] -macro_rules! write { - ($arg:expr) => { - #[allow(unused_must_use)] - { - let mut stm = $crate::io::print_impl::__SerialWriter::new(false); - stm.write_str($arg); - } - }; -} - -/// Macro for printing a static string to the standard error. -/// -/// Does not panic on failure to write - instead silently ignores errors. -#[macro_export] -macro_rules! ewrite { - ($arg:expr) => {{ - #[allow(unused_must_use)] - { - let mut stm = $crate::io::print_impl::__SerialWriter::new(true); - stm.write_str($arg); - } - }}; -} - -/// Macro for printing a static string to the standard output, with a newline. -/// -/// Does not panic on failure to write - instead silently ignores errors. -#[macro_export] -macro_rules! writeln { - ($arg:expr) => { - #[allow(unused_must_use)] - { - let mut stm = $crate::io::print_impl::__SerialWriter::new(false); - stm.write_str($arg); - stm.write_nl(); - } - }; -} - -/// Macro for printing a static string to the standard error, with a newline. -/// -/// Does not panic on failure to write - instead silently ignores errors. -#[macro_export] -macro_rules! ewriteln { - ($arg:expr) => {{ - #[allow(unused_must_use)] - { - let mut stm = $crate::io::print_impl::__SerialWriter::new(true); - stm.write_str($arg); - stm.write_nl(); - } - }}; -} - -/// Prints and returns the value of a given expression for quick and dirty -/// debugging. -/// -/// An example: -/// -/// ```rust -/// let a = 2; -/// let b = dbg!(a * 2) + 1; -/// // ^-- prints: [src/main.rs:2] a * 2 = 4 -/// assert_eq!(b, 5); -/// ``` -/// -/// See [dbg!](https://doc.rust-lang.org/std/macro.dbg.html) for full documentation. -#[macro_export] -macro_rules! dbg { - () => { - $crate::eprintln!("[{}:{}]", $file!(), $line!()) - }; - ($val:expr $(,)?) => { - match $val { - tmp => { - $crate::eprintln!("[{}:{}] {} = {:#?}", file!(), line!(), stringify!($val), &tmp); - tmp - } - } - }; - ($($val:expr),+ $(,)?) => { - ($($crate::dbg!($val)),+,) - }; -} diff --git a/packages/pros/src/lib.rs b/packages/pros/src/lib.rs index f9b6a4a2..d4f76885 100644 --- a/packages/pros/src/lib.rs +++ b/packages/pros/src/lib.rs @@ -83,6 +83,8 @@ pub mod usd; pub type Result = core::result::Result>; +use crate::io::println; + pub trait AsyncRobot { fn opcontrol(&mut self) -> impl Future { async { Ok(()) } @@ -355,9 +357,10 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { // panic message here println!("task '{task_name}' {info}"); + #[cfg(target_arch = "wasm32")] + wasm_env::sim_log_backtrace(); + unsafe { - #[cfg(target_arch = "wasm32")] - wasm_env::sim_log_backtrace(); pros_sys::exit(1); } } @@ -371,7 +374,6 @@ pub mod prelude { pub use crate::{ async_robot, async_runtime::*, - dbg, devices::{ adi::{ analog::{AdiAnalogIn, AdiAnalogOut}, @@ -397,13 +399,12 @@ pub mod prelude { SmartDevice, SmartPort, }, }, - eprint, eprintln, error::PortError, - io::{BufRead, Read, Seek, Write}, + io::{dbg, eprint, eprintln, print, println, BufRead, Read, Seek, Write}, lcd::{buttons::Button, llemu_print, llemu_println, LcdError}, os_task_local, pid::*, - print, println, sync_robot, + sync_robot, task::{delay, sleep, spawn}, AsyncRobot, SyncRobot, }; From 710fedebad18990751526a2a08a3e44775066e3a Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Fri, 8 Mar 2024 12:49:46 -0600 Subject: [PATCH 4/5] refactor: distance_confidence 0-1, docs, method naming --- packages/pros-devices/src/smart/distance.rs | 31 +++++++++++++-------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/pros-devices/src/smart/distance.rs b/packages/pros-devices/src/smart/distance.rs index 607991ca..53fa0849 100644 --- a/packages/pros-devices/src/smart/distance.rs +++ b/packages/pros-devices/src/smart/distance.rs @@ -29,33 +29,40 @@ impl DistanceSensor { }) as u32) } - /// returns the velocity of the object the sensor detects in m/s - pub fn object_velocity(&self) -> Result { - // all VEX Distance Sensor functions return PROS_ERR on failure even though + /// Returns the velocity of the object the sensor detects in m/s + pub fn velocity(&self) -> Result { + // All VEX Distance Sensor functions return PROS_ERR on failure even though // some return floating point values (not PROS_ERR_F) Ok(bail_on!(PROS_ERR as c_double, unsafe { pros_sys::distance_get_object_velocity(self.port.index()) })) } - /// Get the current guess at relative object size. + /// Get the current guess at relative "object size". /// - /// This is a value that has a range of 0 to 400. - /// A 18" x 30" grey card will return a value of approximately 75 - /// in typical room lighting. - pub fn object_size(&self) -> Result { + /// This is a value that has a range of 0 to 400. A 18" x 30" grey card will return + /// a value of approximately 75 in typical room lighting. + /// + /// This sensor reading is unusual, as it is entirely unitless with the seemingly arbitrary + /// range of 0-400 existing due to VEXCode's [`vex::sizeType`] enum having four variants. It's + /// unknown what the sensor is *actually* measuring here either, so use this data with a grain + /// of salt. + /// + /// [`vex::sizeType`]: https://api.vexcode.cloud/v5/search/sizeType/sizeType/enum + pub fn relative_size(&self) -> Result { Ok(bail_on!(PROS_ERR, unsafe { pros_sys::distance_get_object_size(self.port.index()) }) as u32) } - /// Returns the confidence in the distance measurement from 0% to 100%. - pub fn distance_confidence(&self) -> Result { + /// Returns the confidence in the distance measurement from 0.0 to 1.0. + pub fn distance_confidence(&self) -> Result { // 0 -> 63 let confidence = bail_on!(PROS_ERR, unsafe { pros_sys::distance_get_confidence(self.port.index()) - }) as f32; - Ok(confidence * 100.0 / 63.0) + }) as f64; + + Ok(confidence / 63.0) } } From 5d2c30ae832b7605c335dac5c75d6d520684e0e4 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Fri, 8 Mar 2024 12:55:00 -0600 Subject: [PATCH 5/5] docs: update changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ebeeaf5..ce48a9eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,12 +23,15 @@ Before releasing: ### Added -- `object_size` method on `DistanceSensor` for getting a guess at an object's relative size. +- `relative_size` method on `DistanceSensor` for getting a guess at an object's relative size. (#73) ### Fixed ### Changed +- Renamed `DistanceSensor::object_velocity` to `DistanceSensor::velocity`. +- Adjusted `distance_confidence` to return a value from [`0.0`, `1.0`] rather than 0-100 to match other percentage getters. + ### Removed ## [0.8.0]