Files
2026-06-12 15:25:13 +02:00

154 lines
3.8 KiB
C++

/**
* @file TriggerEngine.cpp
* @brief Hub-side trigger FSM implementation (web client semantics).
*/
#include "TriggerEngine.h"
#include "AdvancedErrorManagement.h"
namespace StreamHub {
TriggerEngine::TriggerEngine()
: epoch_(0u),
state_(kTrigIdle),
stopped_(false),
prevValue_(0.0),
prevValid_(false),
trigTime_(0.0),
firedPreSec_(0.0),
firedPostSec_(0.0),
firedValid_(false) {
}
void TriggerEngine::SetConfig(const TriggerConfig &cfg) {
(void) mutex_.FastLock();
config_ = cfg;
/* Clamp to web UI bounds */
if (config_.windowSec < 1.0e-4) { config_.windowSec = 1.0e-4; }
if (config_.windowSec > 10.0) { config_.windowSec = 10.0; }
if (config_.prePercent < 0.0) { config_.prePercent = 0.0; }
if (config_.prePercent > 100.0) { config_.prePercent = 100.0; }
epoch_++;
prevValid_ = false;
prevValue_ = 0.0;
mutex_.FastUnLock();
}
TriggerConfig TriggerEngine::GetConfig() const {
(void) mutex_.FastLock();
TriggerConfig ret = config_;
mutex_.FastUnLock();
return ret;
}
uint32 TriggerEngine::GetConfigEpoch() const {
(void) mutex_.FastLock();
uint32 ret = epoch_;
mutex_.FastUnLock();
return ret;
}
void TriggerEngine::Arm() {
(void) mutex_.FastLock();
state_ = kTrigArmed;
prevValid_ = false;
prevValue_ = 0.0;
mutex_.FastUnLock();
}
void TriggerEngine::Disarm() {
(void) mutex_.FastLock();
state_ = kTrigIdle;
stopped_ = false;
prevValid_ = false;
prevValue_ = 0.0;
firedValid_ = false;
mutex_.FastUnLock();
}
void TriggerEngine::SetStopped(bool stopped) {
(void) mutex_.FastLock();
stopped_ = stopped;
mutex_.FastUnLock();
}
bool TriggerEngine::GetStopped() const {
(void) mutex_.FastLock();
bool ret = stopped_;
mutex_.FastUnLock();
return ret;
}
void TriggerEngine::CheckSample(float64 t, float64 v) {
(void) mutex_.FastLock();
if (state_ != kTrigArmed) {
mutex_.FastUnLock();
return;
}
if (!prevValid_) {
prevValue_ = v;
prevValid_ = true;
mutex_.FastUnLock();
return;
}
const float64 thr = config_.threshold;
const bool up = (prevValue_ < thr) && (v >= thr);
const bool down = (prevValue_ > thr) && (v <= thr);
prevValue_ = v;
bool fired = false;
switch (config_.edge) {
case kEdgeRising: fired = up; break;
case kEdgeFalling: fired = down; break;
case kEdgeBoth: fired = (up || down); break;
default: break;
}
if (fired) {
state_ = kTrigCollecting;
trigTime_ = t;
/* Latch the window at fire time so later config edits do not
* affect this capture (web client snap._preS/_postS). */
firedPreSec_ = config_.windowSec * config_.prePercent / 100.0;
firedPostSec_ = config_.windowSec - firedPreSec_;
firedValid_ = true;
REPORT_ERROR_STATIC(MARTe::ErrorManagement::Information,
"TriggerEngine: fired at t=%.6f (pre=%.4fs post=%.4fs)",
t, firedPreSec_, firedPostSec_);
}
mutex_.FastUnLock();
}
TrigState TriggerEngine::GetState() const {
(void) mutex_.FastLock();
TrigState ret = state_;
mutex_.FastUnLock();
return ret;
}
bool TriggerEngine::GetFiredWindow(float64 &trigTime, float64 &preSec,
float64 &postSec) const {
(void) mutex_.FastLock();
const bool ok = firedValid_;
if (ok) {
trigTime = trigTime_;
preSec = firedPreSec_;
postSec = firedPostSec_;
}
mutex_.FastUnLock();
return ok;
}
void TriggerEngine::MarkTriggered() {
(void) mutex_.FastLock();
if (state_ == kTrigCollecting) {
state_ = kTrigTriggered;
}
mutex_.FastUnLock();
}
} /* namespace StreamHub */