#![cfg(feature = "optical_flow")]
use embassy_sync::{
blocking_mutex::raw::CriticalSectionRawMutex,
pubsub::{PubSubChannel, Publisher, Subscriber},
};
use static_cell::StaticCell;
use crate::optical_flow_sensors::{OpticalFlow, OpticalFlowDevice, OpticalFlowMessage};
const MAX_OPTICAL_FLOW_SUBSCRIBER_COUNT: usize = 4;
const OPTICAL_FLOW_PUBLISHER_COUNT: usize = 1;
const OPTICAL_FLOW_PUB_SUB_CAPACITY: usize = 1;
static OPTICAL_FLOW_PUB_SUB_CHANNEL: PubSubChannel<
CriticalSectionRawMutex,
OpticalFlowMessage,
OPTICAL_FLOW_PUB_SUB_CAPACITY,
MAX_OPTICAL_FLOW_SUBSCRIBER_COUNT,
OPTICAL_FLOW_PUBLISHER_COUNT,
> = PubSubChannel::new();
type OpticalFlowPublisher = Publisher<
'static,
CriticalSectionRawMutex,
OpticalFlowMessage,
OPTICAL_FLOW_PUB_SUB_CAPACITY,
MAX_OPTICAL_FLOW_SUBSCRIBER_COUNT,
OPTICAL_FLOW_PUBLISHER_COUNT,
>;
pub type OpticalFlowSubscriber = Subscriber<
'static,
CriticalSectionRawMutex,
OpticalFlowMessage,
OPTICAL_FLOW_PUB_SUB_CAPACITY,
MAX_OPTICAL_FLOW_SUBSCRIBER_COUNT,
OPTICAL_FLOW_PUBLISHER_COUNT,
>;
#[allow(clippy::expect_used)]
pub fn optical_flow_subscriber() -> OpticalFlowSubscriber {
OPTICAL_FLOW_PUB_SUB_CHANNEL.subscriber().expect("optical_flow_subscriber failed")
}
static OPTICAL_FLOW_CTX: StaticCell<OpticalFlowContext> = StaticCell::new();
pub struct OpticalFlowContext {
pub optical_flow: OpticalFlow,
pub optical_flow_publisher: OpticalFlowPublisher,
}
pub fn init(optical_flow: OpticalFlow) -> &'static mut OpticalFlowContext {
let ctx = OpticalFlowContext {
optical_flow,
#[allow(clippy::expect_used)]
optical_flow_publisher: OPTICAL_FLOW_PUB_SUB_CHANNEL.publisher().expect("optical_flow_publisher failed"),
};
OPTICAL_FLOW_CTX.init(ctx)
}
#[embassy_executor::task]
pub async fn run(ctx: &'static mut OpticalFlowContext) {
const TASK_FREQUENCY_HZ: u64 = 50;
let mut ticker = embassy_time::Ticker::every(embassy_time::Duration::from_hz(TASK_FREQUENCY_HZ));
let mut loop_count: u32 = 0;
log::info!("OPTICAL_FLOW: task started");
loop {
ticker.next().await;
let optical_flow_message = ctx.optical_flow.message();
ctx.optical_flow_publisher.publish_immediate(optical_flow_message);
if loop_count.is_multiple_of(10) {
log::info!(" OPTICAL_FLOW:loop {loop_count}");
}
loop_count = loop_count.wrapping_add(1);
}
}