added scheduling implementation from example

This commit is contained in:
lkoester 2023-02-01 11:05:57 +01:00
parent 62784b32cc
commit 27790242b0
15 changed files with 614 additions and 132 deletions

283
Cargo.lock generated
View File

@ -43,12 +43,6 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "bitflags"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -84,6 +78,12 @@ dependencies = [
"parking_lot_core",
]
[[package]]
name = "byte_conv"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "649972315d4931137a26fc2bf3ca95ee257ad796a5b57bdeb04205c91a4b5780"
[[package]]
name = "byteorder"
version = "1.4.3"
@ -109,9 +109,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
dependencies = [
"iana-time-zone",
"js-sys",
"num-integer",
"num-traits",
"serde",
"time",
"wasm-bindgen",
"winapi",
]
@ -173,7 +176,7 @@ checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
dependencies = [
"bstr",
"csv-core",
"itoa",
"itoa 0.4.8",
"ryu",
"serde",
]
@ -254,6 +257,12 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2"
[[package]]
name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "embed-doc-image"
version = "0.1.4"
@ -266,13 +275,43 @@ dependencies = [
"syn",
]
[[package]]
name = "embedded-can"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438"
dependencies = [
"nb",
]
[[package]]
name = "eurosim-obsw"
version = "0.1.0"
dependencies = [
"chrono",
"embedded-can",
"fern",
"libc",
"log",
"num",
"num-derive",
"num-traits",
"satrs-core",
"satrs-mib",
"serde",
"serde_json",
"socketcan",
"strum",
"strum_macros",
]
[[package]]
name = "fern"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bdd7b0849075e79ee9a1836df22c717d1eba30451796fdc631b04565dd11e2a"
dependencies = [
"log",
]
[[package]]
@ -284,6 +323,12 @@ dependencies = [
"ahash",
]
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -295,9 +340,9 @@ dependencies = [
[[package]]
name = "hex"
version = "0.2.0"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "iana-time-zone"
@ -325,9 +370,12 @@ dependencies = [
[[package]]
name = "itertools"
version = "0.4.19"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4a9b56eb56058f43dc66e58f40a214b2ccbc9f3df51861b63d51dec7b65bc3f"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
@ -335,6 +383,12 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "js-sys"
version = "0.3.60"
@ -387,13 +441,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "nix"
version = "0.5.1"
name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"bitflags 0.4.0",
"autocfg",
]
[[package]]
name = "nb"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
[[package]]
name = "neli"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1805440578ced23f85145d00825c0a831e43c587132a90e100552172543ae30"
dependencies = [
"byteorder",
"libc",
"log",
"neli-proc-macros",
]
[[package]]
name = "neli-proc-macros"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4"
dependencies = [
"either",
"proc-macro2",
"quote",
"serde",
"syn",
]
[[package]]
name = "nix"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46a58d1d356c6597d08cde02c2f09d785b09e28711837b1ed667dc652c08a694"
dependencies = [
"bitflags",
"cfg-if",
"libc",
"memoffset",
"pin-utils",
"static_assertions",
]
[[package]]
@ -402,6 +500,51 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]]
name = "num"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
dependencies = [
"num-bigint",
"num-complex",
"num-integer",
"num-iter",
"num-rational",
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-complex"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19"
dependencies = [
"num-traits",
]
[[package]]
name = "num-derive"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-integer"
version = "0.1.45"
@ -412,6 +555,29 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
@ -456,6 +622,12 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro2"
version = "1.0.47"
@ -480,7 +652,7 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags 1.3.2",
"bitflags",
]
[[package]]
@ -489,6 +661,12 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "rustversion"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70"
[[package]]
name = "ryu"
version = "1.0.12"
@ -497,7 +675,7 @@ checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "satrs-core"
version = "0.1.0"
version = "0.1.0-alpha.0"
dependencies = [
"bus",
"crossbeam-channel",
@ -570,6 +748,17 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
dependencies = [
"itoa 1.0.5",
"ryu",
"serde",
]
[[package]]
name = "smallvec"
version = "0.6.14"
@ -587,22 +776,25 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "socketcan"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3101efc6ef5af6f1c1a488241b469757b7a183baca63af958cd90e4696446c80"
version = "2.0.0-pre.0"
source = "git+https://github.com/socketcan-rs/socketcan-rs.git?rev=1307b1fa76f7b98bbf7d414b88d8f30a41a753b4#1307b1fa76f7b98bbf7d414b88d8f30a41a753b4"
dependencies = [
"bitflags",
"byte_conv",
"embedded-can",
"hex",
"itertools",
"libc",
"nb",
"neli",
"nix",
"try_from",
]
[[package]]
name = "spacepackets"
version = "0.4.0"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9199251260fa674673a195bbe68703ba8d7ac0875d97df05cd4b5618218da054"
checksum = "a31966b4c2a1ca1902c6d34050648e4fbffeb124144775396422a94340068efd"
dependencies = [
"chrono",
"crc",
@ -612,6 +804,34 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strum"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]]
name = "syn"
version = "1.0.105"
@ -633,10 +853,15 @@ dependencies = [
]
[[package]]
name = "try_from"
version = "0.2.2"
name = "time"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "923a7ee3e97dbfe8685261beb4511cc9620a1252405d02693d43169729570111"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "unicode-ident"
@ -656,6 +881,12 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasm-bindgen"
version = "0.2.83"

View File

@ -13,7 +13,25 @@ categories = ["aerospace", "hardware-support", "embedded"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
socketcan = {version = "1.7.0", optional = true }
# socketcan = {version = "1.7.0", optional = true }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
log = "0.4"
fern = "0.6"
chrono = "0.4"
embedded-can = "0.4"
libc = "0.2"
strum = { version = "0.24", features = ["derive"] }
strum_macros = "0.24"
num = "0.4"
num-derive = "0.3"
num-traits = "0.2"
[dependencies.socketcan]
git = "https://github.com/socketcan-rs/socketcan-rs.git"
rev = "1307b1fa76f7b98bbf7d414b88d8f30a41a753b4"
optional = true
#[dependencies.spacepackets]
#path = "../satrs-launchpad/spacepackets"

View File

@ -4,19 +4,22 @@ import enum
import struct
import sys
import time
from typing import Optional, Tuple
from typing import Optional
import datetime
import tmtccmd
from spacepackets.ecss import PusTelemetry, PusTelecommand, PusVerificator
from spacepackets.ecss.pus_17_test import Service17Tm
from spacepackets.ecss.pus_1_verification import UnpackParams, Service1Tm
from spacepackets.ccsds.time import CdsShortTimestamp
from tmtccmd import CcsdsTmtcBackend, TcHandlerBase, ProcedureParamsWrapper
from tmtccmd.tc.pus_3_fsfw_hk import generate_one_hk_command, make_sid, Subservices
from tmtccmd.tc.pus_3_fsfw_hk import generate_one_hk_command, make_sid
from tmtccmd.tc.pus_11_tc_sched import create_time_tagged_cmd
from tmtccmd.core.base import BackendRequest
from tmtccmd.pus import VerificationWrapper
from tmtccmd.tm import CcsdsTmHandler, SpecificApidHandlerBase
from tmtccmd.com_if import ComInterface
from tmtccmd.com import ComInterface
from tmtccmd.config import (
default_json_path,
SetupParams,
@ -41,7 +44,7 @@ from tmtccmd.tc import (
SendCbParams,
DefaultPusQueueHelper,
)
from tmtccmd.tm.pus_5_event import Service5Tm
from tmtccmd.tm.pus_5_fsfw_event import Service5Tm
from tmtccmd.util import FileSeqCountProvider, PusFileSeqCountProvider
from tmtccmd.util.obj_id import ObjectIdDictT
@ -108,6 +111,14 @@ class SatRsConfigHook(TmTcCfgHookBase):
op_code_entry=oce
)
srv_11 = OpCodeEntry()
srv_11.add("0", "Scheduled TC Test")
defs.add_service(
name=CoreServiceList.SERVICE_11,
info="PUS Service 11 TC Scheduling",
op_code_entry=srv_11,
)
return defs
def perform_mode_operation(self, tmtc_backend: CcsdsTmtcBackend, mode: int):
@ -284,6 +295,14 @@ class TcHandler(TcHandlerBase):
return q.add_pus_tc(
PusTelecommand(service=8, subservice=1, app_data=make_target_id(RequestTargetId.PLD))
)
if service == CoreServiceList.SERVICE_11:
q.add_log_cmd("Sending PUS scheduled TC telecommand")
crt_time = CdsShortTimestamp.from_now()
time_stamp = crt_time + datetime.timedelta(seconds=10)
time_stamp = time_stamp.pack()
return q.add_pus_tc(
create_time_tagged_cmd(time_stamp, PusTelecommand(service=8, subservice=1, app_data=make_target_id(RequestTargetId.PLD)))
)
if service == ServiceList.AOCS:
if op_code in AocsOpCodes.ONE_SHOT:
q.add_log_cmd("Sending HK one shot request")

View File

@ -1 +1,2 @@
tmtccmd == 3.0.0
# tmtccmd == 3.0.0
-e git+https://github.com/robamu-org/tmtccmd@97e5e51101a08b21472b3ddecc2063359f7e307a#egg=tmtccmd

View File

@ -1,5 +1,5 @@
use satrs_core::tmtc::AddressableId;
use eurosim_obsw::RequestTargetId;
use satrs_core::tmtc::AddressableId;
pub type CollectionIntervalFactor = u32;
@ -19,4 +19,4 @@ pub enum Subservice {
ImageRequest = 1,
OrientationRequest = 2,
PointingRequest = 3,
}
}

View File

@ -0,0 +1 @@

View File

@ -4,7 +4,6 @@ pub type CollectionIntervalFactor = u32;
//#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum CameraRequest {
OneShot(AddressableId),

View File

@ -152,20 +152,20 @@ impl CanTxHandler {
let value = self.package_map.get(&package_id).unwrap();
if value.get_sender() == DeviceId::OBC {
//if value.get_thread() == self.thread_id {
if data.len() <= 8 {
let frame_id = package_id_to_can_id(&package_id);
let frame = CanFrame::new(frame_id, data);
if let Some(frame) = frame {
self.socket
.write_frame(&frame)
.expect("Error writing frame.");
}
} else {
warn!(
"Message dismissed, data length ({:?}) exceeds 8 bytes",
data.len()
);
if data.len() <= 8 {
let frame_id = package_id_to_can_id(&package_id);
let frame = CanFrame::new(frame_id, data);
if let Some(frame) = frame {
self.socket
.write_frame(&frame)
.expect("Error writing frame.");
}
} else {
warn!(
"Message dismissed, data length ({:?}) exceeds 8 bytes",
data.len()
);
}
/*} else {
warn!(
"Message dismissed, mismatched thread id: {:?}",

View File

@ -5,7 +5,6 @@ use std::fs;
use std::sync::mpsc::Sender;
use std::thread::Thread;
pub use num_derive::{FromPrimitive, ToPrimitive};
pub use num_traits::{FromPrimitive, ToPrimitive};
pub use strum::IntoEnumIterator; // 0.17.1
@ -61,7 +60,7 @@ pub enum PackageId {
AOCSDataSunSensor5 = 69,
AOCSDataSunSensor6 = 70,
AOCSDataStarTracker = 71,
CameraImageRequest = 101 ,
CameraImageRequest = 101,
CameraImageRequestConfirmation = 102,
CameraImageExecutionStart = 103,
CameraImageExectutionEnd = 104,
@ -193,7 +192,7 @@ pub fn load_package_ids() -> HashMap<PackageId, SenderReceiverThread> {
SenderReceiverThread::new(DeviceId::SunSensor5, DeviceId::OBC, ThreadId::AOCSThread),
SenderReceiverThread::new(DeviceId::SunSensor6, DeviceId::OBC, ThreadId::AOCSThread),
SenderReceiverThread::new(DeviceId::StarTracker, DeviceId::OBC, ThreadId::AOCSThread),
SenderReceiverThread::new(DeviceId:: OBC , DeviceId:: Camera , ThreadId:: PLDThread ),
SenderReceiverThread::new(DeviceId::OBC, DeviceId::Camera, ThreadId::PLDThread),
SenderReceiverThread::new(DeviceId::Camera, DeviceId::OBC, ThreadId::PLDThread),
SenderReceiverThread::new(DeviceId::Camera, DeviceId::OBC, ThreadId::PLDThread),
SenderReceiverThread::new(DeviceId::Camera, DeviceId::OBC, ThreadId::PLDThread),

View File

@ -1,15 +1,15 @@
use crate::can_ids::{DeviceId, PackageId, PackageModel, ThreadId};
use log::{info, warn};
use socketcan::{errors, frame, socket, CanFrame, Socket};
use std::collections::HashMap;
use std::hash::Hash;
use std::sync::mpsc::{Receiver, RecvError, Sender};
use log::{info, warn};
use crate::can_ids::{DeviceId, PackageId, PackageModel, ThreadId};
use socketcan::{errors, frame, socket, CanFrame, Socket};
use crate::can::{CanRxHandler, CanTxHandler};
pub use num_derive::{FromPrimitive, ToPrimitive};
pub use num_traits::{FromPrimitive, ToPrimitive};
pub use strum::IntoEnumIterator; // 0.17.1
pub use strum_macros::EnumIter;
use crate::can::{CanRxHandler, CanTxHandler}; // 0.17.1
pub use strum_macros::EnumIter; // 0.17.1
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum DeviceState {
@ -26,23 +26,31 @@ pub struct CanDeviceHandler {
}
impl CanDeviceHandler {
pub fn new(can_tx_handler: CanTxHandler, can_rx_receiver: Receiver<PackageModel>) -> CanDeviceHandler {
let mut device_state_map:HashMap<DeviceId, DeviceState> = HashMap::new();
pub fn new(
can_tx_handler: CanTxHandler,
can_rx_receiver: Receiver<PackageModel>,
) -> CanDeviceHandler {
let mut device_state_map: HashMap<DeviceId, DeviceState> = HashMap::new();
for id in DeviceId::iter() {
device_state_map.insert(id, DeviceState::Unknown);
}
CanDeviceHandler { device_state_map, can_tx_handler, can_rx_receiver }
CanDeviceHandler {
device_state_map,
can_tx_handler,
can_rx_receiver,
}
}
pub fn power_on(&mut self, id: DeviceId) -> Result<(),()> {
pub fn power_on(&mut self, id: DeviceId) -> Result<(), ()> {
if !self.device_state_map.contains_key(&id) {
return Err(());
}
info!("Powering on device {:?}", id);
let msg_data: [u8; 1] = [id as u8];
self.can_tx_handler.tx_socket(PackageId::DevicePowerOnRequest, &msg_data);
self.can_tx_handler
.tx_socket(PackageId::DevicePowerOnRequest, &msg_data);
let request_confirmation = self.can_rx_receiver.recv();
match request_confirmation {
@ -93,14 +101,15 @@ impl CanDeviceHandler {
Ok(())
}
pub fn power_off(&mut self, id: DeviceId) -> Result<(),()> {
pub fn power_off(&mut self, id: DeviceId) -> Result<(), ()> {
if !self.device_state_map.contains_key(&id) {
return Err(());
}
info!("Powering on device {:?}", id);
let msg_data: [u8; 1] = [id as u8];
self.can_tx_handler.tx_socket(PackageId::DevicePowerOffRequest, &msg_data);
self.can_tx_handler
.tx_socket(PackageId::DevicePowerOffRequest, &msg_data);
let request_confirmation = self.can_rx_receiver.recv();
match request_confirmation {
@ -153,23 +162,26 @@ impl CanDeviceHandler {
pub fn get_power_states(&mut self) -> HashMap<DeviceId, DeviceState> {
for id in DeviceId::iter() {
self.update_power_state(id).expect("Error updating power state.");
self.update_power_state(id)
.expect("Error updating power state.");
}
self.device_state_map.clone()
}
pub fn get_power_state(&mut self, id: DeviceId) -> Option<&DeviceState> {
self.update_power_state(id).expect("Error updating power state.");
self.update_power_state(id)
.expect("Error updating power state.");
self.device_state_map.get(&id)
}
pub fn update_power_state(&mut self, id: DeviceId) -> Result<(),()> {
pub fn update_power_state(&mut self, id: DeviceId) -> Result<(), ()> {
if !self.device_state_map.contains_key(&id) {
return Err(());
}
let msg_data: [u8; 1] = [id as u8];
self.can_tx_handler.tx_socket(PackageId::DevicePowerStatusRequest, &msg_data);
self.can_tx_handler
.tx_socket(PackageId::DevicePowerStatusRequest, &msg_data);
let response = self.can_rx_receiver.recv();
if let Ok(response) = response {
@ -193,15 +205,18 @@ impl CanDeviceHandler {
pub fn power_up_sequence(mut device_handler: CanDeviceHandler) -> HashMap<DeviceId, DeviceState> {
for id in DeviceId::iter() {
device_handler.power_on(id).expect("Error powering on device.");
device_handler
.power_on(id)
.expect("Error powering on device.");
}
device_handler.get_power_states()
}
pub fn power_down_sequence(mut device_handler: CanDeviceHandler) -> HashMap<DeviceId, DeviceState> {
for id in DeviceId::iter() {
device_handler.power_off(id).expect("Error powering on device.");
device_handler
.power_off(id)
.expect("Error powering on device.");
}
device_handler.get_power_states()
}

View File

@ -13,4 +13,4 @@ pub enum HkRequest {
Enable(AddressableId),
Disable(AddressableId),
ModifyCollectionInterval(AddressableId, CollectionIntervalFactor),
}
}

View File

@ -1,3 +1,6 @@
mod action;
mod aocs;
mod cam;
mod can;
mod can_ids;
mod ccsds;
@ -7,9 +10,6 @@ mod logger;
mod pus;
mod requests;
mod tmtc;
mod aocs;
mod cam;
mod action;
use crate::hk::{AcsHkIds, HkRequest};
use crate::requests::{Request, RequestWithToken};
@ -332,8 +332,7 @@ fn main() {
ActionRequest::ImageRequest(target_id) => {
assert_eq!(target_id, RequestTargetId::PldSubsystem);
// get current time stamp
let cds_stamp =
TimeProvider::from_now_with_u16_days().unwrap();
let cds_stamp = TimeProvider::from_now_with_u16_days().unwrap();
cds_stamp.write_to_bytes(&mut time_stamp_buf);
// send start verification and get token
@ -353,7 +352,10 @@ fn main() {
loop {
match pld_can_rx.recv() {
Ok(msg) => {
if msg.package_id() == PackageId::CameraImageRequestConfirmation && msg.data()[0] == 1 {
if msg.package_id()
== PackageId::CameraImageRequestConfirmation
&& msg.data()[0] == 1
{
break;
}
}
@ -366,7 +368,10 @@ fn main() {
loop {
match pld_can_rx.recv() {
Ok(msg) => {
if msg.package_id() == PackageId::CameraImageExecutionStart && msg.data()[0] == 1 {
if msg.package_id()
== PackageId::CameraImageExecutionStart
&& msg.data()[0] == 1
{
break;
}
}
@ -379,14 +384,21 @@ fn main() {
loop {
match pld_can_rx.recv() {
Ok(msg) => {
if msg.package_id() == PackageId::CameraImageExectutionEnd && msg.data()[0] == 1 {
if msg.package_id()
== PackageId::CameraImageExectutionEnd
&& msg.data()[0] == 1
{
let cds_stamp =
TimeProvider::from_now_with_u16_days().unwrap();
TimeProvider::from_now_with_u16_days()
.unwrap();
cds_stamp.write_to_bytes(&mut time_stamp_buf);
// send end verification with token
reporter_pld
.completion_success(start_token, Some(&time_stamp_buf))
.completion_success(
start_token,
Some(&time_stamp_buf),
)
.expect("Error sending start success.");
break;
}
@ -409,7 +421,6 @@ fn main() {
}
});
println!("Starting TM funnel task");
let builder4 = thread::Builder::new().name("TMFunnelThread".into());
let jh4 = builder4.spawn(move || {
@ -427,7 +438,9 @@ fn main() {
}
});
jh0.unwrap().join().expect("Joining UDP TMTC server thread failed");
jh0.unwrap()
.join()
.expect("Joining UDP TMTC server thread failed");
jh1.unwrap()
.join()
.expect("Joining CAN Bus Listening thread failed");
@ -446,4 +459,4 @@ struct MgmData {
x: i16,
y: i16,
z: i16,
}
}

View File

@ -1,7 +1,7 @@
use crate::hk::{CollectionIntervalFactor, HkRequest};
use crate::requests::{Request, RequestWithToken};
use crate::tmtc::{PusTcSource, TmStore};
use eurosim_obsw::{hk_err, RequestTargetId, tmtc_err};
use eurosim_obsw::{hk_err, tmtc_err, RequestTargetId};
use satrs_core::events::EventU32;
use satrs_core::pool::StoreAddr;
use satrs_core::pus::event::Subservices;
@ -14,16 +14,19 @@ use satrs_core::res_code::ResultU16;
use satrs_core::tmtc::tm_helper::PusTmWithCdsShortHelper;
use satrs_core::tmtc::{AddressableId, PusServiceProvider};
use satrs_core::{
spacepackets::ecss::PusPacket, spacepackets::tc::PusTc, spacepackets::time::cds::TimeProvider,
spacepackets::time::TimeWriter, spacepackets::SpHeader,
spacepackets, spacepackets::ecss::PusPacket, spacepackets::tc::PusTc,
spacepackets::time::cds::TimeProvider, spacepackets::time::TimeWriter, spacepackets::SpHeader,
};
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::mpsc::Sender;
use satrs_core::spacepackets::ecss::PusServiceId::Action;
use eurosim_obsw::RequestTargetId::{AcsSubsystem, PldSubsystem};
use crate::action;
use crate::action::ActionRequest;
use eurosim_obsw::RequestTargetId::{AcsSubsystem, PldSubsystem};
use satrs_core::pus::scheduling::PusScheduler;
use satrs_core::spacepackets::ecss::PusServiceId::Action;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::mpsc::Sender;
pub struct PusReceiver {
pub tm_helper: PusTmWithCdsShortHelper,
@ -36,6 +39,7 @@ pub struct PusReceiver {
request_map: HashMap<u32, Sender<RequestWithToken>>,
stamper: TimeProvider,
time_stamp: [u8; 7],
scheduler: Rc<RefCell<PusScheduler>>,
}
impl PusReceiver {
@ -47,6 +51,7 @@ impl PusReceiver {
tc_source: PusTcSource,
event_request_tx: Sender<EventRequestWithToken>,
request_map: HashMap<u32, Sender<RequestWithToken>>,
scheduler: Rc<RefCell<PusScheduler>>,
) -> Self {
Self {
tm_helper: PusTmWithCdsShortHelper::new(apid),
@ -58,6 +63,7 @@ impl PusReceiver {
request_map,
stamper: TimeProvider::new_with_u16_days(0, 0),
time_stamp: [0; 7],
scheduler,
}
}
}
@ -85,6 +91,8 @@ impl PusServiceProvider for PusReceiver {
self.handle_hk_request(pus_tc, accepted_token);
} else if service == 8 {
self.handle_function_request(pus_tc, accepted_token);
} else if service == 11 {
self.handle_scheduled_tc(pus_tc, accepted_token);
} else {
self.update_time_stamp();
self.verif_reporter
@ -120,7 +128,11 @@ impl PusReceiver {
self.verif_reporter
.start_failure(
token,
FailParams::new(Some(&self.time_stamp), &tmtc_err::INVALID_PUS_SUBSERVICE, None),
FailParams::new(
Some(&self.time_stamp),
&tmtc_err::INVALID_PUS_SUBSERVICE,
None,
),
)
.expect("Sending start failure TM failed");
}
@ -277,41 +289,38 @@ impl PusReceiver {
}
}
fn handle_function_request(&mut self, pus_tc: &PusTc, token: VerificationToken<TcStateAccepted>) {
fn handle_function_request(
&mut self,
pus_tc: &PusTc,
token: VerificationToken<TcStateAccepted>,
) {
if pus_tc.user_data().is_none() {
self.update_time_stamp();
/*self.verif_reporter
self.verif_reporter
.start_failure(
token,
FailParams::new(&self.time_stamp, &tmtc_err::NOT_ENOUGH_APP_DATA, None),
FailParams::new(Some(&self.time_stamp), &tmtc_err::NOT_ENOUGH_APP_DATA, None),
)
.expect("Sending start failure TM failed");
*/
return;
}
let send_request = |request: ActionRequest| {
match request {
ActionRequest::ImageRequest(target_id) => {
let id = target_id as u32;
let sender = self.request_map.get(&id).unwrap();
sender
.send(RequestWithToken(Request::ActionRequest(request), token))
.unwrap_or_else(|_| panic!("Sending Action request {:?} failed", request));
}
ActionRequest::OrientationRequest(target_id) => {
let id = target_id as u32;
let sender = self.request_map.get(&id).unwrap();
sender
.send(RequestWithToken(Request::ActionRequest(request), token))
.unwrap_or_else(|_| panic!("Sending Action request {:?} failed", request));
}
_ => {}
let send_request = |request: ActionRequest| match request {
ActionRequest::ImageRequest(target_id) => {
let id = target_id as u32;
let sender = self.request_map.get(&id).unwrap();
sender
.send(RequestWithToken(Request::ActionRequest(request), token))
.unwrap_or_else(|_| panic!("Sending Action request {:?} failed", request));
}
ActionRequest::OrientationRequest(target_id) => {
let id = target_id as u32;
let sender = self.request_map.get(&id).unwrap();
sender
.send(RequestWithToken(Request::ActionRequest(request), token))
.unwrap_or_else(|_| panic!("Sending Action request {:?} failed", request));
}
_ => {}
};
if PusPacket::subservice(pus_tc) == action::Subservice::ImageRequest as u8 {
@ -320,4 +329,119 @@ impl PusReceiver {
send_request(ActionRequest::OrientationRequest(AcsSubsystem));
}
}
fn handle_scheduled_tc(&mut self, pus_tc: &PusTc, token: VerificationToken<TcStateAccepted>) {
if pus_tc.user_data().is_none() {
self.update_time_stamp();
self.verif_reporter
.start_failure(
token,
FailParams::new(Some(&self.time_stamp), &tmtc_err::NOT_ENOUGH_APP_DATA, None),
)
.expect("Sending start failure TM failed");
return;
}
self.update_time_stamp();
match pus_tc.subservice() {
1 => {
let start_token = self
.verif_reporter
.start_success(token, Some(&self.time_stamp))
.expect("Error sending start success");
let mut scheduler = self.scheduler.borrow_mut();
scheduler.enable();
if scheduler.is_enabled() {
self.verif_reporter
.completion_success(start_token, Some(&self.time_stamp))
.expect("Error sending completion success");
} else {
panic!("Failed to enable scheduler");
}
drop(scheduler);
}
2 => {
let start_token = self
.verif_reporter
.start_success(token, Some(&self.time_stamp))
.expect("Error sending start success");
let mut scheduler = self.scheduler.borrow_mut();
scheduler.disable();
if !scheduler.is_enabled() {
self.verif_reporter
.completion_success(start_token, Some(&self.time_stamp))
.expect("Error sending completion success");
} else {
panic!("Failed to disable scheduler");
}
drop(scheduler);
}
3 => {
let start_token = self
.verif_reporter
.start_success(token, Some(&self.time_stamp))
.expect("Error sending start success");
let mut pool = self
.tc_source
.tc_store
.pool
.write()
.expect("Locking pool failed");
let mut scheduler = self.scheduler.borrow_mut();
scheduler
.reset(pool.as_mut())
.expect("Error resetting TC Pool");
drop(scheduler);
self.verif_reporter
.completion_success(start_token, Some(&self.time_stamp))
.expect("Error sending completion success");
}
4 => {
let start_token = self
.verif_reporter
.start_success(token, Some(&self.time_stamp))
.expect("Error sending start success");
let mut pool = self
.tc_source
.tc_store
.pool
.write()
.expect("Locking pool failed");
let mut scheduler = self.scheduler.borrow_mut();
scheduler
.insert_wrapped_tc::<TimeProvider>(pus_tc, pool.as_mut())
.expect("TODO: panic message");
let time =
TimeProvider::from_bytes_with_u16_days(&pus_tc.user_data().unwrap()).unwrap();
drop(scheduler);
self.verif_reporter
.completion_success(start_token, Some(&self.time_stamp))
.expect("Error sending completion success");
//let addr = self.tc_source.tc_store.add_pus_tc().unwrap();
//let unix_time = UnixTimestamp::new_only_seconds(self.stamper.unix_seconds());
//let worked = self.scheduler.insert_tc(unix_time, );
}
_ => {
self.verif_reporter
.start_failure(
token,
FailParams::new(
Some(&self.time_stamp),
&tmtc_err::NOT_ENOUGH_APP_DATA,
None,
),
)
.expect("Sending start failure TM failed");
return;
}
}
}
}

View File

@ -1,7 +1,7 @@
use crate::hk::HkRequest;
use satrs_core::pus::verification::{TcStateAccepted, VerificationToken};
use crate::action::ActionRequest;
use crate::cam::CameraRequest;
use crate::hk::HkRequest;
use satrs_core::pus::verification::{TcStateAccepted, VerificationToken};
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Request {

View File

@ -1,11 +1,14 @@
use satrs_core::events::EventU32;
use satrs_core::hal::host::udp_server::{ReceiveResult, UdpTcServer};
use satrs_core::params::Params;
use std::cell::RefCell;
use std::collections::HashMap;
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::net::SocketAddr;
use std::rc::Rc;
use std::sync::mpsc::{Receiver, SendError, Sender, TryRecvError};
use std::sync::{Arc, LockResult, Mutex};
use std::thread;
use std::time::Duration;
@ -14,16 +17,13 @@ use crate::pus::PusReceiver;
use crate::requests::RequestWithToken;
use satrs_core::pool::{SharedPool, StoreAddr, StoreError};
use satrs_core::pus::event_man::EventRequestWithToken;
use satrs_core::pus::scheduling::PusScheduler;
use satrs_core::pus::verification::StdVerifReporterWithSender;
use satrs_core::spacepackets::{ecss::PusPacket, tc::PusTc, tm::PusTm, SpHeader};
use satrs_core::tmtc::{
CcsdsDistributor, CcsdsError, PusServiceProvider, ReceivesCcsdsTc, ReceivesEcssPusTc,
};
use satrs_core::{
spacepackets::ecss::PusPacket, spacepackets::tc::PusTc, spacepackets::tm::PusTm,
spacepackets::SpHeader,
};
pub const PUS_APID: u16 = 0x02;
pub struct OtherArgs {
@ -45,6 +45,12 @@ pub struct TcArgs {
pub tc_receiver: Receiver<StoreAddr>,
}
impl TcArgs {
fn split(self) -> (PusTcSource, Receiver<StoreAddr>) {
(self.tc_source, self.tc_receiver)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MpscStoreAndSendError {
StoreError(StoreError),
@ -55,10 +61,10 @@ impl Display for MpscStoreAndSendError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
MpscStoreAndSendError::StoreError(s) => {
write!(f, "store error {}", s)
write!(f, "store error {s}")
}
MpscStoreAndSendError::SendError(s) => {
write!(f, "send error {}", s)
write!(f, "send error {s}")
}
}
}
@ -156,6 +162,11 @@ impl ReceivesCcsdsTc for PusTcSource {
}
}
pub fn core_tmtc_task(args: OtherArgs, mut tc_args: TcArgs, tm_args: TmArgs) {
let mut scheduler = Rc::new(RefCell::new(
PusScheduler::new_with_current_init_time(Duration::from_secs(5)).unwrap(),
));
let mut sched_clone = scheduler.clone();
let mut pus_receiver = PusReceiver::new(
PUS_APID,
tm_args.tm_sink_sender,
@ -164,11 +175,15 @@ pub fn core_tmtc_task(args: OtherArgs, mut tc_args: TcArgs, tm_args: TmArgs) {
tc_args.tc_source.clone(),
args.event_request_tx,
args.request_map,
sched_clone,
);
let ccsds_receiver = CcsdsReceiver {
tc_source: tc_args.tc_source.clone(),
};
let ccsds_distributor = CcsdsDistributor::new(Box::new(ccsds_receiver));
let udp_tc_server = UdpTcServer::new(args.sock_addr, 2048, Box::new(ccsds_distributor))
.expect("Creating UDP TMTC server failed");
@ -177,8 +192,21 @@ pub fn core_tmtc_task(args: OtherArgs, mut tc_args: TcArgs, tm_args: TmArgs) {
tm_rx: tm_args.tm_server_rx,
tm_store: tm_args.tm_store.pool.clone(),
};
//let (mut tc_source, mut tc_receiver) = tc_args.split();
let mut tc_buf: [u8; 4096] = [0; 4096];
loop {
core_tmtc_loop(&mut udp_tmtc_server, &mut tc_args, &mut pus_receiver);
let mut tmtc_sched = scheduler.clone();
core_tmtc_loop(
&mut udp_tmtc_server,
&mut tc_args,
&mut tc_buf,
//&mut tc_source,
//&mut tc_receiver,
&mut pus_receiver,
tmtc_sched,
);
thread::sleep(Duration::from_millis(400));
}
}
@ -186,8 +214,40 @@ pub fn core_tmtc_task(args: OtherArgs, mut tc_args: TcArgs, tm_args: TmArgs) {
fn core_tmtc_loop(
udp_tmtc_server: &mut UdpTmtcServer,
tc_args: &mut TcArgs,
tc_buf: &mut [u8],
//tc_source: &mut PusTcSource,
//tc_receiver: &mut Receiver<StoreAddr>,
pus_receiver: &mut PusReceiver,
scheduler: Rc<RefCell<PusScheduler>>,
) {
let releaser = |enabled: bool, addr: &StoreAddr| -> bool {
match tc_args.tc_source.tc_source.send(*addr) {
Ok(_) => true,
Err(_) => false,
}
};
let mut pool = tc_args
.tc_source
.tc_store
.pool
.write()
.expect("error locking pool");
let mut scheduler = scheduler.borrow_mut();
scheduler.update_time_from_now().unwrap();
match scheduler.release_telecommands(releaser, pool.as_mut()) {
Ok(released_tcs) => {
if released_tcs > 0 {
println!("{} Tc(s) released from scheduler", released_tcs);
}
}
Err(_) => {}
}
//.expect("error releasing tc");
drop(pool);
drop(scheduler);
while poll_tc_server(udp_tmtc_server) {}
match tc_args.tc_receiver.try_recv() {
Ok(addr) => {
@ -198,15 +258,17 @@ fn core_tmtc_loop(
.read()
.expect("locking tc pool failed");
let data = pool.read(&addr).expect("reading pool failed");
match PusTc::from_bytes(data) {
tc_buf[0..data.len()].copy_from_slice(data);
drop(pool);
match PusTc::from_bytes(tc_buf) {
Ok((pus_tc, _)) => {
pus_receiver
.handle_pus_tc_packet(pus_tc.service(), pus_tc.sp_header(), &pus_tc)
.ok();
}
Err(e) => {
println!("error creating PUS TC from raw data: {}", e);
println!("raw data: {:x?}", data);
println!("error creating PUS TC from raw data: {e}");
println!("raw data: {tc_buf:x?}");
}
}
}
@ -226,7 +288,7 @@ fn poll_tc_server(udp_tmtc_server: &mut UdpTmtcServer) -> bool {
Ok(_) => true,
Err(e) => match e {
ReceiveResult::ReceiverError(e) => match e {
CcsdsError::PacketError(e) => {
CcsdsError::ByteConversionError(e) => {
println!("Got packet error: {e:?}");
true
}
@ -255,7 +317,7 @@ fn core_tm_handling(udp_tmtc_server: &mut UdpTmtcServer, recv_addr: &SocketAddr)
if buf.len() > 9 {
let service = buf[7];
let subservice = buf[8];
println!("Sending PUS TM[{},{}]", service, subservice)
println!("Sending PUS TM[{service},{subservice}]")
} else {
println!("Sending PUS TM");
}