1use crate::{
4 bindings,
5 error::{get_errno, Error},
6 rtos::DataSource,
7};
8
9pub struct RotationSensor {
11 port: u8,
12}
13
14impl RotationSensor {
15 pub unsafe fn new(port: u8, reversed: bool) -> Result<Self, RotationSensorError> {
23 let mut sensor = Self { port };
24
25 sensor.set_reversed(reversed)?;
26
27 Ok(sensor)
28 }
29
30 pub fn reset(&mut self) -> Result<(), RotationSensorError> {
33 match unsafe { bindings::rotation_reset(self.port) } {
34 bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
35 _ => Ok(()),
36 }
37 }
38
39 pub fn set_position(&mut self, rotation: u32) -> Result<(), RotationSensorError> {
41 match unsafe { bindings::rotation_set_position(self.port, rotation) } {
42 bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
43 _ => Ok(()),
44 }
45 }
46
47 pub fn reset_position(&mut self) -> Result<(), RotationSensorError> {
50 match unsafe { bindings::rotation_reset_position(self.port) } {
51 bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
52 _ => Ok(()),
53 }
54 }
55
56 pub fn get_position(&self) -> Result<i32, RotationSensorError> {
58 match unsafe { bindings::rotation_get_position(self.port) } {
59 x if x == bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
60 x => Ok(x),
61 }
62 }
63
64 pub fn get_velocity(&self) -> Result<i32, RotationSensorError> {
66 match unsafe { bindings::rotation_get_velocity(self.port) } {
67 x if x == bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
68 x => Ok(x),
69 }
70 }
71
72 pub fn get_angle(&self) -> Result<i32, RotationSensorError> {
74 match unsafe { bindings::rotation_get_angle(self.port) } {
75 x if x == bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
76 x => Ok(x),
77 }
78 }
79
80 pub fn set_reversed(&mut self, reverse: bool) -> Result<(), RotationSensorError> {
82 match unsafe { bindings::rotation_set_reversed(self.port, reverse) } {
83 bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
84 _ => Ok(()),
85 }
86 }
87
88 pub fn reverse(&mut self) -> Result<(), RotationSensorError> {
90 match unsafe { bindings::rotation_reverse(self.port) } {
91 bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
92 _ => Ok(()),
93 }
94 }
95
96 pub fn get_reversed(&self) -> Result<bool, RotationSensorError> {
98 match unsafe { bindings::rotation_get_reversed(self.port) } {
99 x if x == bindings::PROS_ERR_ => Err(RotationSensorError::from_errno()),
100 x => Ok(x != 0),
101 }
102 }
103}
104
105impl DataSource for RotationSensor {
106 type Data = RotationSensorData;
107
108 type Error = RotationSensorError;
109
110 fn read(&self) -> Result<Self::Data, Self::Error> {
111 Ok(RotationSensorData {
112 position: self.get_position()?,
113 velocity: self.get_velocity()?,
114 angle: self.get_angle()?,
115 })
116 }
117}
118
119#[derive(Clone, Copy, Debug, PartialEq, Eq)]
121pub struct RotationSensorData {
122 pub position: i32,
124 pub velocity: i32,
126 pub angle: i32,
128}
129
130#[derive(Debug)]
132pub enum RotationSensorError {
133 PortOutOfRange,
135 PortNotDistanceSensor,
137 Unknown(i32),
139}
140
141impl RotationSensorError {
142 fn from_errno() -> Self {
143 match get_errno() {
144 libc::ENXIO => Self::PortOutOfRange,
145 libc::ENODEV => Self::PortNotDistanceSensor,
146 x => Self::Unknown(x),
147 }
148 }
149}
150
151impl From<RotationSensorError> for Error {
152 fn from(err: RotationSensorError) -> Self {
153 match err {
154 RotationSensorError::PortOutOfRange => Error::Custom("port out of range".into()),
155 RotationSensorError::PortNotDistanceSensor => {
156 Error::Custom("port not a rotation sensor".into())
157 }
158 RotationSensorError::Unknown(n) => Error::System(n),
159 }
160 }
161}