feat(mavlink): adopt the kaptan-native dialect
This commit is contained in:
1 parent
1c90870634
commit
5f91465e66
87 files changed
+7733
-6850
No files matched your search
@@ -7,13 +7,16 @@
|
||||
|
||||
#![no_std]
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate std;
|
||||
|
||||
use kaptan_config::{ConfigManager, ConfigStore, StartupError};
|
||||
use kaptan_flight_config::{CandidateProfile, VehicleCapabilities};
|
||||
use kaptan_log::{LogRecord, LogSinkQueue};
|
||||
|
||||
/// Default bounded allocation for the MAVLink diagnostic sink. Error records
|
||||
/// are partitioned from optional detail.
|
||||
pub type RuntimeMavlinkLogQueue = LogSinkQueue<8, 16>;
|
||||
type RuntimeMavlinkLogQueue = LogSinkQueue<8, 16>;
|
||||
|
||||
/// One boot-active vehicle runtime. It deliberately has no MAVLink dependency.
|
||||
pub struct FlightRuntime<S> {
|
||||
@@ -45,20 +48,9 @@ where
|
||||
&self.configuration
|
||||
}
|
||||
|
||||
/// Mutably borrows the sole configuration manager for protocol dispatch.
|
||||
pub fn configuration_mut(&mut self) -> &mut ConfigManager<CandidateProfile, S> {
|
||||
&mut self.configuration
|
||||
}
|
||||
|
||||
/// Composition-owned fan-out boundary for one preformatted event.
|
||||
/// A future blackbox adds its independent sink admission here.
|
||||
/// Composition-owned admission boundary for one preformatted event.
|
||||
pub fn publish_log_event(&mut self, record: LogRecord) {
|
||||
let _ = self.mavlink_logs.publish_record(record);
|
||||
}
|
||||
|
||||
/// Peeks the highest-priority pending text log for the sole telemetry link.
|
||||
pub fn pending_mavlink_report(&self) -> Option<LogRecord> {
|
||||
self.mavlink_logs.peek()
|
||||
self.mavlink_logs.publish_record(record);
|
||||
}
|
||||
|
||||
/// Submits the next record and removes it only after transport admission.
|
||||
@@ -68,25 +60,26 @@ where
|
||||
) -> Option<R> {
|
||||
self.mavlink_logs.submit_next(submit)
|
||||
}
|
||||
|
||||
/// Immutable boot-active MAVLink log policy copied from the validated profile.
|
||||
pub const fn mavlink_log_filter(&self) -> kaptan_log::LevelFilter {
|
||||
self.mavlink_logs.filter()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use kaptan_config::{ConfigModel, ConfigStore, ConfigValue};
|
||||
use kaptan_log::{Level, LevelFilter, LogFlags, LogRecord, LogText};
|
||||
use kaptan_log::TransportAdmission;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use super::FlightRuntime;
|
||||
|
||||
static LOG_TEST: Mutex<()> = Mutex::new(());
|
||||
|
||||
struct Store;
|
||||
impl ConfigStore<kaptan_flight_config::CandidateProfile> for Store {
|
||||
type Error = ();
|
||||
|
||||
fn load(&mut self) -> Result<Option<kaptan_flight_config::CandidateProfile>, Self::Error> {
|
||||
fn load(
|
||||
&mut self,
|
||||
_: &kaptan_flight_config::CandidateProfile,
|
||||
) -> Result<Option<kaptan_flight_config::CandidateProfile>, Self::Error> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@@ -100,6 +93,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn runtime_uses_the_active_mavlink_policy_and_owns_one_sink_queue() {
|
||||
let _guard = LOG_TEST.lock().unwrap();
|
||||
while kaptan_log::drain_one(|_| ()).is_some() {}
|
||||
let mut runtime = FlightRuntime::recover(
|
||||
kaptan_flight_config::CandidateProfile::factory(),
|
||||
kaptan_flight_config::VehicleCapabilities::quad_x(),
|
||||
@@ -108,24 +103,29 @@ mod tests {
|
||||
.expect("factory configuration validates");
|
||||
assert_eq!(
|
||||
runtime.configuration().active().mavlink_logging(),
|
||||
runtime.mavlink_log_filter()
|
||||
kaptan_log::LevelFilter::Info
|
||||
);
|
||||
kaptan_log::info!("runtime ready");
|
||||
runtime.publish_log_event(kaptan_log::drain_one(|record| *record).unwrap());
|
||||
assert_eq!(
|
||||
runtime.submit_next_mavlink(|record| {
|
||||
assert_eq!(record.level(), kaptan_log::Level::Info);
|
||||
(TransportAdmission::Accepted, ())
|
||||
}),
|
||||
Some(())
|
||||
);
|
||||
runtime.publish_log_event(LogRecord::new(
|
||||
Level::Info,
|
||||
LogFlags::NONE,
|
||||
LogText::from_message("runtime ready"),
|
||||
));
|
||||
assert!(runtime.pending_mavlink_report().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn disabled_mavlink_sink_filters_every_level() {
|
||||
let _guard = LOG_TEST.lock().unwrap();
|
||||
while kaptan_log::drain_one(|_| ()).is_some() {}
|
||||
let mut factory = kaptan_flight_config::CandidateProfile::factory();
|
||||
let level_filter = kaptan_flight_config::CandidateProfile::descriptors()
|
||||
.find(|descriptor| descriptor.display_key == "mavlink.logging.level_filter")
|
||||
.expect("MAVLink log-level descriptor");
|
||||
factory
|
||||
.set_field(level_filter.id, ConfigValue::U32(0))
|
||||
.set_field(level_filter.id, ConfigValue::U8(0))
|
||||
.unwrap();
|
||||
let mut runtime = FlightRuntime::recover(
|
||||
factory,
|
||||
@@ -134,12 +134,15 @@ mod tests {
|
||||
)
|
||||
.expect("disabled MAVLink sink is valid");
|
||||
|
||||
assert_eq!(runtime.mavlink_log_filter(), LevelFilter::Off);
|
||||
runtime.publish_log_event(LogRecord::new(
|
||||
Level::Error,
|
||||
LogFlags::NONE,
|
||||
LogText::from_message("not routed to MAVLink"),
|
||||
));
|
||||
assert!(runtime.pending_mavlink_report().is_none());
|
||||
assert_eq!(
|
||||
runtime.configuration().active().mavlink_logging(),
|
||||
kaptan_log::LevelFilter::Off
|
||||
);
|
||||
kaptan_log::error!("not routed to MAVLink");
|
||||
runtime.publish_log_event(kaptan_log::drain_one(|record| *record).unwrap());
|
||||
assert_eq!(
|
||||
runtime.submit_next_mavlink(|_| (TransportAdmission::Accepted, ())),
|
||||
None
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user