use crate::{
bindings,
error::{get_errno, Error},
rtos::DataSource,
};
pub struct RotationSensor {
port: u8,
}
impl RotationSensor {
pub unsafe fn new(port: u8, reversed: bool) -> Result<Self, RotationSensorError> {
let mut sensor = Self { port };
sensor.set_reversed(reversed)?;
Ok(sensor)
}
pub fn reset(&mut self) -> Result<(), RotationSensorError> {
match unsafe { bindings::rotation_reset(self.port) } {
bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
_ => Ok(()),
}
}
pub fn set_position(&mut self, rotation: u32) -> Result<(), RotationSensorError> {
match unsafe { bindings::rotation_set_position(self.port, rotation) } {
bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
_ => Ok(()),
}
}
pub fn reset_position(&mut self) -> Result<(), RotationSensorError> {
match unsafe { bindings::rotation_reset_position(self.port) } {
bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
_ => Ok(()),
}
}
pub fn get_position(&self) -> Result<i32, RotationSensorError> {
match unsafe { bindings::rotation_get_position(self.port) } {
x if x == bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
x => Ok(x),
}
}
pub fn get_velocity(&self) -> Result<i32, RotationSensorError> {
match unsafe { bindings::rotation_get_velocity(self.port) } {
x if x == bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
x => Ok(x),
}
}
pub fn get_angle(&self) -> Result<i32, RotationSensorError> {
match unsafe { bindings::rotation_get_angle(self.port) } {
x if x == bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
x => Ok(x),
}
}
pub fn set_reversed(&mut self, reverse: bool) -> Result<(), RotationSensorError> {
match unsafe { bindings::rotation_set_reversed(self.port, reverse) } {
bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
_ => Ok(()),
}
}
pub fn reverse(&mut self) -> Result<(), RotationSensorError> {
match unsafe { bindings::rotation_reverse(self.port) } {
bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
_ => Ok(()),
}
}
pub fn get_reversed(&self) -> Result<bool, RotationSensorError> {
match unsafe { bindings::rotation_get_reversed(self.port) } {
x if x == bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
x => Ok(x != 0),
}
}
}
impl DataSource for RotationSensor {
type Data = RotationSensorData;
type Error = RotationSensorError;
fn read(&self) -> Result<Self::Data, Self::Error> {
Ok(RotationSensorData {
position: self.get_position()?,
velocity: self.get_velocity()?,
angle: self.get_angle()?,
})
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RotationSensorData {
pub position: i32,
pub velocity: i32,
pub angle: i32,
}
#[derive(Debug)]
pub enum RotationSensorError {
PortOutOfRange,
PortNotDistanceSensor,
Unknown(i32),
}
impl RotationSensorError {
fn from_errno() -> Self {
match get_errno() {
libc::ENXIO => Self::PortOutOfRange,
libc::ENODEV => Self::PortNotDistanceSensor,
x => Self::Unknown(x),
}
}
}
impl From<RotationSensorError> for Error {
fn from(err: RotationSensorError) -> Self {
match err {
RotationSensorError::PortOutOfRange => Error::Custom("port out of range".into()),
RotationSensorError::PortNotDistanceSensor => {
Error::Custom("port not a rotation sensor".into())
}
RotationSensorError::Unknown(n) => Error::System(n),
}
}
}