eurosim-obsw/src/aocs.rs

977 lines
35 KiB
Rust
Raw Permalink Normal View History

use crate::aocs::AOCSSensorMode::{Idle, SendingData};
2023-04-26 17:17:35 +02:00
use crate::can_ids::{DeviceId, MessageId, MessageModel};
use crate::helpers::{ModeHelper, VerifHelper};
2023-04-26 17:17:35 +02:00
use crate::hk::{AocsDataMap, AocsDataType, CSS_SUN_VECTOR_1, CSS_SUN_VECTOR_2, CSS_SUN_VECTOR_3, CSS_VOLTAGE_4, CSS_VOLTAGE_5, CSS_VOLTAGE_6, GPS_ALTITUDE, GPS_LATITUDE, GPS_LONGITUDE, MGM_FIELD_1, MGM_FIELD_2, MGM_FIELD_3, STR_QUATERNION_1, STR_QUATERNION_2, STR_QUATERNION_3, STR_QUATERNION_4};
2023-02-24 07:29:37 +01:00
use crate::power_handler::{DeviceState, PowerSwitcher};
use crate::requests::{Request, RequestWithToken};
2023-03-09 09:54:21 +01:00
use byteorder::{ByteOrder, LittleEndian};
2023-02-24 07:29:37 +01:00
use num_derive::ToPrimitive;
use satrs_core::mode::{ModeAndSubmode, ModeRequest};
use satrs_core::power::{PowerSwitcherCommandSender, SwitchId};
2023-02-24 07:29:37 +01:00
use satrs_core::seq_count::SeqCountProviderSyncClonable;
2023-04-26 17:17:35 +02:00
use std::sync::mpsc::{Receiver, Sender};
2023-03-09 09:54:21 +01:00
use std::sync::{Arc, Mutex};
2023-03-25 20:22:07 +01:00
use log::debug;
#[derive(ToPrimitive, PartialEq, Copy, Clone)]
2023-02-24 07:29:37 +01:00
pub enum AOCSSensorMode {
Idle = 0,
SendingData = 1,
}
pub trait AocsSensorHandler {
2023-02-24 07:29:37 +01:00
type Error;
2023-04-26 17:17:35 +02:00
fn get_package_id(&mut self) -> Result<MessageId, Self::Error>;
fn send_message(&mut self, id: MessageId, buf: &[u8]) -> Result<(), Self::Error>;
2023-02-24 07:29:37 +01:00
fn enable_sensor_data_generation(&mut self) -> Result<(), Self::Error> {
let id = self.get_package_id()?;
self.send_message(id, &[1])
}
fn disable_sensor_data_generation(&mut self) -> Result<(), Self::Error> {
let id = self.get_package_id()?;
self.send_message(id, &[0])
}
fn request_sensor_data_oneshot(&mut self) -> Result<(), Self::Error> {
let id = self.get_package_id()?;
self.send_message(id, &[2])
}
}
pub struct CSSHandler {
power_switcher: PowerSwitcher,
device_id: DeviceId,
switch_id: SwitchId,
device_state: DeviceState,
mode: AOCSSensorMode,
aocs_data: Arc<Mutex<AocsDataMap>>,
2023-04-26 17:17:35 +02:00
can_tx: Sender<MessageModel>,
can_rx: Receiver<MessageModel>,
request_rx: Receiver<RequestWithToken>,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
2023-02-24 07:29:37 +01:00
}
impl AocsSensorHandler for CSSHandler {
type Error = ();
2023-04-26 17:17:35 +02:00
fn get_package_id(&mut self) -> Result<MessageId, Self::Error> {
Ok(MessageId::AOCSDataRequestSunSensor1)
2023-02-24 07:29:37 +01:00
}
2023-04-26 17:17:35 +02:00
fn send_message(&mut self, id: MessageId, buf: &[u8]) -> Result<(), Self::Error> {
self.can_tx
2023-04-26 17:17:35 +02:00
.send(MessageModel::new(id, buf).unwrap())
.unwrap();
return Ok(());
2023-03-09 09:54:21 +01:00
}
}
2023-02-24 07:29:37 +01:00
impl CSSHandler {
pub fn new(
power_switcher: PowerSwitcher,
device_id: DeviceId,
device_state: DeviceState,
aocs_data: Arc<Mutex<AocsDataMap>>,
2023-04-26 17:17:35 +02:00
can_tx: Sender<MessageModel>,
can_rx: Receiver<MessageModel>,
request_rx: Receiver<RequestWithToken>,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
) -> Self {
let switch_id = device_id as u16;
Self {
power_switcher,
device_id,
switch_id,
device_state,
mode: Idle,
aocs_data,
can_tx,
can_rx,
request_rx,
verif_helper,
mode_helper,
}
2023-02-24 07:29:37 +01:00
}
pub fn periodic_op(&mut self) {
self.handle_requests();
self.read_can();
2023-02-24 07:29:37 +01:00
}
fn handle_requests(&mut self) {
if let Ok(req) = self.request_rx.try_recv() {
let (req, start_token) = self
.verif_helper
.start_and_unwrap(req)
.expect("error sending start of execution");
match req {
Request::HkRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
Request::ModeRequest(req) => match req {
ModeRequest::SetMode(mode_submode) => {
if let Some(aocs_mode) = mode_submode_to_aocs_mode(mode_submode) {
2023-03-25 20:22:07 +01:00
self.update_mode(aocs_mode);
}
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
}
ModeRequest::ReadMode => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
}
ModeRequest::AnnounceMode => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
ModeRequest::AnnounceModeRecursive => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion failure");
}
}
},
Request::ActionRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
}
}
2023-02-24 07:29:37 +01:00
}
2023-03-25 20:22:07 +01:00
fn update_mode(&mut self, mode: AOCSSensorMode) {
if mode != self.mode {
match mode {
Idle => { self.set_mode_idle() }
SendingData => { self.set_mode_reading() }
}
}
}
fn set_mode_reading(&mut self) {
if self.mode == SendingData {
return;
}
2023-02-24 07:29:37 +01:00
// TODO: currently unrecoverable, should probably be changed
self.power_switcher
.send_switch_on_cmd(self.switch_id)
.expect("error sending switch on cmd");
self.enable_sensor_data_generation()
.expect("error enabling sensor data generation");
self.mode = SendingData;
}
2023-02-24 07:29:37 +01:00
fn set_mode_idle(&mut self) {
if self.mode == Idle {
return;
2023-03-09 09:54:21 +01:00
}
self.disable_sensor_data_generation()
.expect("error disabling sensor data generation");
self.power_switcher
.send_switch_off_cmd(self.switch_id)
.expect("error sending switch off cmd");
self.mode = Idle;
2023-02-24 07:29:37 +01:00
}
fn read_can(&mut self) {
if let Ok(package) = self.can_rx.try_recv() {
let mut map = self.aocs_data.lock().expect("error locking data map");
let float_data = self.decode_sensor_data(package.data());
2023-04-26 17:17:35 +02:00
match package.message_id() {
MessageId::AOCSDataSunSensor1 => {
map.update_value(CSS_SUN_VECTOR_1, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataSunSensor2 => {
map.update_value(CSS_SUN_VECTOR_2, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataSunSensor3 => {
map.update_value(CSS_SUN_VECTOR_3, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataSunSensor4 => {
map.update_value(CSS_VOLTAGE_4, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataSunSensor5 => {
map.update_value(CSS_VOLTAGE_5, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataSunSensor6 => {
map.update_value(CSS_VOLTAGE_6, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
_ => {}
}
drop(map);
2023-03-09 09:54:21 +01:00
}
}
2023-02-24 07:29:37 +01:00
fn decode_sensor_data(&self, buf: &[u8]) -> f64 {
LittleEndian::read_f64(&buf)
2023-02-24 07:29:37 +01:00
}
}
pub struct MGMHandler {
2023-02-24 07:29:37 +01:00
power_switcher: PowerSwitcher,
device_id: DeviceId,
switch_id: SwitchId,
device_state: DeviceState,
mode: AOCSSensorMode,
aocs_data: Arc<Mutex<AocsDataMap>>,
2023-04-26 17:17:35 +02:00
can_tx: Sender<MessageModel>,
can_rx: Receiver<MessageModel>,
2023-02-24 07:29:37 +01:00
request_rx: Receiver<RequestWithToken>,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
2023-02-24 07:29:37 +01:00
}
impl AocsSensorHandler for MGMHandler {
2023-02-24 07:29:37 +01:00
type Error = ();
2023-04-26 17:17:35 +02:00
fn get_package_id(&mut self) -> Result<MessageId, Self::Error> {
Ok(MessageId::AOCSDataRequestMGM1)
2023-02-24 07:29:37 +01:00
}
2023-04-26 17:17:35 +02:00
fn send_message(&mut self, id: MessageId, buf: &[u8]) -> Result<(), Self::Error> {
2023-03-09 09:54:21 +01:00
self.can_tx
2023-04-26 17:17:35 +02:00
.send(MessageModel::new(id, buf).unwrap())
2023-03-09 09:54:21 +01:00
.unwrap();
2023-02-24 07:29:37 +01:00
return Ok(());
}
}
impl MGMHandler {
2023-02-24 07:29:37 +01:00
pub fn new(
power_switcher: PowerSwitcher,
device_id: DeviceId,
device_state: DeviceState,
aocs_data: Arc<Mutex<AocsDataMap>>,
2023-04-26 17:17:35 +02:00
can_tx: Sender<MessageModel>,
can_rx: Receiver<MessageModel>,
2023-02-24 07:29:37 +01:00
request_rx: Receiver<RequestWithToken>,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
) -> Self {
let switch_id = device_id as u16;
Self {
2023-03-09 09:54:21 +01:00
power_switcher,
device_id,
switch_id,
device_state,
mode: Idle,
aocs_data,
2023-03-09 09:54:21 +01:00
can_tx,
can_rx,
request_rx,
verif_helper,
mode_helper,
2023-03-09 09:54:21 +01:00
}
2023-02-24 07:29:37 +01:00
}
pub fn periodic_op(&mut self) {
self.handle_requests();
self.read_can();
2023-02-24 07:29:37 +01:00
}
fn handle_requests(&mut self) {
if let Ok(req) = self.request_rx.try_recv() {
2023-03-25 20:22:07 +01:00
debug!("request received");
let (req, start_token) = self
.verif_helper
.start_and_unwrap(req)
.expect("error sending start of execution");
match req {
Request::HkRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
Request::ModeRequest(req) => match req {
ModeRequest::SetMode(mode_submode) => {
if let Some(aocs_mode) = mode_submode_to_aocs_mode(mode_submode) {
2023-03-25 20:22:07 +01:00
self.update_mode(aocs_mode);
}
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
}
ModeRequest::ReadMode => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
}
ModeRequest::AnnounceMode => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
ModeRequest::AnnounceModeRecursive => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion failure");
}
}
},
Request::ActionRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
}
}
}
fn update_mode(&mut self, mode: AOCSSensorMode) {
if mode != self.mode {
match mode {
Idle => { self.set_mode_idle() }
SendingData => { self.set_mode_reading() }
}
}
}
fn set_mode_reading(&mut self) {
if self.mode == SendingData {
return;
}
// TODO: currently unrecoverable, should probably be changed
self.power_switcher
.send_switch_on_cmd(self.switch_id)
.expect("error sending switch on cmd");
self.enable_sensor_data_generation()
.expect("error enabling sensor data generation");
self.mode = SendingData;
}
fn set_mode_idle(&mut self) {
if self.mode == Idle {
return;
}
self.disable_sensor_data_generation()
.expect("error disabling sensor data generation");
self.power_switcher
.send_switch_off_cmd(self.switch_id)
.expect("error sending switch off cmd");
self.mode = Idle;
}
fn read_can(&mut self) {
if let Ok(package) = self.can_rx.try_recv() {
let mut map = self.aocs_data.lock().expect("error locking data map");
let float_data = self.decode_sensor_data(package.data());
2023-04-26 17:17:35 +02:00
match package.message_id() {
MessageId::AOCSDataMGM1 => {
map.update_value(MGM_FIELD_1, AocsDataType::FloatValue(float_data))
2023-03-25 20:22:07 +01:00
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataMGM2 => {
map.update_value(MGM_FIELD_2, AocsDataType::FloatValue(float_data))
2023-03-25 20:22:07 +01:00
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataMGM3 => {
map.update_value(MGM_FIELD_3, AocsDataType::FloatValue(float_data))
2023-03-25 20:22:07 +01:00
.expect("error updating value");
}
_ => {}
}
drop(map);
}
}
fn decode_sensor_data(&self, buf: &[u8]) -> f64 {
LittleEndian::read_f64(&buf)
}
}
pub struct STRHandler {
power_switcher: PowerSwitcher,
device_id: DeviceId,
switch_id: SwitchId,
device_state: DeviceState,
mode: AOCSSensorMode,
aocs_data: Arc<Mutex<AocsDataMap>>,
2023-04-26 17:17:35 +02:00
can_tx: Sender<MessageModel>,
can_rx: Receiver<MessageModel>,
2023-03-25 20:22:07 +01:00
request_rx: Receiver<RequestWithToken>,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
}
impl AocsSensorHandler for STRHandler {
type Error = ();
2023-04-26 17:17:35 +02:00
fn get_package_id(&mut self) -> Result<MessageId, Self::Error> {
Ok(MessageId::AOCSDataRequestStarTracker)
2023-03-25 20:22:07 +01:00
}
2023-04-26 17:17:35 +02:00
fn send_message(&mut self, id: MessageId, buf: &[u8]) -> Result<(), Self::Error> {
2023-03-25 20:22:07 +01:00
self.can_tx
2023-04-26 17:17:35 +02:00
.send(MessageModel::new(id, buf).unwrap())
2023-03-25 20:22:07 +01:00
.unwrap();
return Ok(());
}
}
impl STRHandler {
pub fn new(
power_switcher: PowerSwitcher,
device_id: DeviceId,
device_state: DeviceState,
aocs_data: Arc<Mutex<AocsDataMap>>,
2023-04-26 17:17:35 +02:00
can_tx: Sender<MessageModel>,
can_rx: Receiver<MessageModel>,
2023-03-25 20:22:07 +01:00
request_rx: Receiver<RequestWithToken>,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
) -> Self {
let switch_id = device_id as u16;
Self {
power_switcher,
device_id,
switch_id,
device_state,
mode: Idle,
aocs_data,
can_tx,
can_rx,
request_rx,
verif_helper,
mode_helper,
}
}
pub fn periodic_op(&mut self) {
self.handle_requests();
self.read_can();
}
fn handle_requests(&mut self) {
if let Ok(req) = self.request_rx.try_recv() {
let (req, start_token) = self
.verif_helper
.start_and_unwrap(req)
.expect("error sending start of execution");
match req {
Request::HkRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
Request::ModeRequest(req) => match req {
ModeRequest::SetMode(mode_submode) => {
if let Some(aocs_mode) = mode_submode_to_aocs_mode(mode_submode) {
self.update_mode(aocs_mode);
}
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
}
ModeRequest::ReadMode => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
}
ModeRequest::AnnounceMode => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
ModeRequest::AnnounceModeRecursive => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion failure");
}
}
},
Request::ActionRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
}
}
2023-02-24 07:29:37 +01:00
}
2023-03-25 20:22:07 +01:00
fn update_mode(&mut self, mode: AOCSSensorMode) {
if mode != self.mode {
match mode {
Idle => { self.set_mode_idle() }
SendingData => { self.set_mode_reading() }
}
}
}
fn set_mode_reading(&mut self) {
if self.mode == SendingData {
return;
}
2023-02-24 07:29:37 +01:00
// TODO: currently unrecoverable, should probably be changed
self.power_switcher
.send_switch_on_cmd(self.switch_id)
.expect("error sending switch on cmd");
self.enable_sensor_data_generation()
.expect("error enabling sensor data generation");
self.mode = SendingData;
}
fn set_mode_idle(&mut self) {
if self.mode == Idle {
return;
2023-02-24 07:29:37 +01:00
}
self.disable_sensor_data_generation()
.expect("error disabling sensor data generation");
self.power_switcher
.send_switch_off_cmd(self.switch_id)
.expect("error sending switch off cmd");
self.mode = Idle;
2023-02-24 07:29:37 +01:00
}
fn read_can(&mut self) {
if let Ok(package) = self.can_rx.try_recv() {
let mut map = self.aocs_data.lock().expect("error locking data map");
let float_data = self.decode_sensor_data(package.data());
2023-04-26 17:17:35 +02:00
match package.message_id() {
MessageId::AOCSDataStarTracker1 => {
map.update_value(STR_QUATERNION_1, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataStarTracker2 => {
map.update_value(STR_QUATERNION_2, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataStarTracker3 => {
map.update_value(STR_QUATERNION_3, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataStarTracker4 => {
map.update_value(STR_QUATERNION_4, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-03-09 09:54:21 +01:00
_ => {}
}
drop(map);
2023-02-24 07:29:37 +01:00
}
}
fn decode_sensor_data(&self, buf: &[u8]) -> f64 {
LittleEndian::read_f64(&buf)
2023-02-24 07:29:37 +01:00
}
}
2023-03-25 20:22:07 +01:00
pub struct GPSHandler {
2023-02-24 07:29:37 +01:00
power_switcher: PowerSwitcher,
device_id: DeviceId,
switch_id: SwitchId,
device_state: DeviceState,
mode: AOCSSensorMode,
aocs_data: Arc<Mutex<AocsDataMap>>,
2023-04-26 17:17:35 +02:00
can_tx: Sender<MessageModel>,
can_rx: Receiver<MessageModel>,
2023-02-24 07:29:37 +01:00
request_rx: Receiver<RequestWithToken>,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
2023-02-24 07:29:37 +01:00
}
2023-03-25 20:22:07 +01:00
impl AocsSensorHandler for GPSHandler {
2023-02-24 07:29:37 +01:00
type Error = ();
2023-04-26 17:17:35 +02:00
fn get_package_id(&mut self) -> Result<MessageId, Self::Error> {
Ok(MessageId::AOCSDataRequestGPS)
2023-02-24 07:29:37 +01:00
}
2023-04-26 17:17:35 +02:00
fn send_message(&mut self, id: MessageId, buf: &[u8]) -> Result<(), Self::Error> {
2023-03-09 09:54:21 +01:00
self.can_tx
2023-04-26 17:17:35 +02:00
.send(MessageModel::new(id, buf).unwrap())
2023-03-09 09:54:21 +01:00
.unwrap();
2023-02-24 07:29:37 +01:00
return Ok(());
}
}
2023-03-25 20:22:07 +01:00
impl GPSHandler {
2023-02-24 07:29:37 +01:00
pub fn new(
power_switcher: PowerSwitcher,
device_id: DeviceId,
device_state: DeviceState,
aocs_data: Arc<Mutex<AocsDataMap>>,
2023-04-26 17:17:35 +02:00
can_tx: Sender<MessageModel>,
can_rx: Receiver<MessageModel>,
request_rx: Receiver<RequestWithToken>,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
) -> Self {
2023-02-24 07:29:37 +01:00
let switch_id = device_id as u16;
Self {
2023-02-24 07:29:37 +01:00
power_switcher,
device_id,
switch_id,
device_state,
mode: Idle,
aocs_data,
2023-02-24 07:29:37 +01:00
can_tx,
can_rx,
request_rx,
verif_helper,
mode_helper,
2023-02-24 07:29:37 +01:00
}
}
pub fn periodic_op(&mut self) {
self.handle_requests();
self.read_can();
2023-02-24 07:29:37 +01:00
}
fn handle_requests(&mut self) {
if let Ok(req) = self.request_rx.try_recv() {
let (req, start_token) = self
.verif_helper
.start_and_unwrap(req)
.expect("error sending start of execution");
match req {
Request::HkRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
Request::ModeRequest(req) => match req {
ModeRequest::SetMode(mode_submode) => {
if let Some(aocs_mode) = mode_submode_to_aocs_mode(mode_submode) {
2023-03-25 20:22:07 +01:00
self.update_mode(aocs_mode);
}
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
2023-02-24 07:29:37 +01:00
}
ModeRequest::ReadMode => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
2023-02-24 07:29:37 +01:00
}
ModeRequest::AnnounceMode => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
ModeRequest::AnnounceModeRecursive => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion failure");
}
}
},
Request::ActionRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
2023-02-24 07:29:37 +01:00
}
}
}
}
}
2023-03-25 20:22:07 +01:00
fn update_mode(&mut self, mode: AOCSSensorMode) {
if mode != self.mode {
match mode {
Idle => { self.set_mode_idle() }
SendingData => { self.set_mode_reading() }
}
}
}
fn set_mode_reading(&mut self) {
if self.mode == SendingData {
return;
2023-02-24 07:29:37 +01:00
}
// TODO: currently unrecoverable, should probably be changed
self.power_switcher
.send_switch_on_cmd(self.switch_id)
.expect("error sending switch on cmd");
self.enable_sensor_data_generation()
.expect("error enabling sensor data generation");
self.mode = SendingData;
2023-02-24 07:29:37 +01:00
}
fn set_mode_idle(&mut self) {
if self.mode == Idle {
return;
2023-02-24 07:29:37 +01:00
}
self.disable_sensor_data_generation()
.expect("error disabling sensor data generation");
self.power_switcher
.send_switch_off_cmd(self.switch_id)
.expect("error sending switch off cmd");
self.mode = Idle;
}
2023-02-24 07:29:37 +01:00
fn read_can(&mut self) {
2023-02-24 07:29:37 +01:00
if let Ok(package) = self.can_rx.try_recv() {
let mut map = self.aocs_data.lock().expect("error locking data map");
2023-02-24 07:29:37 +01:00
let float_data = self.decode_sensor_data(package.data());
2023-04-26 17:17:35 +02:00
match package.message_id() {
MessageId::AOCSDataGPSLatitude => {
map.update_value(GPS_LATITUDE, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataGPSLongitude => {
map.update_value(GPS_LONGITUDE, AocsDataType::FloatValue(float_data))
.expect("error updating value");
}
2023-04-26 17:17:35 +02:00
MessageId::AOCSDataGPSAltitude => {
map.update_value(GPS_ALTITUDE, AocsDataType::FloatValue(float_data))
.expect("error updating value");
2023-02-24 07:29:37 +01:00
}
_ => {}
2023-02-24 07:29:37 +01:00
}
drop(map);
2023-02-24 07:29:37 +01:00
}
}
fn decode_sensor_data(&self, buf: &[u8]) -> f64 {
2023-02-24 07:29:37 +01:00
LittleEndian::read_f64(&buf)
}
}
pub struct AocsController {
2023-02-24 07:29:37 +01:00
request_rx: Receiver<RequestWithToken>,
mgm_request_tx: Sender<RequestWithToken>,
css_request_tx: Sender<RequestWithToken>,
str_request_tx: Sender<RequestWithToken>,
2023-03-25 20:22:07 +01:00
gps_request_tx: Sender<RequestWithToken>,
seq_count_provider: SeqCountProviderSyncClonable,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
mode: AOCSSensorMode,
}
impl AocsController {
pub fn new(
request_rx: Receiver<RequestWithToken>,
mgm_request_tx: Sender<RequestWithToken>,
css_request_tx: Sender<RequestWithToken>,
str_request_tx: Sender<RequestWithToken>,
2023-03-25 20:22:07 +01:00
gps_request_tx: Sender<RequestWithToken>,
seq_count_provider: SeqCountProviderSyncClonable,
verif_helper: VerifHelper,
mode_helper: ModeHelper,
) -> Self {
Self {
request_rx,
mgm_request_tx,
css_request_tx,
str_request_tx,
2023-03-25 20:22:07 +01:00
gps_request_tx,
seq_count_provider,
verif_helper,
mode_helper,
mode: Idle,
}
}
pub fn periodic_op(&mut self) {
self.handle_requests();
}
fn handle_requests(&mut self) {
if let Ok(req) = self.request_rx.try_recv() {
let (req, start_token) = self
.verif_helper
.start_and_unwrap(req)
.expect("error sending start of execution");
match req {
Request::HkRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
Request::ModeRequest(req) => match req {
ModeRequest::SetMode(mode_submode) => {
if let Some(aocs_mode) = mode_submode_to_aocs_mode(mode_submode) {
self.mode = aocs_mode;
}
self.mgm_request_tx
.send(RequestWithToken(Request::ModeRequest(req), None))
.expect("error sending to mgm");
self.css_request_tx
.send(RequestWithToken(Request::ModeRequest(req), None))
.expect("error sending to css");
self.str_request_tx
.send(RequestWithToken(Request::ModeRequest(req), None))
.expect("error sending to str");
2023-03-25 20:22:07 +01:00
self.gps_request_tx
.send(RequestWithToken(Request::ModeRequest(req), None))
.expect("error sending to str");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
}
ModeRequest::ReadMode => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion success");
}
}
ModeRequest::AnnounceMode => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
ModeRequest::AnnounceModeRecursive => {
self.mode_helper
.make_and_send_mode_reply(aocs_mode_to_mode_submode(self.mode))
.expect("error sending mode reply");
self.mgm_request_tx
.send(RequestWithToken(Request::ModeRequest(req), None))
.expect("error sending mode request to mgm handler");
self.css_request_tx
.send(RequestWithToken(Request::ModeRequest(req), None))
.expect("error sending mode request to css handler");
self.str_request_tx
.send(RequestWithToken(Request::ModeRequest(req), None))
.expect("error sending mode request to str handler");
2023-03-25 20:22:07 +01:00
self.gps_request_tx
.send(RequestWithToken(Request::ModeRequest(req), None))
.expect("error sending mode request to str handler");
if let Some(token) = start_token {
self.verif_helper
.completion(token)
.expect("error sending completion failure");
}
}
},
Request::ActionRequest(_) => {
if let Some(token) = start_token {
self.verif_helper
.completion_failure(token)
.expect("error sending completion failure");
}
}
}
}
}
}
fn aocs_mode_to_mode_submode(sensor_mode: AOCSSensorMode) -> ModeAndSubmode {
match sensor_mode {
Idle => ModeAndSubmode::new(0, 0),
SendingData => ModeAndSubmode::new(1, 0),
}
}
fn mode_submode_to_aocs_mode(mode_submode: ModeAndSubmode) -> Option<AOCSSensorMode> {
match mode_submode.mode() {
0 => Some(Idle),
1 => Some(SendingData),
_ => None,
}
2023-02-24 07:29:37 +01:00
}
2023-03-09 09:54:21 +01:00
pub fn core_aocs_loop() {}