camera_tests #13
@ -42,12 +42,16 @@ pub enum GroupId {
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref HOME_PATH: PathBuf = {
|
pub static ref HOME_PATH: PathBuf = {
|
||||||
let mut home_path = PathBuf::new();
|
let mut home_path = PathBuf::new();
|
||||||
let home_path_default = homedir::get_my_home().expect("Getting home dir from OS failed.").expect("No home dir found.");
|
let home_path_default = homedir::get_my_home()
|
||||||
|
.expect("Getting home dir from OS failed.")
|
||||||
|
.expect("No home dir found.");
|
||||||
|
|
||||||
home_path.push(if Path::new(HOME_FOLDER_EXPERIMENT).exists() {
|
home_path.push(if Path::new(HOME_FOLDER_EXPERIMENT).exists() {
|
||||||
HOME_FOLDER_EXPERIMENT
|
HOME_FOLDER_EXPERIMENT
|
||||||
} else {
|
} else {
|
||||||
home_path_default.to_str().expect("Error converting to string.")
|
home_path_default
|
||||||
|
.to_str()
|
||||||
|
.expect("Error converting to string.")
|
||||||
});
|
});
|
||||||
home_path
|
home_path
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::fmt;
|
use crate::pus::action::send_data_reply;
|
||||||
use std::fmt::Formatter;
|
|
||||||
/// Device handler implementation for the IMS-100 Imager used on the OPS-SAT mission.
|
/// Device handler implementation for the IMS-100 Imager used on the OPS-SAT mission.
|
||||||
///
|
///
|
||||||
/// from the [OPSSAT Experimenter Wiki](https://opssat1.esoc.esa.int/projects/experimenter-information/wiki/Camera_Introduction):
|
/// from the [OPSSAT Experimenter Wiki](https://opssat1.esoc.esa.int/projects/experimenter-information/wiki/Camera_Introduction):
|
||||||
@ -32,14 +31,15 @@ use log::{debug, info};
|
|||||||
use ops_sat_rs::TimeStampHelper;
|
use ops_sat_rs::TimeStampHelper;
|
||||||
use satrs::action::{ActionRequest, ActionRequestVariant};
|
use satrs::action::{ActionRequest, ActionRequestVariant};
|
||||||
use satrs::hk::HkRequest;
|
use satrs::hk::HkRequest;
|
||||||
|
use satrs::pus::action::{ActionReplyPus, ActionReplyVariant};
|
||||||
|
use satrs::pus::EcssTmtcError;
|
||||||
use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId};
|
use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId};
|
||||||
use satrs::tmtc::PacketAsVec;
|
use satrs::tmtc::PacketAsVec;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
use std::fmt::Formatter;
|
||||||
use std::process::{Command, Output};
|
use std::process::{Command, Output};
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use satrs::pus::action::{ActionReplyPus, ActionReplyVariant};
|
|
||||||
use satrs::pus::EcssTmtcError;
|
|
||||||
use crate::pus::action::send_data_reply;
|
|
||||||
|
|
||||||
// const IMS_TESTAPP: &str = "scripts/ims100_testapp";
|
// const IMS_TESTAPP: &str = "scripts/ims100_testapp";
|
||||||
const IMS_TESTAPP: &str = "ims100_testapp";
|
const IMS_TESTAPP: &str = "ims100_testapp";
|
||||||
@ -181,7 +181,7 @@ impl fmt::Display for CameraError {
|
|||||||
write!(f, "{}", io_error)
|
write!(f, "{}", io_error)
|
||||||
}
|
}
|
||||||
CameraError::EcssTmtcError(ecss_tmtc_error) => {
|
CameraError::EcssTmtcError(ecss_tmtc_error) => {
|
||||||
write!(f ,"{}", ecss_tmtc_error)
|
write!(f, "{}", ecss_tmtc_error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,7 +264,8 @@ impl IMS100BatchHandler {
|
|||||||
requestor_info: &MessageMetadata,
|
requestor_info: &MessageMetadata,
|
||||||
action_request: &ActionRequest,
|
action_request: &ActionRequest,
|
||||||
) -> Result<(), CameraError> {
|
) -> Result<(), CameraError> {
|
||||||
let param = match CameraActionId::try_from(action_request.action_id).expect("Invalid action id") {
|
let param =
|
||||||
|
match CameraActionId::try_from(action_request.action_id).expect("Invalid action id") {
|
||||||
CameraActionId::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS,
|
CameraActionId::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS,
|
||||||
CameraActionId::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS,
|
CameraActionId::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS,
|
||||||
CameraActionId::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS,
|
CameraActionId::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS,
|
||||||
@ -292,7 +293,12 @@ impl IMS100BatchHandler {
|
|||||||
let output = self.take_picture(param)?;
|
let output = self.take_picture(param)?;
|
||||||
debug!("Sending action reply!");
|
debug!("Sending action reply!");
|
||||||
send_data_reply(self.id, output.stdout, &self.stamp_helper, &self.tm_tx)?;
|
send_data_reply(self.id, output.stdout, &self.stamp_helper, &self.tm_tx)?;
|
||||||
self.action_reply_tx.send(GenericMessage::new(*requestor_info, ActionReplyPus::new(action_request.action_id, ActionReplyVariant::Completed))).unwrap();
|
self.action_reply_tx
|
||||||
|
.send(GenericMessage::new(
|
||||||
|
*requestor_info,
|
||||||
|
ActionReplyPus::new(action_request.action_id, ActionReplyVariant::Completed),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,16 +334,13 @@ impl IMS100BatchHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_current_images(&self) -> Result<Vec<String>, CameraError> {
|
pub fn list_current_images(&self) -> Result<Vec<String>, CameraError> {
|
||||||
let output = Command::new("ls").arg("-l")
|
let output = Command::new("ls").arg("-l").arg("*.png").output()?;
|
||||||
.arg("*.png")
|
|
||||||
.output()?;
|
|
||||||
|
|
||||||
if output.status.success() {
|
if output.status.success() {
|
||||||
let output_str = String::from_utf8(output.stdout).unwrap();
|
let output_str = String::from_utf8(output.stdout).unwrap();
|
||||||
let files: Vec<String> = output_str.lines().map(|s| s.to_string()).collect();
|
let files: Vec<String> = output_str.lines().map(|s| s.to_string()).collect();
|
||||||
Ok(files)
|
Ok(files)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Err(CameraError::ListFileError)
|
Err(CameraError::ListFileError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,19 +394,29 @@ mod tests {
|
|||||||
use ops_sat_rs::config::components::CAMERA_HANDLER;
|
use ops_sat_rs::config::components::CAMERA_HANDLER;
|
||||||
use ops_sat_rs::TimeStampHelper;
|
use ops_sat_rs::TimeStampHelper;
|
||||||
use satrs::action::{ActionRequest, ActionRequestVariant};
|
use satrs::action::{ActionRequest, ActionRequestVariant};
|
||||||
|
use satrs::pus::action::ActionReplyPus;
|
||||||
use satrs::request::{GenericMessage, MessageMetadata};
|
use satrs::request::{GenericMessage, MessageMetadata};
|
||||||
use satrs::tmtc::PacketAsVec;
|
use satrs::tmtc::PacketAsVec;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::mpsc::{Receiver, Sender};
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
use satrs::pus::action::ActionReplyPus;
|
|
||||||
|
|
||||||
fn create_handler() -> (IMS100BatchHandler, Sender<GenericMessage<CompositeRequest>>, Receiver<PacketAsVec>, Receiver<GenericMessage<ActionReplyPus>>) {
|
fn create_handler() -> (
|
||||||
|
IMS100BatchHandler,
|
||||||
|
Sender<GenericMessage<CompositeRequest>>,
|
||||||
|
Receiver<PacketAsVec>,
|
||||||
|
Receiver<GenericMessage<ActionReplyPus>>,
|
||||||
|
) {
|
||||||
let (composite_request_tx, composite_request_rx) = mpsc::channel();
|
let (composite_request_tx, composite_request_rx) = mpsc::channel();
|
||||||
let (tm_tx, tm_rx) = mpsc::channel();
|
let (tm_tx, tm_rx) = mpsc::channel();
|
||||||
let (action_reply_tx, action_reply_rx) = mpsc::channel();
|
let (action_reply_tx, action_reply_rx) = mpsc::channel();
|
||||||
let time_helper = TimeStampHelper::default();
|
let time_helper = TimeStampHelper::default();
|
||||||
let cam_handler: IMS100BatchHandler =
|
let cam_handler: IMS100BatchHandler = IMS100BatchHandler::new(
|
||||||
IMS100BatchHandler::new(CAMERA_HANDLER, composite_request_rx, tm_tx, action_reply_tx, time_helper);
|
CAMERA_HANDLER,
|
||||||
|
composite_request_rx,
|
||||||
|
tm_tx,
|
||||||
|
action_reply_tx,
|
||||||
|
time_helper,
|
||||||
|
);
|
||||||
(cam_handler, composite_request_tx, tm_rx, action_reply_rx)
|
(cam_handler, composite_request_tx, tm_rx, action_reply_rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ pub fn setup_logger() -> Result<(), fern::InitError> {
|
|||||||
eprintln!("Failed to create log folder '{}'", LOG_FOLDER);
|
eprintln!("Failed to create log folder '{}'", LOG_FOLDER);
|
||||||
}
|
}
|
||||||
let mut path_buf = PathBuf::from(LOG_FOLDER);
|
let mut path_buf = PathBuf::from(LOG_FOLDER);
|
||||||
path_buf.push(format!("output.log"));
|
path_buf.push("output.log");
|
||||||
println!("{:?}", path_buf);
|
println!("{:?}", path_buf);
|
||||||
fern::Dispatch::new()
|
fern::Dispatch::new()
|
||||||
.format(move |out, message, record| {
|
.format(move |out, message, record| {
|
||||||
|
11
src/main.rs
11
src/main.rs
@ -14,8 +14,8 @@ use ops_sat_rs::config::{
|
|||||||
VALID_PACKET_ID_LIST,
|
VALID_PACKET_ID_LIST,
|
||||||
};
|
};
|
||||||
use ops_sat_rs::config::{tasks::FREQ_MS_UDP_TMTC, OBSW_SERVER_ADDR, SERVER_PORT};
|
use ops_sat_rs::config::{tasks::FREQ_MS_UDP_TMTC, OBSW_SERVER_ADDR, SERVER_PORT};
|
||||||
use satrs::hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer};
|
|
||||||
use ops_sat_rs::TimeStampHelper;
|
use ops_sat_rs::TimeStampHelper;
|
||||||
|
use satrs::hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer};
|
||||||
|
|
||||||
use crate::handlers::camera::IMS100BatchHandler;
|
use crate::handlers::camera::IMS100BatchHandler;
|
||||||
use crate::pus::{PusTcDistributor, PusTcMpscRouter};
|
use crate::pus::{PusTcDistributor, PusTcMpscRouter};
|
||||||
@ -184,8 +184,13 @@ fn main() {
|
|||||||
.expect("creating TCP SPP client failed");
|
.expect("creating TCP SPP client failed");
|
||||||
|
|
||||||
let timestamp_helper = TimeStampHelper::default();
|
let timestamp_helper = TimeStampHelper::default();
|
||||||
let mut camera_handler: IMS100BatchHandler =
|
let mut camera_handler: IMS100BatchHandler = IMS100BatchHandler::new(
|
||||||
IMS100BatchHandler::new(CAMERA_HANDLER, camera_composite_rx, tm_funnel_tx.clone(), pus_action_reply_tx.clone(), timestamp_helper);
|
CAMERA_HANDLER,
|
||||||
|
camera_composite_rx,
|
||||||
|
tm_funnel_tx.clone(),
|
||||||
|
pus_action_reply_tx.clone(),
|
||||||
|
timestamp_helper,
|
||||||
|
);
|
||||||
|
|
||||||
// Main Task Thread Definitions
|
// Main Task Thread Definitions
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
|
use ops_sat_rs::config::components::PUS_ACTION_SERVICE;
|
||||||
use ops_sat_rs::config::tmtc_err;
|
use ops_sat_rs::config::tmtc_err;
|
||||||
|
use ops_sat_rs::TimeStampHelper;
|
||||||
use satrs::action::{ActionRequest, ActionRequestVariant};
|
use satrs::action::{ActionRequest, ActionRequestVariant};
|
||||||
use satrs::params::WritableToBeBytes;
|
use satrs::params::WritableToBeBytes;
|
||||||
use satrs::pus::action::{
|
use satrs::pus::action::{
|
||||||
@ -9,17 +11,19 @@ use satrs::pus::verification::{
|
|||||||
FailParams, FailParamsWithStep, TcStateAccepted, TcStateStarted, VerificationReporter,
|
FailParams, FailParamsWithStep, TcStateAccepted, TcStateStarted, VerificationReporter,
|
||||||
VerificationReportingProvider, VerificationToken,
|
VerificationReportingProvider, VerificationToken,
|
||||||
};
|
};
|
||||||
use satrs::pus::{ActiveRequestProvider, EcssTcAndToken, EcssTcInVecConverter, EcssTmSender, EcssTmtcError, GenericConversionError, PusPacketHandlerResult, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter, PusTmVariant};
|
use satrs::pus::{
|
||||||
|
ActiveRequestProvider, EcssTcAndToken, EcssTcInVecConverter, EcssTmSender, EcssTmtcError,
|
||||||
|
GenericConversionError, PusPacketHandlerResult, PusReplyHandler, PusServiceHelper,
|
||||||
|
PusTcToRequestConverter, PusTmVariant,
|
||||||
|
};
|
||||||
use satrs::request::{GenericMessage, UniqueApidTargetId};
|
use satrs::request::{GenericMessage, UniqueApidTargetId};
|
||||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
|
use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||||
use satrs::spacepackets::ecss::{EcssEnumU16, PusPacket};
|
use satrs::spacepackets::ecss::{EcssEnumU16, PusPacket};
|
||||||
|
use satrs::spacepackets::SpHeader;
|
||||||
use satrs::tmtc::PacketAsVec;
|
use satrs::tmtc::PacketAsVec;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
|
||||||
use satrs::spacepackets::SpHeader;
|
|
||||||
use ops_sat_rs::config::components::PUS_ACTION_SERVICE;
|
|
||||||
use ops_sat_rs::TimeStampHelper;
|
|
||||||
|
|
||||||
use crate::requests::GenericRequestRouter;
|
use crate::requests::GenericRequestRouter;
|
||||||
|
|
||||||
@ -271,20 +275,23 @@ impl TargetedPusService for ActionServiceWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_data_reply<TmSender: EcssTmSender>(apid_target: UniqueApidTargetId, reply_data: Vec<u8>, stamp_helper: &TimeStampHelper, tm_sender: &TmSender) -> Result<(), EcssTmtcError> {
|
pub fn send_data_reply<TmSender: EcssTmSender>(
|
||||||
|
apid_target: UniqueApidTargetId,
|
||||||
|
reply_data: Vec<u8>,
|
||||||
|
stamp_helper: &TimeStampHelper,
|
||||||
|
tm_sender: &TmSender,
|
||||||
|
) -> Result<(), EcssTmtcError> {
|
||||||
let sp_header = SpHeader::new_from_apid(apid_target.apid);
|
let sp_header = SpHeader::new_from_apid(apid_target.apid);
|
||||||
let sec_header = PusTmSecondaryHeader::new(8, DATA_REPLY, 0, 0, stamp_helper.stamp());
|
let sec_header = PusTmSecondaryHeader::new(8, DATA_REPLY, 0, 0, stamp_helper.stamp());
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
data.extend(apid_target.apid.to_be_bytes());
|
data.extend(apid_target.apid.to_be_bytes());
|
||||||
data.extend(apid_target.unique_id.to_be_bytes());
|
data.extend(apid_target.unique_id.to_be_bytes());
|
||||||
data.extend(reply_data);
|
data.extend(reply_data);
|
||||||
debug!("{}", String::from_utf8(data.clone()[6..].to_vec()).expect("Error decoding data reply."));
|
debug!(
|
||||||
let data_reply_tm = PusTmCreator::new(
|
"{}",
|
||||||
sp_header,
|
String::from_utf8(data.clone()[6..].to_vec()).expect("Error decoding data reply.")
|
||||||
sec_header,
|
|
||||||
&data,
|
|
||||||
true,
|
|
||||||
);
|
);
|
||||||
|
let data_reply_tm = PusTmCreator::new(sp_header, sec_header, &data, true);
|
||||||
tm_sender.send_tm(apid_target.id(), PusTmVariant::Direct(data_reply_tm))
|
tm_sender.send_tm(apid_target.id(), PusTmVariant::Direct(data_reply_tm))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user