From 5ad4bb12a5417d4c8893941d69c40f62c7947ccd Mon Sep 17 00:00:00 2001 From: Aaron Chan Date: Tue, 16 Jun 2026 13:56:14 -0700 Subject: [PATCH 1/3] Rebroadcast boost alerts and make sure we note time since boost --- .../sensor_module/include/c_detection_handler.h | 3 +++ app/backplane/sensor_module/src/c_detection_handler.cpp | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/app/backplane/sensor_module/include/c_detection_handler.h b/app/backplane/sensor_module/include/c_detection_handler.h index ecd50157a..3a7982d5a 100644 --- a/app/backplane/sensor_module/include/c_detection_handler.h +++ b/app/backplane/sensor_module/include/c_detection_handler.h @@ -45,6 +45,9 @@ class CDetectionHandler { static constexpr uint64_t BOOST_NOT_YET_HAPPENED = ~0; uint64_t boost_detected_time = BOOST_NOT_YET_HAPPENED; + static constexpr uint32_t boostAlertResendCycles = 20; + uint32_t boostAlertResendsRemaining = 0; + /** * Process sensor information * @param uptime uptime in milliseconds of the system diff --git a/app/backplane/sensor_module/src/c_detection_handler.cpp b/app/backplane/sensor_module/src/c_detection_handler.cpp index 3eec1f6b1..aa9f02cd7 100644 --- a/app/backplane/sensor_module/src/c_detection_handler.cpp +++ b/app/backplane/sensor_module/src/c_detection_handler.cpp @@ -42,6 +42,15 @@ void CDetectionHandler::HandleData(const uint64_t timestamp, const NTypes::Senso if (!controller.HasEventOccurred(Events::Boost)) { HandleBoost(timestamp, data, sensor_states); + if (controller.HasEventOccurred(Events::Boost)) { + // Boost confirmed so record for noseover and ground detection to + // measure time since boost and schedule rebroadcast of alert + boost_detected_time = timestamp; + boostAlertResendsRemaining = boostAlertResendCycles; + } + } else if (boostAlertResendsRemaining > 0) { + alertMessagePort.Send(boostNotification); + boostAlertResendsRemaining--; } // Don't worry about the rest until we've got boost if (!controller.HasEventOccurred(Events::Boost)) { From 08cc5937f1766d56fa37e84a41e331874a5dd9d8 Mon Sep 17 00:00:00 2001 From: Aaron Chan Date: Tue, 16 Jun 2026 14:03:48 -0700 Subject: [PATCH 2/3] Fixtimer landing path --- .../sensor_module/include/c_detection_handler.h | 7 ++++++- app/backplane/sensor_module/src/c_detection_handler.cpp | 9 +++++++-- app/backplane/sensor_module/src/c_sensing_tenant.cpp | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/backplane/sensor_module/include/c_detection_handler.h b/app/backplane/sensor_module/include/c_detection_handler.h index 3a7982d5a..16ffdb250 100644 --- a/app/backplane/sensor_module/include/c_detection_handler.h +++ b/app/backplane/sensor_module/include/c_detection_handler.h @@ -45,8 +45,13 @@ class CDetectionHandler { static constexpr uint64_t BOOST_NOT_YET_HAPPENED = ~0; uint64_t boost_detected_time = BOOST_NOT_YET_HAPPENED; - static constexpr uint32_t boostAlertResendCycles = 20; + static constexpr uint32_t alertResendCycles = 20; uint32_t boostAlertResendsRemaining = 0; + uint32_t landedAlertResendsRemaining = alertResendCycles; + + // Rebroadcast the landed alert once GroundHit occurs. Covers both the + // barometer and timer paths, and survives UDP loss like the boost alert. + void ServiceLandedAlert(); /** * Process sensor information diff --git a/app/backplane/sensor_module/src/c_detection_handler.cpp b/app/backplane/sensor_module/src/c_detection_handler.cpp index aa9f02cd7..6f2860f3e 100644 --- a/app/backplane/sensor_module/src/c_detection_handler.cpp +++ b/app/backplane/sensor_module/src/c_detection_handler.cpp @@ -46,7 +46,7 @@ void CDetectionHandler::HandleData(const uint64_t timestamp, const NTypes::Senso // Boost confirmed so record for noseover and ground detection to // measure time since boost and schedule rebroadcast of alert boost_detected_time = timestamp; - boostAlertResendsRemaining = boostAlertResendCycles; + boostAlertResendsRemaining = alertResendCycles; } } else if (boostAlertResendsRemaining > 0) { alertMessagePort.Send(boostNotification); @@ -84,11 +84,16 @@ void CDetectionHandler::HandleGround(const uint32_t t_plus_ms, const NTypes::Sen if (primaryBaromGroundDetector.Passed() && sensor_states.primaryBarometerOk) { controller.SubmitEvent(Sources::BaromMS5611, Events::GroundHit); - alertMessagePort.Send(landedNotification); } if (secondaryBaromGroundDetector.Passed() && sensor_states.secondaryBarometerOk) { controller.SubmitEvent(Sources::BaromBMP, Events::GroundHit); + } +} + +void CDetectionHandler::ServiceLandedAlert() { + if (controller.HasEventOccurred(Events::GroundHit) && landedAlertResendsRemaining > 0) { alertMessagePort.Send(landedNotification); + landedAlertResendsRemaining--; } } diff --git a/app/backplane/sensor_module/src/c_sensing_tenant.cpp b/app/backplane/sensor_module/src/c_sensing_tenant.cpp index 02cbe7342..edcebdbf8 100644 --- a/app/backplane/sensor_module/src/c_sensing_tenant.cpp +++ b/app/backplane/sensor_module/src/c_sensing_tenant.cpp @@ -55,6 +55,7 @@ void CSensingTenant::Startup() { void CSensingTenant::PostStartup() {} void CSensingTenant::Run() { + detectionHandler.ServiceLandedAlert(); if (!detectionHandler.ContinueCollecting()) { return; } From 917623d22fedadb8ae1c38d73f9dbefcc0fde955 Mon Sep 17 00:00:00 2001 From: Aaron Chan Date: Tue, 16 Jun 2026 14:20:49 -0700 Subject: [PATCH 3/3] Append radio fc state --- .../include/c_downlink_scheduler_tenant.h | 4 +++ .../src/c_downlink_scheduler_tenant.cpp | 27 ++++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/app/backplane/radio_module/include/c_downlink_scheduler_tenant.h b/app/backplane/radio_module/include/c_downlink_scheduler_tenant.h index 26ffbf3d4..02db0ebce 100644 --- a/app/backplane/radio_module/include/c_downlink_scheduler_tenant.h +++ b/app/backplane/radio_module/include/c_downlink_scheduler_tenant.h @@ -51,6 +51,10 @@ class CDownlinkSchedulerTenant : public CRunnableTenant, public CPadFlightLanded void GroundRun() override; private: + // Send a telemetry frame, piggybacking the flight phase onto GNSS frames + // (port 12005) so the ground can observe the radio's state. + void SendFrame(LaunchLoraFrame& frame); + CMessagePort& loraDownlinkMessagePort; CHashMap*> telemetryMessagePortMap; CHashMap> telemetryDownlinkTimers; diff --git a/app/backplane/radio_module/src/c_downlink_scheduler_tenant.cpp b/app/backplane/radio_module/src/c_downlink_scheduler_tenant.cpp index 0e95b52d1..99cdd148e 100644 --- a/app/backplane/radio_module/src/c_downlink_scheduler_tenant.cpp +++ b/app/backplane/radio_module/src/c_downlink_scheduler_tenant.cpp @@ -23,6 +23,18 @@ CDownlinkSchedulerTenant::CDownlinkSchedulerTenant( }(telemetryDownlinkTimers.GetPtr(NNetworkDefs::RADIO_MODULE_GNSS_DATA_PORT))); } +void CDownlinkSchedulerTenant::SendFrame(LaunchLoraFrame& frame) { + // Piggyback the flight phase onto GNSS frames. Reflects the radio's belief + // of the phase, not independent confirmation of physical events. + if (frame.Port == NNetworkDefs::RADIO_MODULE_GNSS_DATA_PORT && frame.Size < sizeof(frame.Payload)) { + frame.Payload[frame.Size++] = static_cast(state); + } + + if (loraDownlinkMessagePort.Send(frame, K_NO_WAIT) < 0) { + LOG_ERR("Failed to send telemetry frame on port %d", frame.Port); + } +} + void CDownlinkSchedulerTenant::HandleFrame(const ReceivedLaunchLoraFrame& rxFrame) { const LaunchLoraFrame& frame = rxFrame.Frame; if (this->state == State::PAD || this->state == State::LANDED) { @@ -43,10 +55,7 @@ void CDownlinkSchedulerTenant::HandleFrame(const ReceivedLaunchLoraFrame& rxFram LOG_ERR("Failed to receive telemetry frame on port %d", port); } - ret = loraDownlinkMessagePort.Send(telemFrame, K_NO_WAIT); - if (ret < 0) { - LOG_ERR("Failed to send telemetry frame on port %d", port); - } + SendFrame(telemFrame); } } } @@ -83,10 +92,7 @@ void CDownlinkSchedulerTenant::FlightRun() { continue; } - ret = loraDownlinkMessagePort.Send(telemFrame, K_NO_WAIT); - if (ret < 0) { - LOG_ERR("Failed to send telemetry frame on port %d", port); - } + SendFrame(telemFrame); } } } @@ -107,10 +113,7 @@ void CDownlinkSchedulerTenant::LandedRun() { return; } - ret = loraDownlinkMessagePort.Send(telemFrame, K_NO_WAIT); - if (ret < 0) { - LOG_ERR("Failed to send GNSS telemetry frame"); - } + SendFrame(telemFrame); } }