board: make telemetry profile selection explicit
This commit is contained in:
1 parent
c44286bdcf
commit
01463fa878
5 files changed
+158
-96
No files matched your search
@@ -2,7 +2,8 @@
|
||||
//!
|
||||
//! This crate owns fixed-rate scheduling, mailbox consumption, vertical-data
|
||||
//! freshness, MAVLink encoding, and bounded queue classification. A platform
|
||||
//! supplies only mailbox references, health/arming state, and a transport sink.
|
||||
//! supplies only mailbox references, a declared MAVLink state, arming state,
|
||||
//! and a transport sink.
|
||||
|
||||
#![no_std]
|
||||
|
||||
@@ -57,6 +58,8 @@ pub struct VerticalDataConfig {
|
||||
/// Data-channel construction failure.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum DataChannelError {
|
||||
/// Rejected profiles must not construct a physical telemetry channel.
|
||||
NotTelemetryProfile,
|
||||
/// A configured channel must be due at least once per second.
|
||||
ZeroRate,
|
||||
/// A configured channel exceeds the service frequency.
|
||||
@@ -92,7 +95,10 @@ where
|
||||
vertical: VerticalDataConfig,
|
||||
sources: DataSources<'a>,
|
||||
) -> Result<Self, DataChannelError> {
|
||||
let schedule = Schedule::from_rates(config.data_channel)?;
|
||||
let telemetry = config
|
||||
.telemetry()
|
||||
.ok_or(DataChannelError::NotTelemetryProfile)?;
|
||||
let schedule = Schedule::from_rates(telemetry.data_channel)?;
|
||||
Ok(Self {
|
||||
sink,
|
||||
encoder: MavlinkEncoder::new(config.mavlink.system_id, config.mavlink.component_id),
|
||||
@@ -114,7 +120,7 @@ where
|
||||
/// No schedule token escapes this method. It refreshes cached vertical
|
||||
/// observations, selects due data, encodes the MAVLink message, and admits
|
||||
/// it with the correct bounded-queue class.
|
||||
pub fn on_service_tick(&mut self, imu_healthy: bool, motors_armed: bool) {
|
||||
pub fn on_service_tick(&mut self, system_status: MavState, motors_armed: bool) {
|
||||
self.refresh_vertical_data();
|
||||
|
||||
match self.schedule.next_due() {
|
||||
@@ -148,14 +154,7 @@ where
|
||||
}
|
||||
Some(DueData::Heartbeat) => self.sink.send(
|
||||
FrameClass::Critical,
|
||||
self.encoder.heartbeat(
|
||||
if imu_healthy {
|
||||
MavState::MAV_STATE_STANDBY
|
||||
} else {
|
||||
MavState::MAV_STATE_CRITICAL
|
||||
},
|
||||
motors_armed,
|
||||
),
|
||||
self.encoder.heartbeat(system_status, motors_armed),
|
||||
),
|
||||
Some(DueData::Distance | DueData::OpticalFlow) | None => {}
|
||||
}
|
||||
@@ -281,7 +280,7 @@ mod tests {
|
||||
};
|
||||
use kaptan_board::{BoardConfig, DataChannelRates, MavlinkEndpoint, VerticalSensingKind};
|
||||
use kaptan_dma::TxCompletion;
|
||||
use kaptan_mavlink::{MavlinkFrame, transmitter::FrameClass};
|
||||
use kaptan_mavlink::{MavlinkFrame, message::MavState, transmitter::FrameClass};
|
||||
use kaptan_sensor::{
|
||||
imu::ImuSnapshot, optical_flow::OpticalFlowSnapshot, range::RangeSnapshot,
|
||||
};
|
||||
@@ -312,14 +311,16 @@ mod tests {
|
||||
system_id: 1,
|
||||
component_id: 1,
|
||||
},
|
||||
vertical_sensing: VerticalSensingKind::RangeAndOpticalFlow,
|
||||
data_channel: DataChannelRates {
|
||||
service_hz: 100,
|
||||
raw_imu_hz: 20,
|
||||
range_hz: Some(20),
|
||||
optical_flow_hz: Some(20),
|
||||
heartbeat_hz: 2,
|
||||
},
|
||||
profile: kaptan_board::BoardProfile::TelemetryOnly(kaptan_board::TelemetryProfile {
|
||||
vertical_sensing: VerticalSensingKind::RangeAndOpticalFlow,
|
||||
data_channel: DataChannelRates {
|
||||
service_hz: 100,
|
||||
raw_imu_hz: 20,
|
||||
range_hz: Some(20),
|
||||
optical_flow_hz: Some(20),
|
||||
heartbeat_hz: 2,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -367,7 +368,7 @@ mod tests {
|
||||
100,
|
||||
100,
|
||||
));
|
||||
channel.on_service_tick(true, false);
|
||||
channel.on_service_tick(MavState::MAV_STATE_STANDBY, false);
|
||||
}
|
||||
channel.on_dma_complete(TxCompletion::Complete);
|
||||
|
||||
|
||||
Reference in new issue
Block a user