pCCU新增锂电池通信/协调操作 + 电源协调状态机骨架(惰性)
锂电池通信(docs/锂电池协议20230324.docx): - 协议层 BatProtocol:自检0x0000(2B)/设备控制0x0001(17B)/电池组状态0x0003(80B)/ 电池包报警0x0004(68B),uint32字节和校验、小端 - 链路层 BatLinkManager:动力/仪表锂电池独立UDP链路,本机监听与远端IP端口 均由.moos配置(dyn_bat_*/ins_bat_*/bat_work_condition) - SystemData/SnapshotBuilder/网页:电池数据按动力/仪表归类展示(运行状态/接触器 电气量/电池包电压温度/报警),收发帧落库SQLite,网页新增电池标签页 操作->指令下发(PowerCoordinator): - 操作接口:自检/上下电(母线接触器55H接通77H断开,含预充)/功率设定(0~500kW)/ 电池切换(低压->高压6步、高压->低压5步,按协议时序) - 步骤引擎:每电池独立步骤队列,下发->状态反馈确认->超时兜底;周期1s心跳控制帧 - PM操控指令insBatCmd/dynBatCmd/dynBatPower自动映射为电池操作 电源协调状态机骨架(CoordFsm, TinyFSM): - 事件Tick/PmControl/StepDone + 状态Normal/Switching/Fault,react均为TODO占位 - 当前未接线(无start/dispatch调用,运行行为与接入前一致),CoordFsm.hpp头部附接线指南 测试与部署: - pccuTest新增电池协议编解码/帧长/链路分发用例(175项通过);集成测试覆盖电池 心跳、启停映射(0x10->0x55/0x20->0x77)、状态落库;同步pccu_it.moos与ws_check - h100.moos与pCCU.moos增加锂电池链路配置;归档锂电池协议文档
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
#ifndef PCCU_COORD_FSM_HPP
|
||||
#define PCCU_COORD_FSM_HPP
|
||||
|
||||
#include "../fsm/tinyfsm.hpp"
|
||||
#include "../protocol/FcProtocol.h"
|
||||
#include "../protocol/PmProtocol.h"
|
||||
#include "../protocol/BatProtocol.h"
|
||||
#include "PowerCoordinator.h"
|
||||
|
||||
namespace ccu {
|
||||
|
||||
class SystemData;
|
||||
|
||||
//============================================================================
|
||||
// CoordFsm:pCCU 电源协调状态机骨架(TinyFSM,事件驱动)。
|
||||
//
|
||||
// 【当前状态:框架已参与编译,未接入运行流程(惰性)】
|
||||
// - 无任何代码调用 CoordFsm::start() / CoordFsm::dispatch(),
|
||||
// 运行行为与接入前完全一致;
|
||||
// - 各状态 react() 均为 TODO 空实现,由开发者填写协调策略。
|
||||
//
|
||||
// 【设计约定】
|
||||
// - 边沿事件走 dispatch:指令到达(PmControlEvent)、操作步骤完成(StepDoneEvent)、
|
||||
// 周期节拍(TickEvent);
|
||||
// - 电平状态不进事件:最新 FC/电池状态由状态机在 TickEvent 中直接读取
|
||||
// SystemData 快照,避免 1Hz 状态报文淹没事件队列;
|
||||
// - TinyFSM 非线程安全:dispatch 必须收敛到单线程(MOOS 主循环线程),
|
||||
// 链路接收线程产生的事件一律经 PowerCoordinator::pushEvent() 排队,
|
||||
// 由 tick() 在主线程统一 drain 后逐个 dispatch(见接线指南第 1 步)。
|
||||
//
|
||||
// 【接线指南:将来启用时按以下步骤操作】
|
||||
//
|
||||
// 1) PowerCoordinator 增加事件桥(core/PowerCoordinator.h/.cpp):
|
||||
// a. 新增成员:
|
||||
// std::function<void(double)> m_tickHook = nullptr; // 节拍转发
|
||||
// std::mutex m_evtMutex;
|
||||
// std::deque<std::function<void()>> m_events; // 事件队列(闭包)
|
||||
// 新增方法:
|
||||
// void setTickHook(std::function<void(double)> h) { m_tickHook = std::move(h); }
|
||||
// void pushEvent(std::function<void()> fn) { // 线程安全;带上限防积压
|
||||
// std::lock_guard<std::mutex> l(m_evtMutex);
|
||||
// if (m_events.size() >= 512) { m_events.pop_front(); /*LOG告警*/ }
|
||||
// m_events.push_back(std::move(fn));
|
||||
// }
|
||||
// b. tick() 末尾 drain(单线程执行闭包;coordinationTick 占位改为转发):
|
||||
// if (m_tickHook) m_tickHook(now);
|
||||
// std::deque<std::function<void()>> evs;
|
||||
// { std::lock_guard<std::mutex> l(m_evtMutex); evs.swap(m_events); }
|
||||
// for (auto& f : evs) f();
|
||||
// c. processSteps 步骤完成/超时处(pop_front 之前,仅接线后产生事件):
|
||||
// if (m_tickHook) {
|
||||
// BatOpStep info = s; // 拷贝步骤信息
|
||||
// BatStatusValue st = m_sys ? m_sys->batStatus(static_cast<int>(s.role))
|
||||
// : BatStatusValue();
|
||||
// bool ok = confirmed;
|
||||
// pushEvent([info, st, ok]() {
|
||||
// CoordFsm::dispatch(StepDoneEvent(info.role, info.type, ok, st));
|
||||
// });
|
||||
// }
|
||||
// (事件产生以 m_tickHook 非空为前提:未接线时零开销、零行为)
|
||||
//
|
||||
// 2) CCU::OnStartUp(m_coord->setup(...) 之后):
|
||||
// CoordFsm::init(m_coord, m_sysData);
|
||||
// CoordFsm::start();
|
||||
// m_coord->setTickHook([](double now) {
|
||||
// CoordFsm::dispatch(TickEvent(now));
|
||||
// });
|
||||
//
|
||||
// 3) CCU::handlePmMessage 的 0x0001 分支(decode 成功后):
|
||||
// m_coord->pushEvent([c]() { CoordFsm::dispatch(PmControlEvent(c)); });
|
||||
// (c 为已解析的 PmControlValue,按值捕获)
|
||||
//
|
||||
// 4) 验证:编译运行后日志出现 "[CoordFsm] 进入状态: CoordNormalState" 即接线成功。
|
||||
//
|
||||
// 【状态说明】
|
||||
// CoordNormalState 正常运行(初始状态):周期功率分配/阈值判断、响应主机指令
|
||||
// CoordSwitchingState 电池切换中:等待 StepDoneEvent 推进,完成后返回 Normal
|
||||
// CoordFaultState 故障处理:告警抑制/降级运行/恢复判断
|
||||
//============================================================================
|
||||
|
||||
//---- 事件定义(边沿触发) ------------------------------------------------
|
||||
|
||||
// 周期节拍:由 coordinationTick 转发(AppTick 频率,默认 4Hz)
|
||||
struct TickEvent : tinyfsm::Event {
|
||||
double now; // MOOSTime
|
||||
TickEvent() : now(0) {}
|
||||
explicit TickEvent(double t) : now(t) {}
|
||||
};
|
||||
|
||||
// 主机操控指令到达:PM 0x0001 每次成功解析触发一次
|
||||
struct PmControlEvent : tinyfsm::Event {
|
||||
PmControlValue cmd;
|
||||
PmControlEvent() {}
|
||||
explicit PmControlEvent(const PmControlValue& c) : cmd(c) {}
|
||||
};
|
||||
|
||||
// 电池操作步骤完成/超时:由协调器步骤引擎产生
|
||||
struct StepDoneEvent : tinyfsm::Event {
|
||||
BatRole role; // 目标电池
|
||||
BatOpType type; // 步骤类型
|
||||
bool confirmed; // true=状态反馈确认;false=超时未确认
|
||||
BatStatusValue status; // 完成时刻状态快照(含接触器状态/报警标识字,可判 0x33/0x44 等故障)
|
||||
StepDoneEvent()
|
||||
: role(BatRole::Dyn), type(BatOpType::ApplyControl), confirmed(false) {}
|
||||
StepDoneEvent(BatRole r, BatOpType t, bool ok, const BatStatusValue& s)
|
||||
: role(r), type(t), confirmed(ok), status(s) {}
|
||||
};
|
||||
|
||||
//---- 状态机 ---------------------------------------------------------------
|
||||
|
||||
class CoordFsm : public tinyfsm::Fsm<CoordFsm> {
|
||||
public:
|
||||
// 启用时注入上下文(见接线指南)
|
||||
static void init(PowerCoordinator* coord, SystemData* sys) {
|
||||
m_coord = coord;
|
||||
m_sys = sys;
|
||||
}
|
||||
static PowerCoordinator* coord() { return m_coord; }
|
||||
static SystemData* sys() { return m_sys; }
|
||||
|
||||
// 事件处理默认实现:状态类按需覆盖;未覆盖的事件静默忽略
|
||||
virtual void react(tinyfsm::Event const &) {}
|
||||
virtual void react(TickEvent const &) {}
|
||||
virtual void react(PmControlEvent const &) {}
|
||||
virtual void react(StepDoneEvent const &) {}
|
||||
|
||||
// 状态进入/退出钩子(状态类覆盖以打日志/做进出动作)
|
||||
virtual void entry() {}
|
||||
virtual void exit() {}
|
||||
|
||||
private:
|
||||
static PowerCoordinator* m_coord;
|
||||
static SystemData* m_sys;
|
||||
};
|
||||
|
||||
//---- 状态类 ---------------------------------------------------------------
|
||||
|
||||
// 正常运行(初始状态)
|
||||
class CoordNormalState : public CoordFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void exit() override;
|
||||
void react(TickEvent const &e) override;
|
||||
void react(PmControlEvent const &e) override;
|
||||
void react(StepDoneEvent const &e) override;
|
||||
};
|
||||
|
||||
// 电池切换中(提交 submitSwitchLowToHigh/HighToLow 后进入)
|
||||
class CoordSwitchingState : public CoordFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void exit() override;
|
||||
void react(TickEvent const &e) override;
|
||||
void react(StepDoneEvent const &e) override;
|
||||
};
|
||||
|
||||
// 故障处理
|
||||
class CoordFaultState : public CoordFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void exit() override;
|
||||
void react(TickEvent const &e) override;
|
||||
void react(StepDoneEvent const &e) override;
|
||||
};
|
||||
|
||||
} // namespace ccu
|
||||
|
||||
#endif // PCCU_COORD_FSM_HPP
|
||||
Reference in New Issue
Block a user