refactor(firmware): simplify configuration and diagnostics
This commit is contained in:
1 parent
ba9c97ed3b
commit
fdf82a5114
96 files changed
+1612
-2772
No files matched your search
@@ -9,20 +9,20 @@ version.workspace = true
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
kaptan-err-propagate = { path = "../../libs/kaptan-err-propagate" }
|
||||
kaptan-control = { path = "../../libs/kaptan-control" }
|
||||
kaptan-config = { path = "../../libs/kaptan-config" }
|
||||
kaptan-config-mavlink = { path = "../../libs/kaptan-config-mavlink" }
|
||||
kaptan-flight-config = { path = "../../libs/kaptan-flight-config" }
|
||||
kaptan-flight-runtime = { path = "../../libs/kaptan-flight-runtime" }
|
||||
kaptan-log = { path = "../../libs/kaptan-log", features = ["facade"] }
|
||||
kaptan-log-mavlink = { path = "../../libs/kaptan-log-mavlink" }
|
||||
kaptan-log = { path = "../../libs/kaptan-log" }
|
||||
kaptan-diagnostics-mavlink = { path = "../../libs/kaptan-diagnostics-mavlink" }
|
||||
kaptan-mavlink = { path = "../../libs/kaptan-mavlink" }
|
||||
kaptan-math = { path = "../../libs/kaptan-math" }
|
||||
kaptan-navigation = { path = "../../libs/kaptan-navigation", features = ["sitl"] }
|
||||
kaptan-safety = { path = "../../libs/kaptan-safety" }
|
||||
kaptan-time = { path = "../../libs/kaptan-time" }
|
||||
minicbor = "0.25"
|
||||
log = { version = "0.4.33", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
mavlink = { version = "0.18", default-features = false, features = ["embedded"] }
|
||||
@@ -1,32 +1,8 @@
|
||||
//! Host-only standard-log facade composition.
|
||||
//! Host-side access to the common bounded log ingress.
|
||||
|
||||
use std::sync::Once;
|
||||
use kaptan_log::LogRecord;
|
||||
|
||||
use kaptan_log::{FacadeIngress, GlobalLogger, LogRecord};
|
||||
|
||||
const SITL_LOG_INGRESS_CAPACITY: usize = 16;
|
||||
static SITL_LOG_INGRESS: FacadeIngress<SITL_LOG_INGRESS_CAPACITY> = FacadeIngress::new();
|
||||
static SITL_LOGGER: GlobalLogger<SITL_LOG_INGRESS_CAPACITY> =
|
||||
GlobalLogger::new(&SITL_LOG_INGRESS, sitl_forbidden_log_context);
|
||||
static INSTALL_SITL_LOGGER: Once = Once::new();
|
||||
|
||||
const fn sitl_forbidden_log_context() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Installs the host-only standard logging facade once for the SITL process.
|
||||
///
|
||||
/// SITL has no ISR, panic, or hard-fault context. Flight targets deliberately
|
||||
/// do not enable this host-only feature.
|
||||
pub fn install_log_facade() {
|
||||
INSTALL_SITL_LOGGER.call_once(|| {
|
||||
SITL_LOGGER
|
||||
.install()
|
||||
.expect("SITL owns the process-global log facade")
|
||||
});
|
||||
}
|
||||
|
||||
/// Removes one transport-neutral event for composition-level sink fanout.
|
||||
pub(super) fn take() -> Option<LogRecord> {
|
||||
SITL_LOG_INGRESS.take()
|
||||
/// Visits one transport-neutral event for composition-level sink fanout.
|
||||
pub(super) fn drain_one<R>(consume: impl FnOnce(&LogRecord) -> R) -> Option<R> {
|
||||
kaptan_log::drain_one(consume)
|
||||
}
|
||||
@@ -11,7 +11,6 @@ mod store;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use logging::install_log_facade;
|
||||
pub use runtime::{CAPABILITIES, SitlConfigRuntime, configuration_service};
|
||||
pub use store::{
|
||||
FileConfigStore, FileStoreError, default_profile, load_profile, write_default_profile,
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
use kaptan_config::ConfigManager;
|
||||
use kaptan_config_mavlink::{ConfigCommand, ConfigProtocol, Principal, ServiceResponse, Target};
|
||||
use kaptan_diagnostics_mavlink::encode_log;
|
||||
use kaptan_flight_config::{CandidateProfile, VehicleCapabilities, VehicleProfile};
|
||||
use kaptan_flight_runtime::FlightRuntime;
|
||||
use kaptan_log::TransportAdmission;
|
||||
use kaptan_log_mavlink::{DiagnosticPayload, encode_diagnostic};
|
||||
use kaptan_mavlink::message::kaptan::KAPTAN_LOG_DATA;
|
||||
|
||||
use super::{FileConfigStore, logging};
|
||||
|
||||
@@ -51,12 +52,11 @@ impl SitlConfigRuntime {
|
||||
/// Drains one standard `log` facade record and exposes the generated
|
||||
/// diagnostic payload for the host's sole MAVLink link owner. This
|
||||
/// host-only harness accepts the bounded handoff synchronously.
|
||||
pub fn pending_diagnostic_payload(&mut self) -> Option<DiagnosticPayload> {
|
||||
if let Some(record) = logging::take() {
|
||||
self.runtime.publish_log_event(record);
|
||||
}
|
||||
pub fn pending_log_payload(&mut self) -> Option<KAPTAN_LOG_DATA> {
|
||||
let runtime = &mut self.runtime;
|
||||
let _ = logging::drain_one(|record| runtime.publish_log_event(*record));
|
||||
self.runtime
|
||||
.submit_next_mavlink(|record| (TransportAdmission::Accepted, encode_diagnostic(record)))
|
||||
.submit_next_mavlink(|record| (TransportAdmission::Accepted, encode_log(record)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ impl SitlConfigRuntime {
|
||||
/// SITL/GCS integration. Flight targets must supply authenticated authority
|
||||
/// and a reviewed journal/activation coordinator before constructing one.
|
||||
pub fn configuration_service(store: FileConfigStore) -> Result<SitlConfigRuntime, String> {
|
||||
logging::install_log_facade();
|
||||
let runtime = FlightRuntime::recover(CandidateProfile::factory(), CAPABILITIES, store)
|
||||
.map_err(|error| format!("configuration recovery failed: {error:?}"))?;
|
||||
Ok(SitlConfigRuntime {
|
||||
|
||||
@@ -7,11 +7,11 @@ use std::{
|
||||
};
|
||||
|
||||
use kaptan_config::ConfigStore;
|
||||
use kaptan_err_propagate::KaptanError;
|
||||
use kaptan_flight_config::{
|
||||
CandidateProfile, CborEncodeError, CborError, MAXIMUM_CANDIDATE_BYTES, VehicleProfile,
|
||||
decode_candidate, encode_candidate,
|
||||
};
|
||||
use kaptan_log::KaptanError;
|
||||
|
||||
use super::{CAPABILITIES, configuration_service};
|
||||
|
||||
@@ -19,12 +19,16 @@ use super::{CAPABILITIES, configuration_service};
|
||||
#[derive(Debug, KaptanError)]
|
||||
pub enum FileStoreError {
|
||||
/// Host filesystem operation failed.
|
||||
#[kaptan_error(id = 12101)]
|
||||
Io(std::io::Error),
|
||||
/// The bounded file record did not decode and validate.
|
||||
#[kaptan_error(id = 12102)]
|
||||
Cbor(CborError),
|
||||
/// The fixed snapshot buffer could not encode the complete candidate.
|
||||
#[kaptan_error(id = 12103)]
|
||||
Encode,
|
||||
/// Factory-only startup deliberately has no durable configuration path.
|
||||
#[kaptan_error(id = 12104)]
|
||||
FactoryOnly,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::fs;
|
||||
|
||||
use kaptan_config::{ConfigModel, ConfigStore};
|
||||
use kaptan_flight_config::{CandidateProfile, decode_candidate};
|
||||
use kaptan_log_mavlink::DiagnosticPayload;
|
||||
use kaptan_mavlink::{
|
||||
encoder::MavlinkEncoder,
|
||||
message::{Message, kaptan::MavMessage},
|
||||
@@ -49,15 +48,14 @@ fn standard_log_macro_reaches_the_generated_mavlink_log_payload() {
|
||||
let _ = fs::remove_file(&path);
|
||||
let mut service = configuration_service(FileConfigStore::new(&path)).unwrap();
|
||||
|
||||
log::info!("SITL configuration service ready");
|
||||
let Some(DiagnosticPayload::Log(payload)) = service.pending_diagnostic_payload() else {
|
||||
panic!("info facade record must reach KAPTAN_LOG");
|
||||
};
|
||||
assert_eq!(payload.level, kaptan_log::Severity::Info.wire_value());
|
||||
kaptan_log::info!("SITL configuration service ready");
|
||||
let payload = service
|
||||
.pending_log_payload()
|
||||
.expect("info facade record must reach KAPTAN_LOG");
|
||||
assert_eq!(payload.level, 6);
|
||||
let message = std::str::from_utf8(&payload.message[..usize::from(payload.message_length)])
|
||||
.expect("facade text remains UTF-8");
|
||||
assert!(message.contains("config::tests"));
|
||||
assert!(message.ends_with("SITL configuration service ready"));
|
||||
assert_eq!(message, "SITL configuration service ready");
|
||||
let mut encoder = MavlinkEncoder::new(1, 1);
|
||||
let frame = encoder.custom(&payload);
|
||||
assert_eq!(frame.message_id(), 51_020);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//! dialect. It is confined to one host network namespace and is versioned so
|
||||
//! malformed simulator traffic never becomes estimator or motor authority.
|
||||
|
||||
use kaptan_log::KaptanError;
|
||||
use kaptan_err_propagate::KaptanError;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
pub const SENSOR_PORT: u16 = 14_660;
|
||||
@@ -42,8 +42,11 @@ pub const STATUS_OUTPUT_PERMITTED: u16 = 1 << 3;
|
||||
pub const STATUS_ACTUATOR_TRANSPORT: u16 = 1 << 4;
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, KaptanError)]
|
||||
pub enum PacketError {
|
||||
#[kaptan_error(id = 12001)]
|
||||
Length,
|
||||
#[kaptan_error(id = 12002)]
|
||||
Version,
|
||||
#[kaptan_error(id = 12003)]
|
||||
NonFinite,
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user