Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
refactor: revert wrapper change
Browse files Browse the repository at this point in the history
  • Loading branch information
Tropix126 committed Feb 14, 2024
1 parent 9df9b5d commit dadb8db
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 36 deletions.
32 changes: 23 additions & 9 deletions packages/pros/src/devices/adi/linetracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,47 +23,61 @@
//! 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<Self, AdiError> {
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<f64, AdiError> {
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.
///
/// 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<u16, AdiError> {
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)
}
}

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<u8> {
self.analog_in.expander_port_index()
self.port.expander_index()
}

fn device_type(&self) -> AdiDeviceType {
Expand Down
44 changes: 31 additions & 13 deletions packages/pros/src/devices/adi/solenoid.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
//! 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<Self, AdiError> {
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,
})
}

/// 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(())
}

Expand All @@ -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.
Expand All @@ -54,24 +72,24 @@ 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)
}
}

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<u8> {
self.digital_out.expander_port_index()
self.port.expander_index()
}

fn device_type(&self) -> AdiDeviceType {
Expand Down
47 changes: 33 additions & 14 deletions packages/pros/src/devices/adi/switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self, AdiError> {
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<LogicLevel, AdiError> {
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<bool, AdiError> {
self.digital_in.is_high()
Ok(self.level()?.is_high())
}

/// Returns `true` if the switch has been pressed again since the last time this
Expand All @@ -47,24 +60,30 @@ impl AdiSwitch {
pub fn was_pressed(&mut self) -> Result<bool, AdiError> {
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<AdiDigitalIn> 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<u8> {
self.digital_in.expander_port_index()
self.port.expander_index()
}

fn device_type(&self) -> AdiDeviceType {
Expand Down

0 comments on commit dadb8db

Please sign in to comment.