-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Arm debounce #66
Arm debounce #66
Changes from 3 commits
aead514
c81f4d1
4ab9134
cac1921
567a923
ebe4a7f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,31 @@ | ||
use self::response::Statuses; | ||
use std::sync::{Arc, Mutex}; | ||
use std::thread; | ||
|
||
use anyhow::Result; | ||
use itertools::Itertools; | ||
use tokio::io::AsyncReadExt; | ||
use tokio_serial::{DataBits, Parity, SerialStream, StopBits}; | ||
|
||
use self::response::Statuses; | ||
|
||
pub mod response; | ||
|
||
#[derive(Debug)] | ||
pub struct MainElectronicsBoard { | ||
statuses: Statuses, | ||
arm_count: Arc<Mutex<Vec<bool>>>, | ||
arm_state: Arc<Mutex<Option<bool>>>, | ||
} | ||
|
||
impl MainElectronicsBoard { | ||
pub async fn new<T>(read_connection: T) -> Self | ||
where | ||
T: 'static + AsyncReadExt + Unpin + Send, | ||
where | ||
T: 'static + AsyncReadExt + Unpin + Send, | ||
{ | ||
Self { | ||
statuses: Statuses::new(read_connection).await, | ||
arm_count: Arc::new(Mutex::new(vec![false; 24])), | ||
arm_state: Arc::new(Mutex::new(Some(false))), | ||
} | ||
} | ||
|
||
|
@@ -49,7 +57,24 @@ impl MainElectronicsBoard { | |
} | ||
|
||
pub async fn thruster_arm(&self) -> Option<bool> { | ||
*self.statuses.thruster_arm().read().await | ||
let arm_count = self.arm_count.clone(); | ||
let arm_state = self.arm_state.clone(); | ||
let current_arm_state = *self.statuses.thruster_arm().read().await; | ||
|
||
let t1 = thread::spawn(move || { | ||
let mut locked_arm_count = arm_count.lock().unwrap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of handling this with a thread like so, it is probably more effective to do this in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've moved the arm debounce logic into its own function in Statuses. I also moved the unit tests into the same file. I'm not entirely sure the |
||
let mut locked_arm_state = arm_state.lock().unwrap(); | ||
vwu1888 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
locked_arm_count.push(current_arm_state.unwrap_or(false)); | ||
locked_arm_count.remove(0); | ||
|
||
if locked_arm_count.iter().all_equal() { | ||
*locked_arm_state = current_arm_state; | ||
} | ||
}); | ||
|
||
t1.join().unwrap(); | ||
self.arm_state.lock().unwrap().clone() | ||
} | ||
|
||
pub async fn system_voltage(&self) -> Option<f32> { | ||
|
@@ -60,3 +85,66 @@ impl MainElectronicsBoard { | |
*self.statuses.shutdown().read().await | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
|
||
#[tokio::test] | ||
async fn thruster_is_armed() { | ||
let meb = MainElectronicsBoard::new(tokio::io::empty()).await; | ||
|
||
// Receive 24 consecutive messages with thruster arm set to true | ||
for _ in 0..24 { | ||
meb.statuses.thruster_arm().write().await.replace(true); | ||
meb.thruster_arm().await; | ||
} | ||
|
||
assert_eq!(meb.thruster_arm().await, Some(true)); | ||
} | ||
|
||
#[tokio::test] | ||
async fn thruster_is_not_armed() { | ||
let meb = MainElectronicsBoard::new(tokio::io::empty()).await; | ||
|
||
// Receive 24 consecutive messages with thruster arm set to false | ||
for _ in 0..24 { | ||
meb.statuses.thruster_arm().write().await.replace(false); | ||
meb.thruster_arm().await; | ||
} | ||
|
||
assert_eq!(meb.thruster_arm().await, Some(false)); | ||
} | ||
|
||
#[tokio::test] | ||
async fn thrust_arm_debounce() { | ||
let meb = MainElectronicsBoard::new(tokio::io::empty()).await; | ||
|
||
meb.statuses.thruster_arm().write().await.replace(false); | ||
assert_eq!(meb.thruster_arm().await, Some(false)); | ||
|
||
for _ in 0..10 { | ||
meb.statuses.thruster_arm().write().await.replace(true); | ||
meb.thruster_arm().await; | ||
} | ||
assert_eq!(meb.thruster_arm().await, Some(false)); | ||
|
||
for _ in 0..24 { | ||
meb.statuses.thruster_arm().write().await.replace(true); | ||
meb.thruster_arm().await; | ||
} | ||
assert_eq!(meb.thruster_arm().await, Some(true)); | ||
|
||
for _ in 0..10 { | ||
meb.statuses.thruster_arm().write().await.replace(false); | ||
meb.thruster_arm().await; | ||
} | ||
assert_eq!(meb.thruster_arm().await, Some(true)); | ||
|
||
for _ in 0..24 { | ||
meb.statuses.thruster_arm().write().await.replace(false); | ||
meb.thruster_arm().await; | ||
} | ||
assert_eq!(meb.thruster_arm().await, Some(false)); | ||
} | ||
} |
Check warning
Code scanning / clippy
unused import: itertools::Itertools Warning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why cargo is saying this is unused. On line 168, the
all_equal()
is a part of this import, and the build breaks when I remove the import. Does anyone know why or should we dismiss it?