eis/eqpalg/utility/fb_state_machine.h

123 lines
4.2 KiB
C
Raw Normal View History

2026-05-15 13:19:19 +08:00
// eqpalg/utility/fb_state_machine.h
#pragma once
#include <chrono>
#include <map>
#include <string>
using TimePoint = std::chrono::system_clock::time_point;
using TimeDur = std::chrono::milliseconds;
/**
* @brief
*/
enum class FbState {
Idle, // 空闲(无活动动作)
Started, // 刚启动(首周期检测到触发条件,下次检查反馈)
InProgress, // 进行中(等待反馈条件满足或超时)
Done, // 反馈条件满足,动作完成
NotHold, // keep_mode 下触发条件丢失
Timeout // 超时
};
/**
* @brief FbStateMachine::update()
*/
struct FbUpdateResult {
FbState state;
bool funVarsNeedReset; // 本周期是否需要标记 fun_vars 重置
};
/**
* @brief
*
* ExpBase 4 act_start_done/act_not_hold/act_done/act_timeout
* 4 act_started_/act_triggered_/feedback_triggered_/feedback_done_
*
*
* Idle Started InProgress Done/NotHold/Timeout Idle
*
* VarManager
*/
class FbStateMachine {
public:
FbStateMachine() = default;
~FbStateMachine() = default;
// ========== 配置 ==========
/**
* @param keepMode 退
* @param timeout -32768ms
*/
void configure(bool keepMode, TimeDur timeout);
// ========== 每周期调用 ==========
/**
* @brief mon
*
* @param actTriggered exp_act_->evaluate()
* @param now
* @param mm_vars /
* @param tag_count tag
*
* @return FbUpdateResult + fun_vars
*/
FbUpdateResult update(bool actTriggered, TimePoint now,
std::map<std::string, double>& mm_vars,
size_t tag_count);
/**
* @brief update() InProgress
*
* @param fbCondition exp_feedback_->evaluate()
* @param now
* @param mm_vars
*
* @return true Done
* @return false InProgress
*/
bool checkFeedback(bool fbCondition, TimePoint now,
std::map<std::string, double>& mm_vars);
// ========== 查询 ==========
bool isActive() const; // Started 或 InProgress
bool isKeepMode() const { return keep_mode_; }
TimePoint actionStartTime() const { return start_time_; }
FbState currentState() const { return state_; }
// ========== 外部强制重置PRR=false 时调用)==========
void forceReset();
// ========== 获取 m_timemode供外部判断报警消息格式==========
bool isTimeMode() const { return time_mode_; }
void setTimeMode(bool v) { time_mode_ = v; }
private:
bool keep_mode_ = false;
TimeDur timeout_ = std::chrono::minutes(10);
FbState state_ = FbState::Idle;
TimePoint start_time_;
bool time_mode_ = false; // 原 ExpBase::m_timemode
// ========== 内部变量操作(替代分散在 act_* 方法中的变量更新)==========
void snapshotActionStart(TimePoint now,
std::map<std::string, double>& mm_vars,
size_t tag_count);
void updateActionVars(TimePoint now,
std::map<std::string, double>& mm_vars,
size_t tag_count);
void recordActionEnd(TimePoint now,
std::map<std::string, double>& mm_vars);
void clearActionAccumulators(std::map<std::string, double>& mm_vars,
size_t tag_count);
bool isAccumulatorNearOverflow(
const std::map<std::string, double>& mm_vars,
size_t tag_count) const;
};