376 lines
12 KiB
C++
376 lines
12 KiB
C++
/************************************************************/
|
|
/* NAME: */
|
|
/* ORGN: MIT, Cambridge MA */
|
|
/* FILE: PowerManger.cpp */
|
|
/* DATE: December 29th, 1963 */
|
|
/************************************************************/
|
|
|
|
#include <iterator>
|
|
#include "MBUtils.h"
|
|
#include "ACTable.h"
|
|
#include "PowerManger.h"
|
|
#include "logc/loguru.hpp"
|
|
#include <memory>
|
|
|
|
using namespace std;
|
|
|
|
|
|
bool _FsmCB(void * pParam)
|
|
{
|
|
PowerManger* pMe = (PowerManger* )pParam;
|
|
return pMe->FsmLoop();
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Constructor()
|
|
|
|
PowerManger::PowerManger()
|
|
{
|
|
workCondition = 0;
|
|
currentMod = 0;
|
|
powerState = 0;
|
|
faultLevel = 0;
|
|
soc = 0;
|
|
sustainableTime = 0;
|
|
m_faultNum = 0;
|
|
m_ticker = 0;
|
|
m_leakage = 0;
|
|
faultCode.clear();
|
|
|
|
m_skew = 2;
|
|
|
|
m_pmCurrentState = {};
|
|
m_currentDisBreakerState = {};
|
|
m_targetDisBreakerState = {};
|
|
m_currentDriverState = {};
|
|
m_MSDriverCmd = {};
|
|
m_subDisSysCmd = {};
|
|
m_subDisSysState = {};
|
|
//初始化控制指令
|
|
initControlCmd();
|
|
|
|
//初始化下位机通信
|
|
m_lowerCommManager = new LowerCommManager(this,IPORT,CCUPORT,CCUHOST);
|
|
m_lowerCommManager->initUdpComm();
|
|
m_lowerCommManager->startListenThread();
|
|
|
|
//初始化上位机通信
|
|
m_upperCommManager = new UpperCommManager(this);
|
|
|
|
//初始化数据库
|
|
m_db = new SQLite("power_data.db");
|
|
m_db->createTable();
|
|
|
|
//初始化系统数据
|
|
m_systemData = new SystemData();
|
|
|
|
//初始化http服务器
|
|
m_httpServer = new HttpServer(8090);
|
|
m_httpServer->setPowerManger(this);
|
|
m_httpServer->setLowerCommManager(m_lowerCommManager);
|
|
m_httpServer->setSystemData(m_systemData);
|
|
m_httpServer->start();
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Destructor
|
|
|
|
PowerManger::~PowerManger()
|
|
{
|
|
delete m_db;
|
|
delete m_lowerCommManager;
|
|
delete m_upperCommManager;
|
|
delete m_systemData;
|
|
delete m_httpServer;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Procedure: OnNewMail()
|
|
|
|
bool PowerManger::OnNewMail(MOOSMSG_LIST &NewMail)
|
|
{
|
|
AppCastingMOOSApp::OnNewMail(NewMail);
|
|
|
|
MOOSMSG_LIST::iterator p;
|
|
for(p=NewMail.begin(); p!=NewMail.end(); p++)
|
|
{
|
|
CMOOSMsg &msg = *p;
|
|
string key = msg.GetKey();
|
|
string strJson = msg.GetString();
|
|
double dfT;
|
|
msg.IsSkewed(m_curr_time, &dfT);
|
|
if(fabs(dfT) > m_skew)
|
|
{
|
|
LOG_F(INFO, "Message from %s at time %f is Skewed", msg.GetSource().c_str(), dfT);
|
|
return true;
|
|
}
|
|
//处理上位机发送的控制指令
|
|
if(!m_upperCommManager->processUpperMsg(key,strJson))
|
|
{
|
|
LOG_F(ERROR, "上位机消息处理错误: %s", key.c_str());
|
|
}
|
|
|
|
#if 0 // Keep these around just for template
|
|
string comm = msg.GetCommunity();
|
|
double dval = msg.GetDouble();
|
|
string sval = msg.GetString();
|
|
string msrc = msg.GetSource();
|
|
double mtime = msg.GetTime();
|
|
bool mdbl = msg.IsDouble();
|
|
bool mstr = msg.IsString();
|
|
#endif
|
|
|
|
if(key == "FOO")
|
|
LOG_F(INFO, "Received FOO message");
|
|
|
|
else if(key != "APPCAST_REQ") // handled by AppCastingMOOSApp
|
|
reportRunWarning("Unhandled Mail: " + key);
|
|
}
|
|
|
|
return(true);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Procedure: OnConnectToServer()
|
|
|
|
bool PowerManger::OnConnectToServer()
|
|
{
|
|
registerVariables();
|
|
return(true);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Procedure: Iterate()
|
|
// happens AppTick times per second
|
|
//固定为4Hz
|
|
bool PowerManger::Iterate()
|
|
{
|
|
AppCastingMOOSApp::Iterate();
|
|
// 触发定时任务
|
|
CycleTriggeredEvent cycleEvent;
|
|
PowerManagerFsm::dispatch(cycleEvent);
|
|
faultLevel = getFaultLevel();
|
|
// 更新系统数据
|
|
// m_systemData->updateSystemData(m_pmCurrentState.ccustate);
|
|
// m_systemData->updateSystemData(m_pmCurrentState.bus1State);
|
|
// m_systemData->updateSystemData(m_pmCurrentState.bus2State);
|
|
// m_systemData->updateSystemData(m_pmCurrentState.bus3State);
|
|
// m_systemData->updateSystemData(m_pmCurrentState.bus4State);
|
|
// m_systemData->device_common_status.ccu_status.lastUpdateTime = m_lowerCommManager->msg_CcuStateFbMsg_Update_time;
|
|
// m_systemData->device_common_status.dis_hv_c1.lastUpdateTime = m_lowerCommManager->msg_disHighVolBusFbMsg_Update_time;
|
|
// m_systemData->device_common_status.dis_hv_c2.lastUpdateTime = m_lowerCommManager->msg_disHighAVolBusFbMsg_Update_time;
|
|
// m_systemData->device_common_status.dis_lv_c1.lastUpdateTime = m_lowerCommManager->msg_disHighBVolBusFbMsg_Update_time;
|
|
// m_systemData->device_common_status.dis_lv_c2.lastUpdateTime = m_lowerCommManager->msg_disLowBusFbMsg_Update_time;
|
|
m_systemData->updateCommonStatus();
|
|
// m_CcuColCmd.heartbeat
|
|
if (m_ticker++ % 5 == 0)
|
|
{
|
|
m_CcuColCmd.heartbeat++;
|
|
m_lowerCommManager->processPeriodicTasks();
|
|
m_upperCommManager->processPeriodicTasks();
|
|
}
|
|
return(true);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Procedure: OnStartUp()
|
|
// happens before connection is open
|
|
|
|
bool PowerManger::OnStartUp()
|
|
{
|
|
AppCastingMOOSApp::OnStartUp();
|
|
|
|
STRING_LIST sParams;
|
|
m_MissionReader.EnableVerbatimQuoting(false);
|
|
if(!m_MissionReader.GetConfiguration(GetAppName(), sParams))
|
|
reportConfigWarning("No config block found for " + GetAppName());
|
|
|
|
STRING_LIST::iterator p;
|
|
for(p=sParams.begin(); p!=sParams.end(); p++) {
|
|
string orig = *p;
|
|
string line = *p;
|
|
string param = tolower(biteStringX(line, '='));
|
|
string value = line;
|
|
|
|
bool handled = false;
|
|
if(param == "foo") {
|
|
handled = true;
|
|
}
|
|
else if(param == "bar") {
|
|
handled = true;
|
|
}
|
|
|
|
if(!handled)
|
|
reportUnhandledConfigWarning(orig);
|
|
|
|
}
|
|
|
|
registerVariables();
|
|
|
|
// 初始化状态机
|
|
PowerManagerFsm::init(this);
|
|
PowerManagerFsm::start();
|
|
InitEvent initEvent;
|
|
PowerManagerFsm::dispatch(initEvent);
|
|
return(true);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Procedure: registerVariables()
|
|
|
|
void PowerManger::registerVariables()
|
|
{
|
|
AppCastingMOOSApp::RegisterVariables();
|
|
// Register(DB_TO_PM_SUBDISSTATE, 0);
|
|
|
|
Register(DB_TO_PM_MSCMD, 0);
|
|
Register(DB_TO_PM_EQUIPMENTCMD, 0);
|
|
Register(m_upperCommManager->m_secdistStateMsg.key_fb,0);
|
|
Register(DB_TO_PM_MISSION,0);
|
|
Register(DB_TO_PM_DEEPTH,0);
|
|
Register(DB_TO_PM_SETOPCONDITION,0);
|
|
Register(DB_TO_PM_SETOPMODE,0);
|
|
Register(DB_TO_PM_SETPMSYS,0);
|
|
Register(DB_TO_PM_SETDEVSWITCH,0);
|
|
Register(DB_TO_PM_TASKSTOP,0);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------
|
|
// Procedure: buildReport()
|
|
|
|
bool PowerManger::buildReport()
|
|
{
|
|
m_msgs << "============================================" << endl;
|
|
m_msgs << "File: " << endl;
|
|
m_msgs << "============================================" << endl;
|
|
|
|
ACTable actab(4);
|
|
actab << "Alpha | Bravo | Charlie | Delta";
|
|
actab.addHeaderLines();
|
|
actab << "one" << "two" << "three" << "four";
|
|
m_msgs << actab.getFormattedString();
|
|
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
bool PowerManger::FsmLoop()
|
|
{
|
|
//状态机循环
|
|
// while (!m_FsmThread.IsQuitRequested())
|
|
// {
|
|
// // // 检查故障并触发事件
|
|
// // if(int error = checkError()) {
|
|
// // m_fsm.triggerFaultEvent(error);
|
|
// // } else {
|
|
// // // 自动状态转换由状态机内部处理
|
|
// // MOOSPause(1000);
|
|
// // }
|
|
|
|
// //延时1s
|
|
// usleep(1000000);
|
|
// }
|
|
return true;
|
|
}
|
|
|
|
int PowerManger::checkError()
|
|
{
|
|
//TODO:更新协议
|
|
//1.检查复合管控器状态
|
|
// if(m_pmCurrentState.ccustate.fcuGZ_1H != 0 ||
|
|
// m_pmCurrentState.ccustate.fcuGZ_1L != 0 ||
|
|
// m_pmCurrentState.ccustate.fcuGZ_2H != 0 ||
|
|
// m_pmCurrentState.ccustate.fcuGZ_2L != 0 ||
|
|
// m_pmCurrentState.ccustate.fcuGZ_3H != 0 ||
|
|
// m_pmCurrentState.ccustate.fcuGZ_3L != 0 ||
|
|
// m_pmCurrentState.ccustate.insEmergencyStatusWord != 0)
|
|
return 0;
|
|
//2.检查断路器状态
|
|
}
|
|
|
|
void PowerManger::printState(const std::string& stateName, const std::string& desp){
|
|
if (desp.find("故障") != string::npos) {
|
|
LOG_F(ERROR, "STATE %s -> %s", stateName.c_str(), desp.c_str());
|
|
} else {
|
|
LOG_F(INFO, "STATE %s -> %s", stateName.c_str(), desp.c_str());
|
|
}
|
|
}
|
|
|
|
|
|
void PowerManger::initControlCmd()
|
|
{
|
|
//================初始化配电指令=============================
|
|
m_targetDisBreakerState.bus1Breaker.fuelCellCircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus1Breaker.powerLithiumBatteryCircuitBreaker = 1; //动力锂电池默认接入
|
|
m_targetDisBreakerState.bus1Breaker.propulsionMotorCircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus1Breaker.lithiumBatteryGroupInstrumentCircuitBreaker = 1; //仪表锂电池默认接入
|
|
m_targetDisBreakerState.bus1Breaker.dcDc5ModuleCircuitBreaker = 1; //DC-DC模块默认接入
|
|
m_targetDisBreakerState.bus1Breaker.bowHighVoltageDistributionBoxCircuitBreaker = 1; //艏部高压母线断路器默认接入
|
|
m_targetDisBreakerState.bus1Breaker.sternFTDevice45CircuitBreaker = 0; // sternFTDevice45CircuitBreaker默认接入
|
|
m_targetDisBreakerState.bus1Breaker.sternRudderSwitch1CircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus1Breaker.sternRudderSwitch2CircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus1Breaker.fbReservedCircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus1Breaker.tyzReservedCircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus1Breaker.reservedCircuitBreaker = 0;
|
|
|
|
m_targetDisBreakerState.bus2Breaker.bowFTDevice123CircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus2Breaker.actuatorCircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus2Breaker.mastSteeringGearControlBoxCircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus2Breaker.xczCircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus2Breaker.bowRudderControlBoxCircuitBreaker = 0;
|
|
m_targetDisBreakerState.bus2Breaker.openWaterCoverStartCylinderCircuitBreaker = 0;
|
|
//锂电池默认接入
|
|
m_targetDisBreakerState.bus3Breaker.lithiumBatteryGroupInstrumentCircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus3Breaker.bowLowVoltageDistributionBoxCircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus3Breaker.unit4InstrumentDC48VCircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus3Breaker.dcC1DCDistributionPanelCircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus3Breaker.reservedCircuitBreaker1 = 0;
|
|
m_targetDisBreakerState.bus3Breaker.reservedCircuitBreaker2 = 0;
|
|
m_targetDisBreakerState.bus3Breaker.emergencyLithiumBatteryGroup2CircuitBreaker = 1;
|
|
|
|
m_targetDisBreakerState.bus4Breaker.unit1CircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus4Breaker.unit2CircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus4Breaker.unit3CircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus4Breaker.unit5CircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus4Breaker.bowPZDeviceCircuitBreaker = 1;
|
|
m_targetDisBreakerState.bus4Breaker.reservedCircuitBreaker1 = 0;
|
|
m_targetDisBreakerState.bus4Breaker.reservedCircuitBreaker2 = 0;
|
|
m_targetDisBreakerState.bus4Breaker.emergencyLithiumBatteryGroup1CircuitBreaker = 1; //紧急锂电池默认接入
|
|
//================初始化复合管控=============================
|
|
m_CcuColCmd.fcmode = 0x00; //默认无效
|
|
m_CcuColCmd.fcuCmd = 0x00; //无效指令
|
|
m_CcuColCmd.fcuPowerEfficiency = 15; //默认为15kw
|
|
m_CcuColCmd.insChargeEnable = 0x30; //不允许充电
|
|
m_CcuColCmd.insBatCmd = 0x00; //无效指令
|
|
m_CcuColCmd.powerBatCmd = 0x00; //无效指令
|
|
m_CcuColCmd.powerBatEfficiency = 230; //默认为最大
|
|
m_CcuColCmd.heartbeat = 0;
|
|
m_CcuColCmd.masterState = 0xAA;//主站状态,运行中
|
|
//================初始化上位机指令=========================
|
|
m_msCmd.modCMD = 99;
|
|
m_msCmd.powerCMD = 99;
|
|
m_msCmd.workCMD = 99;
|
|
//================初始化设备驱动指令========================
|
|
|
|
}
|
|
|
|
unsigned char PowerManger::getFaultLevel()
|
|
{
|
|
unsigned char maxLevel = 0;
|
|
for (auto code : faultCode) {
|
|
// 提取0xabcd中的b位 (右移8位后取低4位)
|
|
unsigned char level = (code >> 8) & 0xF;
|
|
if (level > maxLevel) {
|
|
maxLevel = level;
|
|
}
|
|
}
|
|
return maxLevel;
|
|
}
|
|
|
|
void PowerManger::injectFault(unsigned type,unsigned int faultCode){
|
|
LOG_F(INFO, "注入故障: %d %d", type, faultCode);
|
|
TestEvent testEvent("故障注入测试",type,faultCode);
|
|
PowerManagerFsm::dispatch(testEvent);
|
|
} |