为数据库插入增加保护
This commit is contained in:
Vendored
+2
-1
@@ -94,5 +94,6 @@
|
||||
"marscode.codeCompletionPro": {
|
||||
"enableCodeCompletionPro": true
|
||||
},
|
||||
"marscode.enableInlineCommand": true
|
||||
"marscode.enableInlineCommand": true,
|
||||
"idf.pythonInstallPath": "/usr/bin/python"
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
# DESCRIPTION: CMakeLists.txt file for the moos-ivp-extend source directory
|
||||
##############################################################################
|
||||
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -g -O1")
|
||||
|
||||
#============================================================================
|
||||
# Add the libraries in the current directory to the include path
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
#--------------------------------------------------------
|
||||
# The CMakeLists.txt for: pPowerManger
|
||||
# Author(s):
|
||||
#--------------------------------------------------------
|
||||
|
||||
# Set System Specific Libraries
|
||||
if (${WIN32})
|
||||
# Windows Libraries
|
||||
SET(SYSTEM_LIBS
|
||||
wsock32 )
|
||||
else (${WIN32})
|
||||
# Linux and Apple Libraries
|
||||
SET(SYSTEM_LIBS
|
||||
m
|
||||
pthread )
|
||||
endif (${WIN32})
|
||||
|
||||
# Use local SQLite3 source
|
||||
SET(SQLITE_SRC
|
||||
sqlit3/SQLite.cpp
|
||||
sqlit3/sqlite3.c
|
||||
)
|
||||
|
||||
SET(HTTP_SRC
|
||||
httpserver/mongoose.c
|
||||
httpserver/httpserver.cpp)
|
||||
|
||||
SET(LOG_SRC
|
||||
logc/loguru.cpp)
|
||||
|
||||
SET(UDP_COMM_SRC
|
||||
udpcomm/udpComm.cpp)
|
||||
|
||||
SET(FSMLIB_SRC
|
||||
fsm/PowerManagerFsm.cpp
|
||||
fsm/CruiseMode.cpp
|
||||
fsm/DJMode.cpp
|
||||
fsm/FaultState.cpp
|
||||
fsm/FloatAdjust.cpp
|
||||
fsm/FloatDown.cpp
|
||||
fsm/HighSpeedMode.cpp
|
||||
fsm/InitState.cpp
|
||||
fsm/RemoteControl.cpp
|
||||
fsm/ShoreBasedReady.cpp
|
||||
fsm/StandbyState.cpp
|
||||
fsm/SurfaceSurvey.cpp
|
||||
fsm/UnderwaterSurvey.cpp
|
||||
fsm/WaterBasedReady.cpp
|
||||
)
|
||||
|
||||
SET(SRC
|
||||
${FSMLIB_SRC}
|
||||
${SQLITE_SRC}
|
||||
${HTTP_SRC}
|
||||
${UDP_COMM_SRC}
|
||||
${LOG_SRC}
|
||||
PowerManger.cpp
|
||||
PowerManger_Info.cpp
|
||||
# udpComm.cpp
|
||||
main.cpp
|
||||
# SQLiteDB.cpp
|
||||
driver.cpp
|
||||
LowerCommManager.cpp
|
||||
UpperCommManager.cpp
|
||||
# loguru.cpp
|
||||
upmsg/upmsg_definitions.cpp
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(pPowerManger ${SRC})
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(pPowerManger PRIVATE sqlit3)
|
||||
|
||||
TARGET_LINK_LIBRARIES(pPowerManger
|
||||
${MOOS_LIBRARIES}
|
||||
apputil
|
||||
mbutil
|
||||
m
|
||||
pthread
|
||||
jsoncpp
|
||||
${SYSTEM_LIBS}
|
||||
dl
|
||||
)
|
||||
|
||||
# Add SQLiteDB static library
|
||||
SET(UDPCOMM_SRC
|
||||
udpComm.cpp
|
||||
)
|
||||
|
||||
# SET(SQLITEDB_SRC
|
||||
# SQLiteDB.cpp
|
||||
# )
|
||||
|
||||
SET(DRIVER_SRC
|
||||
driver.cpp)
|
||||
|
||||
# SET(POWERMANGE_SRC
|
||||
# PowerManger.cpp
|
||||
# PowerManger_Info.cpp
|
||||
# udpComm.cpp
|
||||
# SQLiteDB.cpp
|
||||
# driver.cpp
|
||||
# PowerManagerFsm.cpp)
|
||||
|
||||
# ADD_LIBRARY(SQLiteDB STATIC ${SQLITEDB_SRC})
|
||||
# ADD_LIBRARY(UDPComm STATIC ${UDPCOMM_SRC})
|
||||
# # ADD_LIBRARY(FSMLib STATIC ${FSMLIB_SRC})
|
||||
# ADD_LIBRARY(Driver STATIC ${DRIVER_SRC})
|
||||
# ADD_LIBRARY(PowerMange STATIC ${POWERMANGE_SRC})
|
||||
@@ -0,0 +1,929 @@
|
||||
#include "LowerCommManager.h"
|
||||
#include "PowerManger.h"
|
||||
#include "driver.h"
|
||||
#include "udpcomm/udpComm.h"
|
||||
|
||||
bool _ListenCB(void * pParam)
|
||||
{
|
||||
LowerCommManager* pMe = (LowerCommManager* )pParam;
|
||||
return pMe->listenThreadFunc();
|
||||
}
|
||||
|
||||
LowerCommManager::LowerCommManager(PowerManger* pm, long myPort, long ccuPort, const std::string& cccHost){
|
||||
m_pm = pm;
|
||||
m_udpComm = new udpComm();
|
||||
m_port = myPort;
|
||||
m_udpComm->ccuHost = cccHost;
|
||||
m_udpComm->ccuPort = ccuPort;
|
||||
m_udpComm->udpScoket = new XPCUdpSocket(m_port);
|
||||
|
||||
std::cout << MOOS::ConsoleColours::yellow() << "╔════════════════════════╗" << MOOS::ConsoleColours::reset() << std::endl;
|
||||
std::cout << MOOS::ConsoleColours::yellow() << "║ [LOCAL PORT] "
|
||||
<< MOOS::ConsoleColours::cyan() << m_port
|
||||
<< MOOS::ConsoleColours::yellow() << std::setw(15) << " ║" << MOOS::ConsoleColours::reset() << std::endl;
|
||||
|
||||
std::cout << MOOS::ConsoleColours::yellow() << "║ [CCU HOST ] "
|
||||
<< MOOS::ConsoleColours::cyan() << m_udpComm->ccuHost
|
||||
<< MOOS::ConsoleColours::yellow() << std::setw(8) << " ║" << MOOS::ConsoleColours::reset() << std::endl;
|
||||
|
||||
std::cout << MOOS::ConsoleColours::yellow() << "║ [CCU PORT ] "
|
||||
<< MOOS::ConsoleColours::cyan() << m_udpComm->ccuPort
|
||||
<< MOOS::ConsoleColours::yellow() << std::setw(15) << " ║" << MOOS::ConsoleColours::reset() << std::endl;
|
||||
std::cout << MOOS::ConsoleColours::yellow() << "╚════════════════════════╝" << MOOS::ConsoleColours::reset() << std::endl;
|
||||
}
|
||||
|
||||
LowerCommManager::~LowerCommManager(){
|
||||
try {
|
||||
stopListenThread();
|
||||
if (m_udpComm) {
|
||||
delete m_udpComm;
|
||||
m_udpComm = nullptr;
|
||||
}
|
||||
} catch (...) {
|
||||
cerr << "Error during cleanup" << endl;
|
||||
}
|
||||
}
|
||||
bool LowerCommManager::initUdpComm(){
|
||||
if (m_udpComm->udpScoket) {
|
||||
try {
|
||||
std::cout << MOOS::ConsoleColours::yellow() << "Attempting to bind UDP socket..." << MOOS::ConsoleColours::reset() << std::endl;
|
||||
m_udpComm->udpScoket->vBindSocket(); // 可能会抛出 XPCException 或其他 std::exception
|
||||
std::cout << MOOS::ConsoleColours::green() << "UDP bind succeeded!" << MOOS::ConsoleColours::reset() << std::endl;
|
||||
LOG_F(INFO, "UDP bind succeeded!");
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << MOOS::ConsoleColours::red()
|
||||
<< "[UDP Bind Failed] Exception: " << e.what()
|
||||
<< MOOS::ConsoleColours::reset() << std::endl;
|
||||
LOG_F(ERROR, "UDP bind failed: %s", e.what());
|
||||
return false;
|
||||
}
|
||||
catch (...) {
|
||||
std::cerr << MOOS::ConsoleColours::red()
|
||||
<< "[UDP Bind Failed] Unknown exception occurred!"
|
||||
<< MOOS::ConsoleColours::reset() << std::endl;
|
||||
LOG_F(ERROR, "Unknown exception occurred during UDP bind");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
std::cerr << MOOS::ConsoleColours::red()
|
||||
<< "[UDP Init Failed] udpSocket is null!"
|
||||
<< MOOS::ConsoleColours::reset() << std::endl;
|
||||
LOG_F(ERROR, "udpSocket is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void LowerCommManager::processPeriodicTasks() {
|
||||
sendCcuCommand(m_pm->m_CcuColCmd);
|
||||
m_pm->m_db->insertData(m_pm->m_CcuColCmd);
|
||||
//延时5ms
|
||||
usleep(5000);
|
||||
if(m_pm->m_systemData->device_common_status.dis_hv_c1.isTimeout )
|
||||
{
|
||||
disHighVolBusCmd clr1{};
|
||||
m_udpComm->sendDisSysCmd(clr1);
|
||||
MOOSPause(200);
|
||||
}
|
||||
if(m_pm->m_systemData->device_common_status.dis_lv_c1.isTimeout )
|
||||
{
|
||||
disHighBVolBusCmd clr3{};
|
||||
m_udpComm->sendDisSysCmd(clr3);
|
||||
MOOSPause(200);
|
||||
}
|
||||
m_udpComm->clearMsgQueue();
|
||||
}
|
||||
void LowerCommManager::operate_hold()
|
||||
{
|
||||
disHighVolBusCmd clr1{};
|
||||
disHighAVolBusCmd clr2{};
|
||||
disHighBVolBusCmd clr3{};
|
||||
disLowBusCmd clr4{};
|
||||
m_udpComm->sendDisSysCmd(clr1);
|
||||
MOOSPause(200);
|
||||
m_udpComm->sendDisSysCmd(clr2);
|
||||
MOOSPause(200);
|
||||
m_udpComm->sendDisSysCmd(clr3);
|
||||
MOOSPause(200);
|
||||
m_udpComm->sendDisSysCmd(clr4);
|
||||
}
|
||||
bool LowerCommManager::sendCcuCommand(const ccuColCmd cmd){
|
||||
// m_pm->m_db->insertCcuSysCmd(cmd);
|
||||
if(!m_udpComm->sendCcuColCmd(cmd))
|
||||
cout << "send ccu command failed!" << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerCommManager::sendDisSysCommand(const disSysBreakerList& cmd){
|
||||
//根据目标状态进行断路器操作
|
||||
//a. 高压母线的断路器
|
||||
disHighVolBusCmd a;
|
||||
a.fuelCellCircuitBreaker = getBreakerOption(cmd.bus1Breaker.fuelCellCircuitBreaker);
|
||||
a.lithiumBatteryGroupInstrumentCircuitBreaker = getBreakerOption(cmd.bus1Breaker.lithiumBatteryGroupInstrumentCircuitBreaker);
|
||||
a.dcDc5ModuleCircuitBreaker = getBreakerOption(cmd.bus1Breaker.dcDc5ModuleCircuitBreaker);
|
||||
a.powerLithiumBatteryCircuitBreaker = getBreakerOption(cmd.bus1Breaker.powerLithiumBatteryCircuitBreaker);
|
||||
a.propulsionMotorCircuitBreaker = getBreakerOption(cmd.bus1Breaker.propulsionMotorCircuitBreaker);
|
||||
a.bowHighVoltageDistributionBoxCircuitBreaker = getBreakerOption(cmd.bus1Breaker.bowHighVoltageDistributionBoxCircuitBreaker);
|
||||
a.tyzReservedCircuitBreaker = getBreakerOption(cmd.bus1Breaker.tyzReservedCircuitBreaker);
|
||||
a.sternFTDevice45CircuitBreaker = getBreakerOption(cmd.bus1Breaker.sternFTDevice45CircuitBreaker);
|
||||
a.sternRudderSwitch1CircuitBreaker = getBreakerOption(cmd.bus1Breaker.sternRudderSwitch1CircuitBreaker);
|
||||
a.sternRudderSwitch2CircuitBreaker = getBreakerOption(cmd.bus1Breaker.sternRudderSwitch2CircuitBreaker);
|
||||
a.reservedCircuitBreaker = getBreakerOption(cmd.bus1Breaker.reservedCircuitBreaker);
|
||||
a.fbReservedCircuitBreaker = getBreakerOption(cmd.bus1Breaker.fbReservedCircuitBreaker);
|
||||
a.dcdc5Module = getBreakerOption(cmd.bus1Breaker.dcdcmodel);
|
||||
a.coolingSystem = getBreakerOption(cmd.bus1Breaker.coolingSystem);
|
||||
|
||||
m_udpComm->sendDisSysCmd(a);
|
||||
m_pm->m_db->insertData(a);
|
||||
usleep(5000);
|
||||
//b. 高压汇流排A断路器
|
||||
disHighAVolBusCmd b;
|
||||
b.bowFTDevice123CircuitBreaker = getBreakerOption(cmd.bus2Breaker.bowFTDevice123CircuitBreaker);
|
||||
b.actuatorCircuitBreaker = getBreakerOption(cmd.bus2Breaker.actuatorCircuitBreaker);
|
||||
b.mastSteeringGearControlBoxCircuitBreaker = getBreakerOption(cmd.bus2Breaker.mastSteeringGearControlBoxCircuitBreaker);
|
||||
b.xczCircuitBreaker = getBreakerOption(cmd.bus2Breaker.xczCircuitBreaker);
|
||||
b.bowRudderControlBoxCircuitBreaker = getBreakerOption(cmd.bus2Breaker.bowRudderControlBoxCircuitBreaker);
|
||||
b.openWaterCoverStartCylinderCircuitBreaker = getBreakerOption(cmd.bus2Breaker.openWaterCoverStartCylinderCircuitBreaker);
|
||||
m_udpComm->sendDisSysCmd(b);
|
||||
m_pm->m_db->insertData(b);
|
||||
usleep(5000);
|
||||
//c. 低压主母线断路器
|
||||
disHighBVolBusCmd c;
|
||||
|
||||
c.lithiumBatteryGroupInstrumentCircuitBreaker = 0x55;
|
||||
c.bowLowVoltageDistributionBoxCircuitBreaker = 0xAA;
|
||||
c.unit4InstrumentDC48VCircuitBreaker = 0xAA;
|
||||
c.dcC1DCDistributionPanelCircuitBreaker = 0xAA;
|
||||
c.reservedCircuitBreaker1 = 0xAA;
|
||||
c.reservedCircuitBreaker2 = 0xAA;
|
||||
c.emergencyLithiumBatteryGroup2CircuitBreaker = 0xAA;
|
||||
|
||||
m_udpComm->sendDisSysCmd(c);
|
||||
m_pm->m_db->insertData(c);
|
||||
usleep(5000);
|
||||
//d. 闭合低压汇流排断路器
|
||||
disLowBusCmd d;
|
||||
d.unit1CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit1CircuitBreaker);
|
||||
d.unit2CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit2CircuitBreaker);
|
||||
d.unit3CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit3CircuitBreaker);
|
||||
d.unit5CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit5CircuitBreaker);
|
||||
d.bowPZDeviceCircuitBreaker = getBreakerOption(cmd.bus4Breaker.bowPZDeviceCircuitBreaker);
|
||||
d.reservedCircuitBreaker1 = getBreakerOption(cmd.bus4Breaker.reservedCircuitBreaker1);
|
||||
d.reservedCircuitBreaker2 = getBreakerOption(cmd.bus4Breaker.reservedCircuitBreaker2);
|
||||
d.emergencyLithiumBatteryGroup1CircuitBreaker = getBreakerOption(cmd.bus4Breaker.emergencyLithiumBatteryGroup1CircuitBreaker);
|
||||
m_udpComm->sendDisSysCmd(d);
|
||||
m_pm->m_db->insertData(d);
|
||||
usleep(5000);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LowerCommManager::clearMsgQueue(){
|
||||
m_udpComm->clearMsgQueue();
|
||||
}
|
||||
|
||||
|
||||
bool LowerCommManager::updatePoweSystemStates(){
|
||||
// std::cout << "updatePoweSystemStates" << std::endl;
|
||||
if(!m_udpComm->m_qReceiveCcuStateBuffer.empty())
|
||||
{
|
||||
double time;
|
||||
m_udpComm->popMsgFormQueue(time,m_CcuCurrentState);
|
||||
m_pm->m_pmCurrentState.ccustate = m_CcuCurrentState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.ccustate); //写入数据库
|
||||
//DEBUG
|
||||
//写入文件
|
||||
// std::ofstream outFile("ccuState.txt", std::ios::app);
|
||||
// coutMsg(m_CcuCurrentState, outFile);
|
||||
// coutMsg(m_CcuCurrentState,std::cout);
|
||||
msg_CcuStateFbMsg_Update_time = time;
|
||||
}
|
||||
if(!m_udpComm->m_qReceiveDisHighVolBusBuffer.empty())
|
||||
{
|
||||
double time;
|
||||
m_udpComm->popMsgFormQueue(time,m_disHighVolBusCurrentState);
|
||||
m_pm->m_pmCurrentState.bus1State = m_disHighVolBusCurrentState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus1State); //写入数据库
|
||||
msg_disHighVolBusFbMsg_Update_time = time;
|
||||
|
||||
disBus1Breaker* pdis1=new disBus1Breaker;
|
||||
(m_pm->m_pmCurrentState.bus1State.fuelCellCircuitBreaker == BREAK_ON) ? pdis1 -> fuelCellCircuitBreaker = 1 : pdis1 -> fuelCellCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.powerLithiumBatteryCircuitBreaker == BREAK_ON) ? pdis1 -> powerLithiumBatteryCircuitBreaker = 1 : pdis1 -> powerLithiumBatteryCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.propulsionMotorCircuitBreaker == BREAK_ON) ? pdis1 -> propulsionMotorCircuitBreaker = 1 : pdis1 -> propulsionMotorCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.lithiumBatteryGroupInstrumentCircuitBreaker == BREAK_ON) ? pdis1 -> lithiumBatteryGroupInstrumentCircuitBreaker = 1 : pdis1 -> lithiumBatteryGroupInstrumentCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.dcDc5ModuleCircuitBreaker == BREAK_ON) ? pdis1 -> dcDc5ModuleCircuitBreaker = 1 : pdis1 -> dcDc5ModuleCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.bowHighVoltageDistributionBoxCircuitBreaker == BREAK_ON) ? pdis1 -> bowHighVoltageDistributionBoxCircuitBreaker = 1 : pdis1 -> bowHighVoltageDistributionBoxCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.sternFTDevice45CircuitBreaker == BREAK_ON) ? pdis1 -> sternFTDevice45CircuitBreaker = 1 : pdis1 -> sternFTDevice45CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.sternRudderSwitch1CircuitBreaker == BREAK_ON) ? pdis1 -> sternRudderSwitch1CircuitBreaker = 1 : pdis1 -> sternRudderSwitch1CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.sternRudderSwitch2CircuitBreaker == BREAK_ON) ? pdis1 -> sternRudderSwitch2CircuitBreaker = 1 : pdis1 -> sternRudderSwitch2CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.fbReservedCircuitBreaker == BREAK_ON) ? pdis1 -> fbReservedCircuitBreaker = 1 : pdis1 -> fbReservedCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.tyzReservedCircuitBreaker == BREAK_ON) ? pdis1 -> tyzReservedCircuitBreaker = 1 : pdis1 -> tyzReservedCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.reservedCircuitBreaker == BREAK_ON) ? pdis1 -> reservedCircuitBreaker = 1 : pdis1 -> reservedCircuitBreaker = 0;
|
||||
pdis1 -> paceholder = 0;
|
||||
m_pm->m_currentDisBreakerState.bus1Breaker = *pdis1;
|
||||
delete pdis1;
|
||||
}
|
||||
if(!m_udpComm->m_qReceiveDisHighAVolBusBuffer.empty())
|
||||
{
|
||||
double time;
|
||||
m_udpComm->popMsgFormQueue(time,m_disHighAVolBusCurrentState);
|
||||
m_pm->m_pmCurrentState.bus2State = m_disHighAVolBusCurrentState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus2State); //写入数据库
|
||||
msg_disHighAVolBusFbMsg_Update_time = time;
|
||||
|
||||
disBus2Breaker* pdis2=new disBus2Breaker;
|
||||
(m_pm->m_pmCurrentState.bus2State.bowFTDevice123CircuitBreaker == BREAK_ON)? pdis2 -> bowFTDevice123CircuitBreaker = 1 : pdis2 -> bowFTDevice123CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.actuatorCircuitBreaker == BREAK_ON)? pdis2 -> actuatorCircuitBreaker = 1 : pdis2 -> actuatorCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.mastSteeringGearControlBoxCircuitBreaker == BREAK_ON)? pdis2 -> mastSteeringGearControlBoxCircuitBreaker = 1 : pdis2 -> mastSteeringGearControlBoxCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.xczCircuitBreaker == BREAK_ON)? pdis2 -> xczCircuitBreaker = 1 : pdis2 -> xczCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.bowRudderControlBoxCircuitBreaker == BREAK_ON)? pdis2 -> bowRudderControlBoxCircuitBreaker = 1 : pdis2 -> bowRudderControlBoxCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.openWaterCoverStartCylinderCircuitBreaker == BREAK_ON)? pdis2 -> openWaterCoverStartCylinderCircuitBreaker = 1 : pdis2 -> openWaterCoverStartCylinderCircuitBreaker = 0;
|
||||
pdis2 -> paceholder = 0;
|
||||
m_pm->m_currentDisBreakerState.bus2Breaker = *pdis2;
|
||||
delete pdis2;
|
||||
}
|
||||
if(!m_udpComm->m_qReceiveDisHighBVolBusBuffer.empty())
|
||||
{
|
||||
double time;
|
||||
m_udpComm->popMsgFormQueue(time,m_disHighBVolBusCurrentState);
|
||||
m_pm->m_pmCurrentState.bus3State = m_disHighBVolBusCurrentState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus3State); //写入数据库
|
||||
msg_disHighBVolBusFbMsg_Update_time = time;
|
||||
|
||||
disBus3Breaker* pdis3=new disBus3Breaker;
|
||||
(m_pm->m_pmCurrentState.bus3State.lithiumBatteryGroupInstrumentCircuitBreaker == BREAK_ON)? pdis3 -> lithiumBatteryGroupInstrumentCircuitBreaker = 1 : pdis3 -> lithiumBatteryGroupInstrumentCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.bowLowVoltageDistributionBoxCircuitBreaker == BREAK_ON)? pdis3 -> bowLowVoltageDistributionBoxCircuitBreaker = 1 : pdis3 -> bowLowVoltageDistributionBoxCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.unit4InstrumentDC48VCircuitBreaker == BREAK_ON)? pdis3 -> unit4InstrumentDC48VCircuitBreaker = 1 : pdis3 -> unit4InstrumentDC48VCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.dcC1DCDistributionPanelCircuitBreaker == BREAK_ON)? pdis3 -> dcC1DCDistributionPanelCircuitBreaker = 1 : pdis3 -> dcC1DCDistributionPanelCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.reservedCircuitBreaker1 == BREAK_ON)? pdis3 -> reservedCircuitBreaker1 = 1 : pdis3 -> reservedCircuitBreaker1 = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.reservedCircuitBreaker2 == BREAK_ON)? pdis3 -> reservedCircuitBreaker2 = 1 : pdis3 -> reservedCircuitBreaker2 = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.emergencyLithiumBatteryGroup2CircuitBreaker == BREAK_ON)? pdis3 -> emergencyLithiumBatteryGroup2CircuitBreaker = 1 : pdis3 -> emergencyLithiumBatteryGroup2CircuitBreaker = 0;
|
||||
pdis3->paceholder = 0;
|
||||
m_pm->m_currentDisBreakerState.bus3Breaker = *pdis3;
|
||||
delete pdis3;
|
||||
}
|
||||
if(!m_udpComm->m_qReceiveDisLowBusBuffer.empty())
|
||||
{
|
||||
double time;
|
||||
m_udpComm->popMsgFormQueue(time,m_disLowBusState);
|
||||
m_pm->m_pmCurrentState.bus4State = m_disLowBusState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus4State); //写入数据库
|
||||
msg_disLowBusFbMsg_Update_time = time;
|
||||
|
||||
disBus4Breaker* pdis4=new disBus4Breaker;
|
||||
(m_pm->m_pmCurrentState.bus4State.unit1CircuitBreaker == BREAK_ON)? pdis4 -> unit1CircuitBreaker = 1 : pdis4 -> unit1CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.unit2CircuitBreaker == BREAK_ON)? pdis4 -> unit2CircuitBreaker = 1 : pdis4 -> unit2CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.unit3CircuitBreaker == BREAK_ON)? pdis4 -> unit3CircuitBreaker = 1 : pdis4 -> unit3CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.unit5CircuitBreaker == BREAK_ON)? pdis4 -> unit5CircuitBreaker = 1 : pdis4 -> unit5CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.bowPZDeviceCircuitBreaker == BREAK_ON)? pdis4 -> bowPZDeviceCircuitBreaker = 1 : pdis4 -> bowPZDeviceCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.reservedCircuitBreaker1 == BREAK_ON)? pdis4 -> reservedCircuitBreaker1 = 1 : pdis4 -> reservedCircuitBreaker1 = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.reservedCircuitBreaker2 == BREAK_ON)? pdis4 -> reservedCircuitBreaker2 = 1 : pdis4 -> reservedCircuitBreaker2 = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.emergencyLithiumBatteryGroup1CircuitBreaker == BREAK_ON)? pdis4 -> emergencyLithiumBatteryGroup1CircuitBreaker = 1 : pdis4 -> emergencyLithiumBatteryGroup1CircuitBreaker = 0;
|
||||
pdis4 -> paceholder = 0;
|
||||
m_pm->m_currentDisBreakerState.bus4Breaker = *pdis4;
|
||||
delete pdis4;
|
||||
}
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.ccustate);
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus1State);
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus2State);
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus3State);
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus4State);
|
||||
m_pm->m_systemData->device_common_status.ccu_status.lastUpdateTime = m_pm->m_lowerCommManager->msg_CcuStateFbMsg_Update_time;
|
||||
m_pm->m_systemData->device_common_status.dis_hv_c1.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighVolBusFbMsg_Update_time;
|
||||
m_pm->m_systemData->device_common_status.dis_hv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighAVolBusFbMsg_Update_time;
|
||||
m_pm->m_systemData->device_common_status.dis_lv_c1.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighBVolBusFbMsg_Update_time;
|
||||
m_pm->m_systemData->device_common_status.dis_lv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disLowBusFbMsg_Update_time;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerCommManager::listenThreadFunc()
|
||||
{
|
||||
cout<<MOOS::ConsoleColours::green()<< "LowerCommManager::listenThreadFunc" << MOOS::ConsoleColours::reset() << endl;
|
||||
unsigned char Buff[1024];
|
||||
while(!m_ListenThread.IsQuitRequested())
|
||||
{
|
||||
try
|
||||
{
|
||||
int nRead = m_udpComm->udpScoket->iRecieveMessage(Buff, sizeof(Buff));
|
||||
cout<<MOOS::ConsoleColours::yellow()<< "RECEVE DATA COUNT:" << nRead << MOOS::ConsoleColours::reset() << endl;
|
||||
if(nRead > 0)
|
||||
{
|
||||
try {
|
||||
if(!m_udpComm->pushMsgToQueue(Buff))
|
||||
{
|
||||
for(int i=0; i<m_udpComm->sError.size(); i++)
|
||||
{
|
||||
cout<<MOOS::ConsoleColours::red()<< m_udpComm->sError[i] << MOOS::ConsoleColours::reset() << endl;
|
||||
}
|
||||
}
|
||||
//更新当前状态
|
||||
if(!updatePoweSystemStates())
|
||||
{
|
||||
std::cerr << "Error updating power system states" << std::endl;
|
||||
}
|
||||
}
|
||||
catch(const std::exception& e) {
|
||||
cerr << "Error processing message: " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 打印通信错误信息
|
||||
if(!m_udpComm->sError.empty())
|
||||
{
|
||||
for(int i=0; i<m_udpComm->sError.size(); i++)
|
||||
{
|
||||
cout<<MOOS::ConsoleColours::red() << m_udpComm->sError[i] << MOOS::ConsoleColours::reset() << endl;
|
||||
}
|
||||
m_udpComm->sError.clear();
|
||||
}
|
||||
}
|
||||
catch(const XPCException& e)
|
||||
{
|
||||
cerr << "XPCException in listenThreadFunc" << endl;
|
||||
// 短暂休眠后继续尝试
|
||||
MOOSPause(100);
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
cerr << "Exception in listenThreadFunc: " << e.what() << endl;
|
||||
MOOSPause(100);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "Unknown exception in listenThreadFunc" << endl;
|
||||
MOOSPause(100);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LowerCommManager::startListenThread()
|
||||
{
|
||||
if(!m_ListenThread.IsThreadRunning())
|
||||
{
|
||||
m_ListenThread.Initialise(_ListenCB,this);
|
||||
m_ListenThread.Start();
|
||||
std::cout << "LowerCommManager::startListenThread" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void LowerCommManager::stopListenThread()
|
||||
{
|
||||
if(m_ListenThread.IsThreadRunning())
|
||||
{
|
||||
m_ListenThread.Stop();
|
||||
std::cout << "LowerCommManager::stopListenThread" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
char LowerCommManager::getBreakerOption(char cmd)
|
||||
{
|
||||
if(cmd ==1)
|
||||
return 0x55;
|
||||
else if(cmd ==0)
|
||||
return 0xAA;
|
||||
else
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void LowerCommManager::coutMsg(const msg_CcuStateFbMsg& p, std::ostream& os){
|
||||
os << std::hex << std::setfill('0') << std::uppercase;
|
||||
|
||||
os << "起始符1 (start1): 0x" << std::setw(2) << static_cast<int>(p.header.start1) << "\n";
|
||||
os << "起始符2 (start2): 0x" << std::setw(2) << static_cast<int>(p.header.start2) << "\n";
|
||||
os << "标识符 (identifier): 0x" << std::setw(4) << p.header.id << "\n";
|
||||
os << std::dec << "数据长度 (length): " << p.header.length << "\n";
|
||||
|
||||
|
||||
os << "运行模式 (fc_mode): 0x" << std::hex << std::setw(2) << static_cast<int>(p.data.fc_mode) << "\n";
|
||||
os << "燃料电池状态 (fc_status): 0x" << std::setw(2) << static_cast<int>(p.data.fc_status) << "\n";
|
||||
os << "故障等级 (fc_fault_level): 0x" << std::setw(2) << static_cast<int>(p.data.fc_fault_level) << "\n";
|
||||
|
||||
os << std::dec;
|
||||
os << "输出功率限制 (output_power_limit): " << p.data.output_power_limit << " W\n";
|
||||
os << "累计发电时间 (total_generation_time): " << p.data.total_generation_time * 0.1 << " 小时\n";
|
||||
os << "发电总功率 (total_generation_power): " << p.data.total_generation_power << " W\n";
|
||||
os << "一级故障字 (fault_level_1): 0x" << std::hex << p.data.fault_level_1 << "\n";
|
||||
os << "二级故障字 (fault_level_2): 0x" << p.data.fault_level_2 << "\n";
|
||||
os << "三级故障字 (fault_level_3): 0x" << p.data.fault_level_3 << "\n";
|
||||
os << "四级故障字 (fault_level_4): 0x" << p.data.fault_level_4 << "\n";
|
||||
|
||||
os << std::dec;
|
||||
os << "储氢剩余容量 (hydrogen_capacity): " << static_cast<int>(p.data.hydrogen_capacity) << "%\n";
|
||||
os << "液氧剩余容量 (liquid_oxygen_capacity): " << static_cast<int>(p.data.liquid_oxygen_capacity) << "%\n";
|
||||
os << "钯膜最高温度 (palladium_temp): " << p.data.palladium_temp << " ℃\n";
|
||||
os << "主水路压力 (main_pipe_pressure): " << p.data.main_pipe_pressure * 0.01 << " kPa\n";
|
||||
os << "辅水路压力 (aux_pipe_pressure): " << p.data.aux_pipe_pressure * 0.01 << " kPa\n";
|
||||
|
||||
os << "舱室压力1 (cabin_pressure1): " << p.data.cabin_pressure1 * 0.01 << " kPa\n";
|
||||
os << "舱室压力2 (cabin_pressure2): " << p.data.cabin_pressure2 * 0.01 << " kPa\n";
|
||||
os << "舱室温度1 (cabin_temp1): " << p.data.cabin_temp1 * 0.01 << " ℃\n";
|
||||
os << "舱室温度2 (cabin_temp2): " << p.data.cabin_temp2 * 0.01 << " ℃\n";
|
||||
os << "舱室湿度1 (cabin_humidity1): " << p.data.cabin_humidity1 * 0.01 << " %RH\n";
|
||||
os << "舱室湿度2 (cabin_humidity2): " << p.data.cabin_humidity2 * 0.01 << " %RH\n";
|
||||
|
||||
os << "火焰探测器1状态 (flame_detector1): 0x" << std::hex << static_cast<int>(p.data.flame_detector1) << "\n";
|
||||
os << "火焰探测器2状态 (flame_detector2): 0x" << static_cast<int>(p.data.flame_detector2) << "\n";
|
||||
|
||||
os << std::dec;
|
||||
os << "氢气浓度1 (h2_concentration1): " << p.data.h2_concentration1 * 0.01 << "% LEL\n";
|
||||
os << "氢气浓度2 (h2_concentration2): " << p.data.h2_concentration2 * 0.01 << "% LEL\n";
|
||||
os << "氢气浓度3 (h2_concentration3): " << p.data.h2_concentration3 * 0.01 << "% LEL\n";
|
||||
os << "氧气浓度1 (o2_concentration1): " << p.data.o2_concentration1 * 0.01 << "% LEL\n";
|
||||
os << "氧气浓度2 (o2_concentration2): " << p.data.o2_concentration2 * 0.01 << "% LEL\n";
|
||||
os << "甲醇浓度1 (ch3oh_concentration1): " << p.data.ch3oh_concentration1 * 0.01 << "% LEL\n";
|
||||
os << "甲醇浓度2 (ch3oh_concentration2): " << p.data.ch3oh_concentration2 * 0.01 << "% LEL\n";
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
os << "保留字段 reserved1[" << i << "]: 0x" << std::hex << p.data.reserved1[i] << "\n";
|
||||
|
||||
os << "仪表舱 氧气浓度 (cabin_ox_concentration): " << p.data.cabin_ox_concentration * 0.1 << "%\n";
|
||||
os << "仪表舱 温度 (cabin_temperature): " << static_cast<int16_t> (p.data.cabin_temperature) * 0.1 << "°C\n";
|
||||
os << "仪表舱 湿度 (cabin_humidity): " << p.data.cabin_humidity * 0.1 << "% RH\n";
|
||||
os << "仪表舱 大气压 (cabin_pressure): " << p.data.cabin_pressure * 0.2 << " kPa\n";
|
||||
|
||||
os << "动力舱 氧气浓度 (power_cabin_ox_concentration): " << p.data.power_cabin_ox_concentration * 0.1 << "%\n";
|
||||
os << "动力舱 温度 (power_cabin_temperature): " << static_cast<int16_t> (p.data.power_cabin_temperature) * 0.1 << "°C\n";
|
||||
os << "动力舱 湿度 (power_cabin_humidity): " << p.data.power_cabin_humidity * 0.1 << "% RH\n";
|
||||
os << "动力舱 大气压 (power_cabin_pressure): " << p.data.power_cabin_pressure * 0.2 << " kPa\n";
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
os << "动力电池报警标志 dyn_alarm_flag[" << i << "]: 0x" << std::hex << static_cast<int>(p.data.dyn_alarm_flag[i]) << "\n";
|
||||
for (int i = 0; i < 6; ++i)
|
||||
os << "仪表电池报警标志 ins_alarm_flag[" << i << "]: 0x" << std::hex << static_cast<int>(p.data.ins_alarm_flag[i]) << "\n";
|
||||
|
||||
|
||||
os << "仪表正极/充电继电器状态 (ins_relay_status1): 0x" << std::hex << static_cast<int>(p.data.ins_relay_status1) << "\n";
|
||||
os << "仪表预充/负极继电器状态 (ins_relay_status2): 0x" << static_cast<int>(p.data.ins_relay_status2) << "\n";
|
||||
os << "动力正极/充电继电器状态 (dyn_relay_status1): 0x" << static_cast<int>(p.data.dyn_relay_status1) << "\n";
|
||||
os << "动力预充/负极继电器状态 (dyn_relay_status2): 0x" << static_cast<int>(p.data.dyn_relay_status2) << "\n";
|
||||
|
||||
os << std::dec;
|
||||
os << "仪表最大放电功率 (ins_max_discharge_power): " << p.data.ins_max_discharge_power * 0.05 << " kW\n";
|
||||
os << "动力最大放电功率 (dyn_max_discharge_power): " << p.data.dyn_max_discharge_power * 0.05 << " kW\n";
|
||||
|
||||
os << "仪表SOC (ins_soc): " << static_cast<int>(p.data.ins_soc) << "%\n";
|
||||
os << "动力SOC (dyn_soc): " << static_cast<int>(p.data.dyn_soc) << "%\n";
|
||||
|
||||
os << "仪表电池总能量 (ins_total_energy): " << p.data.ins_total_energy * 0.1 << " kWh\n";
|
||||
os << "动力电池总能量 (dyn_total_energy): " << p.data.dyn_total_energy * 0.1 << " kWh\n";
|
||||
|
||||
os << "仪表输入功率 (ins_power_input): " << p.data.ins_power_input * 0.1 << " kW\n";
|
||||
os << "动力输入功率 (dyn_power_input): " << p.data.dyn_power_input * 0.1 << " kW\n";
|
||||
|
||||
os << "仪表充电状态 (ins_charge_status): 0x" << std::hex << static_cast<int>(p.data.ins_charge_status) << "\n";
|
||||
os << "动力充电状态 (dyn_charge_status): 0x" << static_cast<int>(p.data.dyn_charge_status) << "\n";
|
||||
|
||||
os << std::dec;
|
||||
os << "仪表LINK电压: " << p.data.ins_voltage_link * 0.01 << " V\n";
|
||||
os << "仪表PACK电压: " << p.data.ins_voltage_pack * 0.01 << " V\n";
|
||||
os << "仪表电流: " << static_cast<int16_t> (p.data.ins_current) * 0.05 << " A\n";
|
||||
os << "仪表正端绝缘电阻: " << p.data.ins_resistance_pos << " kΩ\n";
|
||||
os << "仪表负端绝缘电阻: " << p.data.ins_resistance_neg << " kΩ\n";
|
||||
os << "动力LINK电压: " << p.data.dyn_voltage_link * 0.01 << " V\n";
|
||||
os << "动力PACK电压: " << p.data.dyn_voltage_pack * 0.01 << " V\n";
|
||||
os << "动力电流: " << static_cast<int16_t> (p.data.dyn_current) * 0.05 << " A\n";
|
||||
os << "动力正端绝缘电阻: " << p.data.dyn_resistance_pos << " kΩ\n";
|
||||
os << "动力负端绝缘电阻: " << p.data.dyn_resistance_neg << " kΩ\n";
|
||||
|
||||
os << "仪表紧急状态 (ins_emergency_status): 0x" << std::hex << static_cast<int>(p.data.ins_emergency_status) << "\n";
|
||||
os << "动力紧急状态 (dyn_emergency_status): 0x" << static_cast<int>(p.data.dyn_emergency_status) << "\n";
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
os << "保留字段 reserved2[" << i << "]: 0x" << std::hex << static_cast<int>(p.data.reserved2[i]) << "\n";
|
||||
for (int i = 0; i < 6; ++i)
|
||||
os << "SOC门限值 ins_soc_threshold" << i+1 << ": 0x" << std::hex << static_cast<int>(p.data.ins_soc_threshold1) << "\n";
|
||||
for (int i = 0; i < 4; ++i)
|
||||
os << "功率限制 ins_power_limit" << i+1 << ": 0x" << std::hex << static_cast<int>(p.data.ins_power_limit1) << "\n";
|
||||
|
||||
os << "设备在线状态1 (device_online_flag1): 0x" << std::hex << p.data.device_online_flag1 << "\n";
|
||||
os << "设备在线状态2 (device_online_flag2): 0x" << p.data.device_online_flag2 << "\n";
|
||||
|
||||
// os << "保留字段 reserved3: 0x" << p.data.reserved1 << "\n";
|
||||
os << "主机心跳 (reserved4): 0x" << p.data.heartbeat << "\n";
|
||||
os << "校验和 (checksum): 0x" << p.checkCode << "\n";
|
||||
|
||||
os << std::dec;
|
||||
}
|
||||
//================================================================================================================
|
||||
// 高电压母线断路器操作函数
|
||||
bool LowerCommManager::operate_HV_fuelCellCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_fuelCellCircuit_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.fuelCellCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.fuelCellCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_powerLithiumBattery_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_powerLithiumBattery_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.powerLithiumBatteryCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.powerLithiumBatteryCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_propulsionMotor_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_propulsionMotor_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.propulsionMotorCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.propulsionMotorCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_lithiumBatteryMeter_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_lithiumBatteryMeter_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.lithiumBatteryGroupInstrumentCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.lithiumBatteryGroupInstrumentCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_dcDc5Module_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_dcDc5Module_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.dcDc5ModuleCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.dcDc5ModuleCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_bowHighVoltageBox_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_bowHighVoltageBox_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.bowHighVoltageDistributionBoxCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.bowHighVoltageDistributionBoxCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_sternFt45_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_sternFt45_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.sternFTDevice45CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.sternFTDevice45CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_sternRudder1_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_sternRudder1_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.sternRudderSwitch1CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.sternRudderSwitch1CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_sternRudder2_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_sternRudder2_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.sternRudderSwitch2CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.sternRudderSwitch2CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_fbReserved_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_fbReserved_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.fbReservedCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.fbReservedCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_tyzReserved_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_tyzReserved_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.tyzReservedCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.tyzReservedCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HV_reserved_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
"HV_reserved_Breaker",
|
||||
opt,
|
||||
[&](disHighVolBusCmd& c){ c.reservedCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus1State.reservedCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
// bool LowerCommManager::operate_HV_dcDc5_Breaker(char opt){
|
||||
// return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
// "HV_dcDc5_Breaker",
|
||||
// opt,
|
||||
// [&](disHighVolBusCmd& c){ c.dcdc5Module = getBreakerOption(opt); },
|
||||
// [&](){ return m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1&(0x02); }
|
||||
// );
|
||||
// }
|
||||
bool LowerCommManager::operate_HV_dcDc5_Breaker(char opt)
|
||||
{
|
||||
disHighVolBusCmd cmd{}; // 默认全零
|
||||
double t0 = MOOSTime();
|
||||
bool ok = false;
|
||||
string name = "DCDC Module";
|
||||
LOG_F(INFO, "operate %s: opt=%d", name, opt);
|
||||
|
||||
cmd.dcdc5Module = getBreakerOption(opt);
|
||||
|
||||
m_udpComm->sendDisSysCmd(cmd);
|
||||
|
||||
// ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1&(0x02);
|
||||
ok = m_pm->m_systemData->m_dcdcStatus.workingStatus;
|
||||
|
||||
MOOSPause(100);
|
||||
while ( !ok ) {
|
||||
if( m_pm->m_systemData->m_dcdcStatus.workingStatus )
|
||||
{
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
if (!m_udpComm->sendDisSysCmd(cmd)) {
|
||||
LOG_F(ERROR, "operate %s: sendDisSysCmd failed", name);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (MOOSTime() > t0 + 6) {
|
||||
LOG_F(ERROR, "operate %s: timeout", name);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
MOOSPause(200);
|
||||
}
|
||||
//继电器复位
|
||||
disHighVolBusCmd clr{};
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
m_udpComm->sendDisSysCmd(clr);
|
||||
MOOSPause(200);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// bool LowerCommManager::operate_HV_coolingSystem_Breaker(char opt){
|
||||
// return operateBreakerGeneric<disHighVolBusCmd, char>(
|
||||
// "HV_coolingSystem_Breaker",
|
||||
// opt,
|
||||
// [&](disHighVolBusCmd& c){ c.coolingSystem = getBreakerOption(opt); },
|
||||
// [&](){ return (m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1 & 0x20) ? 0x55 : 0xAA; }
|
||||
// );
|
||||
// }
|
||||
bool LowerCommManager::operate_HV_coolingSystem_Breaker(char opt)
|
||||
{
|
||||
disHighVolBusCmd cmd{}; // 默认全零
|
||||
double t0 = MOOSTime();
|
||||
bool ok = false;
|
||||
string name = "CoolingSystem";
|
||||
LOG_F(INFO, "operate %s: opt=%d", name, opt);
|
||||
|
||||
cmd.coolingSystem = getBreakerOption(opt);
|
||||
|
||||
m_udpComm->sendDisSysCmd(cmd);
|
||||
|
||||
// ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1 & 0x60;
|
||||
ok = m_pm->m_systemData->m_dcdcStatus.coolingPump1Running || m_pm->m_systemData->m_dcdcStatus.coolingPump2Running;
|
||||
|
||||
MOOSPause(100);
|
||||
while ( !ok ) {
|
||||
if( (m_pm->m_systemData->m_dcdcStatus.coolingPump1Running || m_pm->m_systemData->m_dcdcStatus.coolingPump2Running) )
|
||||
{
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
if (!m_udpComm->sendDisSysCmd(cmd)) {
|
||||
LOG_F(ERROR, "operate %s: sendDisSysCmd failed", name);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (MOOSTime() > t0 + 6) {
|
||||
LOG_F(ERROR, "operate %s: timeout", name);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
MOOSPause(200);
|
||||
}
|
||||
//继电器复位
|
||||
disHighVolBusCmd clr{};
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
m_udpComm->sendDisSysCmd(clr);
|
||||
MOOSPause(200);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// 高压汇流排断路器操作函数
|
||||
bool LowerCommManager::operate_HVA_bowFTDevice123Circuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighAVolBusCmd, char>(
|
||||
"HVA_bowFTDevice123Circuit_Breaker",
|
||||
opt,
|
||||
[&](disHighAVolBusCmd& c){ c.bowFTDevice123CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus2State.bowFTDevice123CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HVA_actuatorCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighAVolBusCmd, char>(
|
||||
"HVA_actuatorCircuit_Breaker",
|
||||
opt,
|
||||
[&](disHighAVolBusCmd& c){ c.actuatorCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus2State.actuatorCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighAVolBusCmd, char>(
|
||||
"HVA_mastSteeringGearControlBoxCircuit_Breaker",
|
||||
opt,
|
||||
[&](disHighAVolBusCmd& c){ c.mastSteeringGearControlBoxCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus2State.mastSteeringGearControlBoxCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HVA_xczCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighAVolBusCmd, char>(
|
||||
"HVA_xczCircuit_Breaker",
|
||||
opt,
|
||||
[&](disHighAVolBusCmd& c){ c.xczCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus2State.xczCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HVA_bowRudderControlBoxCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighAVolBusCmd, char>(
|
||||
"HVA_bowRudderControlBoxCircuit_Breaker",
|
||||
opt,
|
||||
[&](disHighAVolBusCmd& c){ c.bowRudderControlBoxCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus2State.bowRudderControlBoxCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disHighAVolBusCmd, char>(
|
||||
"HVA_openWaterCoverStartCylinderCircuit_Breaker",
|
||||
opt,
|
||||
[&](disHighAVolBusCmd& c){ c.openWaterCoverStartCylinderCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus2State.openWaterCoverStartCylinderCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
|
||||
// 仪表汇流排断路器操作函数
|
||||
|
||||
bool LowerCommManager::operate_LVA_unit1Circuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowBusCmd, char>(
|
||||
"LVA_unit1Circuit_Breaker",
|
||||
opt,
|
||||
[&](disLowBusCmd& c){ c.unit1CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus4State.unit1CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LVA_unit2Circuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowBusCmd, char>(
|
||||
"LVA_unit2Circuit_Breaker",
|
||||
opt,
|
||||
[&](disLowBusCmd& c){ c.unit2CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus4State.unit2CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LVA_unit3Circuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowBusCmd, char>(
|
||||
"LVA_unit3Circuit_Breaker",
|
||||
opt,
|
||||
[&](disLowBusCmd& c){ c.unit3CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus4State.unit3CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LVA_unit5Circuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowBusCmd, char>(
|
||||
"LVA_unit5Circuit_Breaker",
|
||||
opt,
|
||||
[&](disLowBusCmd& c){ c.unit5CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus4State.unit5CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LVA_bowPZDeviceCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowBusCmd, char>(
|
||||
"LVA_bowPZDeviceCircuit_Breaker",
|
||||
opt,
|
||||
[&](disLowBusCmd& c){ c.bowPZDeviceCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus4State.bowPZDeviceCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LVA_reservedCircuit1_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowBusCmd, char>(
|
||||
"LVA_reservedCircuit1_Breaker",
|
||||
opt,
|
||||
[&](disLowBusCmd& c){ c.reservedCircuitBreaker1 = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus4State.reservedCircuitBreaker1; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LVA_reservedCircuit2_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowBusCmd, char>(
|
||||
"LVA_reservedCircuit2_Breaker",
|
||||
opt,
|
||||
[&](disLowBusCmd& c){ c.reservedCircuitBreaker2 = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus4State.reservedCircuitBreaker2; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LVA_mergencyLithiumBatteryGroup1Circuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowBusCmd, char>(
|
||||
"LVA_mergencyLithiumBatteryGroup1Circuit_Breaker",
|
||||
opt,
|
||||
[&](disLowBusCmd& c){ c.emergencyLithiumBatteryGroup1CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus4State.emergencyLithiumBatteryGroup1CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
|
||||
// 仪表母线断路器操作函数
|
||||
bool LowerCommManager::operate_LV_lithiumBatteryGroupInstrumentCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowMainBusCmd, char>(
|
||||
"lithiumBatteryGroupInstrumentCircuitBreaker",
|
||||
opt,
|
||||
[&](disLowMainBusCmd& c){ c.lithiumBatteryGroupInstrumentCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus3State.lithiumBatteryGroupInstrumentCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LV_bowLowVoltageDistributionBoxCircuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowMainBusCmd, char>(
|
||||
"bowLowVoltageDistributionBoxCircuitBreaker",
|
||||
opt,
|
||||
[&](disLowMainBusCmd& c){ c.bowLowVoltageDistributionBoxCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus3State.bowLowVoltageDistributionBoxCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LV_unit4Dc48V_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowMainBusCmd, char>(
|
||||
"unit4InstrumentDC48VCircuitBreaker",
|
||||
opt,
|
||||
[&](disLowMainBusCmd& c){ c.unit4InstrumentDC48VCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus3State.unit4InstrumentDC48VCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LV_dcC1Panel_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowMainBusCmd, char>(
|
||||
"dcC1DCDistributionPanelCircuitBreaker",
|
||||
opt,
|
||||
[&](disLowMainBusCmd& c){ c.dcC1DCDistributionPanelCircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus3State.dcC1DCDistributionPanelCircuitBreaker; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LV_reservedCircuit1_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowMainBusCmd, char>(
|
||||
"reservedCircuitBreaker1",
|
||||
opt,
|
||||
[&](disLowMainBusCmd& c){ c.reservedCircuitBreaker1 = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus3State.reservedCircuitBreaker1; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LV_reservedCircuit2_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowMainBusCmd, char>(
|
||||
"reservedCircuitBreaker2",
|
||||
opt,
|
||||
[&](disLowMainBusCmd& c){ c.reservedCircuitBreaker2 = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus3State.reservedCircuitBreaker2; }
|
||||
);
|
||||
}
|
||||
bool LowerCommManager::operate_LV_mergencyLithiumBatteryGroup2Circuit_Breaker(char opt){
|
||||
return operateBreakerGeneric<disLowMainBusCmd, char>(
|
||||
"emergencyLithiumBatteryGroup2CircuitBreaker",
|
||||
opt,
|
||||
[&](disLowMainBusCmd& c){ c.emergencyLithiumBatteryGroup2CircuitBreaker = getBreakerOption(opt); },
|
||||
[&](){ return m_pm->m_pmCurrentState.bus3State.emergencyLithiumBatteryGroup2CircuitBreaker; }
|
||||
);
|
||||
}
|
||||
|
||||
// 通用模板
|
||||
template<typename CmdT, typename StateT>
|
||||
bool LowerCommManager::operateBreakerGeneric(
|
||||
char const* name,
|
||||
char opt,
|
||||
std::function<void(CmdT&)> fillCmd, // 填 cmd 对应字段
|
||||
std::function<StateT()> readState // 读 pmCurrentState 对应字段
|
||||
) {
|
||||
CmdT cmd{}; // 默认全零
|
||||
double t0 = MOOSTime();
|
||||
bool ok = false;
|
||||
LOG_F(INFO, "operate %s: opt=%d", name, opt);
|
||||
|
||||
// 第一次发包
|
||||
fillCmd(cmd);
|
||||
m_udpComm->sendDisSysCmd(cmd);
|
||||
MOOSPause(100);
|
||||
while ( !ok ) {
|
||||
if( readState() == getBreakerOption(opt) )
|
||||
{
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
if (!m_udpComm->sendDisSysCmd(cmd)) {
|
||||
LOG_F(ERROR, "operate %s: sendDisSysCmd failed", name);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (MOOSTime() > t0 + 6) {
|
||||
LOG_F(ERROR, "operate %s: timeout", name);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
MOOSPause(200);
|
||||
}
|
||||
//继电器复位
|
||||
CmdT clr{};
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
m_udpComm->sendDisSysCmd(clr);
|
||||
MOOSPause(200);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
#ifndef LOWER_COMM_MANAGER_H
|
||||
#define LOWER_COMM_MANAGER_H
|
||||
#define UNIX
|
||||
|
||||
#include "MOOS/libMOOS/Comms/XPCUdpSocket.h"
|
||||
#include "MOOS/libMOOS/Utils/MOOSThread.h"
|
||||
#include "MOOS/libMOOS/Utils/MOOSLock.h"
|
||||
#include "../udpcomm/ccuUdpMsg.h"
|
||||
#include "pmSysvariable.h"
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include "udpcomm/udpComm.h"
|
||||
#include <functional>
|
||||
|
||||
class PowerManger; // 前向声明
|
||||
|
||||
class LowerCommManager {
|
||||
public:
|
||||
LowerCommManager(PowerManger* pm, long myPort, long ccuPort, const std::string& cccHost);
|
||||
~LowerCommManager();
|
||||
|
||||
//processPeriodicTasks
|
||||
void processPeriodicTasks();
|
||||
//clearMsgQueue
|
||||
void clearMsgQueue();
|
||||
|
||||
public:
|
||||
// 初始化UDP通信
|
||||
bool initUdpComm();
|
||||
|
||||
// 更新设备状态
|
||||
bool updatePoweSystemStates();
|
||||
//================================断路器操作函数=======================================
|
||||
template<typename CmdT, typename StateT>
|
||||
bool operateBreakerGeneric(
|
||||
char const* name,
|
||||
char opt,
|
||||
std::function<void(CmdT&)> fillCmd, // 填 cmd 对应字段
|
||||
std::function<StateT()> readState // 读 pmCurrentState 对应字段
|
||||
);
|
||||
// 高电压母线
|
||||
bool operate_HV_fuelCellCircuit_Breaker(char opt);
|
||||
bool operate_HV_powerLithiumBattery_Breaker(char opt);
|
||||
bool operate_HV_propulsionMotor_Breaker(char opt);
|
||||
bool operate_HV_lithiumBatteryMeter_Breaker(char opt);
|
||||
bool operate_HV_dcDc5Module_Breaker(char opt);
|
||||
bool operate_HV_bowHighVoltageBox_Breaker(char opt);
|
||||
bool operate_HV_sternFt45_Breaker(char opt);
|
||||
bool operate_HV_sternRudder1_Breaker(char opt);
|
||||
bool operate_HV_sternRudder2_Breaker(char opt);
|
||||
bool operate_HV_fbReserved_Breaker(char opt);
|
||||
bool operate_HV_tyzReserved_Breaker(char opt);
|
||||
bool operate_HV_reserved_Breaker(char opt);
|
||||
bool operate_HV_dcDc5_Breaker(char opt);
|
||||
bool operate_HV_coolingSystem_Breaker(char opt);
|
||||
// 高压汇流排
|
||||
bool operate_HVA_bowFTDevice123Circuit_Breaker(char opt);
|
||||
bool operate_HVA_actuatorCircuit_Breaker(char opt);
|
||||
bool operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(char opt);
|
||||
bool operate_HVA_xczCircuit_Breaker(char opt);
|
||||
bool operate_HVA_bowRudderControlBoxCircuit_Breaker(char opt);
|
||||
bool operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(char opt);
|
||||
// 仪表母线
|
||||
bool operate_LV_lithiumBatteryGroupInstrumentCircuit_Breaker(char opt);
|
||||
bool operate_LV_bowLowVoltageDistributionBoxCircuit_Breaker(char opt);
|
||||
bool operate_LV_unit4Dc48V_Breaker(char opt);
|
||||
bool operate_LV_dcC1Panel_Breaker(char opt);
|
||||
bool operate_LV_reservedCircuit1_Breaker(char opt);
|
||||
bool operate_LV_reservedCircuit2_Breaker(char opt);
|
||||
bool operate_LV_mergencyLithiumBatteryGroup2Circuit_Breaker(char opt);
|
||||
// 仪表汇流排
|
||||
bool operate_LVA_unit1Circuit_Breaker(char opt);
|
||||
bool operate_LVA_unit2Circuit_Breaker(char opt);
|
||||
bool operate_LVA_unit3Circuit_Breaker(char opt);
|
||||
bool operate_LVA_unit5Circuit_Breaker(char opt);
|
||||
bool operate_LVA_bowPZDeviceCircuit_Breaker(char opt);
|
||||
bool operate_LVA_reservedCircuit1_Breaker(char opt);
|
||||
bool operate_LVA_reservedCircuit2_Breaker(char opt);
|
||||
bool operate_LVA_mergencyLithiumBatteryGroup1Circuit_Breaker(char opt);
|
||||
|
||||
//保持指令
|
||||
void operate_hold();
|
||||
//================================复合管控器操作函数====================================
|
||||
// 发送CCU控制命令
|
||||
bool sendCcuCommand(const ccuColCmd cmd);
|
||||
bool sendDisSysCommand(const disSysBreakerList& cmd); //已废弃,不同时操作多个继电器设备
|
||||
|
||||
// 启动/停止监听线程
|
||||
void startListenThread();
|
||||
void stopListenThread();
|
||||
void coutMsg(const msg_CcuStateFbMsg& p, std::ostream& os = std::cout);
|
||||
|
||||
//转换函数
|
||||
char getBreakerOption(char cmd);
|
||||
|
||||
// 配电和CCU的反馈状态
|
||||
msg_CcuStateFbMsg m_CcuCurrentState;
|
||||
msg_disHighVolBusFbMsg m_disHighVolBusCurrentState;
|
||||
msg_disHighAVolBusFbMsg m_disHighAVolBusCurrentState;
|
||||
msg_disLowMainBusFbMsg m_disHighBVolBusCurrentState;
|
||||
msg_disLowBusFbMsg m_disLowBusState;
|
||||
// 配电和CCU的反馈状态时间戳
|
||||
double msg_CcuStateFbMsg_Update_time;
|
||||
// double msg_CcuSetParmFbMsg_Update_time;
|
||||
double msg_disHighVolBusFbMsg_Update_time;
|
||||
double msg_disHighAVolBusFbMsg_Update_time;
|
||||
double msg_disHighBVolBusFbMsg_Update_time;
|
||||
double msg_disLowBusFbMsg_Update_time;
|
||||
public:
|
||||
long m_port;
|
||||
long m_ccuPort;
|
||||
std::string m_ccuHost;
|
||||
std::string m_host;
|
||||
|
||||
PowerManger* m_pm;
|
||||
udpComm* m_udpComm;
|
||||
|
||||
CMOOSThread m_ListenThread;
|
||||
int m_connectState;
|
||||
|
||||
// UDP监听线程函数
|
||||
bool listenThreadFunc();
|
||||
};
|
||||
|
||||
#endif // LOWER_COMM_MANAGER_H
|
||||
@@ -0,0 +1,403 @@
|
||||
/************************************************************/
|
||||
/* 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();
|
||||
}
|
||||
|
||||
bool _CommCB(void * pParam)
|
||||
{
|
||||
PowerManger* pMe = (PowerManger* )pParam;
|
||||
return pMe->commLoop();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Constructor()
|
||||
|
||||
PowerManger::PowerManger()
|
||||
{
|
||||
workCondition = 0;
|
||||
currentMod = 0;
|
||||
powerState = 0;
|
||||
faultLevel = 0;
|
||||
soc = 0;
|
||||
sustainableTime = 0;
|
||||
m_faultNum = 0;
|
||||
m_ticker = 0;
|
||||
m_leakage = 0;
|
||||
m_thrustRpm = 0;
|
||||
m_thrustEnable = 0;
|
||||
faultCode.clear();
|
||||
|
||||
m_skew = 10;
|
||||
|
||||
m_pmCurrentState = {};
|
||||
m_currentDisBreakerState = {};
|
||||
m_targetDisBreakerState = {};
|
||||
m_currentDriverState = {};
|
||||
m_MSDriverCmd = {};
|
||||
m_subDisSysCmd = {};
|
||||
m_subDisSysState = {};
|
||||
m_subDisSysFault = {};
|
||||
//初始化控制指令
|
||||
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()
|
||||
{
|
||||
m_commThread.Stop();
|
||||
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->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);
|
||||
|
||||
//初始化通信线程
|
||||
m_commThread.Initialise(_CommCB,this);
|
||||
m_commThread.Start();
|
||||
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);
|
||||
|
||||
Register(uDetect_xcVoltage_cmd::key,0);
|
||||
Register(uDetect_zdpVoltage_cmd::key,0);
|
||||
Register(uDevice_thruster_st::key,0);
|
||||
// Register(uExternComm_setThrustSpeed_cmd::key,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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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 = 8; //默认为8kw
|
||||
m_CcuColCmd.insChargeEnable = 0x30; //不允许充电
|
||||
m_CcuColCmd.insBatCmd = 0x00; //无效指令
|
||||
m_CcuColCmd.powerBatCmd = 0x00; //无效指令
|
||||
m_CcuColCmd.powerBatEfficiency = 00; //默认为最大
|
||||
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;
|
||||
}
|
||||
|
||||
bool PowerManger::commLoop()
|
||||
{
|
||||
while(!m_commThread.IsQuitRequested())
|
||||
{
|
||||
m_CcuColCmd.heartbeat++;
|
||||
m_lowerCommManager->processPeriodicTasks();
|
||||
m_upperCommManager->processPeriodicTasks();
|
||||
// 延时1秒
|
||||
usleep(1000000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PowerManger::injectFault(unsigned type,unsigned int faultCode){
|
||||
LOG_F(INFO, "注入故障: %d %d", type, faultCode);
|
||||
TestEvent testEvent("故障注入测试",type,faultCode);
|
||||
PowerManagerFsm::dispatch(testEvent);
|
||||
}
|
||||
|
||||
|
||||
void PowerManger::pushDeviceCommand(DeviceSwitchCmd cmd) {
|
||||
std::lock_guard<std::mutex> lock(m_deviceCmdMutex);
|
||||
m_deviceCmdQuenue.push(cmd);
|
||||
}
|
||||
|
||||
bool PowerManger::popDeviceCommand(DeviceSwitchCmd &cmd) {
|
||||
std::lock_guard<std::mutex> lock(m_deviceCmdMutex);
|
||||
if(m_deviceCmdQuenue.empty()) {
|
||||
return false;
|
||||
}
|
||||
cmd = m_deviceCmdQuenue.front();
|
||||
m_deviceCmdQuenue.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PowerManger::isDeviceCmdEmpty() const {
|
||||
std::lock_guard<std::mutex> lock(m_deviceCmdMutex);
|
||||
return m_deviceCmdQuenue.empty();
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* @Author: zhaojingkui 1553836110@qq.com
|
||||
* @Date: 2024-10-22 16:47:01
|
||||
* @LastEditors: zhaojingkui 1553836110@qq.com
|
||||
* @LastEditTime: 2024-10-22 18:03:29
|
||||
* @FilePath: /H100PowerManger/src/pPowerManger/PowerManger.h
|
||||
* @Description:
|
||||
*
|
||||
* Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
|
||||
*/
|
||||
/************************************************************/
|
||||
/* NAME: */
|
||||
/* ORGN: MIT, Cambridge MA */
|
||||
/* FILE: PowerManger.h */
|
||||
/* DATE: December 29th, 1963 */
|
||||
/************************************************************/
|
||||
|
||||
#ifndef PowerManger_HEADER
|
||||
#define PowerManger_HEADER
|
||||
#define UNIX
|
||||
#define JSON_USE_EXCEPTION 1
|
||||
|
||||
#include <queue>
|
||||
#include "logc/loguru.hpp"
|
||||
#include "MOOS/libMOOS/Thirdparty/AppCasting/AppCastingMOOSApp.h"
|
||||
#include "MOOS/libMOOS/Utils/MOOSThread.h"
|
||||
#include "MOOS/libMOOS/Utils/MOOSUtilityFunctions.h"
|
||||
#include "MOOS/libMOOS/Utils/ConsoleColours.h"
|
||||
#include "../udpcomm/ccuUdpMsg.h"
|
||||
#include "json/json.h"
|
||||
#include "udpcomm/udpComm.h"
|
||||
#include "pmSysvariable.h"
|
||||
#include "fsm/PowerManagerFsm.hpp"
|
||||
#include "driver.h"
|
||||
#include "LowerCommManager.h"
|
||||
#include "UpperCommManager.h"
|
||||
#include "sqlit3/SQLite.h"
|
||||
#include "systemData.h"
|
||||
#include "httpserver/httpserver.h"
|
||||
#include "faultCode.h"
|
||||
#define IPORT 5001
|
||||
#define CCUPORT 7000
|
||||
#define CCUHOST "192.168.0.140"
|
||||
// #define CCUHOST "127.0.0.0"
|
||||
#define MAX_UDP_PKT_SIZE 65535
|
||||
#define SKEW_TOLERANCE 5
|
||||
|
||||
class PowerManger : public AppCastingMOOSApp
|
||||
{
|
||||
public:
|
||||
PowerManger();
|
||||
~PowerManger();
|
||||
public:
|
||||
bool FsmLoop();
|
||||
|
||||
protected: // Standard MOOSApp functions to overload
|
||||
bool OnNewMail(MOOSMSG_LIST &NewMail);
|
||||
bool Iterate();
|
||||
bool OnConnectToServer();
|
||||
bool OnStartUp();
|
||||
bool buildReport();
|
||||
void registerVariables();
|
||||
|
||||
public:
|
||||
void updateTime(){m_current_time = MOOSTime();}
|
||||
unsigned char getFaultLevel();
|
||||
//数据库
|
||||
SQLite* m_db;
|
||||
//http
|
||||
HttpServer* m_httpServer;
|
||||
//系统数据
|
||||
SystemData* m_systemData;
|
||||
/************************************************************/
|
||||
/* |<------------FEEDBACK--------<-- */
|
||||
/* | | */
|
||||
/* IN-->+-------[STATE CONTROL]---------+--->OUT */
|
||||
/* */
|
||||
/************************************************************/
|
||||
public:
|
||||
//===========================IN============================================
|
||||
DriverTable m_MSDriverCmd;
|
||||
MSControlCmd m_msCmd;
|
||||
//===========================OUT===========================================
|
||||
DriverTable m_subDisSysCmd;
|
||||
ccuColCmd m_CcuColCmd;
|
||||
disSysBreakerList m_targetDisBreakerState;
|
||||
//===========================FEEDBACK======================================
|
||||
pmState m_pmCurrentState; //能源系统的当前状态(由下位机线程修改)
|
||||
disSysBreakerList m_currentDisBreakerState; //配电断路器状态
|
||||
DriverTable m_currentDriverState;
|
||||
DriverTable m_subDisSysState;
|
||||
DriverTable m_subDisSysFault;
|
||||
int m_depth;
|
||||
MissionState m_missionState;
|
||||
//===========================STATE=========================================
|
||||
unsigned char workCondition;
|
||||
unsigned char currentMod;
|
||||
unsigned char powerState;
|
||||
unsigned char faultLevel;
|
||||
vector<unsigned int> faultCode;
|
||||
|
||||
unsigned int soc;
|
||||
unsigned int sustainableTime;
|
||||
unsigned int m_faultNum;
|
||||
Driver m_driver; //设备表处理
|
||||
unsigned char m_leakage;
|
||||
std::set<unsigned int> m_faultCodes;
|
||||
int m_thrustRpm;
|
||||
int m_thrustEnable;
|
||||
// std::set<unsigned int> m_disSysFaultCodes;
|
||||
//============================Device Option================================
|
||||
std::queue<DeviceSwitchCmd> m_deviceCmdQuenue;
|
||||
mutable std::mutex m_deviceCmdMutex;
|
||||
void pushDeviceCommand(DeviceSwitchCmd cmd);
|
||||
bool popDeviceCommand(DeviceSwitchCmd &cmd);
|
||||
bool isDeviceCmdEmpty() const;
|
||||
//===========================CONFIG========================================
|
||||
long m_lPort;
|
||||
unsigned int m_nReceiveBufferSizeKB;
|
||||
unsigned int m_nSendBufferSizeKB;
|
||||
double m_current_time;
|
||||
unsigned int m_ticker;
|
||||
double m_skew;
|
||||
int connectState;
|
||||
//=============================过程函数======================================
|
||||
void initControlCmd();
|
||||
|
||||
public:
|
||||
CMOOSThread m_commThread;
|
||||
LowerCommManager* m_lowerCommManager;
|
||||
UpperCommManager* m_upperCommManager;
|
||||
|
||||
// PowerManagerFsm m_fsm;
|
||||
|
||||
public:
|
||||
//===========================状态机接口=======================================
|
||||
void printState(const std::string& stateName, const std::string& desp);
|
||||
bool FSM_RUN_IS_OK = true;
|
||||
|
||||
//==================================================================================
|
||||
bool commLoop();
|
||||
int checkError();
|
||||
|
||||
bool sendNotification(const std::string& key, const std::string& value) {
|
||||
return Notify(key, value);
|
||||
}
|
||||
bool sendNotification(const std::string& key, double value) {
|
||||
return Notify(key, value);
|
||||
}
|
||||
public:
|
||||
double GetPublicAppFreq() { return GetAppFreq(); }
|
||||
unsigned int GetPublicCommsFreq() { return GetCommsFreq(); }
|
||||
double GetPublicAppStartTime() { return GetAppStartTime(); }
|
||||
double GetPublicCPULoad() { return GetCPULoad(); }
|
||||
double GetPublicTimeSinceIterate() { return GetTimeSinceIterate(); }
|
||||
double GetPublicLastIterateTime() { return GetLastIterateTime(); }
|
||||
int GetPublicIterateCount() { return GetIterateCount(); }
|
||||
string GetServerHost() { return m_sServerHost; }
|
||||
int GetServerPort() { return m_lServerPort; }
|
||||
public:
|
||||
//故障注入
|
||||
void injectFault(unsigned type,unsigned int faultCode);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,115 @@
|
||||
/****************************************************************/
|
||||
/* NAME: */
|
||||
/* ORGN: MIT, Cambridge MA */
|
||||
/* FILE: PowerManger_Info.cpp */
|
||||
/* DATE: December 29th, 1963 */
|
||||
/****************************************************************/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include "PowerManger_Info.h"
|
||||
#include "ColorParse.h"
|
||||
#include "ReleaseInfo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Procedure: showSynopsis
|
||||
|
||||
void showSynopsis()
|
||||
{
|
||||
blk("SYNOPSIS: ");
|
||||
blk("------------------------------------ ");
|
||||
blk(" The pPowerManger application is used for ");
|
||||
blk(" ");
|
||||
blk(" ");
|
||||
blk(" ");
|
||||
blk(" ");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Procedure: showHelpAndExit
|
||||
|
||||
void showHelpAndExit()
|
||||
{
|
||||
blk(" ");
|
||||
blu("=============================================================== ");
|
||||
blu("Usage: pPowerManger file.moos [OPTIONS] ");
|
||||
blu("=============================================================== ");
|
||||
blk(" ");
|
||||
showSynopsis();
|
||||
blk(" ");
|
||||
blk("Options: ");
|
||||
mag(" --alias","=<ProcessName> ");
|
||||
blk(" Launch pPowerManger with the given process name ");
|
||||
blk(" rather than pPowerManger. ");
|
||||
mag(" --example, -e ");
|
||||
blk(" Display example MOOS configuration block. ");
|
||||
mag(" --help, -h ");
|
||||
blk(" Display this help message. ");
|
||||
mag(" --interface, -i ");
|
||||
blk(" Display MOOS publications and subscriptions. ");
|
||||
mag(" --version,-v ");
|
||||
blk(" Display the release version of pPowerManger. ");
|
||||
blk(" ");
|
||||
blk("Note: If argv[2] does not otherwise match a known option, ");
|
||||
blk(" then it will be interpreted as a run alias. This is ");
|
||||
blk(" to support pAntler launching conventions. ");
|
||||
blk(" ");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Procedure: showExampleConfigAndExit
|
||||
|
||||
void showExampleConfigAndExit()
|
||||
{
|
||||
blk(" ");
|
||||
blu("=============================================================== ");
|
||||
blu("pPowerManger Example MOOS Configuration ");
|
||||
blu("=============================================================== ");
|
||||
blk(" ");
|
||||
blk("ProcessConfig = pPowerManger ");
|
||||
blk("{ ");
|
||||
blk(" AppTick = 4 ");
|
||||
blk(" CommsTick = 4 ");
|
||||
blk(" ");
|
||||
blk("} ");
|
||||
blk(" ");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Procedure: showInterfaceAndExit
|
||||
|
||||
void showInterfaceAndExit()
|
||||
{
|
||||
blk(" ");
|
||||
blu("=============================================================== ");
|
||||
blu("pPowerManger INTERFACE ");
|
||||
blu("=============================================================== ");
|
||||
blk(" ");
|
||||
showSynopsis();
|
||||
blk(" ");
|
||||
blk("SUBSCRIPTIONS: ");
|
||||
blk("------------------------------------ ");
|
||||
blk(" NODE_MESSAGE = src_node=alpha,dest_node=bravo,var_name=FOO, ");
|
||||
blk(" string_val=BAR ");
|
||||
blk(" ");
|
||||
blk("PUBLICATIONS: ");
|
||||
blk("------------------------------------ ");
|
||||
blk(" Publications are determined by the node message content. ");
|
||||
blk(" ");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Procedure: showReleaseInfoAndExit
|
||||
|
||||
void showReleaseInfoAndExit()
|
||||
{
|
||||
showReleaseInfo("pPowerManger", "gpl");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/****************************************************************/
|
||||
/* NAME: */
|
||||
/* ORGN: MIT, Cambridge MA */
|
||||
/* FILE: PowerManger_Info.h */
|
||||
/* DATE: Dececmber 29th, 1963 */
|
||||
/****************************************************************/
|
||||
|
||||
#ifndef PowerManger_INFO_HEADER
|
||||
#define PowerManger_INFO_HEADER
|
||||
|
||||
void showSynopsis();
|
||||
void showHelpAndExit();
|
||||
void showExampleConfigAndExit();
|
||||
void showInterfaceAndExit();
|
||||
void showReleaseInfoAndExit();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
#include "UpperCommManager.h"
|
||||
#include "PowerManger.h"
|
||||
#include "driver.h"
|
||||
#include "fsm/PowerManagerFsm.hpp"
|
||||
|
||||
UpperCommManager::UpperCommManager(PowerManger* pm) :
|
||||
m_pm(pm),
|
||||
m_secdistStateMsg(),
|
||||
m_setOpConditionMsg(),
|
||||
m_depthMsg(),
|
||||
m_taskStartMsg(),
|
||||
m_equInsStateMsg(),
|
||||
m_equStateMsg(),
|
||||
m_setPMSysMsg(),
|
||||
m_disSysStateMsg(),
|
||||
m_currentStateMsg(),
|
||||
m_pmStateMsg(),
|
||||
m_fcsStateMsg(),
|
||||
m_liBatStateMsg(),
|
||||
m_setOpModeMsg(),
|
||||
m_taskStopMsg(),
|
||||
m_setDevSwitchMsg(),
|
||||
m_sysStateMsg(),
|
||||
m_msCmd(),
|
||||
m_driver() {
|
||||
}
|
||||
DriverTable uDevice_secdistStateMsg::fault_state = {0};
|
||||
|
||||
bool UpperCommManager::processUpperMsg(const string& key, const string& strJson) {
|
||||
if (key == m_sysStateMsg.key)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_sysStateMsg_st_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
m_pm->m_msCmd = m_sysStateMsg.getMasterControlCmd(key, strJson);
|
||||
MasterCommandEvent event;
|
||||
PowerManagerFsm::dispatch(event);
|
||||
return true;
|
||||
}
|
||||
// 设备状态处理
|
||||
else if(key == m_equStateMsg.key_cmd)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_equStateMsg_cmd_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
m_pm->m_MSDriverCmd = m_equStateMsg.getEquipmentCmd(key, strJson);
|
||||
vector<DriverCommand> devCmdExt = m_pm->m_driver.loadDriverIdFromJson(strJson);
|
||||
if (devCmdExt.empty())
|
||||
{
|
||||
LOG_F(WARNING, "控制指令为空");
|
||||
}
|
||||
else {
|
||||
for (auto& cmd : devCmdExt) {
|
||||
DevCmdExt event(cmd.id, cmd.cmd);
|
||||
PowerManagerFsm::dispatch(event);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// 次级配电状态处理
|
||||
else if(key == m_secdistStateMsg.key_fb)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_secdistStateMsg_fb_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
m_secdistStateMsg.parseMsg(strJson, m_pm->m_subDisSysState);
|
||||
//TODO:自动更新到设备状态 调试
|
||||
//m_pm->m_subDisSysState = m_pm->m_deviceState;
|
||||
return true;
|
||||
}
|
||||
// 深度获取
|
||||
else if(key == m_depthMsg.key)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_depthMsg_st_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
m_pm->m_depth = m_depthMsg.getDepth(key, strJson);
|
||||
return true;
|
||||
}
|
||||
else if(key == m_taskStartMsg.key)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_taskStartMsg_st_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
m_pm->m_missionState = m_taskStartMsg.getMission(key, strJson);
|
||||
TaskStartEvent event;
|
||||
event.type = m_pm->m_missionState.type;
|
||||
event.enableBowRudder = m_pm->m_missionState.enableBowRudder;
|
||||
event.enableBuoyancyAdjustment = m_pm->m_missionState.enableBuoyancyAdjustment;
|
||||
PowerManagerFsm::dispatch(event);
|
||||
return true;
|
||||
}
|
||||
else if(key == m_setOpModeMsg.key)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_setOpModeMsg_st_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
m_pm->m_msCmd.modCMD = m_setOpModeMsg.getSetOpMode(key, strJson);
|
||||
MasterCommandEvent event;
|
||||
PowerManagerFsm::dispatch(event);
|
||||
return true;
|
||||
} else if(key == m_setOpConditionMsg.key)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_setOpConditionMsg_st_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
m_pm->m_msCmd.workCMD = m_setOpConditionMsg.getSetOpCondition(key, strJson);
|
||||
MasterCommandEvent event;
|
||||
PowerManagerFsm::dispatch(event);
|
||||
return true;
|
||||
}
|
||||
else if(key == m_setPMSysMsg.key)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_setPMSysMsg_st_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
m_pm->m_msCmd.powerCMD = m_setPMSysMsg.getSetPMSys(key, strJson);
|
||||
MasterCommandEvent event;
|
||||
PowerManagerFsm::dispatch(event);
|
||||
return true;
|
||||
}
|
||||
else if(key == m_setDevSwitchMsg.key)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_setDevSwitchMsg_st_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
DeviceSwitchCmd cmd;
|
||||
cmd = m_setDevSwitchMsg.getSetDevSwitch(key, strJson);
|
||||
if (cmd.id < 0) {
|
||||
LOG_F(WARNING, "parse device switch error:%s", strJson.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
DevCmdExt devCmdExt;
|
||||
devCmdExt.id = cmd.id;
|
||||
devCmdExt.cmd = cmd.cmd;
|
||||
PowerManagerFsm::dispatch(devCmdExt);
|
||||
LOG_F(INFO, "set dev switch success");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(key == m_taskStopMsg.key)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_taskStopMsg_st_debug = std::make_pair(key, strJson);
|
||||
#endif
|
||||
bool stop = m_taskStopMsg.getTaskStop(key, strJson);
|
||||
if (stop) {
|
||||
LOG_F(INFO, "task stop success");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
LOG_F(WARNING, "task stop error:%s", strJson.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(key == uDetect_xcVoltage_cmd::key)
|
||||
{
|
||||
uDetect_xcVoltage_cmd xcCmd;
|
||||
xcCmd.xcHighVoltageAdd_int32 = 0;
|
||||
xcCmd.xcLowVoltageAdd_int32 = 0;
|
||||
xcCmd.fromJsonString(strJson);
|
||||
SideSonarCmd sideSonarCmd;
|
||||
sideSonarCmd.xcHighVoltageAdd = xcCmd.xcHighVoltageAdd_int32;
|
||||
sideSonarCmd.xcLowVoltageAdd = xcCmd.xcLowVoltageAdd_int32;
|
||||
PowerManagerFsm::dispatch(sideSonarCmd);
|
||||
return true;
|
||||
}
|
||||
else if(key == uDetect_zdpVoltage_cmd::key)
|
||||
{
|
||||
uDetect_zdpVoltage_cmd zdpCmd;
|
||||
zdpCmd.fromJsonString(strJson);
|
||||
|
||||
DevCmdExt devCmdExt;
|
||||
devCmdExt.id = DeviceId::lowFreqSonar;
|
||||
devCmdExt.cmd = zdpCmd.zdpVoltageAdd_int32;
|
||||
PowerManagerFsm::dispatch(devCmdExt);
|
||||
LOG_F(INFO, "set dev switch success");
|
||||
return true;
|
||||
}
|
||||
else if(key == uDevice_thruster_st::key)
|
||||
{
|
||||
uDevice_thruster_st thrusterSt;
|
||||
thrusterSt.fromJsonString(strJson);
|
||||
m_pm->m_thrustRpm = thrusterSt.rpm_int16;
|
||||
if(thrusterSt.maxTorque_uint16 == 0)
|
||||
m_pm->m_thrustEnable = 0;
|
||||
else
|
||||
m_pm->m_thrustEnable = 1;
|
||||
return true;
|
||||
};
|
||||
LOG_F(WARNING, "Unknown key: %s", key.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
void UpperCommManager::processPeriodicTasks() {
|
||||
buildSystemReport();
|
||||
std::string strJson;
|
||||
//发送当前设备状态
|
||||
strJson = m_equStateMsg.buildMsg(m_pm->m_currentDriverState);
|
||||
m_pm->sendNotification(m_equStateMsg.key, strJson);
|
||||
//发送次级配电指令 修改后的代码
|
||||
strJson = m_secdistStateMsg.buildMsg(m_pm->m_subDisSysCmd,m_pm->m_subDisSysState, m_pm->m_subDisSysFault);
|
||||
m_pm->sendNotification(m_secdistStateMsg.key_cmd, strJson);
|
||||
//发送仪表电状态
|
||||
m_pm->sendNotification(m_equInsStateMsg.key,m_equInsStateMsg.buildMsg(m_pm->m_subDisSysState));
|
||||
#ifdef _DEBUG
|
||||
m_equInsStateMsg_fb_degub = std::make_pair(m_equInsStateMsg.key,m_equInsStateMsg.buildMsg(m_pm->m_subDisSysState));
|
||||
m_secdistStateMsg_cmd_debug = std::make_pair(m_secdistStateMsg.key_cmd,strJson);
|
||||
m_equStateMsg_fb_debug = std::make_pair(m_equStateMsg.key_cmd,m_equStateMsg.buildMsg(m_pm->m_currentDriverState));
|
||||
strJson = m_pm->m_driver.saveDriverTableToJson(&m_pm->m_subDisSysFault);
|
||||
m_pm->sendNotification("uPower_subDisFault_st",strJson);
|
||||
#endif
|
||||
}
|
||||
|
||||
void UpperCommManager::buildSystemReport() {
|
||||
m_pmStateMsg.state.workCondition = m_pm->workCondition;
|
||||
m_pmStateMsg.state.currentMod = m_pm->currentMod;
|
||||
m_pmStateMsg.state.powerState = m_pm->powerState;
|
||||
m_pmStateMsg.state.faultLevel = m_pm->faultLevel;
|
||||
m_pmStateMsg.state.faultCode = m_pm->faultCode;
|
||||
// cout << "m_pmStateMsg.state.faultCode.size():" << m_pmStateMsg.state.faultCode.size() << endl;
|
||||
m_pmStateMsg.state.soc = m_pm->soc;
|
||||
m_pmStateMsg.state.sustainableTime = m_pm->sustainableTime;
|
||||
// m_pmStateMsg.state.m_leakage = m_pm->m_leakage;
|
||||
m_pmStateMsg.state.m_leakage = m_pm->m_systemData->generateLeakageCode();
|
||||
m_pmStateMsg.state.m_faultNum = m_pm->m_faultNum;
|
||||
|
||||
m_pm->sendNotification(m_pmStateMsg.key, m_pmStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_pm->sendNotification(m_fcsStateMsg.key, m_fcsStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_pm->sendNotification(m_liBatStateMsg.key, m_liBatStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_pm->sendNotification(m_disSysStateMsg.key, m_disSysStateMsg.buildMsg(*(m_pm->m_systemData),m_pm->m_currentDisBreakerState));
|
||||
m_pm->sendNotification(m_currentStateMsg.key, m_currentStateMsg.buildMsg(m_pm->m_pmCurrentState));
|
||||
|
||||
#ifdef _DEBUG
|
||||
m_pmStateMsg_fb_debug = std::make_pair(m_pmStateMsg.key, m_pmStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_fcsStateMsg_st_debug = std::make_pair(m_fcsStateMsg.key, m_fcsStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_liBatStateMsg_st_debug = std::make_pair(m_liBatStateMsg.key, m_liBatStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_disSysStateMsg_st_debug = std::make_pair(m_disSysStateMsg.key, m_disSysStateMsg.buildMsg(*(m_pm->m_systemData),m_pm->m_currentDisBreakerState));
|
||||
m_currentStateMsg_st_debug = std::make_pair(m_currentStateMsg.key, m_currentStateMsg.buildMsg(m_pm->m_pmCurrentState));
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
#ifndef UPPER_COMM_MANAGER_H
|
||||
#define UPPER_COMM_MANAGER_H
|
||||
|
||||
#include "MOOS/libMOOS/Thirdparty/AppCasting/AppCastingMOOSApp.h"
|
||||
#include "pmSysvariable.h"
|
||||
#include "driver.h"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "upmsg/uPower_equInsState.h"
|
||||
#include "upmsg/uDevice_secdistState.h"
|
||||
#include "upmsg/uPower_equState.h"
|
||||
#include "upmsg/uPower_disSysState.h"
|
||||
#include "upmsg/uPower_currentState_st.h"
|
||||
#include "upmsg/uPower_pmState.h"
|
||||
#include "upmsg/uPower_fcsState.h"
|
||||
#include "upmsg/uPower_liBatState.h"
|
||||
#include "upmsg/uDevice_depth.h"
|
||||
#include "upmsg/uExternComm_setOpCondition.h"
|
||||
#include "upmsg/uExternComm_setOpMode.h"
|
||||
#include "upmsg/uPlan_taskStart.h"
|
||||
#include "upmsg/uPlan_planStop.h"
|
||||
#include "upmsg/uExternComm_setDeviceSwitch.h"
|
||||
#include "upmsg/uExternComm_setPowerSystem.h"
|
||||
#include "upmsg/uPower_equState.h"
|
||||
#include "upmsg/uPower_sysState.h"
|
||||
#include "upmsg/uDetect_zdpVoltage_cmd.h"
|
||||
#include "upmsg/uDetect_xcVoltage_cmd.h"
|
||||
#include "upmsg/uDevice_thruster_st.h"
|
||||
|
||||
#define _DEBUG
|
||||
|
||||
using namespace std;
|
||||
#define VAR_TO_STR(var) #var
|
||||
//控制消息
|
||||
#define DB_TO_PM_MSCMD "uPower_sysState_cmd"
|
||||
#define DB_TO_PM_EQUIPMENTCMD "uPower_equState_cmd"
|
||||
|
||||
//决策消息
|
||||
#define DB_TO_PM_DEEPTH "uDevice_depth_st"
|
||||
// #define DB_TO_PM_MISSION "uPlan_taskStart_cmd"
|
||||
#define DB_TO_PM_TASKSTOP "uPlan_planStop_st"
|
||||
|
||||
//外部通信消息
|
||||
#define DB_TO_PM_SETOPCONDITION "uExternComm_setOpCondition_cmd"
|
||||
#define DB_TO_PM_SETOPMODE "uExternComm_setOpMode_cmd"
|
||||
#define DB_TO_PM_SETPMSYS "uExternComm_setPowerSystem_cmd"
|
||||
#define DB_TO_PM_SETDEVSWITCH "uExternComm_setDeviceSwitch_cmd"
|
||||
|
||||
class PowerManger; // 前向声明
|
||||
|
||||
class UpperCommManager {
|
||||
public:
|
||||
UpperCommManager(PowerManger* powerManager);
|
||||
~UpperCommManager(){};
|
||||
|
||||
// 周期调用
|
||||
void processPeriodicTasks();
|
||||
|
||||
// 处理上位机消息
|
||||
bool processUpperMsg(const std::string& key, const std::string& msg);
|
||||
|
||||
// 生成系统报告
|
||||
void buildSystemReport();
|
||||
|
||||
public:
|
||||
//定义上位机消息
|
||||
uPower_equInsStateMsg m_equInsStateMsg;
|
||||
uDevice_secdistStateMsg m_secdistStateMsg;
|
||||
uPower_equStateMsg m_equStateMsg;
|
||||
uPower_disSysStateMsg m_disSysStateMsg;
|
||||
uPower_currentStateMsg m_currentStateMsg;
|
||||
uPower_pmStateMsg m_pmStateMsg;
|
||||
uPower_fcsStateMsg m_fcsStateMsg;
|
||||
uPower_liBatStateMsg m_liBatStateMsg;
|
||||
|
||||
//上位机订阅消息
|
||||
uDevice_depthMsg m_depthMsg;
|
||||
uExternComm_setOpConditionMsg m_setOpConditionMsg;
|
||||
uExternComm_setOpModeMsg m_setOpModeMsg;
|
||||
uPlan_taskStartMsg m_taskStartMsg;
|
||||
uPlan_planStopMsg m_taskStopMsg;
|
||||
uExternComm_setDeviceSwitchMsg m_setDevSwitchMsg;
|
||||
uExternComm_setPowerSystemMsg m_setPMSysMsg;
|
||||
uPower_sysStateMsg m_sysStateMsg;
|
||||
private:
|
||||
PowerManger* m_pm;
|
||||
MSControlCmd m_msCmd;
|
||||
Driver m_driver;
|
||||
|
||||
#ifdef _DEBUG
|
||||
public:
|
||||
std::pair<string, string> m_equInsStateMsg_fb_degub;
|
||||
std::pair<string, string> m_secdistStateMsg_cmd_debug;
|
||||
std::pair<string, string> m_secdistStateMsg_fb_debug;
|
||||
|
||||
std::pair<string, string> m_equStateMsg_cmd_debug;
|
||||
std::pair<string, string> m_equStateMsg_fb_debug;
|
||||
std::pair<string, string> m_disSysStateMsg_st_debug;
|
||||
std::pair<string, string> m_currentStateMsg_st_debug;
|
||||
std::pair<string, string> m_pmStateMsg_fb_debug;
|
||||
std::pair<string, string> m_fcsStateMsg_st_debug;
|
||||
std::pair<string, string> m_liBatStateMsg_st_debug;
|
||||
|
||||
std::pair<string, string> m_depthMsg_st_debug;
|
||||
std::pair<string, string> m_setOpConditionMsg_st_debug;
|
||||
std::pair<string, string> m_setOpModeMsg_st_debug;
|
||||
std::pair<string, string> m_taskStartMsg_st_debug;
|
||||
std::pair<string, string> m_taskStopMsg_st_debug;
|
||||
std::pair<string, string> m_setDevSwitchMsg_st_debug;
|
||||
std::pair<string, string> m_setPMSysMsg_st_debug;
|
||||
std::pair<string, string> m_sysStateMsg_st_debug;
|
||||
#endif
|
||||
// bool parseControlCmdFromJson(MSControlCmd &cmd, const std::string &strJson);
|
||||
};
|
||||
|
||||
#endif // UPPER_COMM_MANAGER_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,138 @@
|
||||
#ifndef DRIVER_H
|
||||
#define DRIVER_H
|
||||
#include <memory>
|
||||
#include "json/json.h"
|
||||
#include "iostream"
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include "pmSysvariable.h"
|
||||
|
||||
#define DRIVER_POWER_OFF 0x00
|
||||
#define DRIVER_FULL_POWER_ON 0x01
|
||||
#define DRIVER_INSTRUMENT_POWER_ON 0x02
|
||||
#define DRIVER_MOTIVE_POWER_ON 0x03
|
||||
#define DRIVER_STANDBY 0x04
|
||||
|
||||
using namespace std;
|
||||
struct DriverTable
|
||||
{
|
||||
unsigned char depth1;
|
||||
unsigned char depth2;
|
||||
unsigned char depth3;
|
||||
unsigned char overDeep1;
|
||||
unsigned char overDeep2;
|
||||
unsigned char ctd1;
|
||||
unsigned char ctd2;
|
||||
unsigned char soundVeloc;
|
||||
unsigned char commMast;
|
||||
unsigned char ins;
|
||||
unsigned char ntp;
|
||||
unsigned char inputWaterSensor1;
|
||||
unsigned char inputWaterSensor2;
|
||||
unsigned char inputWaterSensor3;
|
||||
//水声设备
|
||||
unsigned char singleBeamSonar1;
|
||||
unsigned char singleBeamSonar2;
|
||||
unsigned char singleBeamSonar3;
|
||||
unsigned char singleBeamSonar4;
|
||||
unsigned char singleBeamSonar5;
|
||||
unsigned char singleBeamSonar6;
|
||||
unsigned char singleBeamSonar7;
|
||||
unsigned char singleBeamSonar8;
|
||||
unsigned char forwardSonar;
|
||||
unsigned char DVL;
|
||||
unsigned char lowFreqSonar;
|
||||
unsigned char USBL;
|
||||
//执行机构
|
||||
unsigned char bowWaterInet1;
|
||||
unsigned char bowWaterInet2;
|
||||
unsigned char bowWaterInet3;
|
||||
unsigned char bowWaterInet4;
|
||||
unsigned char bowWaterInet5;
|
||||
unsigned char bowWaterInet6;
|
||||
unsigned char bowWaterInet7;
|
||||
unsigned char bowWaterInet8;
|
||||
unsigned char bowRudderDeploy;
|
||||
unsigned char bowRudderServo1;
|
||||
unsigned char bowRudderServo2;
|
||||
unsigned char bowCover1;
|
||||
unsigned char bowCover2;
|
||||
unsigned char bowCover3;
|
||||
unsigned char bowCover4;
|
||||
unsigned char bowCover5;
|
||||
unsigned char bowCover6;
|
||||
unsigned char waterInject;
|
||||
unsigned char mastLiftingServo;
|
||||
unsigned char buoyancyAdjust1;
|
||||
unsigned char buoyancyAdjust2;
|
||||
unsigned char buoyancyAdjust3;
|
||||
unsigned char buoyancyAdjust4;
|
||||
unsigned char buoyancyAdjust5;
|
||||
unsigned char sternRudderServo1;
|
||||
unsigned char sternRudderServo2;
|
||||
unsigned char sternRudderServo3;
|
||||
unsigned char sternRudderServo4;
|
||||
unsigned char thruster;
|
||||
unsigned char bowThrow;
|
||||
unsigned char sternThrow;
|
||||
//负载
|
||||
unsigned char photoSensor;
|
||||
unsigned char electSensor;
|
||||
unsigned char launchControler;
|
||||
unsigned char sideSonar;
|
||||
unsigned char buoyage;
|
||||
};
|
||||
|
||||
struct DriverCommand
|
||||
{
|
||||
int id;
|
||||
int cmd;
|
||||
};
|
||||
|
||||
|
||||
class Driver
|
||||
{
|
||||
public:
|
||||
Driver();
|
||||
~Driver();
|
||||
void setDebug(bool debug);
|
||||
|
||||
public:
|
||||
std::unique_ptr<DriverTable> currentDriverTable;
|
||||
std::unique_ptr<DriverTable> nextDriverTable;
|
||||
|
||||
//操作函数,操作指定设备
|
||||
void setDeviceState(DriverTable &driverTable, DeviceId::Type deviceId, unsigned char s);
|
||||
unsigned char getDeviceState(const DriverTable &driverTable, DeviceId::Type deviceId);
|
||||
|
||||
void getSTANDBYTable(DriverTable* driverTable);
|
||||
void getSHORE_BASED_READYable(DriverTable* driverTable);
|
||||
void getWATER_BASED_READYable(DriverTable* driverTable);
|
||||
void getCRUISE_MODEable(DriverTable* driverTable);
|
||||
void getHIGH_SPEED_MODEable(DriverTable* driverTable);
|
||||
void getASCEND_DESCENDable(DriverTable* driverTable);
|
||||
void getBUOYANCY_ADJUSTable(DriverTable* driverTable);
|
||||
void getUNDERWATER_RECONable(DriverTable* driverTable);
|
||||
void getSURFACE_RECONable(DriverTable* driverTable);
|
||||
void getDJ_MODEable(DriverTable* driverTable);
|
||||
|
||||
// void setDriverTable(DriverTable* driverTable, );
|
||||
|
||||
std::string getDriverTableJson();
|
||||
std::string getSubDisCmdJson(const DriverTable* driverTable);
|
||||
std::string getDriveStateJson(const DriverTable* driverTable);
|
||||
|
||||
std::string saveDriverTableToJson(const DriverTable* driverTable);
|
||||
int loadDriverTableFromJson(const std::string &strJson, DriverTable& table);
|
||||
vector<DriverCommand> loadDriverIdFromJson(const std::string &strJson);
|
||||
|
||||
int SafeReadUInt(const Json::Value& root, const std::string& key, unsigned char& value);
|
||||
|
||||
private:
|
||||
|
||||
bool debug;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // DRIVER_H
|
||||
@@ -0,0 +1,125 @@
|
||||
#ifndef FAULTCODE_H
|
||||
#define FAULTCODE_H
|
||||
|
||||
/**
|
||||
* @file faultCode.h
|
||||
* @brief 锂电池故障码定义及映射表
|
||||
*/
|
||||
|
||||
// 故障码映射表
|
||||
typedef struct {
|
||||
int id; // 序号
|
||||
int level; // 故障级别
|
||||
const uint8_t code; // 16进制故障码
|
||||
const char* desc; // 报警信息
|
||||
} FaultMap;
|
||||
|
||||
static const FaultMap batfaultMap[] = {
|
||||
//四级故障
|
||||
{1, 4, 0xC1, "MBMS绝缘故障"},
|
||||
{2, 4, 0xC2, "温度过高"},
|
||||
{3, 4, 0xC3, "MBMS预充失败"},
|
||||
{4, 4, 0xC4, "MBMS正主极继电器失效"},
|
||||
{5, 4, 0xC5, "MBMS负主极继电器失效"},
|
||||
{6, 4, 0xC6, "MBMS燃电充电正极继电器正极失效[仪器]"},
|
||||
{7, 4, 0xC7, "母线高压回路异常"},
|
||||
{8, 4, 0xC9, "MBMS电压测量异常"},
|
||||
{9, 4, 0xCA, "MBMS电流测量异常"},
|
||||
//三级故障
|
||||
{10, 3, 0x81, "MBMS绝缘故障3级"},
|
||||
{11, 3, 0x82, "温度过高3级"},
|
||||
{12, 3, 0x83, "温度过低3级"},
|
||||
{13, 3, 0x84, "MBMS总放电超功率3级"},
|
||||
{14, 3, 0x85, "MBMS总充电电流过大3级"},
|
||||
//二级故障
|
||||
{15, 1, 0x31, "BMS均衡模块故障2级"},
|
||||
{16, 2, 0x41, "MBMS绝缘故障2级"},
|
||||
{17, 2, 0x42, "MBMS总放电超功率2级"},
|
||||
{18, 2, 0x43, "电池包放电超功率2级"},
|
||||
{19, 2, 0x44, "MBMS总放电过流2级"},
|
||||
{20, 2, 0x45, "单包异常剔除2级"},
|
||||
{21, 2, 0x46, "单包没有电流2级"},
|
||||
{22, 2, 0x47, "自检有重复ID号2级"},
|
||||
{23, 2, 0x48, "电池包接入失败2级"},
|
||||
{24, 2, 0x49, "电池包充电电流过大2级"},
|
||||
{25, 2, 0x51, "电池包绝缘故障2级"},
|
||||
{26, 2, 0x52, "电池包温度过高2级"},
|
||||
{27, 2, 0x53, "电池包温度过低2级"},
|
||||
{28, 2, 0x54, "电池包单体电压不均衡2级"},
|
||||
{29, 2, 0x55, "电池包单体温度不均衡2级"},
|
||||
{30, 2, 0x56, "电池包过流2级"},
|
||||
{31, 2, 0x57, "电池包充电电流过大2级"},
|
||||
{32, 2, 0x58, "电池包单体电压过高2级"},
|
||||
{33, 2, 0x59, "电池包单体电压过低2级"},
|
||||
{34, 2, 0x5A, "电池包总电压过高2级"},
|
||||
{35, 2, 0x5B, "电池包总电压过低2级"},
|
||||
{36, 2, 0x5C, "电池包内部通讯故障2级"},
|
||||
{37, 2, 0x5D, "电池包初始化故障2级"},
|
||||
{38, 2, 0x62, "电池包高压回路连接异常2级"},
|
||||
{39, 2, 0x65, "电池包烟雾报警2级"},
|
||||
{40, 2, 0x72, "MBMS在线燃电充电超温2级"},
|
||||
//一级故障
|
||||
{41, 1, 0x01, "MBMS绝缘故障1级"},
|
||||
{42, 1, 0x02, "MBMS总放电超功率1级"},
|
||||
{43, 1, 0x11, "电池包绝缘故障1级"},
|
||||
{44, 1, 0x12, "电池包最高温度过高1级"},
|
||||
{45, 1, 0x13, "电池包最低温度过低1级"},
|
||||
{46, 1, 0x14, "电池包单体电压不均衡1级"},
|
||||
{47, 1, 0x15, "电池包单体温度不均衡1级"},
|
||||
{48, 1, 0x16, "电池包放电过流1级"},
|
||||
{49, 1, 0x17, "电池包充电电流过大1级"},
|
||||
{50, 1, 0x18, "电池包单体电压过高1级"},
|
||||
{51, 1, 0x19, "电池包单体电压过低1级"},
|
||||
{52, 1, 0x1A, "电池包总电压过高1级"},
|
||||
{53, 1, 0x1B, "电池包总电压过低1级"},
|
||||
{54, 1, 0x1D, "电池包烟雾报警1级"},
|
||||
};
|
||||
|
||||
static const FaultMap disfaultMap[] = {
|
||||
{1, 3, 1, "燃料电池断路器故障脱扣"},
|
||||
{2, 4, 2, "动力锂电池断路器故障脱扣"},
|
||||
{3, 4, 3, "推进电机断路器故障脱扣"},
|
||||
{4, 4, 4, "锂电池组仪表断路器故障脱扣"},
|
||||
{5, 4, 5, "DC/DC5模块断路器故障脱扣"},
|
||||
{6, 4, 6, "艏部高压配电箱断路器故障脱扣"},
|
||||
{7, 4, 7, "艉部FT装置4/5断路器故障脱扣"},
|
||||
{8, 4, 8, "艉舵开关1断路器故障脱扣"},
|
||||
{9, 4, 9, "艉舵开关2断路器故障脱扣"},
|
||||
{10, 4, 10, "FB预留断路器故障脱扣"},
|
||||
{11, 4, 11, "TYZ预留断路器故障脱扣"},
|
||||
{12, 4, 12, "预留断路器故障脱扣"},
|
||||
{13, 4, 13, "艏部FT装置1-3 断路器故障脱扣"},
|
||||
{14, 4, 14, "启闭机构断路器故障脱扣"},
|
||||
{15, 4, 15, "桅杆舵机控制箱断路器故障脱扣"},
|
||||
{16, 4, 16, "XCZ 断路器故障脱扣"},
|
||||
{17, 4, 17, "艏舵控制箱断路器故障脱扣"},
|
||||
{18, 4, 18, "敞水盖启动电缸断路器故障脱扣"},
|
||||
{19, 4, 19, "锂电池组(仪表)断路器故障脱扣"},
|
||||
{20, 4, 20, "艏部低压配电箱断路器故障脱扣"},
|
||||
{21, 4, 21, "UNIT4仪表DC48V断路器故障脱扣"},
|
||||
{22, 4, 22, "DC-DC1直流配电板断路器故障脱扣"},
|
||||
{23, 4, 23, "预留断路器故障脱扣"},
|
||||
{24, 4, 24, "预留断路器故障脱扣"},
|
||||
{25, 4, 25, "应急锂电池组2断路器"},
|
||||
{26, 4, 26, "UNIT1断路器故障脱扣"},
|
||||
{27, 4, 27, "UNIT2断路器故障脱扣"},
|
||||
{28, 4, 28, "UNIT3断路器故障脱扣"},
|
||||
{29, 4, 29, "UNIT5断路器故障脱扣"},
|
||||
{30, 4, 30, "艏部PZ装置断路器故障脱扣"},
|
||||
{31, 4, 31, "预留断路器故障脱扣"},
|
||||
{32, 4, 32, "预留断路器故障脱扣"},
|
||||
{33, 4, 33, "应急锂电池组1断路器故障脱扣"},
|
||||
{34, 4, 34, "动力母排绝缘低"},
|
||||
{35, 4, 35, "A汇流排绝缘低"},
|
||||
{36, 4, 36, "高压母线配电控制器仪表电源失电信号"},
|
||||
{37, 4, 37, "高压母线配电控制器应急电源失电信号"},
|
||||
{38, 4, 38, "高压汇流排A仪表电源失电信号"},
|
||||
{39, 4, 39, "高压汇流排A应急电源失电信号"},
|
||||
{40, 4, 40, "高压汇流排A仪表汇流排绝缘低"},
|
||||
{41, 4, 41, "高压汇流排B仪表电源失电信号"},
|
||||
{42, 4, 42, "高压汇流排B应急电源失电信号"},
|
||||
{43, 4, 43, "高压汇流排B仪表汇流排绝缘低"},
|
||||
{44, 4, 44, "仪表汇流排失电信号"},
|
||||
{45, 4, 45, "仪表汇流排浸水报警"}
|
||||
};
|
||||
#endif // FAULTCODE_H
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
void CruiseMode::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
// pm->m_driver.getCRUISE_MODEable(&pm->m_subDisSysCmd);
|
||||
handleCuriseWork();
|
||||
//解除非必要动力电设备
|
||||
//1 解除启闭机构
|
||||
unsigned char cmd = 0;
|
||||
if(pm->m_currentDriverState.bowCover1 != 0 ||
|
||||
pm->m_currentDriverState.bowCover2 != 0 ||
|
||||
pm->m_currentDriverState.bowCover3 != 0 ||
|
||||
pm->m_currentDriverState.bowCover4 != 0 ||
|
||||
pm->m_currentDriverState.bowCover5 != 0 ||
|
||||
pm->m_currentDriverState.bowCover6 != 0)
|
||||
{
|
||||
pm->m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover6, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
}
|
||||
|
||||
//2 解除敞水机构
|
||||
if(pm->m_currentDriverState.bowWaterInet1 != 0 ||
|
||||
pm->m_currentDriverState.bowWaterInet2 != 0 ||
|
||||
pm->m_currentDriverState.bowWaterInet3 != 0 ||
|
||||
pm->m_currentDriverState.bowWaterInet4 != 0 ||
|
||||
pm->m_currentDriverState.bowWaterInet5 != 0 ||
|
||||
pm->m_currentDriverState.bowWaterInet6 != 0 ||
|
||||
pm->m_currentDriverState.bowWaterInet7 != 0 ||
|
||||
pm->m_currentDriverState.bowWaterInet8 != 0)
|
||||
{
|
||||
pm->m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet6, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet7, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet8, (unsigned char)cmd);
|
||||
}
|
||||
pm->workCondition = WorkCondition::CRUISE_MODE;
|
||||
LOG_F(INFO, "进入巡航模式");
|
||||
}
|
||||
|
||||
// CruiseMode实现
|
||||
void CruiseMode::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
|
||||
// DJMode实现
|
||||
void DJMode::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void DJMode::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
handleCuriseWork();
|
||||
//1 启动载荷装置
|
||||
pm->m_subDisSysCmd.launchControler = 1;
|
||||
//启动启闭机构和电缸
|
||||
unsigned char cmd = 1;
|
||||
//2.1 启闭机构
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover6, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(10);
|
||||
pm->m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(1);
|
||||
//2.2 敞水电缸
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet6, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet7, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet8, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(10);
|
||||
pm->m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(1);
|
||||
pm->workCondition = WorkCondition::DJ_MODE;
|
||||
LOG_F(INFO, "进入DJ模式");
|
||||
}
|
||||
|
||||
|
||||
void DJMode::exit() {
|
||||
PowerManagerFsm::exit();
|
||||
//1 解除启闭机构
|
||||
unsigned char cmd = 0;
|
||||
pm->m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover6, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
//2 解除敞水机构
|
||||
pm->m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet6, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet7, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet8, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
// FaultState实现
|
||||
void FaultState::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
if(pm->m_missionState.type == TaskType::THROW_LOAD)
|
||||
{
|
||||
LOG_F(INFO, "检测到抛载");
|
||||
}
|
||||
}
|
||||
|
||||
void FaultState::react(FaultEvent const & e) {
|
||||
LOG_F(INFO, "FaultState 处理故障事件");
|
||||
}
|
||||
|
||||
void FaultState::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
// FloatAdjust实现
|
||||
void FloatAdjust::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void FloatAdjust::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
handleCuriseWork();
|
||||
pm->workCondition = WorkCondition::BUOYANCY_ADJUST;
|
||||
LOG_F(INFO, "进入浮调模式");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
void FloatDown::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
handleCuriseWork();
|
||||
pm->workCondition = WorkCondition::ASCEND_DESCEND;
|
||||
LOG_F(INFO, "进入上浮下潜模式");
|
||||
}
|
||||
|
||||
// FloatDown实现
|
||||
void FloatDown::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
void HighSpeedMode::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
handleCuriseWork();
|
||||
pm->workCondition = WorkCondition::HIGH_SPEED_MODE;
|
||||
LOG_F(INFO, "进入高速模式");
|
||||
}
|
||||
|
||||
// HighSpeedMode实现
|
||||
void HighSpeedMode::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
// InitState实现
|
||||
void InitState::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
LOG_F(INFO, "进入初始化状态");
|
||||
pm->initControlCmd();
|
||||
pm->m_lowerCommManager->operate_hold();
|
||||
transit<StandbyState>();
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
void Lifting::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
//1. 关闭所有水声设备
|
||||
LOG_F(INFO,"前视声纳关机指令");
|
||||
pm->sendNotification("uExternComm_frontSonarControl_cmd","0");
|
||||
MOOSPause(10000);
|
||||
for(auto iter : underWterDevices)
|
||||
{
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, static_cast<DeviceId::Type>(iter), 0);
|
||||
}
|
||||
//2. 关闭动力电设备
|
||||
//2.1 断开所有艏部高压断路器
|
||||
pm->m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_bowFTDevice123Circuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_bowRudderControlBoxCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_xczCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
//2.2 断开所有艉部高压设备断路器
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_sternFt45_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_sternRudder1_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_sternRudder2_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_fbReserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_tyzReserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_reserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(0);
|
||||
MOOSPause(3);
|
||||
|
||||
//2.5 断开动力电断路器
|
||||
pm->m_lowerCommManager->operate_HV_bowHighVoltageBox_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5Module_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0);
|
||||
//3. 关闭燃料电池
|
||||
//4. 关闭动力锂电池
|
||||
MOOSPause(3);
|
||||
{
|
||||
int count=0;
|
||||
while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02))
|
||||
{
|
||||
LOG_F(INFO,"动力锂电池下电中...");
|
||||
MOOSPause(3);
|
||||
if(count>10)
|
||||
{
|
||||
LOG_F(INFO, "动力锂电池无下电反馈");
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
LOG_F(INFO, "动力锂电池已下电");
|
||||
pm->workCondition = WorkCondition::LIFT_MODE;
|
||||
LOG_F(INFO, "WorkCondition %d", pm->workCondition);
|
||||
}
|
||||
|
||||
void Lifting::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void Lifting::react(DevCmdExt const &e)
|
||||
{
|
||||
LOG_F(INFO, "DevCmdExt 执行");
|
||||
PowerManagerFsm::react(e);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,300 @@
|
||||
#ifndef POWER_MANAGER_FSM_HPP
|
||||
#define POWER_MANAGER_FSM_HPP
|
||||
#include "tinyfsm.hpp"
|
||||
#include "../logc/loguru.hpp"
|
||||
#include <iostream>
|
||||
#include <chrono> // 新增头文件
|
||||
#include <iomanip> // 新增头文件
|
||||
#include <ctime> // 新增头文件,用于localtime函数
|
||||
#include <cxxabi.h> // 新增头文件,用于demangle功能
|
||||
#include "../pmSysvariable.h"
|
||||
#include "../driver.h"
|
||||
#include "../PowerManger.h"
|
||||
#include "../upmsg/uExternComm_setThrustSpeed_cmd.h"
|
||||
|
||||
|
||||
#define OVER_DEPTH 0.1
|
||||
|
||||
// 前向声明
|
||||
class PowerManger;
|
||||
|
||||
enum class PowerSystemState {
|
||||
INIT,
|
||||
STANDBY,
|
||||
FAULT,
|
||||
};
|
||||
|
||||
//==================状态切换事件=============================
|
||||
struct InitEvent : tinyfsm::Event { };
|
||||
struct StandbyEvent : tinyfsm::Event { };
|
||||
struct TaskStopEvent : tinyfsm::Event { };
|
||||
struct TaskStartEvent : tinyfsm::Event {
|
||||
int type;
|
||||
bool enableBowRudder;
|
||||
bool enableBuoyancyAdjustment;
|
||||
TaskStartEvent() : type(0), enableBowRudder(false), enableBuoyancyAdjustment(false) {};
|
||||
TaskStartEvent(int type, bool bowRudder, bool buoyancyAdjustment) : type(type), enableBowRudder(bowRudder), enableBuoyancyAdjustment(buoyancyAdjustment) {};
|
||||
};
|
||||
//==================状态流程事件============================
|
||||
struct CycleTriggeredEvent : tinyfsm::Event {};
|
||||
struct MasterCommandEvent : tinyfsm::Event {};
|
||||
struct DeviceCmd : tinyfsm::Event {};
|
||||
struct DevCmdExt : tinyfsm::Event {
|
||||
int id;
|
||||
int cmd;
|
||||
DevCmdExt() : id(0), cmd(0) {};
|
||||
DevCmdExt(int id, int cmd) : id(id), cmd(cmd) {};
|
||||
};
|
||||
struct SideSonarCmd : tinyfsm::Event {
|
||||
int xcLowVoltageAdd;
|
||||
int xcHighVoltageAdd;
|
||||
SideSonarCmd() : xcLowVoltageAdd(0),xcHighVoltageAdd(0) {};
|
||||
SideSonarCmd(int xcLowVoltageAdd,int xcHighVoltageAdd) : xcLowVoltageAdd(xcLowVoltageAdd),xcHighVoltageAdd(xcHighVoltageAdd) {};
|
||||
};
|
||||
//==================测试事件================================
|
||||
struct TestEvent : tinyfsm::Event {
|
||||
std::string eventName;
|
||||
unsigned int type;
|
||||
unsigned int eventId;
|
||||
TestEvent() : eventName(""), eventId(0),type(0) {};
|
||||
TestEvent(std::string eventName, unsigned int type,unsigned int eventId) : eventName(eventName), eventId(eventId),type(type) {};
|
||||
};
|
||||
struct FaultEvent : tinyfsm::Event {
|
||||
unsigned int subDisSysFaultCode;
|
||||
unsigned int disSysFaultCode;
|
||||
unsigned int powerFaultCode;
|
||||
unsigned int fcsFaultCode;
|
||||
unsigned int ccsFaultCode;
|
||||
unsigned int injectionFaultCode;
|
||||
FaultEvent() : subDisSysFaultCode(0), disSysFaultCode(0), powerFaultCode(0), fcsFaultCode(0), ccsFaultCode(0),injectionFaultCode(0) {};
|
||||
FaultEvent(unsigned int subDisSysFaultCode,
|
||||
unsigned int disSysFaultCode,
|
||||
unsigned int powerFaultCode,
|
||||
unsigned int fcsFaultCode,
|
||||
unsigned int ccsFaultCode,
|
||||
unsigned int injectionFaultCode)
|
||||
: subDisSysFaultCode(subDisSysFaultCode),
|
||||
disSysFaultCode(disSysFaultCode),
|
||||
powerFaultCode(powerFaultCode),
|
||||
fcsFaultCode(fcsFaultCode),
|
||||
ccsFaultCode(ccsFaultCode),
|
||||
injectionFaultCode(injectionFaultCode) {};
|
||||
};
|
||||
|
||||
class PowerManagerFsm : public tinyfsm::Fsm<PowerManagerFsm> {
|
||||
protected:
|
||||
static PowerManger* pm;
|
||||
static DriverTable m_currentDriver;
|
||||
|
||||
public:
|
||||
static void init(PowerManger* powerManager) {
|
||||
pm = powerManager;
|
||||
}
|
||||
|
||||
virtual void react(tinyfsm::Event const &) { std::cout << "[ Reseve Envt ] " << "No Idear" << std::endl; }
|
||||
virtual void react(InitEvent const &) {};
|
||||
virtual void react(StandbyEvent const &) {};
|
||||
virtual void react(MasterCommandEvent const &) { LOG_F(INFO, "MasterCommandEvent");};
|
||||
// virtual void react(DeviceCmd const &);
|
||||
virtual void react(DevCmdExt const &e);
|
||||
virtual void react(TaskStartEvent const &e);
|
||||
virtual void react(FaultEvent const &e);
|
||||
virtual void react(TaskStopEvent const &e);
|
||||
virtual void react(CycleTriggeredEvent const &e);
|
||||
virtual void react(SideSonarCmd const &e);
|
||||
|
||||
|
||||
//测试事件
|
||||
virtual void react(TestEvent const &);
|
||||
|
||||
//======================操作函数=============================
|
||||
void handelPowerCmd();
|
||||
void handleModCmd();
|
||||
void handleWorkCmd();
|
||||
void handleDeviceCmd();
|
||||
|
||||
void handleCuriseWork();
|
||||
|
||||
void handleNoPowerDeviceCmd(int id , int cmd); // 非水声仪表设备
|
||||
void handleHydroacousticDeviceCmd(int id , int cmd); // 水声设备处理
|
||||
void handleBowRudderSystemCmd(int id, int cmd); // 艏舵设备处理
|
||||
void handleActuatorCmd(int id, int cmd); // 启闭机构处理
|
||||
void handleOpenWaterCmd(int id, int cmd); // 敞水机构处理
|
||||
void handleSternRudderCmd(int id, int cmd); // 艉舵设备处理
|
||||
void handlePropulsionMotorCmd(int id, int cmd); // 推进电机处理
|
||||
void handleBuoyancyAdjustmentCmd(int id, int cmd); // 浮调设备处理
|
||||
void handleFBSystemCmd(int id, int cmd); // FB设备处理
|
||||
void handleSideSonarCmd(int id, int cmd); // 舷侧设备处理
|
||||
void handleMastFoldingSystemCmd(int id, int cmd); // 桅杆设备处理
|
||||
|
||||
//获取仅仪表设备状态
|
||||
void getNoPowerDeviceStatus(DriverTable &s);
|
||||
void getBowRudderSystemStatus(DriverTable &s);
|
||||
void getActuatorStatus(DriverTable &s);
|
||||
void getSternRudderStatus(DriverTable &s);
|
||||
void getPropulsionMotorStatus(DriverTable &s);
|
||||
void getBuoyancyAdjustmentStatus(DriverTable &s);
|
||||
void getFBSystemCmdStatus(DriverTable &s);
|
||||
void getSideSonarStatus(DriverTable &s);
|
||||
void getMastFoldingSystem(DriverTable &s);
|
||||
void getOpenWaterStatus(DriverTable &s);
|
||||
|
||||
//故障处理
|
||||
void basicNavigationFault(FaultEvent const &e);
|
||||
void extendedNavigationFault(FaultEvent const &e);
|
||||
void obstacleAvoidanceFault(FaultEvent const &e);
|
||||
void buoyancyControlFault(FaultEvent const &e);
|
||||
void communicationSystemFault(FaultEvent const &e);
|
||||
void payloadSystemFault(FaultEvent const &e);
|
||||
void emergencySystemFault(FaultEvent const &e);
|
||||
void sensorSystemFault(FaultEvent const &e);
|
||||
|
||||
void basicNavigationFault();
|
||||
void extendedNavigationFault();
|
||||
void obstacleAvoidanceFault();
|
||||
void buoyancyControlFault();
|
||||
void communicationSystemFault();
|
||||
void payloadSystemFault();
|
||||
void emergencySystemFault();
|
||||
void sensorSystemFault();
|
||||
|
||||
// void handleFaultOfDisSys();
|
||||
// 状态机生命周期方法
|
||||
virtual void entry() {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto now_time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
int status = 0;
|
||||
char* demangled = abi::__cxa_demangle(typeid(*this).name(), nullptr, nullptr, &status);
|
||||
std::string typeName = (status == 0) ? demangled : typeid(*this).name();
|
||||
if (demangled) free(demangled);
|
||||
|
||||
std::cout << "\033[1;38;5;51m╭──────────────────────────────────────────────────────\n"
|
||||
<< "│ \033[1;38;5;226m⮞⮞⮞ \033[0;38;5;51m[" << std::put_time(std::localtime(&now_time), "%Y-%m-%d %H:%M:%S")
|
||||
<< "] \033[1;38;5;255m进入状态: \033[1;38;5;213m" << typeName << "\n"
|
||||
<< "│ \033[0m" << std::endl;
|
||||
|
||||
LOG_F(INFO, "进入状态: %s", typeName.c_str());
|
||||
}
|
||||
|
||||
virtual void exit() {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto now_time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
int status = 0;
|
||||
char* demangled = abi::__cxa_demangle(typeid(*this).name(), nullptr, nullptr, &status);
|
||||
std::string typeName = (status == 0) ? demangled : typeid(*this).name();
|
||||
if (demangled) free(demangled);
|
||||
|
||||
std::cout << "\033[1;38;5;203m│ \n"
|
||||
<< "│ \033[1;38;5;208m⮜⮜⮜ \033[0;38;5;203m[" << std::put_time(std::localtime(&now_time), "%Y-%m-%d %H:%M:%S")
|
||||
<< "] \033[1;38;5;255m离开状态: \033[1;38;5;213m" << typeName << "\n"
|
||||
<< "╰──────────────────────────────────────────────────────\033[0m" << std::endl;
|
||||
|
||||
LOG_F(INFO, "离开状态: %s", typeName.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
class InitState : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
};
|
||||
|
||||
//待机状态
|
||||
class StandbyState : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(StandbyEvent const &) override;
|
||||
void react(DevCmdExt const &e) override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
};
|
||||
|
||||
// 岸基备航
|
||||
class ShoreBasedReady : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
private:
|
||||
};
|
||||
// 水中备航
|
||||
class WaterBasedReady : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
void react(DevCmdExt const &e) override;
|
||||
private:
|
||||
};
|
||||
// 巡航模式
|
||||
class CruiseMode : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
private:
|
||||
};
|
||||
// 上浮下潜
|
||||
class FloatDown : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
private:
|
||||
};
|
||||
// 高速模式
|
||||
class HighSpeedMode : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
private:
|
||||
};
|
||||
|
||||
// 浮调模式
|
||||
class FloatAdjust : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
private:
|
||||
};
|
||||
// 水下侦查
|
||||
class UnderwaterSurvey : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
private:
|
||||
};
|
||||
// 水面侦查
|
||||
class SurfaceSurvey : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
private:
|
||||
};
|
||||
// DJ模式
|
||||
class DJMode : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
void exit() override;
|
||||
private:
|
||||
};
|
||||
// 遥控工况
|
||||
class RemoteControl : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
private:
|
||||
};
|
||||
|
||||
class FaultState : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(FaultEvent const &);
|
||||
void react(MasterCommandEvent const &) override;
|
||||
};
|
||||
|
||||
class Lifting : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
};
|
||||
|
||||
#endif // POWER_MANAGER_FSM_HPP
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
// RemoteControl实现
|
||||
void RemoteControl::react(MasterCommandEvent const &){
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void RemoteControl::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::REMOTE_CONTROL;
|
||||
LOG_F(INFO, "进入遥控工况");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
// ShoreBasedReady实现
|
||||
void ShoreBasedReady::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void ShoreBasedReady::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->m_driver.getSHORE_BASED_READYable(&pm->m_subDisSysCmd);
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
//依次接入执行机构动力电设备
|
||||
//1. 开启动力电
|
||||
//1.1 动力锂电池上电
|
||||
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start;
|
||||
//1.2 闭合动力电断路器
|
||||
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(1);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5Module_Breaker(1);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(1);
|
||||
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(1);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_bowHighVoltageBox_Breaker(1);
|
||||
MOOSPause(100);
|
||||
//2. 启动动力电设备
|
||||
unsigned char cmd = 1;
|
||||
//2.0 艉舵
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::sternRudderServo1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::sternRudderServo2, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
pm->m_lowerCommManager->operate_HV_sternRudder1_Breaker(1);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::sternRudderServo3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::sternRudderServo4, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
pm->m_lowerCommManager->operate_HV_sternRudder2_Breaker(1);
|
||||
//2.1 启闭机构
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover6, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(1);
|
||||
//2.2 敞水电缸
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet3, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet6, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet7, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet8, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(1);
|
||||
//2.3 艏舵
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowRudderDeploy, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowRudderServo1, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_bowRudderControlBoxCircuit_Breaker(1);
|
||||
//2.4 桅杆舵机
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::mastLiftingServo, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(1);
|
||||
//2.5 艏部浮调机构
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust3, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_bowFTDevice123Circuit_Breaker(1);
|
||||
//2.6 艉部浮调机构
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust5, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_sternFt45_Breaker(1);
|
||||
//2.7 推进电机
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::thruster, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(1);
|
||||
pm->workCondition = WorkCondition::SHORE_BASED_READY;
|
||||
LOG_F(INFO, "进入岸基备航状态");
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
// StandbyState实现
|
||||
void StandbyState::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::STANDBY;
|
||||
pm->m_driver.getSTANDBYTable(&pm->m_subDisSysCmd);
|
||||
pm->m_lowerCommManager->operate_hold();
|
||||
LOG_F(INFO, "WorkCondition %d", pm->workCondition);
|
||||
}
|
||||
void StandbyState::react(StandbyEvent const &) {
|
||||
transit<StandbyState>();
|
||||
}
|
||||
void StandbyState::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void StandbyState::react(DevCmdExt const &e)
|
||||
{
|
||||
LOG_F(INFO, "DevCmdExt 执行");
|
||||
PowerManagerFsm::react(e);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
// SurfaceSurvey实现
|
||||
void SurfaceSurvey::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void SurfaceSurvey::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
handleCuriseWork();
|
||||
pm->workCondition = WorkCondition::SURFACE_RECON;
|
||||
LOG_F(INFO, "进入水面侦查模式");
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
void UnderwaterSurvey::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
handleCuriseWork();
|
||||
pm->workCondition = WorkCondition::UNDERWATER_RECON;
|
||||
LOG_F(INFO, "进入水下侦查模式");
|
||||
}
|
||||
|
||||
|
||||
// UnderwaterSurvey实现
|
||||
void UnderwaterSurvey::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
|
||||
void WaterBasedReady::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
PowerManagerFsm::handleCuriseWork();
|
||||
//启动水声设备
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::DVL, (unsigned char)EquipmentCommand::ON);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::USBL, (unsigned char)EquipmentCommand::ON);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
pm->workCondition = WorkCondition::WATER_BASED_READY;
|
||||
LOG_F(INFO, "进入水中备航状态");
|
||||
}
|
||||
|
||||
// WaterBasedReady实现
|
||||
void WaterBasedReady::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void WaterBasedReady::react(DevCmdExt const &e)
|
||||
{
|
||||
int id = e.id;
|
||||
int cmd = e.cmd;
|
||||
if(underWterDevices.find(id) != underWterDevices.end())
|
||||
{
|
||||
if (pm->currentMod != PMMode::Debug)
|
||||
{
|
||||
if(pm->m_depth < OVER_DEPTH)
|
||||
{
|
||||
LOG_F(INFO, "水下设备操作上电保护 %d ", id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 如果是前视声纳断电则先关机再断电
|
||||
if(id == DeviceId::forwardSonar)
|
||||
{
|
||||
if(cmd == 0)
|
||||
{
|
||||
LOG_F(INFO,"前视声纳关机指令");
|
||||
pm->sendNotification("uExternComm_frontSonarControl_cmd","0");
|
||||
MOOSPause(10000);
|
||||
}
|
||||
}
|
||||
LOG_F(INFO, "水声设备操作: %s,%d, %d", DeviceId::toString((DeviceId::Type)id), id, cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, (DeviceId::Type)id, (unsigned char)cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pm->currentMod == PMMode::Normal)
|
||||
{
|
||||
LOG_F(INFO,"正常模式:操作禁止");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PowerManagerFsm::react(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* TinyFSM - Tiny Finite State Machine Processor
|
||||
*
|
||||
* Copyright (c) 2012-2022 Axel Burri
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Version: 0.3.3
|
||||
*
|
||||
* API documentation: see "../doc/50-API.md"
|
||||
*
|
||||
* The official TinyFSM website is located at:
|
||||
* https://digint.ch/tinyfsm/
|
||||
*
|
||||
* Author:
|
||||
* Axel Burri <axel@tty0.ch>
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TINYFSM_HPP_INCLUDED
|
||||
#define TINYFSM_HPP_INCLUDED
|
||||
|
||||
#ifndef TINYFSM_NOSTDLIB
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
// #include <iostream>
|
||||
// #define DBG(str) do { std::cerr << str << std::endl; } while( false )
|
||||
// DBG("*** dbg_example *** " << __PRETTY_FUNCTION__);
|
||||
|
||||
namespace tinyfsm
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
struct Event { };
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#ifdef TINYFSM_NOSTDLIB
|
||||
// remove dependency on standard library (silent fail!).
|
||||
// useful in conjunction with -nostdlib option, e.g. if your compiler
|
||||
// does not provide a standard library.
|
||||
// NOTE: this silently disables all static_assert() calls below!
|
||||
template<typename F, typename S>
|
||||
struct is_same_fsm { static constexpr bool value = true; };
|
||||
#else
|
||||
// check if both fsm and state class share same fsmtype
|
||||
template<typename F, typename S>
|
||||
struct is_same_fsm : std::is_same< typename F::fsmtype, typename S::fsmtype > { };
|
||||
#endif
|
||||
|
||||
template<typename S>
|
||||
struct _state_instance
|
||||
{
|
||||
using value_type = S;
|
||||
using type = _state_instance<S>;
|
||||
static S value;
|
||||
};
|
||||
|
||||
template<typename S>
|
||||
typename _state_instance<S>::value_type _state_instance<S>::value;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
template<typename F>
|
||||
class Fsm
|
||||
{
|
||||
public:
|
||||
|
||||
using fsmtype = Fsm<F>;
|
||||
using state_ptr_t = F *;
|
||||
|
||||
static state_ptr_t current_state_ptr;
|
||||
|
||||
// public, leaving ability to access state instance (e.g. on reset)
|
||||
template<typename S>
|
||||
static constexpr S & state(void) {
|
||||
static_assert(is_same_fsm<F, S>::value, "accessing state of different state machine");
|
||||
return _state_instance<S>::value;
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
static constexpr bool is_in_state(void) {
|
||||
static_assert(is_same_fsm<F, S>::value, "accessing state of different state machine");
|
||||
return current_state_ptr == &_state_instance<S>::value;
|
||||
}
|
||||
|
||||
/// state machine functions
|
||||
public:
|
||||
|
||||
// explicitely specialized in FSM_INITIAL_STATE macro
|
||||
static void set_initial_state();
|
||||
|
||||
static void reset() { };
|
||||
|
||||
static void enter() {
|
||||
current_state_ptr->entry();
|
||||
}
|
||||
|
||||
static void start() {
|
||||
set_initial_state();
|
||||
enter();
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
static void dispatch(E const & event) {
|
||||
current_state_ptr->react(event);
|
||||
}
|
||||
|
||||
|
||||
/// state transition functions
|
||||
protected:
|
||||
|
||||
template<typename S>
|
||||
void transit(void) {
|
||||
static_assert(is_same_fsm<F, S>::value, "transit to different state machine");
|
||||
current_state_ptr->exit();
|
||||
current_state_ptr = &_state_instance<S>::value;
|
||||
current_state_ptr->entry();
|
||||
}
|
||||
|
||||
template<typename S, typename ActionFunction>
|
||||
void transit(ActionFunction action_function) {
|
||||
static_assert(is_same_fsm<F, S>::value, "transit to different state machine");
|
||||
current_state_ptr->exit();
|
||||
// NOTE: do not send events in action_function definisions.
|
||||
action_function();
|
||||
current_state_ptr = &_state_instance<S>::value;
|
||||
current_state_ptr->entry();
|
||||
}
|
||||
|
||||
template<typename S, typename ActionFunction, typename ConditionFunction>
|
||||
void transit(ActionFunction action_function, ConditionFunction condition_function) {
|
||||
if(condition_function()) {
|
||||
transit<S>(action_function);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
typename Fsm<F>::state_ptr_t Fsm<F>::current_state_ptr;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
template<typename... FF>
|
||||
struct FsmList;
|
||||
|
||||
template<> struct FsmList<> {
|
||||
static void set_initial_state() { }
|
||||
static void reset() { }
|
||||
static void enter() { }
|
||||
template<typename E>
|
||||
static void dispatch(E const &) { }
|
||||
};
|
||||
|
||||
template<typename F, typename... FF>
|
||||
struct FsmList<F, FF...>
|
||||
{
|
||||
using fsmtype = Fsm<F>;
|
||||
|
||||
static void set_initial_state() {
|
||||
fsmtype::set_initial_state();
|
||||
FsmList<FF...>::set_initial_state();
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
F::reset();
|
||||
FsmList<FF...>::reset();
|
||||
}
|
||||
|
||||
static void enter() {
|
||||
fsmtype::enter();
|
||||
FsmList<FF...>::enter();
|
||||
}
|
||||
|
||||
static void start() {
|
||||
set_initial_state();
|
||||
enter();
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
static void dispatch(E const & event) {
|
||||
fsmtype::template dispatch<E>(event);
|
||||
FsmList<FF...>::template dispatch<E>(event);
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
template<typename... SS> struct StateList;
|
||||
template<> struct StateList<> {
|
||||
static void reset() { }
|
||||
};
|
||||
template<typename S, typename... SS>
|
||||
struct StateList<S, SS...>
|
||||
{
|
||||
static void reset() {
|
||||
_state_instance<S>::value = S();
|
||||
StateList<SS...>::reset();
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
template<typename F>
|
||||
struct MooreMachine : tinyfsm::Fsm<F>
|
||||
{
|
||||
virtual void entry(void) { }; /* entry actions in some states */
|
||||
void exit(void) { }; /* no exit actions */
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
struct MealyMachine : tinyfsm::Fsm<F>
|
||||
{
|
||||
// input actions are modeled in react():
|
||||
// - conditional dependent of event type or payload
|
||||
// - transit<>(ActionFunction)
|
||||
void entry(void) { }; /* no entry actions */
|
||||
void exit(void) { }; /* no exit actions */
|
||||
};
|
||||
|
||||
} /* namespace tinyfsm */
|
||||
|
||||
|
||||
#define FSM_INITIAL_STATE(_FSM, _STATE) \
|
||||
namespace tinyfsm { \
|
||||
template<> void Fsm< _FSM >::set_initial_state(void) { \
|
||||
current_state_ptr = &_state_instance< _STATE >::value; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* TINYFSM_HPP_INCLUDED */
|
||||
@@ -0,0 +1,476 @@
|
||||
#ifndef HTTP_SERVER_BATTERYOPERATION_H
|
||||
#define HTTP_SERVER_BATTERYOPERATION_H
|
||||
|
||||
#include <string>
|
||||
|
||||
const std::string BATTERY_OPERATION_HTML = R"(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>电池操作</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #2563eb;
|
||||
--primary-hover: #1d4ed8;
|
||||
--bg-color: #f8fafc;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background-color: var(--bg-color);
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"sidebar main-content";
|
||||
grid-template-columns: 220px 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
min-height: 100vh;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: unset;
|
||||
background: white;
|
||||
padding: 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 220px;
|
||||
height: 36px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
grid-area: sidebar;
|
||||
background: white;
|
||||
width: 220px;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding: 0.5rem 0.25rem;
|
||||
box-shadow: 1px 0 3px rgba(0, 0, 0, 0.1);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 0.375rem;
|
||||
color: #4b5563;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.sidebar-button:hover {
|
||||
background: var(--bg-color);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
min-width: 1.5rem;
|
||||
margin-right: 1rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
grid-area: main-content;
|
||||
padding: 1px;
|
||||
margin-top: 36px;
|
||||
}
|
||||
|
||||
.control-panel {
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.control-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.control-label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.radio-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.select-control {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: 4px;
|
||||
background-color: white;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.slider-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.slider {
|
||||
flex-grow: 1;
|
||||
height: 6px;
|
||||
-webkit-appearance: none;
|
||||
background: #d1d5db;
|
||||
border-radius: 3px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background: var(--primary-color);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.slider-value {
|
||||
min-width: 50px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background-color: #e5e7eb;
|
||||
color: #1a1a1a;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #d1d5db;
|
||||
}
|
||||
|
||||
.button-secondary {
|
||||
background-color: #e5e7eb;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.button-secondary:hover {
|
||||
background-color: #d1d5db;
|
||||
}
|
||||
|
||||
.button-active {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.button-active:hover {
|
||||
background-color: var(--primary-hover);
|
||||
}
|
||||
|
||||
.form-submit {
|
||||
margin-top: 24px;
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.status-message {
|
||||
margin-top: 16px;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
background-color: #f0fdf4;
|
||||
color: #166534;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.status-message.error {
|
||||
background-color: #fef2f2;
|
||||
color: #991b1b;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-menu">
|
||||
<a href="/" class="sidebar-button">
|
||||
<span class="sidebar-icon">🏠</span>
|
||||
<span>系统主页</span>
|
||||
</a>
|
||||
<a href="/data" class="sidebar-button">
|
||||
<span class="sidebar-icon">📊</span>
|
||||
<span>系统数据</span>
|
||||
</a>
|
||||
<a href="/dashboard" class="sidebar-button">
|
||||
<span class="sidebar-icon">⚡</span>
|
||||
<span>配电操作</span>
|
||||
</a>
|
||||
<a href="/battery" class="sidebar-button">
|
||||
<span class="sidebar-icon">🔋</span>
|
||||
<span>电池操作</span>
|
||||
</a>
|
||||
<a href="/logs" class="sidebar-button">
|
||||
<span class="sidebar-icon">📝</span>
|
||||
<span>系统日志</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<h1>电池操作系统</h1>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="control-panel">
|
||||
<div class="panel-title">燃料电池控制</div>
|
||||
|
||||
<form id="batteryForm" method="POST" action="/battery/control">
|
||||
<div class="control-group">
|
||||
<label class="control-label">燃料电池模式设定</label>
|
||||
<div class="radio-group">
|
||||
<label class="radio-option">
|
||||
<input type="radio" name="fuelCellMode" value="00H" checked>
|
||||
<span>无效</span>
|
||||
</label>
|
||||
<label class="radio-option">
|
||||
<input type="radio" name="fuelCellMode" value="01H">
|
||||
<span>调试</span>
|
||||
</label>
|
||||
<label class="radio-option">
|
||||
<input type="radio" name="fuelCellMode" value="02H">
|
||||
<span>自动</span>
|
||||
</label>
|
||||
<label class="radio-option">
|
||||
<input type="radio" name="fuelCellMode" value="03H">
|
||||
<span>补给</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">燃料电池指令</label>
|
||||
<select class="select-control" name="fuelCellCommand">
|
||||
<option value="00H">无效</option>
|
||||
<option value="01H">自检</option>
|
||||
<option value="02H">启动</option>
|
||||
<option value="03H">停机</option>
|
||||
<option value="04H">复位</option>
|
||||
<option value="05H">紧急停机</option>
|
||||
<option value="06H">补给</option>
|
||||
<option value="07H">制氢预热</option>
|
||||
<option value="08H">停机维护</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">燃料电池动力通路功率配置 (kW)</label>
|
||||
<div class="slider-container">
|
||||
<input type="range" class="slider" name="fuelCellPower" min="0" max="20" value="0" step="1">
|
||||
<span class="slider-value">0</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-title">锂电池控制</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">仪表锂电池启停指令</label>
|
||||
<div class="button-group">
|
||||
<button type="button" class="button button-active" data-command="instrumentBattery" data-value="00H">无效</button>
|
||||
<button type="button" class="button button-secondary" data-command="instrumentBattery" data-value="10H">启动</button>
|
||||
<button type="button" class="button button-secondary" data-command="instrumentBattery" data-value="20H">关闭</button>
|
||||
</div>
|
||||
<input type="hidden" name="instrumentBattery" value="00H">
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">仪表锂电池允许充电</label>
|
||||
<div class="button-group">
|
||||
<button type="button" class="button button-secondary" data-command="instrumentBatteryCharge" data-value="0">允许</button>
|
||||
<button type="button" class="button button-active" data-command="instrumentBatteryCharge" data-value="48">禁止</button>
|
||||
</div>
|
||||
<input type="hidden" name="instrumentBatteryCharge" value="1">
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">动力锂电池启停指令</label>
|
||||
<div class="button-group">
|
||||
<button type="button" class="button button-active" data-command="powerBattery" data-value="00H">无效</button>
|
||||
<button type="button" class="button button-secondary" data-command="powerBattery" data-value="10H">启动</button>
|
||||
<button type="button" class="button button-secondary" data-command="powerBattery" data-value="20H">关闭</button>
|
||||
</div>
|
||||
<input type="hidden" name="powerBattery" value="00H">
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">动力锂电池电池功率配置值 (kW)</label>
|
||||
<div class="slider-container">
|
||||
<input type="range" class="slider" name="powerBatteryPower" min="0" max="400" value="0" step="10">
|
||||
<span class="slider-value">0</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-title">主机状态</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">主机状态指令</label>
|
||||
<div class="radio-group">
|
||||
<label class="radio-option">
|
||||
<input type="radio" name="hostStatus" value="AAH" checked>
|
||||
<span>运行</span>
|
||||
</label>
|
||||
<label class="radio-option">
|
||||
<input type="radio" name="hostStatus" value="FFH">
|
||||
<span>关机</span>
|
||||
</label>
|
||||
<label class="radio-option">
|
||||
<input type="radio" name="hostStatus" value="55H">
|
||||
<span>故障</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="button form-submit">提交配置</button>
|
||||
|
||||
<div id="statusMessage" class="status-message"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 更新滑块值显示
|
||||
document.querySelectorAll('.slider').forEach(slider => {
|
||||
const valueDisplay = slider.nextElementSibling;
|
||||
valueDisplay.textContent = slider.value;
|
||||
|
||||
slider.addEventListener('input', () => {
|
||||
valueDisplay.textContent = slider.value;
|
||||
});
|
||||
});
|
||||
|
||||
// 处理按钮组选择
|
||||
document.querySelectorAll('.button-group button').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const group = button.closest('.button-group');
|
||||
const hiddenInput = group.nextElementSibling;
|
||||
const command = button.dataset.command;
|
||||
const value = button.dataset.value;
|
||||
|
||||
// 更新按钮样式
|
||||
group.querySelectorAll('button').forEach(btn => {
|
||||
btn.classList.remove('button-active');
|
||||
btn.classList.add('button-secondary');
|
||||
});
|
||||
button.classList.remove('button-secondary');
|
||||
button.classList.add('button-active');
|
||||
|
||||
// 更新隐藏输入值
|
||||
hiddenInput.value = value;
|
||||
});
|
||||
});
|
||||
|
||||
// 处理表单提交
|
||||
document.getElementById('batteryForm').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const form = e.target;
|
||||
const formData = new FormData(form);
|
||||
const statusMessage = document.getElementById('statusMessage');
|
||||
|
||||
try {
|
||||
// 将表单数据转换为URL编码格式
|
||||
const params = new URLSearchParams();
|
||||
for (const [key, value] of formData.entries()) {
|
||||
params.append(key, value);
|
||||
}
|
||||
|
||||
const response = await fetch(form.action, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: params.toString()
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
statusMessage.textContent = '配置提交成功';
|
||||
statusMessage.className = 'status-message';
|
||||
statusMessage.style.display = 'block';
|
||||
} else {
|
||||
statusMessage.textContent = result.message || '配置提交失败';
|
||||
statusMessage.className = 'status-message error';
|
||||
statusMessage.style.display = 'block';
|
||||
}
|
||||
} catch (error) {
|
||||
statusMessage.textContent = '网络错误: ' + error.message;
|
||||
statusMessage.className = 'status-message error';
|
||||
statusMessage.style.display = 'block';
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
statusMessage.style.display = 'none';
|
||||
}, 5000);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
)";
|
||||
|
||||
#endif // HTTP_SERVER_BATTERYOPERATION_H
|
||||
@@ -0,0 +1,580 @@
|
||||
|
||||
#ifndef HTTP_SERVER_DASHBOARD_H
|
||||
#define HTTP_SERVER_DASHBOARD_H
|
||||
|
||||
#include <string>
|
||||
|
||||
const std::string DASHBOARD_HTML = R"row(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>断路器控制面板</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 25px;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.column {
|
||||
flex: 1;
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.column:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
}
|
||||
.column-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
color: #2c3e50;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #eee;
|
||||
}
|
||||
.breaker {
|
||||
margin-bottom: 12px;
|
||||
padding: 10px 15px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
border-left: 4px solid #3498db;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.breaker-name {
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
color: #2c3e50;
|
||||
padding: 6px 10px;
|
||||
background-color: rgba(46, 204, 113, 0.1);
|
||||
border-radius: 4px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: fit-content;
|
||||
}
|
||||
.breaker-controls {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
button {
|
||||
padding: 8px 16px;
|
||||
min-width: 70px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
transition: all 0.2s;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
button:hover {
|
||||
opacity: 0.9;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
button:first-of-type {
|
||||
background-color: #2ecc71;
|
||||
color: white;
|
||||
}
|
||||
button:last-of-type {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
.status-message {
|
||||
margin-top: 8px;
|
||||
padding: 6px;
|
||||
font-size: 13px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.status-success {
|
||||
background-color: rgba(46, 204, 113, 0.1);
|
||||
color: #27ae60;
|
||||
}
|
||||
.status-error {
|
||||
background-color: rgba(231, 76, 60, 0.1);
|
||||
color: #c0392b;
|
||||
}
|
||||
.status-pending {
|
||||
background-color: rgba(241, 196, 15, 0.1);
|
||||
color: #f39c12;
|
||||
}
|
||||
.status-timer {
|
||||
font-size: 12px;
|
||||
color: #7f8c8d;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="column">
|
||||
<div class="column-title">高压母线设备</div>
|
||||
<!-- 高压母线断路器列表 -->
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">燃料电池断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'fuel_cell', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'fuel_cell', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-fuel_cell-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-fuel_cell-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">动力锂电池断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'power_battery', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'power_battery', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-power_battery-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-power_battery-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">推进电机断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'propulsion_motor', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'propulsion_motor', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-propulsion_motor-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-propulsion_motor-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">锂电池组仪表断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'battery_meter', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'battery_meter', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-battery_meter-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-battery_meter-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">DC/DC5模块断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'dcdc5', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'dcdc5', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-dcdc5-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-dcdc5-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">艏部高压配电箱断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'bow_distribution', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'bow_distribution', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-bow_distribution-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-bow_distribution-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">艉部FT装置4/5断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'stern_ft45', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'stern_ft45', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-stern_ft45-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-stern_ft45-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">艉舵开关1断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'stern_rudder1', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'stern_rudder1', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-stern_rudder1-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-stern_rudder1-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">艉舵开关2断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'stern_rudder2', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'stern_rudder2', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-stern_rudder2-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-stern_rudder2-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">FB预留断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'fb_reserve', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'fb_reserve', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-fb_reserve-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-fb_reserve-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">TYZ预留断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'tyz_reserve', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'tyz_reserve', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-tyz_reserve-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-tyz_reserve-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">预留断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'reserve', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'reserve', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-reserve-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-reserve-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">DC/DC5模块启动</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'dcdc5_start', 'close')">启动</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'dcdc5_start', 'open')">停止</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-dcdc5_start-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-dcdc5_start-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">冷却系统启动</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('high_vol_bus', 'cooling_system', 'close')">启动</button>
|
||||
<button onclick="sendCommand('high_vol_bus', 'cooling_system', 'open')">停止</button>
|
||||
</div>
|
||||
<div id="high_vol_bus-cooling_system-status-message" class="status-message"></div>
|
||||
<div id="high_vol_bus-cooling_system-timer" class="status-timer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<div class="column-title">艏高压设备</div>
|
||||
<!-- 艏高压断路器列表 -->
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">艏部FT装置1-3断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_high_vol', 'bow_ft1_3', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_high_vol', 'bow_ft1_3', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_high_vol-bow_ft1_3-status-message" class="status-message"></div>
|
||||
<div id="bow_high_vol-bow_ft1_3-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">启闭机构断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_high_vol', 'opening_mechanism', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_high_vol', 'opening_mechanism', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_high_vol-opening_mechanism-status-message" class="status-message"></div>
|
||||
<div id="bow_high_vol-opening_mechanism-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">桅杆舵机控制箱断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_high_vol', 'mast_steering', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_high_vol', 'mast_steering', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_high_vol-mast_steering-status-message" class="status-message"></div>
|
||||
<div id="bow_high_vol-mast_steering-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">XCZ断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_high_vol', 'xcz', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_high_vol', 'xcz', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_high_vol-xcz-status-message" class="status-message"></div>
|
||||
<div id="bow_high_vol-xcz-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">艏舵控制箱断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_high_vol', 'bow_rudder', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_high_vol', 'bow_rudder', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_high_vol-bow_rudder-status-message" class="status-message"></div>
|
||||
<div id="bow_high_vol-bow_rudder-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">敞水盖启动电缸断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_high_vol', 'water_cover', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_high_vol', 'water_cover', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_high_vol-water_cover-status-message" class="status-message"></div>
|
||||
<div id="bow_high_vol-water_cover-timer" class="status-timer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<div class="column-title">仪表母线设备</div>
|
||||
<!-- 仪表母线断路器列表 -->
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">锂电池组(仪表)断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('meter_bus', 'battery_meter', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('meter_bus', 'battery_meter', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="meter_bus-battery_meter-status-message" class="status-message"></div>
|
||||
<div id="meter_bus-battery_meter-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">艏部低压配电箱断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('meter_bus', 'bow_low_dist', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('meter_bus', 'bow_low_dist', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="meter_bus-bow_low_dist-status-message" class="status-message"></div>
|
||||
<div id="meter_bus-bow_low_dist-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">UNIT4仪表DC48V断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('meter_bus', 'unit4_dc48v', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('meter_bus', 'unit4_dc48v', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="meter_bus-unit4_dc48v-status-message" class="status-message"></div>
|
||||
<div id="meter_bus-unit4_dc48v-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">DC-C1直流配电板断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('meter_bus', 'dc_c1', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('meter_bus', 'dc_c1', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="meter_bus-dc_c1-status-message" class="status-message"></div>
|
||||
<div id="meter_bus-dc_c1-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">预留断路器1</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('meter_bus', 'reserve1', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('meter_bus', 'reserve1', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="meter_bus-reserve1-status-message" class="status-message"></div>
|
||||
<div id="meter_bus-reserve1-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">预留断路器2</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('meter_bus', 'reserve2', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('meter_bus', 'reserve2', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="meter_bus-reserve2-status-message" class="status-message"></div>
|
||||
<div id="meter_bus-reserve2-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">应急锂电池组2断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('meter_bus', 'emergency_battery2', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('meter_bus', 'emergency_battery2', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="meter_bus-emergency_battery2-status-message" class="status-message"></div>
|
||||
<div id="meter_bus-emergency_battery2-timer" class="status-timer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<div class="column-title">艏低压设备</div>
|
||||
<!-- 艏低压断路器列表 -->
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">UNIT1断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_low_vol', 'unit1', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_low_vol', 'unit1', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_low_vol-unit1-status-message" class="status-message"></div>
|
||||
<div id="bow_low_vol-unit1-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">UNIT2断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_low_vol', 'unit2', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_low_vol', 'unit2', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_low_vol-unit2-status-message" class="status-message"></div>
|
||||
<div id="bow_low_vol-unit2-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">UNIT3断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_low_vol', 'unit3', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_low_vol', 'unit3', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_low_vol-unit3-status-message" class="status-message"></div>
|
||||
<div id="bow_low_vol-unit3-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">UNIT5断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_low_vol', 'unit5', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_low_vol', 'unit5', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_low_vol-unit5-status-message" class="status-message"></div>
|
||||
<div id="bow_low_vol-unit5-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">艏部PZ装置断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_low_vol', 'bow_pz', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_low_vol', 'bow_pz', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_low_vol-bow_pz-status-message" class="status-message"></div>
|
||||
<div id="bow_low_vol-bow_pz-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">预留断路器1</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_low_vol', 'reserve1', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_low_vol', 'reserve1', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_low_vol-reserve1-status-message" class="status-message"></div>
|
||||
<div id="bow_low_vol-reserve1-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">预留断路器2</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_low_vol', 'reserve2', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_low_vol', 'reserve2', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_low_vol-reserve2-status-message" class="status-message"></div>
|
||||
<div id="bow_low_vol-reserve2-timer" class="status-timer"></div>
|
||||
</div>
|
||||
<div class="breaker">
|
||||
<div class="breaker-name">应急锂电池组1断路器</div>
|
||||
<div class="breaker-controls">
|
||||
<button onclick="sendCommand('bow_low_vol', 'emergency_battery1', 'close')">闭合</button>
|
||||
<button onclick="sendCommand('bow_low_vol', 'emergency_battery1', 'open')">断开</button>
|
||||
</div>
|
||||
<div id="bow_low_vol-emergency_battery1-status-message" class="status-message"></div>
|
||||
<div id="bow_low_vol-emergency_battery1-timer" class="status-timer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 全局存储所有设备的计时器状态
|
||||
const deviceTimers = {};
|
||||
|
||||
function sendCommand(type, id, action, value) {
|
||||
const statusEl = document.getElementById(`${type}-${id}-status-message`);
|
||||
const timerEl = document.getElementById(`${type}-${id}-timer`);
|
||||
const buttons = document.querySelectorAll(`button[onclick*="sendCommand('${type}', '${id}'"]`);
|
||||
|
||||
// 检查是否已有计时器运行
|
||||
if (deviceTimers[`${type}-${id}`]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 禁用按钮
|
||||
buttons.forEach(btn => {
|
||||
btn.disabled = true;
|
||||
btn.style.opacity = '0.6';
|
||||
btn.style.cursor = 'not-allowed';
|
||||
});
|
||||
|
||||
// 显示操作中状态
|
||||
if (statusEl) {
|
||||
statusEl.textContent = '操作中...';
|
||||
statusEl.className = 'status-message status-pending';
|
||||
}
|
||||
|
||||
// 启动5秒计时器
|
||||
if (timerEl) {
|
||||
let seconds = 8;
|
||||
timerEl.textContent = `等待反馈: ${seconds}秒`;
|
||||
timer = setInterval(() => {
|
||||
seconds--;
|
||||
if (seconds > 0) {
|
||||
timerEl.textContent = `等待反馈: ${seconds}秒`;
|
||||
} else {
|
||||
clearInterval(timer);
|
||||
timerEl.textContent = '';
|
||||
if (statusEl && statusEl.textContent === '操作中...') {
|
||||
statusEl.textContent = '操作超时: 未收到设备反馈';
|
||||
statusEl.className = 'status-message status-error';
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// 设置10秒超时
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('请求超时')), 10000)
|
||||
);
|
||||
|
||||
// 存储计时器
|
||||
deviceTimers[`${type}-${id}`] = timer;
|
||||
|
||||
Promise.race([
|
||||
fetch('/control', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ device_type: type, device_id: id, action: action, value: value })
|
||||
}),
|
||||
timeoutPromise
|
||||
])
|
||||
.then(res => {
|
||||
// 立即清除计时器
|
||||
const timerEl = document.getElementById(`${type}-${id}-timer`);
|
||||
const buttons = document.querySelectorAll(`button[onclick*="sendCommand('${type}', '${id}'"]`);
|
||||
|
||||
if (timerEl) {
|
||||
clearInterval(deviceTimers[`${type}-${id}`]);
|
||||
delete deviceTimers[`${type}-${id}`];
|
||||
timerEl.textContent = '';
|
||||
}
|
||||
|
||||
// 恢复按钮状态
|
||||
buttons.forEach(btn => {
|
||||
btn.disabled = false;
|
||||
btn.style.opacity = '1';
|
||||
btn.style.cursor = 'pointer';
|
||||
});
|
||||
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
const statusEl = document.getElementById(`${type}-${id}-status-message`);
|
||||
|
||||
if (statusEl) {
|
||||
statusEl.textContent = data.message || (data.success ? '操作成功' : '操作失败');
|
||||
statusEl.className = data.success ? 'status-message status-success' : 'status-message status-error';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
const statusEl = document.getElementById(`${type}-${id}-status-message`);
|
||||
const timerEl = document.getElementById(`${type}-${id}-timer`);
|
||||
const buttons = document.querySelectorAll(`button[onclick*="sendCommand('${type}', '${id}'"]`);
|
||||
|
||||
if (timerEl) {
|
||||
clearInterval(deviceTimers[`${type}-${id}`]);
|
||||
delete deviceTimers[`${type}-${id}`];
|
||||
timerEl.textContent = '';
|
||||
}
|
||||
|
||||
// 恢复按钮状态
|
||||
buttons.forEach(btn => {
|
||||
btn.disabled = false;
|
||||
btn.style.opacity = '1';
|
||||
btn.style.cursor = 'pointer';
|
||||
});
|
||||
|
||||
if (statusEl) {
|
||||
if (error.message === '请求超时') {
|
||||
statusEl.textContent = '操作超时: 未收到设备反馈';
|
||||
} else {
|
||||
statusEl.textContent = '通信错误: ' + error.message;
|
||||
}
|
||||
statusEl.className = 'status-message status-error';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
)row";
|
||||
#endif // HTTP_SERVER_DASHBOARD_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,466 @@
|
||||
#ifndef HTTP_SERVER_DEBUGPAGE_H
|
||||
#define HTTP_SERVER_DEBUGPAGE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
const std::string DEBUGPAGE_HTML = R"(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Power Manager - 调试页面</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #2563eb;
|
||||
--primary-hover: #1d4ed8;
|
||||
--bg-color: #f8fafc;
|
||||
--sidebar-width: 60px;
|
||||
--sidebar-expanded: 220px;
|
||||
--header-height: 36px;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background-color: var(--bg-color);
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"sidebar main-content";
|
||||
grid-template-columns: var(--sidebar-width) 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
min-height: 100vh;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: unset;
|
||||
background: white;
|
||||
padding: 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: var(--sidebar-width);
|
||||
height: var(--header-height);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
grid-area: sidebar;
|
||||
background: white;
|
||||
width: var(--sidebar-width);
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding: 0.5rem 0.25rem;
|
||||
transition: width 0.3s ease;
|
||||
box-shadow: 1px 0 3px rgba(0, 0, 0, 0.1);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar:hover {
|
||||
width: var(--sidebar-expanded);
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 0.375rem;
|
||||
color: #4b5563;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-button:hover {
|
||||
background: var(--bg-color);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
min-width: 1.5rem;
|
||||
margin-right: 1rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
grid-area: main-content;
|
||||
padding: 1px;
|
||||
margin-top: var(--header-height);
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
position: fixed;
|
||||
top: 4px;
|
||||
right: 8px;
|
||||
background: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
.status-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #4b5563;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.debug-panel {
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
margin: 16px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.debug-section {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.message-cards {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 12px;
|
||||
margin-top: 16px;
|
||||
max-width: 600px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.message-card {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.message-card {
|
||||
background: white;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 12px 16px;
|
||||
background: #f3f4f6;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-header:hover {
|
||||
background: #e5e7eb;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.card-content pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
font-family: monospace;
|
||||
max-height: 150px;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
}
|
||||
|
||||
.card-content pre.expanded {
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.toggle-button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #2563eb;
|
||||
cursor: pointer;
|
||||
font-size: 0.9em;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.toggle-button:hover {
|
||||
background: rgba(37, 99, 235, 0.1);
|
||||
}
|
||||
|
||||
.raw-data {
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
background-color: #f3f4f6;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"header"
|
||||
"main-content";
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.header {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-menu">
|
||||
<a href="/" class="sidebar-button">
|
||||
<span class="sidebar-icon">🏠</span>
|
||||
<span>系统主页</span>
|
||||
</a>
|
||||
<a href="/debug" class="sidebar-button">
|
||||
<span class="sidebar-icon">🐞</span>
|
||||
<span>调试页面</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<h1>Power Manager - 调试页面</h1>
|
||||
<div class="status-bar">
|
||||
<div class="status-info">
|
||||
<span id="wsStatus">🔴 WebSocket: 未连接</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="debug-panel">
|
||||
<div class="panel-title">系统调试信息</div>
|
||||
|
||||
<div class="debug-section">
|
||||
<div class="section-title">订阅消息</div>
|
||||
<div class="message-cards" id="subscribeDataTable">
|
||||
<!-- 订阅消息将通过JavaScript动态填充 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="debug-section">
|
||||
<div class="section-title">发布消息</div>
|
||||
<div class="message-cards" id="publishDataTable">
|
||||
<!-- 发布消息将通过JavaScript动态填充 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="debug-section">
|
||||
<div class="section-title">原始数据</div>
|
||||
<div class="raw-data" id="rawData">
|
||||
等待数据...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let ws = null;
|
||||
|
||||
function initWebSocket() {
|
||||
ws = new WebSocket('ws://' + window.location.host + '/ws/debug');
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log('WebSocket调试连接已建立');
|
||||
updateStatus('🟢 WebSocket: 已连接');
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
console.log('收到调试数据:', data);
|
||||
document.getElementById('rawData').textContent = JSON.stringify(data, null, 2);
|
||||
|
||||
// 更新订阅消息表格
|
||||
const subscribeTable = document.getElementById('subscribeDataTable');
|
||||
const subscribeMessages = [
|
||||
'm_secdistStateMsg_fb_debug',
|
||||
'm_equStateMsg_cmd_debug',
|
||||
'm_depthMsg_st_debug',
|
||||
'm_setOpConditionMsg_st_debug',
|
||||
'm_setOpModeMsg_st_debug',
|
||||
'm_taskStartMsg_st_debug',
|
||||
'm_taskStopMsg_st_debug',
|
||||
'm_setDevSwitchMsg_st_debug',
|
||||
'm_setPMSysMsg_st_debug',
|
||||
'm_sysStateMsg_st_debug'
|
||||
];
|
||||
|
||||
subscribeMessages.forEach(msg => {
|
||||
if (data.debug && data.debug[msg] && data.debug[msg].name) {
|
||||
const msgName = data.debug[msg].name;
|
||||
const existingCard = Array.from(subscribeTable.children).find(card =>
|
||||
card.querySelector('.card-header').textContent === msgName
|
||||
);
|
||||
|
||||
if (existingCard) {
|
||||
existingCard.querySelector('pre').textContent = formatJsonContent(data.debug[msg].content || '无内容');
|
||||
} else if (msgName !== '未知消息') {
|
||||
addDebugRow(subscribeTable, data.debug[msg]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 更新发布消息表格
|
||||
const publishTable = document.getElementById('publishDataTable');
|
||||
const publishMessages = [
|
||||
'm_equInsStateMsg_fb_degub',
|
||||
'm_secdistStateMsg_cmd_debug',
|
||||
'm_equStateMsg_fb_debug',
|
||||
'm_disSysStateMsg_st_debug',
|
||||
'm_currentStateMsg_st_debug',
|
||||
'm_pmStateMsg_fb_debug',
|
||||
'm_fcsStateMsg_st_debug',
|
||||
'm_liBatStateMsg_st_debug'
|
||||
];
|
||||
|
||||
publishMessages.forEach(msg => {
|
||||
if (data.debug && data.debug[msg] && data.debug[msg].name) {
|
||||
const msgName = data.debug[msg].name;
|
||||
const existingCard = Array.from(publishTable.children).find(card =>
|
||||
card.querySelector('.card-header').textContent === msgName
|
||||
);
|
||||
|
||||
if (existingCard) {
|
||||
existingCard.querySelector('pre').textContent = formatJsonContent(data.debug[msg].content || '无内容');
|
||||
} else if (msgName !== '未知消息') {
|
||||
addDebugRow(publishTable, data.debug[msg]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
console.error('解析调试数据出错:', e);
|
||||
document.getElementById('rawData').textContent = '解析错误: ' + e.message + '\n\n原始数据:\n' + event.data;
|
||||
}
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
console.log('WebSocket调试连接已关闭');
|
||||
updateStatus('🔴 WebSocket: 已断开');
|
||||
setTimeout(initWebSocket, 5000);
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error('WebSocket调试错误:', error);
|
||||
updateStatus('⚠️ WebSocket: 错误');
|
||||
};
|
||||
}
|
||||
|
||||
function updateStatus(status) {
|
||||
document.getElementById('wsStatus').textContent = status;
|
||||
}
|
||||
|
||||
function formatJsonContent(content) {
|
||||
try {
|
||||
const parsed = JSON.parse(content);
|
||||
return JSON.stringify(parsed, null, 2);
|
||||
} catch (e) {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
function addDebugRow(container, msgObj) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'message-card';
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.className = 'card-header';
|
||||
header.textContent = msgObj.name || '未知消息';
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.className = 'card-content';
|
||||
|
||||
const pre = document.createElement('pre');
|
||||
pre.textContent = formatJsonContent(msgObj.content || '无内容');
|
||||
|
||||
const toggleBtn = document.createElement('button');
|
||||
toggleBtn.className = 'toggle-button';
|
||||
toggleBtn.textContent = '展开';
|
||||
toggleBtn.onclick = function(e) {
|
||||
e.stopPropagation();
|
||||
pre.classList.toggle('expanded');
|
||||
this.textContent = pre.classList.contains('expanded') ? '收起' : '展开';
|
||||
};
|
||||
|
||||
header.onclick = function(e) {
|
||||
if(e.target !== toggleBtn) {
|
||||
pre.classList.toggle('expanded');
|
||||
toggleBtn.textContent = pre.classList.contains('expanded') ? '收起' : '展开';
|
||||
}
|
||||
};
|
||||
|
||||
content.appendChild(pre);
|
||||
content.appendChild(toggleBtn);
|
||||
card.appendChild(header);
|
||||
card.appendChild(content);
|
||||
container.appendChild(card);
|
||||
}
|
||||
|
||||
window.addEventListener('load', initWebSocket);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
)";
|
||||
|
||||
#endif // HTTP_SERVER_DEBUGPAGE_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
#ifndef HTTP_SERVER_H
|
||||
#define HTTP_SERVER_H
|
||||
#include "MOOS/libMOOS/Utils/MOOSThread.h"
|
||||
#include "mongoose.h"
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "../systemData.h"
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <fstream>
|
||||
#include <deque>
|
||||
#include "../LowerCommManager.h"
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
class HttpServer {
|
||||
public:
|
||||
// 构造函数,传入PowerManger指针和端口号
|
||||
HttpServer(int port = 8000);
|
||||
|
||||
// 析构函数
|
||||
~HttpServer();
|
||||
|
||||
// 启动HTTP服务器线程
|
||||
void start();
|
||||
|
||||
// 停止HTTP服务器线程
|
||||
void stop();
|
||||
|
||||
// 检查服务器是否正在运行
|
||||
bool isRunning() const;
|
||||
|
||||
// 设置系统数据
|
||||
void setSystemData(SystemData* systemData){
|
||||
m_systemData = systemData;
|
||||
}
|
||||
void setLowerCommManager(LowerCommManager* lowerCommManager){
|
||||
m_lowerCommManager = lowerCommManager;
|
||||
}
|
||||
void setPowerManger(PowerManger* powerManger){
|
||||
m_powerManger = powerManger;
|
||||
}
|
||||
|
||||
// 推送系统数据到所有WebSocket客户端
|
||||
void pushSystemData();
|
||||
|
||||
// 监控日志文件变化并推送新内容
|
||||
void monitorLogFile();
|
||||
|
||||
// 处理日志请求
|
||||
void handleLogRequest(struct mg_connection* c, const std::string& msg);
|
||||
|
||||
// 读取日志文件
|
||||
std::vector<std::string> readLogFile(int page, int pageSize, const std::string& level, const std::string& search);
|
||||
|
||||
// 测试页面请求处理函数
|
||||
void handleTestPage(struct mg_connection* c, const std::string& msg);
|
||||
|
||||
private:
|
||||
// WebSocket事件处理函数
|
||||
void handleWebSocketEvent(struct mg_connection* c, int ev, void* ev_data, void* fn_data);
|
||||
|
||||
// 线程回调函数
|
||||
static bool serverThreadCB(void* pParam);
|
||||
bool serverThreadFunc();
|
||||
|
||||
// 后台系统数据
|
||||
SystemData *m_systemData = nullptr;
|
||||
LowerCommManager *m_lowerCommManager = nullptr;
|
||||
PowerManger *m_powerManger = nullptr;
|
||||
|
||||
struct mg_mgr mgr_; // Mongoose管理器
|
||||
int port_; // 监听端口
|
||||
bool running_; // 运行状态标志
|
||||
CMOOSThread m_ServerThread; // 服务器线程
|
||||
std::mutex ws_connections_mutex_; // WebSocket连接锁
|
||||
std::vector<mg_connection*> ws_connections_; // WebSocket连接列表
|
||||
std::unordered_map<mg_connection*, uint64_t> ws_last_io_time_; // 连接最后活动时间
|
||||
|
||||
// 日志文件相关
|
||||
std::string m_logFilePath = "pPowerManger.log";
|
||||
std::ifstream m_logFile;
|
||||
std::streampos m_lastLogPosition = 0;
|
||||
std::deque<std::string> m_logCache; // 缓存最近的日志
|
||||
static const size_t MAX_CACHE_SIZE = 1000; // 最大缓存条数
|
||||
|
||||
};
|
||||
|
||||
#endif // HTTP_SERVER_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,617 @@
|
||||
#ifndef HTTP_SERVER_LOGPAGE_H
|
||||
#define HTTP_SERVER_LOGPAGE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
const std::string LOG_PAGE_HTML = R"(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>系统日志 - Power Manager</title>
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #2563eb;
|
||||
--primary-hover: #1d4ed8;
|
||||
--bg-color: #f8fafc;
|
||||
--sidebar-width: 60px;
|
||||
--sidebar-expanded: 220px;
|
||||
--header-height: 36px;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background-color: var(--bg-color);
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-areas: "sidebar main-content";
|
||||
grid-template-columns: var(--sidebar-width) 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
min-height: 100vh;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: unset;
|
||||
background: white;
|
||||
padding: 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: var(--sidebar-width);
|
||||
height: var(--header-height);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
grid-area: sidebar;
|
||||
background: white;
|
||||
width: var(--sidebar-width);
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding: 0.5rem 0.25rem;
|
||||
transition: width 0.3s ease;
|
||||
box-shadow: 1px 0 3px rgba(0, 0, 0, 0.1);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar:hover {
|
||||
width: var(--sidebar-expanded);
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 0.375rem;
|
||||
color: #4b5563;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-button:hover {
|
||||
background: var(--bg-color);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.sidebar-button.active {
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
min-width: 1.5rem;
|
||||
margin-right: 1rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
grid-area: main-content;
|
||||
padding: 1px;
|
||||
margin-top: var(--header-height);
|
||||
}
|
||||
|
||||
.log-panel {
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
padding: 6px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
height: calc(100vh - var(--header-height));
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.log-controls {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding: 4px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.log-button {
|
||||
padding: 4px 12px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
color: #4b5563;
|
||||
cursor: pointer;
|
||||
font-size: 0.875rem;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.log-button:hover {
|
||||
background: var(--bg-color);
|
||||
border-color: var(--primary-color);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.log-filter {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.log-filter select, .log-filter input {
|
||||
padding: 4px 8px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875rem;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.log-filter input {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.log-pagination {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
padding: 4px;
|
||||
border-top: 1px solid #e5e7eb;
|
||||
justify-content: space-between;
|
||||
font-size: 0.875rem;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.page-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.page-size {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.page-size select {
|
||||
padding: 2px 4px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.page-nav {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.page-nav button {
|
||||
padding: 2px 8px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.page-nav button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.log-content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 8px;
|
||||
font-family: monospace;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
background: #1a1a1a;
|
||||
color: #f8fafc;
|
||||
margin: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.log-entry {
|
||||
margin: 2px 0;
|
||||
padding: 2px 4px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.log-entry:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.log-entry.error {
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
.log-entry.warning {
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.log-entry.info {
|
||||
color: #60a5fa;
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
position: fixed;
|
||||
top: 4px;
|
||||
right: 8px;
|
||||
background: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
.status-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #4b5563;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-menu">
|
||||
<a href="/" class="sidebar-button">
|
||||
<span class="sidebar-icon">🏠</span>
|
||||
<span>系统主页</span>
|
||||
</a>
|
||||
<a href="/data" class="sidebar-button">
|
||||
<span class="sidebar-icon">📊</span>
|
||||
<span>系统数据</span>
|
||||
</a>
|
||||
<a href="/dashboard" class="sidebar-button">
|
||||
<span class="sidebar-icon">⚡</span>
|
||||
<span>配电操作</span>
|
||||
</a>
|
||||
<a href="/logs" class="sidebar-button active">
|
||||
<span class="sidebar-icon">📝</span>
|
||||
<span>系统日志</span>
|
||||
</a>
|
||||
<a href="/testpage" class="sidebar-button">
|
||||
<span class="sidebar-icon">🧪</span>
|
||||
<span>测试页面</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<h1>系统日志</h1>
|
||||
<div class="status-bar">
|
||||
<div class="status-info">
|
||||
<span>🟢 系统状态: <span id="systemStatus">运行中</span></span>
|
||||
<span>⚡ 应用频率: <span id="appFreq">0</span> Hz</span>
|
||||
<span>📡 通信频率: <span id="commFreq">0</span> Hz</span>
|
||||
<span>💻 CPU负载: <span id="cpuLoad">0</span>%</span>
|
||||
<span>⏱️ 迭代间隔: <span id="timeSinceIterate">0</span>ms</span>
|
||||
<span>🕒 更新时间: <time id="updateTime">2025-05-18 15:52</time></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="log-panel">
|
||||
<div class="log-controls">
|
||||
<button class="log-button" id="clearBtn">清空显示</button>
|
||||
<button class="log-button" id="scrollLockBtn">自动滚动</button>
|
||||
<button class="log-button" id="downloadBtn">下载日志</button>
|
||||
<div class="log-filter">
|
||||
<select id="logLevel">
|
||||
<option value="ALL">所有级别</option>
|
||||
<option value="ERROR">错误</option>
|
||||
<option value="WARNING">警告</option>
|
||||
<option value="INFO">信息</option>
|
||||
</select>
|
||||
<input type="text" id="searchInput" placeholder="搜索日志...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-content" id="logContent"></div>
|
||||
<div class="log-pagination">
|
||||
<div class="page-size">
|
||||
每页显示:
|
||||
<select id="pageSize">
|
||||
<option value="100">100</option>
|
||||
<option value="200" selected>200</option>
|
||||
<option value="500">500</option>
|
||||
<option value="1000">1000</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="page-info">
|
||||
<span id="pageInfo">第 0/0 页</span>
|
||||
<div class="page-nav">
|
||||
<button id="firstPage">首页</button>
|
||||
<button id="prevPage">上一页</button>
|
||||
<button id="nextPage">下一页</button>
|
||||
<button id="lastPage">末页</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let ws = null;
|
||||
let autoScroll = true;
|
||||
let logContent = document.getElementById('logContent');
|
||||
let currentPage = 1;
|
||||
let totalPages = 1;
|
||||
let pageSize = 200;
|
||||
let allLogs = [];
|
||||
let filteredLogs = [];
|
||||
let searchTimer = null;
|
||||
|
||||
function initWebSocket() {
|
||||
ws = new WebSocket('ws://' + window.location.host + '/ws');
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log('WebSocket连接已建立');
|
||||
updateStatus('运行中', true);
|
||||
requestLogs();
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
if (data.type === 'log') {
|
||||
// 初始加载的日志数据
|
||||
allLogs = data.content;
|
||||
filterAndDisplayLogs();
|
||||
} else if (data.type === 'new_log') {
|
||||
// 新的日志条目
|
||||
if (Array.isArray(data.content)) {
|
||||
let shouldUpdate = false;
|
||||
data.content.forEach(log => {
|
||||
allLogs.push(log);
|
||||
if (shouldShowLog(log)) {
|
||||
filteredLogs.push(log);
|
||||
shouldUpdate = true;
|
||||
// 如果在最后一页或自动滚动模式下,直接添加到显示
|
||||
if (currentPage === totalPages || autoScroll) {
|
||||
appendLogEntry(log);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (shouldUpdate) {
|
||||
totalPages = Math.ceil(filteredLogs.length / pageSize);
|
||||
updatePagination();
|
||||
|
||||
// 如果开启了自动滚动,确保滚动到底部
|
||||
if (autoScroll) {
|
||||
logContent.scrollTop = logContent.scrollHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (data.moosdb) {
|
||||
// 更新MOOSDB信息
|
||||
document.getElementById('appFreq').textContent = data.moosdb.appFreq.toFixed(2);
|
||||
document.getElementById('commFreq').textContent = data.moosdb.commFreq.toFixed(2);
|
||||
document.getElementById('cpuLoad').textContent = data.moosdb.cpuLoad.toFixed(1);
|
||||
document.getElementById('timeSinceIterate').textContent = data.moosdb.timeSinceIterate.toFixed(0);
|
||||
} else if (data.type === 'system_status') {
|
||||
updateStatus(data.status, true);
|
||||
}
|
||||
updateTime();
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
console.log('WebSocket连接已关闭');
|
||||
updateStatus('已断开', false);
|
||||
// 增加重连延迟,避免快速重连
|
||||
setTimeout(() => {
|
||||
if (!ws || ws.readyState === WebSocket.CLOSED) {
|
||||
initWebSocket();
|
||||
}
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error('WebSocket错误:', error);
|
||||
updateStatus('错误', false);
|
||||
};
|
||||
}
|
||||
|
||||
function requestLogs() {
|
||||
ws.send(JSON.stringify({
|
||||
type: 'get_logs',
|
||||
page: currentPage,
|
||||
pageSize: pageSize,
|
||||
filter: {
|
||||
level: document.getElementById('logLevel').value,
|
||||
search: document.getElementById('searchInput').value
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function shouldShowLog(logEntry) {
|
||||
const level = document.getElementById('logLevel').value;
|
||||
const search = document.getElementById('searchInput').value.toLowerCase();
|
||||
|
||||
if (level !== 'ALL') {
|
||||
if (!logEntry.includes(level)) return false;
|
||||
}
|
||||
|
||||
if (search && !logEntry.toLowerCase().includes(search)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function filterAndDisplayLogs() {
|
||||
filteredLogs = allLogs.filter(shouldShowLog);
|
||||
totalPages = Math.ceil(filteredLogs.length / pageSize);
|
||||
displayCurrentPage();
|
||||
updatePagination();
|
||||
}
|
||||
|
||||
function displayCurrentPage() {
|
||||
logContent.innerHTML = '';
|
||||
const start = (currentPage - 1) * pageSize;
|
||||
const end = Math.min(start + pageSize, filteredLogs.length);
|
||||
|
||||
for (let i = start; i < end; i++) {
|
||||
appendLogEntry(filteredLogs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function updatePagination() {
|
||||
document.getElementById('pageInfo').textContent = `第 ${currentPage}/${totalPages} 页`;
|
||||
document.getElementById('firstPage').disabled = currentPage === 1;
|
||||
document.getElementById('prevPage').disabled = currentPage === 1;
|
||||
document.getElementById('nextPage').disabled = currentPage === totalPages;
|
||||
document.getElementById('lastPage').disabled = currentPage === totalPages;
|
||||
}
|
||||
|
||||
// 事件监听器
|
||||
document.getElementById('logLevel').addEventListener('change', () => {
|
||||
currentPage = 1;
|
||||
filterAndDisplayLogs();
|
||||
});
|
||||
|
||||
document.getElementById('searchInput').addEventListener('input', (e) => {
|
||||
clearTimeout(searchTimer);
|
||||
searchTimer = setTimeout(() => {
|
||||
currentPage = 1;
|
||||
filterAndDisplayLogs();
|
||||
}, 300);
|
||||
});
|
||||
|
||||
document.getElementById('pageSize').addEventListener('change', (e) => {
|
||||
pageSize = parseInt(e.target.value);
|
||||
currentPage = 1;
|
||||
filterAndDisplayLogs();
|
||||
});
|
||||
|
||||
document.getElementById('firstPage').addEventListener('click', () => {
|
||||
currentPage = 1;
|
||||
displayCurrentPage();
|
||||
updatePagination();
|
||||
});
|
||||
|
||||
document.getElementById('prevPage').addEventListener('click', () => {
|
||||
if (currentPage > 1) {
|
||||
currentPage--;
|
||||
displayCurrentPage();
|
||||
updatePagination();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('nextPage').addEventListener('click', () => {
|
||||
if (currentPage < totalPages) {
|
||||
currentPage++;
|
||||
displayCurrentPage();
|
||||
updatePagination();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('lastPage').addEventListener('click', () => {
|
||||
currentPage = totalPages;
|
||||
displayCurrentPage();
|
||||
updatePagination();
|
||||
});
|
||||
|
||||
function appendLogEntry(content) {
|
||||
const entry = document.createElement('div');
|
||||
entry.className = 'log-entry';
|
||||
|
||||
// 根据日志内容设置不同的样式
|
||||
if (content.includes('ERROR') || content.includes('ERR')) {
|
||||
entry.classList.add('error');
|
||||
} else if (content.includes('WARNING') || content.includes('WARN')) {
|
||||
entry.classList.add('warning');
|
||||
} else if (content.includes('INFO')) {
|
||||
entry.classList.add('info');
|
||||
}
|
||||
|
||||
entry.textContent = content;
|
||||
logContent.appendChild(entry);
|
||||
|
||||
// 只在自动滚动模式下滚动到底部
|
||||
if (autoScroll) {
|
||||
logContent.scrollTop = logContent.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
function updateStatus(status, isConnected) {
|
||||
const statusElement = document.querySelector('.status-info span:first-child');
|
||||
statusElement.innerHTML = `${isConnected ? '🟢' : '🔴'} 系统状态: ${status}`;
|
||||
}
|
||||
|
||||
function updateTime() {
|
||||
const now = new Date();
|
||||
const timeStr = now.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
document.getElementById('updateTime').textContent = timeStr;
|
||||
}
|
||||
|
||||
// 按钮事件处理
|
||||
document.getElementById('clearBtn').onclick = () => {
|
||||
logContent.innerHTML = '';
|
||||
};
|
||||
|
||||
document.getElementById('scrollLockBtn').onclick = function() {
|
||||
autoScroll = !autoScroll;
|
||||
this.textContent = autoScroll ? '自动滚动' : '已锁定';
|
||||
this.style.backgroundColor = autoScroll ? 'white' : '#e5e7eb';
|
||||
};
|
||||
|
||||
document.getElementById('downloadBtn').onclick = () => {
|
||||
const text = logContent.innerText;
|
||||
const blob = new Blob([text], { type: 'text/plain' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `system_log_${new Date().toISOString().slice(0,19).replace(/[:-]/g, '')}.txt`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
window.addEventListener('load', initWebSocket);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
)";
|
||||
|
||||
#endif // HTTP_SERVER_LOGPAGE_H
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,458 @@
|
||||
#ifndef HTTP_SERVER_TESTPAGE_H
|
||||
#define HTTP_SERVER_TESTPAGE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
const std::string TESTPAGE_HTML = R"row(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>测试页面</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #2563eb;
|
||||
--primary-hover: #1d4ed8;
|
||||
--bg-color: #f8fafc;
|
||||
--sidebar-width: 60px;
|
||||
--sidebar-expanded: 220px;
|
||||
--header-height: 36px;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background-color: var(--bg-color);
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"sidebar main-content";
|
||||
grid-template-columns: var(--sidebar-width) 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
min-height: 100vh;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: unset;
|
||||
background: white;
|
||||
padding: 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: var(--sidebar-width);
|
||||
height: var(--header-height);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
grid-area: sidebar;
|
||||
background: white;
|
||||
width: var(--sidebar-width);
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding: 0.5rem 0.25rem;
|
||||
transition: width 0.3s ease;
|
||||
box-shadow: 1px 0 3px rgba(0, 0, 0, 0.1);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar:hover {
|
||||
width: var(--sidebar-expanded);
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 0.375rem;
|
||||
color: #4b5563;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-button:hover {
|
||||
background: var(--bg-color);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
min-width: 1.5rem;
|
||||
margin-right: 1rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
grid-area: main-content;
|
||||
padding: 1px;
|
||||
margin-top: var(--header-height);
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
position: fixed;
|
||||
top: 4px;
|
||||
right: 8px;
|
||||
background: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
.status-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #4b5563;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.data-panel {
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
height: calc(100vh - var(--header-height) + 3px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 8px 16px;
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: var(--primary-hover);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"header"
|
||||
"main-content";
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.header {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-menu">
|
||||
<a href="/" class="sidebar-button">
|
||||
<span class="sidebar-icon">🏠</span>
|
||||
<span>系统主页</span>
|
||||
</a>
|
||||
<a href="/data" class="sidebar-button">
|
||||
<span class="sidebar-icon">📊</span>
|
||||
<span>系统数据</span>
|
||||
</a>
|
||||
<a href="/dashboard" class="sidebar-button">
|
||||
<span class="sidebar-icon">⚡</span>
|
||||
<span>配电操作</span>
|
||||
</a>
|
||||
<a href="/logs" class="sidebar-button">
|
||||
<span class="sidebar-icon">📝</span>
|
||||
<span>系统日志</span>
|
||||
</a>
|
||||
<a href="/testpage" class="sidebar-button">
|
||||
<span class="sidebar-icon">🧪</span>
|
||||
<span>测试页面</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<h1>测试页面</h1>
|
||||
<div class="status-bar">
|
||||
<div class="status-info">
|
||||
<span>🟢 系统状态: <span id="systemStatus">运行中</span></span>
|
||||
<span>⚡ 应用频率: <span id="appFreq">0</span> Hz</span>
|
||||
<span>📡 通信频率: <span id="commFreq">0</span> Hz</span>
|
||||
<span>💻 CPU负载: <span id="cpuLoad">0</span>%</span>
|
||||
<span>⏱️ 迭代间隔: <span id="timeSinceIterate">0</span>ms</span>
|
||||
<span>🕒 更新时间: <time id="updateTime">2025-05-19 11:54</time></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="data-panel">
|
||||
<div class="panel-title">测试表单</div>
|
||||
<form id="testForm">
|
||||
<div class="form-section">
|
||||
<div class="panel-subtitle">测试类型/ID设置</div>
|
||||
<div class="form-group">
|
||||
<label for="type" class="form-label">类型</label>
|
||||
<input type="number" id="type" name="type" class="form-input" min="0" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="id" class="form-label">ID</label>
|
||||
<input type="number" id="id" name="id" class="form-input" min="0" required>
|
||||
</div>
|
||||
<button type="button" class="btn" onclick="submitTestForm()">提交类型/ID</button>
|
||||
</div>
|
||||
|
||||
<div class="form-section">
|
||||
<div class="panel-subtitle">MOOSDB测试消息设置</div>
|
||||
<div class="form-group">
|
||||
<label for="key" class="form-label">键(Key)</label>
|
||||
<input type="text" id="key" name="key" class="form-input" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="value" class="form-label">值(Value)</label>
|
||||
<input type="text" id="value" name="value" class="form-input" required>
|
||||
</div>
|
||||
<button type="button" class="btn" onclick="submitKeyValueForm()" style="background-color: #4f46e5;">提交键值对</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<style>
|
||||
.form-section {
|
||||
margin-bottom: 24px;
|
||||
padding: 16px;
|
||||
background: #f9fafb;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.panel-subtitle {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
color: #4b5563;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let ws = null;
|
||||
|
||||
function initWebSocket() {
|
||||
ws = new WebSocket('ws://' + window.location.host + '/ws');
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log('WebSocket连接已建立');
|
||||
updateStatus('运行中', true);
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
console.log('收到系统数据:', data);
|
||||
|
||||
// 更新MOOSDB信息
|
||||
if (data.moosdb) {
|
||||
document.getElementById('appFreq').textContent = data.moosdb.appFreq.toFixed(2);
|
||||
document.getElementById('commFreq').textContent = data.moosdb.commFreq.toFixed(2);
|
||||
document.getElementById('cpuLoad').textContent = data.moosdb.cpuLoad.toFixed(1);
|
||||
document.getElementById('timeSinceIterate').textContent = data.moosdb.timeSinceIterate.toFixed(0);
|
||||
}
|
||||
|
||||
updateTime();
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
console.log('WebSocket连接已关闭');
|
||||
updateStatus('已断开', false);
|
||||
setTimeout(initWebSocket, 5000);
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error('WebSocket错误:', error);
|
||||
updateStatus('错误', false);
|
||||
};
|
||||
}
|
||||
|
||||
function updateStatus(status, isConnected) {
|
||||
const statusElement = document.querySelector('.status-info span:first-child');
|
||||
statusElement.innerHTML = `${isConnected ? '🟢' : '🔴'} 系统状态: ${status}`;
|
||||
}
|
||||
|
||||
function updateTime() {
|
||||
const now = new Date();
|
||||
const timeStr = now.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
document.getElementById('updateTime').textContent = timeStr;
|
||||
}
|
||||
|
||||
function submitTestForm() {
|
||||
const form = document.getElementById('testForm');
|
||||
const typeValue = parseInt(form.type.value);
|
||||
const idValue = parseInt(form.id.value);
|
||||
|
||||
if (typeValue < 0 || idValue < 0) {
|
||||
alert('请输入非负整数');
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = {
|
||||
type: typeValue,
|
||||
id: idValue
|
||||
};
|
||||
|
||||
sendFormData(formData);
|
||||
}
|
||||
|
||||
function submitKeyValueForm() {
|
||||
const key = document.getElementById('key').value.trim();
|
||||
const value = document.getElementById('value').value.trim();
|
||||
|
||||
if (!key || !value) {
|
||||
alert('请输入键和值');
|
||||
return;
|
||||
}
|
||||
|
||||
// 直接构造JSON对象,不通过form
|
||||
const payload = {
|
||||
key: key,
|
||||
value: value
|
||||
};
|
||||
|
||||
// 专门发送到MOOSDB测试消息接口
|
||||
fetch('/moosdb_test', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('MOOSDB测试消息提交成功: ' + data.message);
|
||||
} else {
|
||||
alert('MOOSDB测试消息提交失败: ' + data.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('MOOSDB测试消息提交错误:', error);
|
||||
alert('MOOSDB测试消息提交过程中发生错误: ' + error.message);
|
||||
});
|
||||
}
|
||||
|
||||
function sendFormData(formData) {
|
||||
|
||||
fetch('/testpage', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(formData)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('提交成功: ' + data.message);
|
||||
} else {
|
||||
alert('提交失败: ' + data.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('提交错误:', error);
|
||||
alert('提交过程中发生错误');
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', initWebSocket);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
)row";
|
||||
|
||||
#endif // HTTP_SERVER_TESTPAGE_H
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
/************************************************************/
|
||||
/* NAME: */
|
||||
/* ORGN: MIT, Cambridge MA */
|
||||
/* FILE: main.cpp, Cambridge MA */
|
||||
/* DATE: December 29th, 1963 */
|
||||
/************************************************************/
|
||||
|
||||
#include <string>
|
||||
#include "MBUtils.h"
|
||||
#include "ColorParse.h"
|
||||
#include "PowerManger.h"
|
||||
#include "PowerManger_Info.h"
|
||||
#include "logc/loguru.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 初始化loguru
|
||||
loguru::init(argc, argv);
|
||||
loguru::add_file("pPowerManger.log", loguru::Append, loguru::Verbosity_MAX);
|
||||
|
||||
string mission_file;
|
||||
string run_command = argv[0];
|
||||
|
||||
for(int i=1; i<argc; i++) {
|
||||
string argi = argv[i];
|
||||
if((argi=="-v") || (argi=="--version") || (argi=="-version"))
|
||||
showReleaseInfoAndExit();
|
||||
else if((argi=="-e") || (argi=="--example") || (argi=="-example"))
|
||||
showExampleConfigAndExit();
|
||||
else if((argi == "-h") || (argi == "--help") || (argi=="-help"))
|
||||
showHelpAndExit();
|
||||
else if((argi == "-i") || (argi == "--interface"))
|
||||
showInterfaceAndExit();
|
||||
else if(strEnds(argi, ".moos") || strEnds(argi, ".moos++"))
|
||||
mission_file = argv[i];
|
||||
else if(strBegins(argi, "--alias="))
|
||||
run_command = argi.substr(8);
|
||||
else if(i==2)
|
||||
run_command = argi;
|
||||
}
|
||||
|
||||
if(mission_file == "")
|
||||
showHelpAndExit();
|
||||
|
||||
LOG_F(INFO, "pPowerManger launching as %s", run_command.c_str());
|
||||
|
||||
PowerManger PowerManger;
|
||||
|
||||
PowerManger.Run(run_command.c_str(), mission_file.c_str());
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//SERVERHOST = 192.168.0.223
|
||||
//SERVERPORT = 9000
|
||||
ProcessConfig = pPowerManger
|
||||
{
|
||||
AppTick = 4
|
||||
CommsTick = 4
|
||||
log_level = INFO
|
||||
log_file = /path/to/your/logfile.log
|
||||
}
|
||||
@@ -0,0 +1,964 @@
|
||||
#ifndef PMSYSVARIABLE_H
|
||||
#define PMSYSVARIABLE_H
|
||||
|
||||
//宏定义
|
||||
#include<string>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
|
||||
#define BREAK_OFF 0xAA
|
||||
#define BREAK_ON 0x55
|
||||
#define BREAK_FALSE 0x5A
|
||||
|
||||
//消息结构体变量定义
|
||||
#pragma pack (1)
|
||||
typedef struct ccuState
|
||||
{
|
||||
uint8_t fc_mode; // 燃料电池系统运行模式:00H-无效, 01H-调试, 02H-自动, 03H-补给
|
||||
uint8_t fc_status; // 燃料电池状态:00H-无效, 01H-初始化, ..., 0DH-维护完成(详见协议)
|
||||
uint8_t fc_fault_level; // 燃料电池故障等级:00H-无故障, 10H-一级, 20H-二级, 30H-三级, 40H-四级
|
||||
|
||||
uint16_t output_power_limit; // 系统输出功率限制值,单位:W,范围:0~30000W
|
||||
uint16_t total_generation_time; // 系统累计发电时间,单位:0.1小时,最大值6553.5小时
|
||||
uint16_t total_generation_power; // 系统累计发电总功率,单位:W
|
||||
uint16_t fault_level_1; // 一级故障位,按位表示不同的故障项
|
||||
uint16_t fault_level_2; // 二级故障位
|
||||
uint16_t fault_level_3; // 三级故障位
|
||||
uint16_t fault_level_4; // 四级故障位
|
||||
|
||||
uint8_t hydrogen_capacity; // 储氢罐剩余容量百分比,单位:%,范围:0~100
|
||||
uint8_t liquid_oxygen_capacity; // 液氧罐剩余容量百分比,单位:%,范围:0~100
|
||||
|
||||
uint16_t palladium_temp; // 钯膜最高温度,单位:℃
|
||||
uint16_t main_pipe_pressure; // 主水路压力,单位:0.01kPa
|
||||
uint16_t aux_pipe_pressure; // 辅水路压力,单位:0.01kPa
|
||||
|
||||
uint16_t cabin_pressure1; // 舱室1压力,单位:0.01kPa
|
||||
uint16_t cabin_pressure2; // 舱室2压力,单位:0.01kPa
|
||||
uint16_t cabin_temp1; // 舱室1温度,单位:0.01℃
|
||||
uint16_t cabin_temp2; // 舱室2温度,单位:0.01℃
|
||||
uint16_t cabin_humidity1; // 舱室1湿度,单位:0.01%RH
|
||||
uint16_t cabin_humidity2; // 舱室2湿度,单位:0.01%RH
|
||||
|
||||
uint8_t flame_detector1; // 火焰探测器1状态:00H-无效, 01H-报警, 02H-故障
|
||||
uint8_t flame_detector2; // 火焰探测器2状态:00H-无效, 01H-报警, 02H-故障
|
||||
|
||||
uint16_t h2_concentration1; // 舱室H2浓度1,单位:0.01% LEL
|
||||
uint16_t h2_concentration2; // 舱室H2浓度2,单位:0.01% LEL
|
||||
uint16_t h2_concentration3; // 舱室H2浓度3,单位:0.01% LEL
|
||||
uint16_t o2_concentration1; // 舱室O2浓度1,单位:0.01% LEL
|
||||
uint16_t o2_concentration2; // 舱室O2浓度2,单位:0.01% LEL
|
||||
uint16_t ch3oh_concentration1; // 舱室甲醇气体浓度1,单位:0.01% LEL
|
||||
uint16_t ch3oh_concentration2; // 舱室甲醇气体浓度2,单位:0.01% LEL
|
||||
|
||||
uint16_t reserved1[2]; // 保留字段前2个元素
|
||||
uint16_t emergency_battery1_voltage; // 应急电池1总电压 [V]
|
||||
uint16_t emergency_battery1_current; // 应急电池1总电流 [A]
|
||||
uint16_t emergency_battery1_max_temp; // 应急电池1最高温度 [°C]
|
||||
uint16_t emergency_battery1_fault_word; // 应急电池1故障字
|
||||
uint16_t emergency_battery2_voltage; // 应急电池2总电压 [V]
|
||||
uint16_t emergency_battery2_current; // 应急电池2总电流 [A]
|
||||
uint16_t emergency_battery2_max_temp; // 应急电池2最高温度 [°C]
|
||||
uint16_t emergency_battery2_fault_word; // 应急电池2故障字
|
||||
|
||||
uint16_t cabin_ox_concentration; // 仪表舱内氧气浓度 [%]
|
||||
uint16_t cabin_temperature; // 仪表舱内温度 [°C]
|
||||
uint16_t cabin_humidity; // 仪表舱内湿度 [%RH]
|
||||
uint16_t cabin_pressure; // 仪表舱内大气压 [kPa]
|
||||
|
||||
uint16_t power_cabin_ox_concentration; // 动力舱内氧气浓度 [%]
|
||||
uint16_t power_cabin_temperature; // 动力舱内温度 [°C]
|
||||
uint16_t power_cabin_humidity; // 动力舱内湿度 [%RH]
|
||||
uint16_t power_cabin_pressure; // 动力舱内大气压 [kPa]
|
||||
uint8_t reserved2[1]; // 保留字段,地址范围54~55,共2个uint8_t,协议预留
|
||||
|
||||
uint8_t dyn_alarm_flag[6]; // 动力锂电池报警标志字数组,共6字节,按位表示各类报警
|
||||
uint8_t ins_alarm_flag[6]; // 仪表锂电池报警标志字数组,共6字节,按位表示各类报警
|
||||
|
||||
uint8_t ins_relay_status1; // 仪表电池继电器状态,高4位表示正极继电器,低4位表示充电继电器
|
||||
uint8_t ins_relay_status2; // 仪表电池预充继电器和负极继电器状态
|
||||
uint8_t dyn_relay_status1; // 动力电池正极与充电继电器状态
|
||||
uint8_t dyn_relay_status2; // 动力电池预充与负极继电器状态
|
||||
|
||||
uint16_t ins_max_discharge_power; // 仪表电池最大允许放电功率,单位:kW,精度0.05kW
|
||||
uint16_t dyn_max_discharge_power; // 动力电池最大允许放电功率,单位:kW,精度0.05kW
|
||||
|
||||
uint8_t ins_soc; // 仪表锂电池荷电状态SOC,范围:0~100
|
||||
uint8_t dyn_soc; // 动力锂电池荷电状态SOC,范围:0~100
|
||||
|
||||
uint16_t ins_total_energy; // 仪表电池总能量,单位:kWh
|
||||
uint16_t dyn_total_energy; // 动力电池总能量,单位:kWh
|
||||
|
||||
uint16_t ins_power_input; // 仪表电池输入功率,单位:kW
|
||||
uint16_t dyn_power_input; // 动力电池输入功率,单位:kW
|
||||
|
||||
uint8_t ins_charge_status; // 仪表电池充放电状态:00H-无效,10H-充电,20H-放电
|
||||
uint8_t dyn_charge_status; // 动力电池充放电状态:00H-无效,10H-充电,20H-放电
|
||||
|
||||
uint16_t ins_voltage_link; // 仪表电池LINK端电压,单位:0.01V
|
||||
uint16_t ins_voltage_pack; // 仪表电池PACK端电压,单位:0.01V
|
||||
uint16_t ins_current; // 仪表电池电流,单位:0.01A(正值放电)
|
||||
uint16_t ins_resistance_pos; // 仪表电池正极绝缘电阻,单位:kΩ
|
||||
uint16_t ins_resistance_neg; // 仪表电池负极绝缘电阻,单位:kΩ
|
||||
|
||||
uint16_t dyn_voltage_link; // 动力电池LINK端电压,单位:0.01V
|
||||
uint16_t dyn_voltage_pack; // 动力电池PACK端电压,单位:0.01V
|
||||
uint16_t dyn_current; // 动力电池电流,单位:0.01A(正值放电)
|
||||
uint16_t dyn_resistance_pos; // 动力电池正极绝缘电阻,单位:kΩ
|
||||
uint16_t dyn_resistance_neg; // 动力电池负极绝缘电阻,单位:kΩ
|
||||
|
||||
uint8_t ins_emergency_status; // 仪表电池紧急状态字,按位表示异常或告警状态
|
||||
uint8_t dyn_emergency_status; // 动力电池紧急状态字,按位表示异常或告警状态
|
||||
|
||||
uint8_t reserved3[2]; // 保留字节,协议预留
|
||||
|
||||
uint8_t ins_soc_threshold1; // 仪表电池1 SOC门限,范围:0~100
|
||||
uint8_t ins_soc_threshold2; // 仪表电池2 SOC门限,范围:0~100
|
||||
uint8_t ins_soc_threshold3; // 仪表电池3 SOC门限,范围:0~100
|
||||
uint8_t dyn_soc_threshold1; // 动力电池1 SOC门限,范围:0~100
|
||||
uint8_t dyn_soc_threshold2; // 动力电池2 SOC门限,范围:0~100
|
||||
uint8_t dyn_soc_threshold3; // 动力电池3 SOC门限,范围:0~100
|
||||
|
||||
uint8_t ins_power_limit1; // 仪表电池1功率限制值,单位:%
|
||||
uint8_t ins_power_limit2; // 仪表电池2功率限制值,单位:%
|
||||
uint8_t dyn_power_limit1; // 动力电池1功率限制值,单位:%
|
||||
uint8_t dyn_power_limit2; // 动力电池2功率限制值,单位:%
|
||||
|
||||
uint32_t device_online_flag1; // 设备在线状态标志1,byte0:低压配电板在线标志位 byte1:复合管控主机在线标志位 byte2:复合管控备机在线标志位
|
||||
uint32_t device_online_flag2; // 设备在线状态标志2,byte0:仪表锂电在线标志位 byte1:动力锂电在线标志位 byte2:燃电锂电在线标志位 byte3:高压配电板在线标志位
|
||||
|
||||
uint8_t dyn_charge_level; // 动力电池充电状态:01H-1级(不限), 02H-2级(限功率), 03H-3级(关闭)
|
||||
uint8_t dyn_water_leak_status; // 动力漏水状态:0XH-正常, 1XH-异常漏水
|
||||
uint8_t ins_water_leak_dcdc_status; // 仪表漏水状态与DCDC状态:低4位-漏水状态(0XH正常,1XH异常),高4位-DCDC状态(X0H正常,X1H故障)
|
||||
uint8_t reserved4;
|
||||
// uint32_t reserved4; // 保留字段,协议预留
|
||||
uint32_t heartbeat; // 主机心跳计数器或标志值
|
||||
} ccuState;
|
||||
|
||||
typedef struct {
|
||||
unsigned char insSocHold1;
|
||||
unsigned char insSocHold2;
|
||||
unsigned char insSocHold3;
|
||||
unsigned char fcuToInsLimit1;
|
||||
unsigned char fcuToinsLimit2;
|
||||
unsigned char powerSocHold1;
|
||||
unsigned char powerSocHold2;
|
||||
unsigned char powerSocHold3;
|
||||
unsigned char fcuToPowerLimit1;
|
||||
unsigned char fcuToPowerLimit2;
|
||||
}ccuSetParmCmd;
|
||||
|
||||
typedef struct {
|
||||
unsigned char fcmode;
|
||||
unsigned char fcuCmd;
|
||||
unsigned char fcuPowerEfficiency;
|
||||
unsigned char insChargeEnable;
|
||||
unsigned char insBatCmd;
|
||||
unsigned char powerBatCmd;
|
||||
unsigned short powerBatEfficiency;
|
||||
unsigned char heartbeat;
|
||||
unsigned char masterState;
|
||||
unsigned int paceholder1;
|
||||
unsigned int paceholder2;
|
||||
}ccuColCmd;
|
||||
|
||||
typedef struct disHighVolBusState
|
||||
{
|
||||
//断路器状态
|
||||
// 5: 燃料电池断路器
|
||||
unsigned char fuelCellCircuitBreaker;
|
||||
// 6: 动力锂电池断路器
|
||||
unsigned char powerLithiumBatteryCircuitBreaker;
|
||||
// 7: 推进电机断路器
|
||||
unsigned char propulsionMotorCircuitBreaker;
|
||||
// 8: 锂电池组仪表断路器
|
||||
unsigned char lithiumBatteryGroupInstrumentCircuitBreaker;
|
||||
// 9: DC/DC5模块断路器
|
||||
unsigned char dcDc5ModuleCircuitBreaker;
|
||||
// 10: 艏部高压配电箱断路器
|
||||
unsigned char bowHighVoltageDistributionBoxCircuitBreaker;
|
||||
// 11: 艉部FT装置4/5断路器
|
||||
unsigned char sternFTDevice45CircuitBreaker;
|
||||
|
||||
// 14: FB预留断路器
|
||||
unsigned char fbReservedCircuitBreaker;
|
||||
// 12: 艉舵开关1断路器
|
||||
unsigned char sternRudderSwitch1CircuitBreaker;
|
||||
// 13: 艉舵开关2断路器
|
||||
unsigned char sternRudderSwitch2CircuitBreaker;
|
||||
|
||||
// 15: TYZ预留断路器
|
||||
unsigned char tyzReservedCircuitBreaker;
|
||||
// 16: 预留断路器
|
||||
unsigned char reservedCircuitBreaker;
|
||||
// unsigned char busInsulationLow;
|
||||
// unsigned char busAInsulationHigh;
|
||||
// 17: DC/DC5故障字低
|
||||
// 0x00: 正常状态
|
||||
// Bit0: DC/DC模块过温关机
|
||||
// Bit1: 输出过流
|
||||
// Bit2: 输出过压
|
||||
// Bit3: 输出欠压
|
||||
// Bit4: 输入过压
|
||||
// Bit5: 输入欠压
|
||||
// Bit6: 输出短路保护
|
||||
// Bit7: 内部故障
|
||||
// 18: DC/DC5故障字高
|
||||
unsigned char dcDcFaultWord1;
|
||||
// 0x00: 正常状态
|
||||
// Bit0: 通讯故障报警
|
||||
// Bit1: 工作状态 1:启动,0:关闭
|
||||
// Bit2: 冷却泵1故障 冷却泵1故障 : 1故障, 0 正常
|
||||
// Bit3: 冷却泵2故障 冷却泵2故障 :1故障,0 正常
|
||||
// Bit4: 冷却水泄露
|
||||
// Bit5:冷却泵1运行状态 :1 运行,0 停止
|
||||
// Bit6:冷却泵2运行状态 :1 运行,0 停止
|
||||
unsigned char dcDcFaultWord2;
|
||||
// 19: 动力母排绝缘状态(0x55 正常,0xAA 绝缘低)
|
||||
unsigned char powerBusInsulationStatus;
|
||||
// 20: A汇流排绝缘状态(0x55 正常,0xAA 绝缘低)
|
||||
unsigned char aBusInsulationStatus;
|
||||
// 21: 仪表电源状态 (0x55 正常,0xAA 故障)
|
||||
unsigned char meterPowerLossSignal;
|
||||
// 22: 应急电源状态 (0x55 正常,0xAA 故障)
|
||||
unsigned char emergencyPowerLossSignal;
|
||||
// 22: dc/dc温度
|
||||
unsigned char dcDcTemperature;
|
||||
// 23: 动力汇流排电压
|
||||
unsigned short powerBusVoltage;
|
||||
// 24: DC/DC5模块电流
|
||||
unsigned short dcDc5ModuleCurrent;
|
||||
// 25: 动力汇流排电流
|
||||
unsigned short powerBusCurrent;
|
||||
// 26: A汇流排电压
|
||||
unsigned short busbarAVoltage;
|
||||
// 27: 推进电机控制箱电流
|
||||
unsigned short propulsionMotorControlBoxCurrent;
|
||||
// 28: A汇流排电流
|
||||
unsigned short busbarACurrent;
|
||||
// 29: 锂电池组(仪表)电流
|
||||
unsigned short lithiumBatteryGroupMeterCurrent;
|
||||
// 30: 艏部高压配电箱电流
|
||||
unsigned short bowHighVoltageDistributionBoxCurrent;
|
||||
// 31: 艉部FT装置4/5电流
|
||||
unsigned short sternFTDevice45Current;
|
||||
// 32: TYZ预留开关电流
|
||||
unsigned short tyzReservedSwitchCurrent;
|
||||
// 33: 艉舵开关1电流
|
||||
unsigned short sternRudderSwitch1Current;
|
||||
// 34: 预留电流
|
||||
unsigned short reservedCurrent1; // 改为 reservedCurrent1 以避免重名
|
||||
// 35: 艉舵开关2电流
|
||||
unsigned short sternRudderSwitch2Current;
|
||||
// 36: 预留电流2
|
||||
unsigned short reservedCurrent2; // 改为 reservedCurrent2 以避免重名
|
||||
// 37: FB预留电流
|
||||
unsigned short fbReservedSwitchCurrent;
|
||||
// 38: 预留电流3
|
||||
unsigned short reservedCurrent3; // 改为 reservedCurrent3 以避免重名
|
||||
// 39: 冷却水压力
|
||||
unsigned short coolWaterPressure;
|
||||
}disHighVolBusState;
|
||||
|
||||
typedef struct disHighAVolBusState
|
||||
{
|
||||
//5. 艏部FT装置1/2/3断路器
|
||||
unsigned char bowFTDevice123CircuitBreaker;
|
||||
//6. 启闭机构断路器
|
||||
unsigned char actuatorCircuitBreaker;
|
||||
//7. 桅杆舵机控制箱断路器
|
||||
unsigned char mastSteeringGearControlBoxCircuitBreaker;
|
||||
//8. XCZ断路器
|
||||
unsigned char xczCircuitBreaker;
|
||||
//9. 艏舵控制箱断路器
|
||||
unsigned char bowRudderControlBoxCircuitBreaker;
|
||||
//10. 敞水盖启动电缸断路器
|
||||
unsigned char openWaterCoverStartCylinderCircuitBreaker;
|
||||
//11. 仪表电源失电信号 (0x55 正常,0xAA 故障)
|
||||
unsigned char instrumentPowerFailureSignal;
|
||||
//12. 应急电源失电信号 (0x55 正常,0xAA 故障)
|
||||
unsigned char emergencyPowerFailureSignal;
|
||||
//13. 浸水报警
|
||||
// unsigned char busbarBInsulationStatus;
|
||||
unsigned char waterIngressionAlarm;
|
||||
//14. 汇流排B电压
|
||||
unsigned short busbarBVoltage;
|
||||
//15. 汇流排B电流
|
||||
unsigned short busbarBCurrent;
|
||||
//16. 艏部FT装置1/2/3电流
|
||||
unsigned short bowFTDevice123Current;
|
||||
//17. 启闭机构电流
|
||||
unsigned short actuatorCurrent;
|
||||
//18. 桅杆舵机控制箱电流
|
||||
unsigned short mastSteeringGearControlBoxCurrent;
|
||||
//19. XCZ电流
|
||||
unsigned short xczCurrent;
|
||||
//20. 艏舵控制箱电流
|
||||
unsigned short bowRudderControlBoxCurrent;
|
||||
//21. 敞水盖启动电缸电流
|
||||
unsigned short openWaterCoverStartCylinderCurrent;
|
||||
}disHighAVolBusState;
|
||||
|
||||
typedef struct disHighBVolBusState
|
||||
{
|
||||
//5. 锂电池组(仪表)断路器
|
||||
unsigned char lithiumBatteryGroupInstrumentCircuitBreaker;
|
||||
//6. 艏部低压配电箱断路器
|
||||
unsigned char bowLowVoltageDistributionBoxCircuitBreaker;
|
||||
//7. UNIT4仪表DC48V断路器
|
||||
unsigned char unit4InstrumentDC48VCircuitBreaker;
|
||||
//8. DC-C1直流配电板断路器
|
||||
unsigned char dcC1DCDistributionPanelCircuitBreaker;
|
||||
//9. 预留断路器1
|
||||
unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀
|
||||
//10. 预留断路器2
|
||||
unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀
|
||||
//11. 应急锂电池组2断路器
|
||||
unsigned char emergencyLithiumBatteryGroup2CircuitBreaker;
|
||||
//12. 仪表电源失电信号 (0x55 正常,0xAA 故障)
|
||||
unsigned char instrumentPowerFailureSignal;
|
||||
//13. 应急电源失电信号 (0x55 正常,0xAA 故障)
|
||||
unsigned char emergencyPowerFailureSignal;
|
||||
//14. 仪表汇流排绝缘低 (0x55 正常,0xAA 绝缘低)
|
||||
unsigned char instrumentBusbarInsulationLow;
|
||||
//15. 仪表母排电压
|
||||
unsigned short instrumentBusbarVoltage;
|
||||
//16. 艏部低压配电箱电流
|
||||
unsigned short bowLowVoltageDistributionBoxCurrent;
|
||||
//17. DC-C1(直流配电板1)仪表DC48V电流
|
||||
unsigned short dcC1InstrumentDC48VCurrent;
|
||||
//18. 预留电流
|
||||
unsigned short reservedCurrent1; // 为了区分,添加了数字后缀
|
||||
//19. 应急锂电池组2电流
|
||||
unsigned short emergencyLithiumBatteryGroup2Current;
|
||||
//20. 锂电池组(仪表)电流
|
||||
unsigned short lithiumBatteryGroupInstrumentCurrent;
|
||||
//21. UNIT4仪表DC48V电流
|
||||
unsigned short unit4InstrumentDC48VCurrent;
|
||||
//22. Ushort 预留电流
|
||||
unsigned short reservedCurrent2; // 为了区分,添加了数字后缀
|
||||
//23. 应急2汇流排电压
|
||||
unsigned short emergency2BusbarVoltage;
|
||||
//24. 复合能源管控系统应急DC48V电流
|
||||
unsigned short compositeEnergyManagementSystemEmergencyDC48VCurrent;
|
||||
//25. 燃料电池安全系统应急DC48V电流
|
||||
unsigned short fuelCellSecuritySystemEmergencyDC48VCurrent;
|
||||
//26. PLC控制电源电流
|
||||
unsigned short plcControlPowerCurrent;
|
||||
} disLowMainBusState;
|
||||
|
||||
typedef struct disLowBusState
|
||||
{
|
||||
//5. UNIT1断路器
|
||||
unsigned char unit1CircuitBreaker;
|
||||
//6. UNIT2断路器
|
||||
unsigned char unit2CircuitBreaker;
|
||||
//7. UNIT3断路器
|
||||
unsigned char unit3CircuitBreaker;
|
||||
//8. UNIT5断路器
|
||||
unsigned char unit5CircuitBreaker;
|
||||
//9. 艏部PZ装置断路器
|
||||
unsigned char bowPZDeviceCircuitBreaker;
|
||||
//10. 预留断路器1
|
||||
unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀
|
||||
//11. 预留断路器2
|
||||
unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀
|
||||
//12. 应急锂电池组1断路器
|
||||
unsigned char emergencyLithiumBatteryGroup1CircuitBreaker;
|
||||
//13. 仪表电源失电信号 (0x55 正常,0xAA 故障)
|
||||
unsigned char powerFailureSignal;
|
||||
//14. 应急电源失电信号 (0x55 正常,0xAA 故障)
|
||||
unsigned char emergencyPowerFailureSignal;
|
||||
//15. 浸水报警 (0x55 正常,0xAA 故障)
|
||||
unsigned char waterIngressionAlarm;
|
||||
//16. 仪表母排电压
|
||||
unsigned short instrumentBusbarVoltage;
|
||||
//17. 仪表母排电流
|
||||
unsigned short instrumentBusbarCurrent;
|
||||
//18. UNIT1电流
|
||||
unsigned short unit1Current;
|
||||
//19. UNIT2电流
|
||||
unsigned short unit2Current;
|
||||
//20. UNIT3电流
|
||||
unsigned short unit3Current;
|
||||
//21. UNIT5电流
|
||||
unsigned short unit5Current;
|
||||
//22. 艏部PZ装置电流
|
||||
unsigned short bowPZDeviceCurrent;
|
||||
//23. 应急锂电池组1电流
|
||||
unsigned short emergencyLithiumBatteryGroup1Current;
|
||||
//24. 应急1汇流排电压
|
||||
unsigned short emergency1BusbarVoltage;
|
||||
}disLowBusState;
|
||||
|
||||
typedef struct disHighVolBusCmd
|
||||
{
|
||||
// 5: 燃料电池断路器
|
||||
unsigned char fuelCellCircuitBreaker;
|
||||
// 6: 动力锂电池断路器
|
||||
unsigned char powerLithiumBatteryCircuitBreaker;
|
||||
// 7: 推进电机断路器
|
||||
unsigned char propulsionMotorCircuitBreaker;
|
||||
// 8: 锂电池组仪表断路器
|
||||
unsigned char lithiumBatteryGroupInstrumentCircuitBreaker;
|
||||
// 9: DC/DC5模块断路器
|
||||
unsigned char dcDc5ModuleCircuitBreaker;
|
||||
// 10: 艏部高压配电箱断路器
|
||||
unsigned char bowHighVoltageDistributionBoxCircuitBreaker;
|
||||
// 11: 艉部FT装置4/5断路器
|
||||
unsigned char sternFTDevice45CircuitBreaker;
|
||||
// // 12: 艉舵开关1断路器
|
||||
// unsigned char sternRudderSwitch1CircuitBreaker;
|
||||
// // 13: 艉舵开关2断路器
|
||||
// unsigned char sternRudderSwitch2CircuitBreaker;
|
||||
// // 14: FB预留断路器
|
||||
// unsigned char fbReservedCircuitBreaker;
|
||||
|
||||
// 12: FB预留断路器
|
||||
unsigned char fbReservedCircuitBreaker;
|
||||
// 13: 艉舵开关1断路器
|
||||
unsigned char sternRudderSwitch1CircuitBreaker;
|
||||
// 14: 艉舵开关2断路器
|
||||
unsigned char sternRudderSwitch2CircuitBreaker;
|
||||
|
||||
// 15: TYZ预留断路器
|
||||
unsigned char tyzReservedCircuitBreaker;
|
||||
// 16: 预留断路器
|
||||
unsigned char reservedCircuitBreaker;
|
||||
// 17: DC/DC5模块启动
|
||||
unsigned char dcdc5Module;
|
||||
// 18: 冷却系统启动
|
||||
unsigned char coolingSystem;
|
||||
// unsigned char inputWater;
|
||||
// unsigned char outputWater;
|
||||
}disHighVolBusCmd;
|
||||
|
||||
typedef struct disHighAVolBusCmd
|
||||
{
|
||||
//5. 艏部FT装置1/2/3断路器
|
||||
unsigned char bowFTDevice123CircuitBreaker;
|
||||
//6. 启闭机构断路器
|
||||
unsigned char actuatorCircuitBreaker;
|
||||
//7. 桅杆舵机控制箱断路器
|
||||
unsigned char mastSteeringGearControlBoxCircuitBreaker;
|
||||
//8. XCZ断路器
|
||||
unsigned char xczCircuitBreaker;
|
||||
//9. 艏舵控制箱断路器
|
||||
unsigned char bowRudderControlBoxCircuitBreaker;
|
||||
//10. 敞水盖启动电缸断路器
|
||||
unsigned char openWaterCoverStartCylinderCircuitBreaker;
|
||||
}disHighAVolBusCmd;
|
||||
|
||||
typedef struct disHighBVolBusCmd
|
||||
{
|
||||
//5. 锂电池组(仪表)断路器
|
||||
unsigned char lithiumBatteryGroupInstrumentCircuitBreaker;
|
||||
//6. 艏部低压配电箱断路器
|
||||
unsigned char bowLowVoltageDistributionBoxCircuitBreaker;
|
||||
//7. UNIT4仪表DC48V断路器
|
||||
unsigned char unit4InstrumentDC48VCircuitBreaker;
|
||||
//8. DC-C1直流配电板断路器
|
||||
unsigned char dcC1DCDistributionPanelCircuitBreaker;
|
||||
//9. 预留断路器1
|
||||
unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀
|
||||
//10. 预留断路器2
|
||||
unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀
|
||||
//11. 应急锂电池组2断路器
|
||||
unsigned char emergencyLithiumBatteryGroup2CircuitBreaker;
|
||||
}disLowMainBusCmd;
|
||||
|
||||
typedef struct disLowBusCmd
|
||||
{
|
||||
unsigned char unit1CircuitBreaker;
|
||||
unsigned char unit2CircuitBreaker;
|
||||
unsigned char unit3CircuitBreaker;
|
||||
unsigned char unit5CircuitBreaker;
|
||||
unsigned char bowPZDeviceCircuitBreaker;
|
||||
unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀
|
||||
unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀
|
||||
unsigned char emergencyLithiumBatteryGroup1CircuitBreaker;
|
||||
}disLowBusCmd;
|
||||
|
||||
#pragma pack (0)
|
||||
|
||||
//状态结构体定义
|
||||
typedef struct pmState
|
||||
{
|
||||
ccuState ccustate;
|
||||
disHighVolBusState bus1State;
|
||||
disHighAVolBusState bus2State;
|
||||
disLowMainBusState bus3State;
|
||||
disLowBusState bus4State;
|
||||
} PmState;
|
||||
|
||||
typedef struct disBus1Breaker
|
||||
{
|
||||
unsigned char fuelCellCircuitBreaker : 1;
|
||||
unsigned char powerLithiumBatteryCircuitBreaker : 1;
|
||||
unsigned char propulsionMotorCircuitBreaker : 1;
|
||||
unsigned char lithiumBatteryGroupInstrumentCircuitBreaker : 1;
|
||||
unsigned char dcDc5ModuleCircuitBreaker : 1;
|
||||
unsigned char bowHighVoltageDistributionBoxCircuitBreaker : 1;
|
||||
unsigned char sternFTDevice45CircuitBreaker : 1;
|
||||
unsigned char sternRudderSwitch1CircuitBreaker : 1;
|
||||
unsigned char sternRudderSwitch2CircuitBreaker : 1;
|
||||
unsigned char fbReservedCircuitBreaker : 1;
|
||||
unsigned char tyzReservedCircuitBreaker : 1;
|
||||
unsigned char reservedCircuitBreaker : 1;
|
||||
unsigned char dcdcmodel : 1;
|
||||
unsigned char coolingSystem : 1;
|
||||
unsigned short paceholder : 4;
|
||||
} disBus1Breaker;
|
||||
|
||||
|
||||
typedef struct disBus2Breaker
|
||||
{
|
||||
unsigned char bowFTDevice123CircuitBreaker : 1;
|
||||
unsigned char actuatorCircuitBreaker : 1;
|
||||
unsigned char mastSteeringGearControlBoxCircuitBreaker : 1;
|
||||
unsigned char xczCircuitBreaker : 1;
|
||||
unsigned char bowRudderControlBoxCircuitBreaker : 1;
|
||||
unsigned char openWaterCoverStartCylinderCircuitBreaker : 1;
|
||||
unsigned short paceholder : 10;
|
||||
/* data */
|
||||
} disBus2Breaker;
|
||||
|
||||
|
||||
typedef struct disBus3Breaker
|
||||
{
|
||||
unsigned char lithiumBatteryGroupInstrumentCircuitBreaker : 1;
|
||||
unsigned char bowLowVoltageDistributionBoxCircuitBreaker : 1;
|
||||
unsigned char unit4InstrumentDC48VCircuitBreaker : 1;
|
||||
unsigned char dcC1DCDistributionPanelCircuitBreaker : 1;
|
||||
unsigned char reservedCircuitBreaker1 : 1;
|
||||
unsigned char reservedCircuitBreaker2 : 1;
|
||||
unsigned char emergencyLithiumBatteryGroup2CircuitBreaker : 1;
|
||||
unsigned short paceholder : 9;
|
||||
/* data */
|
||||
} disBus3Breaker;
|
||||
|
||||
|
||||
typedef struct disBus4Breaker
|
||||
{
|
||||
unsigned char unit1CircuitBreaker : 1;
|
||||
unsigned char unit2CircuitBreaker : 1;
|
||||
unsigned char unit3CircuitBreaker : 1;
|
||||
unsigned char unit5CircuitBreaker : 1;
|
||||
unsigned char bowPZDeviceCircuitBreaker : 1;
|
||||
unsigned char reservedCircuitBreaker1 : 1; // 为了区分,添加了数字后缀
|
||||
unsigned char reservedCircuitBreaker2 : 1; // 为了区分,添加了数字后缀
|
||||
unsigned char emergencyLithiumBatteryGroup1CircuitBreaker : 1;
|
||||
unsigned short paceholder : 8;
|
||||
/* data */
|
||||
} disBus4Breaker;
|
||||
|
||||
typedef struct disSysBreakerList
|
||||
{
|
||||
disBus1Breaker bus1Breaker;
|
||||
disBus2Breaker bus2Breaker;
|
||||
disBus3Breaker bus3Breaker;
|
||||
disBus4Breaker bus4Breaker;
|
||||
} disSysBreaker;
|
||||
|
||||
typedef struct MSControlCmd
|
||||
{
|
||||
unsigned int powerCMD;
|
||||
unsigned int modCMD;
|
||||
unsigned int workCMD;
|
||||
}MSControlCmd;
|
||||
|
||||
|
||||
namespace FcuCommand {
|
||||
enum Type : unsigned char {
|
||||
SelfCheck = 0x01,
|
||||
Start = 0x02,
|
||||
Stop = 0x03,
|
||||
Reset = 0x04,
|
||||
EmergencyStop = 0x05,
|
||||
Supply = 0x06,
|
||||
WarmUp = 0x07,
|
||||
Maintenance = 0x08
|
||||
};
|
||||
}
|
||||
|
||||
enum class FcuState : unsigned char {
|
||||
//初始化
|
||||
Init = 0x01,
|
||||
//待机
|
||||
Standby = 0x02,
|
||||
//自检异常
|
||||
SelfCheckError = 0x03,
|
||||
//就绪
|
||||
Ready = 0x04,
|
||||
//启动
|
||||
Start = 0x05,
|
||||
//运行
|
||||
Running = 0x06,
|
||||
//停机
|
||||
Stop = 0x07,
|
||||
//故障
|
||||
Fault = 0x08,
|
||||
//补给
|
||||
Supply = 0x09,
|
||||
//预热
|
||||
WarmUp = 0x0A,
|
||||
//预热完成
|
||||
WarmUpComplete = 0x0B,
|
||||
//维护
|
||||
Maintenance = 0x0C,
|
||||
//维护完成
|
||||
MaintenanceComplete = 0x0D
|
||||
};
|
||||
|
||||
namespace BatteryCommand {
|
||||
enum Type : unsigned char {
|
||||
Start = 0x10,
|
||||
Stop = 0x20,
|
||||
Hold = 0x00
|
||||
};
|
||||
};
|
||||
|
||||
namespace PMMode {
|
||||
enum Type : unsigned char {
|
||||
Normal = 0,
|
||||
Test = 1,
|
||||
Debug = 2
|
||||
};
|
||||
};
|
||||
|
||||
//工况定义
|
||||
namespace WorkCondition {
|
||||
enum Type : unsigned char {
|
||||
CHANING = 0, // 工况切换中
|
||||
STANDBY = 1, // 待机工况
|
||||
SHORE_BASED_READY = 2, // 岸基备航
|
||||
WATER_BASED_READY = 3, // 水中备航
|
||||
REMOTE_CONTROL = 4, // 遥控工况
|
||||
CRUISE_MODE = 5, // 巡航模式
|
||||
HIGH_SPEED_MODE = 6, // 高速模式
|
||||
ASCEND_DESCEND = 7, // 上浮下潜
|
||||
BUOYANCY_ADJUST = 8, // 浮调模式
|
||||
UNDERWATER_RECON = 9, // 水下侦查
|
||||
SURFACE_RECON = 10, // 水面侦查
|
||||
DJ_MODE = 11, // DJ模式
|
||||
LIFT_MODE = 12 // 调试模式
|
||||
};
|
||||
};
|
||||
|
||||
namespace RunMode {
|
||||
enum Type : unsigned char {
|
||||
//正常模式
|
||||
Normal = 0,
|
||||
//测试模式
|
||||
Test = 1,
|
||||
//调试模式
|
||||
Debug = 2
|
||||
};
|
||||
};
|
||||
|
||||
namespace TaskType {
|
||||
enum Type : unsigned char {
|
||||
THROW_LOAD = 1, // 抛载
|
||||
FLOAT_UP = 2, // 运动上浮
|
||||
RECYCLE = 3, // 回收
|
||||
HOVER = 4, // 悬停
|
||||
SAT_COMM = 5, // 上浮通信
|
||||
SAT_CALIBRATE = 6, // 上浮校准
|
||||
TOUR = 7, // 游曳
|
||||
SAIL = 8, // 航行
|
||||
|
||||
EMER_SAT_COMM = 9, //紧急上浮通信
|
||||
EMER_SAIL = 10 //紧急航行
|
||||
};
|
||||
|
||||
inline const std::string toString(Type type) {
|
||||
static const std::map<Type, std::string> names = {
|
||||
{THROW_LOAD, "throwLoad"},
|
||||
{FLOAT_UP, "floatUp"},
|
||||
{RECYCLE, "recycle"},
|
||||
{HOVER, "hover"},
|
||||
{SAT_COMM, "satComm"},
|
||||
{SAT_CALIBRATE, "satCalibrate"},
|
||||
{TOUR, "tour"},
|
||||
{SAIL, "sail"},
|
||||
{EMER_SAT_COMM,"emerSatComm"},
|
||||
{EMER_SAIL,"emerSail"}
|
||||
};
|
||||
auto it = names.find(type);
|
||||
return it != names.end() ? it->second : "unknown";
|
||||
}
|
||||
inline Type fromString(const std::string& str) {
|
||||
static const std::map<std::string, Type> stringToEnum = {
|
||||
{"throwLoad", THROW_LOAD},
|
||||
{"floatUp", FLOAT_UP},
|
||||
{"recycle", RECYCLE},
|
||||
{"hover", HOVER},
|
||||
{"satComm", SAT_COMM},
|
||||
{"emerSatComm",SAT_COMM},
|
||||
{"satCalibrate",SAT_CALIBRATE},
|
||||
{"tour", TOUR},
|
||||
{"sail", SAIL},
|
||||
{"emerSatComm",EMER_SAT_COMM},
|
||||
{"emerSail",EMER_SAIL}
|
||||
};
|
||||
auto it = stringToEnum.find(str);
|
||||
return it != stringToEnum.end() ? it->second : static_cast<Type>(0); // 返回0表示无效类型
|
||||
}
|
||||
}
|
||||
|
||||
namespace EquipmentCommand {
|
||||
enum Type : unsigned char {
|
||||
OFF = 0, //断电
|
||||
ON = 1, //上电
|
||||
//仪表电上电
|
||||
METER_ON = 2,
|
||||
//动力电上电
|
||||
POWER_ON = 3,
|
||||
//仪表电断电
|
||||
METER_OFF = 4,
|
||||
//动力电断电
|
||||
POWER_OFF = 5,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct MissionState
|
||||
{
|
||||
int type;
|
||||
bool enableBowRudder;
|
||||
bool enableBuoyancyAdjustment;
|
||||
};
|
||||
|
||||
struct DeviceSwitchCmd
|
||||
{
|
||||
int id;
|
||||
int cmd;
|
||||
};
|
||||
|
||||
namespace DeviceId {
|
||||
enum Type : unsigned char {
|
||||
singleBeamSonar1 = 0,
|
||||
singleBeamSonar2 = 1,
|
||||
singleBeamSonar3 = 2,
|
||||
singleBeamSonar4 = 3,
|
||||
singleBeamSonar5 = 4,
|
||||
singleBeamSonar6 = 5,
|
||||
singleBeamSonar7 = 6,
|
||||
singleBeamSonar8 = 7,
|
||||
forwardSonar = 8,
|
||||
bowCover1 = 9,
|
||||
bowCover2 = 10,
|
||||
bowCover3 = 11,
|
||||
bowCover4 = 12,
|
||||
bowCover5 = 13,
|
||||
bowCover6 = 14,
|
||||
bowRudderDeploy = 15,
|
||||
bowRudderServo1 = 16,
|
||||
bowRudderServo2 = 17,
|
||||
depth1 = 18,
|
||||
depth2 = 19,
|
||||
depth3 = 20,
|
||||
overDeep1 = 21,
|
||||
overDeep2 = 22,
|
||||
ctd1 = 23,
|
||||
ctd2 = 24,
|
||||
soundVeloc = 25,
|
||||
waterInject = 26,
|
||||
bowWaterInet1 = 27,
|
||||
bowWaterInet2 = 28,
|
||||
bowWaterInet3 = 29,
|
||||
bowWaterInet4 = 30,
|
||||
bowWaterInet5 = 31,
|
||||
bowWaterInet6 = 32,
|
||||
bowWaterInet7 = 33,
|
||||
bowWaterInet8 = 34,
|
||||
sideSonar = 35,
|
||||
lowFreqSonar = 36,
|
||||
launchControler = 37,
|
||||
photoSensor = 38,
|
||||
electSensor = 39,
|
||||
commMast = 40,
|
||||
mastLiftingServo = 41,
|
||||
USBL = 42,
|
||||
DVL = 43,
|
||||
buoyancyAdjust1 = 44,
|
||||
buoyancyAdjust2 = 45,
|
||||
buoyancyAdjust3 = 46,
|
||||
buoyancyAdjust4 = 47,
|
||||
buoyancyAdjust5 = 48,
|
||||
sternRudderServo1 = 49,
|
||||
sternRudderServo2 = 50,
|
||||
sternRudderServo3 = 51,
|
||||
sternRudderServo4 = 52,
|
||||
thruster = 53,
|
||||
bowThrow = 54,
|
||||
sternThrow = 55,
|
||||
buoyage = 56,
|
||||
ins = 57,
|
||||
ntp = 58,
|
||||
inputWaterSensor1 = 59,
|
||||
inputWaterSensor2 = 60,
|
||||
inputWaterSensor3 = 61,
|
||||
};
|
||||
inline const std::string toString(Type type) {
|
||||
static const std::map<Type, std::string> names = {
|
||||
{singleBeamSonar1, "singleBeamSonar1"},
|
||||
{singleBeamSonar2, "singleBeamSonar2"},
|
||||
{singleBeamSonar3, "singleBeamSonar3"},
|
||||
{singleBeamSonar4, "singleBeamSonar4"},
|
||||
{singleBeamSonar5, "singleBeamSonar5"},
|
||||
{singleBeamSonar6, "singleBeamSonar6"},
|
||||
{singleBeamSonar7, "singleBeamSonar7"},
|
||||
{singleBeamSonar8, "singleBeamSonar8"},
|
||||
{forwardSonar, "forwardSonar"},
|
||||
{bowCover1, "bowCover1"},
|
||||
{bowCover2, "bowCover2"},
|
||||
{bowCover3, "bowCover3"},
|
||||
{bowCover4, "bowCover4"},
|
||||
{bowCover5, "bowCover5"},
|
||||
{bowCover6, "bowCover6"},
|
||||
{bowRudderDeploy, "bowRudderDeploy"},
|
||||
{bowRudderServo1, "bowRudderServo1"},
|
||||
{bowRudderServo2, "bowRudderServo2"},
|
||||
{depth1, "depth1"},
|
||||
{depth2, "depth2"},
|
||||
{depth3, "depth3"},
|
||||
{overDeep1, "overDeep1"},
|
||||
{overDeep2, "overDeep2"},
|
||||
{ctd1, "ctd1"},
|
||||
{ctd2, "ctd2"},
|
||||
{soundVeloc, "soundVeloc"},
|
||||
{waterInject, "waterInject"},
|
||||
{bowWaterInet1, "bowWaterInet1"},
|
||||
{bowWaterInet2, "bowWaterInet2"},
|
||||
{bowWaterInet3, "bowWaterInet3"},
|
||||
{bowWaterInet4, "bowWaterInet4"},
|
||||
{bowWaterInet5, "bowWaterInet5"},
|
||||
{bowWaterInet6, "bowWaterInet6"},
|
||||
{bowWaterInet7, "bowWaterInet7"},
|
||||
{bowWaterInet8, "bowWaterInet8"},
|
||||
{sideSonar, "sideSonar"},
|
||||
{lowFreqSonar, "lowFreqSonar"},
|
||||
{launchControler, "launchControler"},
|
||||
{photoSensor, "photoSensor"},
|
||||
{electSensor, "electSensor"},
|
||||
{commMast, "commMast"},
|
||||
{mastLiftingServo, "mastLiftingServo"},
|
||||
{USBL, "USBL"},
|
||||
{DVL, "DVL"},
|
||||
{buoyancyAdjust1, "buoyancyAdjust1"},
|
||||
{buoyancyAdjust2, "buoyancyAdjust2"},
|
||||
{buoyancyAdjust3, "buoyancyAdjust3"},
|
||||
{buoyancyAdjust4, "buoyancyAdjust4"},
|
||||
{buoyancyAdjust5, "buoyancyAdjust5"},
|
||||
{sternRudderServo1, "sternRudderServo1"},
|
||||
{sternRudderServo2, "sternRudderServo2"},
|
||||
{sternRudderServo3, "sternRudderServo3"},
|
||||
{sternRudderServo4, "sternRudderServo4"},
|
||||
{thruster, "thruster"},
|
||||
{bowThrow, "bowThrow"},
|
||||
{sternThrow, "sternThrow"},
|
||||
{buoyage, "buoyage"},
|
||||
{ins, "ins"},
|
||||
{ntp, "ntp"},
|
||||
{inputWaterSensor1, "inputWaterSensor1"},
|
||||
{inputWaterSensor2, "inputWaterSensor2"},
|
||||
{inputWaterSensor3, "inputWaterSensor3"}
|
||||
};
|
||||
auto it = names.find(type);
|
||||
return it != names.end() ? it->second : "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// 设备类id存储
|
||||
static const std::unordered_set<int> underWterDevices = {
|
||||
DeviceId::singleBeamSonar1,
|
||||
DeviceId::singleBeamSonar2,
|
||||
DeviceId::singleBeamSonar3,
|
||||
DeviceId::singleBeamSonar4,
|
||||
DeviceId::singleBeamSonar5,
|
||||
DeviceId::singleBeamSonar6,
|
||||
DeviceId::singleBeamSonar7,
|
||||
DeviceId::singleBeamSonar8,
|
||||
DeviceId::forwardSonar,
|
||||
DeviceId::USBL,
|
||||
DeviceId::DVL,
|
||||
DeviceId::lowFreqSonar
|
||||
};
|
||||
static const std::unordered_set<int> noPowerDevices = {
|
||||
DeviceId::depth1,
|
||||
DeviceId::depth2,
|
||||
DeviceId::depth3,
|
||||
DeviceId::overDeep1,
|
||||
DeviceId::overDeep2,
|
||||
DeviceId::ctd1,
|
||||
DeviceId::ctd2,
|
||||
DeviceId::soundVeloc,
|
||||
DeviceId::waterInject,
|
||||
DeviceId::launchControler,
|
||||
DeviceId::photoSensor,
|
||||
DeviceId::electSensor,
|
||||
DeviceId::commMast,
|
||||
DeviceId::ntp,
|
||||
DeviceId::bowThrow,
|
||||
DeviceId::sternThrow,
|
||||
DeviceId::ins,
|
||||
DeviceId::inputWaterSensor1,
|
||||
DeviceId::inputWaterSensor2,
|
||||
DeviceId::inputWaterSensor3
|
||||
};
|
||||
namespace FaultEnable {
|
||||
enum Type : bool {
|
||||
BasicNavigationFault_1 = false, // 使能故障
|
||||
BasicNavigationFault_2 = false,
|
||||
BasicNavigationFault_3 = false,
|
||||
BasicNavigationFault_4 = false,
|
||||
BasicNavigationFault_5 = false,
|
||||
BasicNavigationFault_6 = false,
|
||||
BasicNavigationFault_7 = false,
|
||||
BasicNavigationFault_8 = false,
|
||||
BasicNavigationFault_9 = false,
|
||||
BasicNavigationFault_10 = false,
|
||||
|
||||
ExtendedNavigationFault_1 = false, // 使能故障
|
||||
ExtendedNavigationFault_2 = false,
|
||||
ExtendedNavigationFault_3 = false,
|
||||
ExtendedNavigationFault_4 = false,
|
||||
|
||||
ObstacleAvoidanceFault_1 = false, // 使能故障
|
||||
ObstacleAvoidanceFault_2 = false,
|
||||
ObstacleAvoidanceFault_3 = false,
|
||||
|
||||
BuoyancyControlFault_1 = false, // 使能故障
|
||||
BuoyancyControlFault_2 = false,
|
||||
BuoyancyControlFault_3 = false,
|
||||
BuoyancyControlFault_4 = false,
|
||||
|
||||
CommunicationSystemFault_1 = false, // 使能故障
|
||||
CommunicationSystemFault_2 = false,
|
||||
CommunicationSystemFault_3 = false,
|
||||
|
||||
PayloadSystemFault_1 = false, // 使能故障
|
||||
PayloadSystemFault_2 = false,
|
||||
PayloadSystemFault_3 = false,
|
||||
PayloadSystemFault_4 = false,
|
||||
PayloadSystemFault_5 = false,
|
||||
PayloadSystemFault_6 = false,
|
||||
PayloadSystemFault_7 = false,
|
||||
|
||||
EmergencySystemFault_1 = false, // 使能故障
|
||||
EmergencySystemFault_2 = false,
|
||||
EmergencySystemFault_3 = false,
|
||||
EmergencySystemFault_4 = false,
|
||||
EmergencySystemFault_5 = false,
|
||||
EmergencySystemFault_6 = false,
|
||||
|
||||
SensorSystemFault_1 = false, // 使能故障
|
||||
SensorSystemFault_2 = false,
|
||||
SensorSystemFault_3 = false,
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
#ifndef SQLITE_H
|
||||
#define SQLITE_H
|
||||
#include "sqlite3.h"
|
||||
#include <string>
|
||||
#include "../pmSysvariable.h"
|
||||
|
||||
class SQLite
|
||||
{
|
||||
private:
|
||||
sqlite3* m_db;
|
||||
public:
|
||||
std::string m_dbPath;
|
||||
SQLite(const std::string& dbName);
|
||||
~SQLite();
|
||||
|
||||
//创建表
|
||||
bool createTable();
|
||||
bool createTable(const std::string& tableName, const std::string& columns);
|
||||
|
||||
// 插入数据函数
|
||||
bool insertData(ccuState data);
|
||||
bool insertData(disHighVolBusState data);
|
||||
bool insertData(disHighAVolBusState data);
|
||||
bool insertData(disLowMainBusState data);
|
||||
bool insertData(disLowBusState data);
|
||||
|
||||
//插入指令数据
|
||||
bool insertData(ccuColCmd cmd);
|
||||
bool insertData(disHighVolBusCmd cmd);
|
||||
bool insertData(disHighAVolBusCmd cmd);
|
||||
bool insertData(disLowMainBusCmd cmd);
|
||||
bool insertData(disLowBusCmd cmd);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,719 @@
|
||||
/*
|
||||
** 2006 June 7
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the SQLite interface for use by
|
||||
** shared libraries that want to be imported as extensions into
|
||||
** an SQLite instance. Shared libraries that intend to be loaded
|
||||
** as extensions by SQLite should #include this file instead of
|
||||
** sqlite3.h.
|
||||
*/
|
||||
#ifndef SQLITE3EXT_H
|
||||
#define SQLITE3EXT_H
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** The following structure holds pointers to all of the SQLite API
|
||||
** routines.
|
||||
**
|
||||
** WARNING: In order to maintain backwards compatibility, add new
|
||||
** interfaces to the end of this structure only. If you insert new
|
||||
** interfaces in the middle of this structure, then older different
|
||||
** versions of SQLite will not be able to load each other's shared
|
||||
** libraries!
|
||||
*/
|
||||
struct sqlite3_api_routines {
|
||||
void * (*aggregate_context)(sqlite3_context*,int nBytes);
|
||||
int (*aggregate_count)(sqlite3_context*);
|
||||
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
|
||||
int (*bind_double)(sqlite3_stmt*,int,double);
|
||||
int (*bind_int)(sqlite3_stmt*,int,int);
|
||||
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
|
||||
int (*bind_null)(sqlite3_stmt*,int);
|
||||
int (*bind_parameter_count)(sqlite3_stmt*);
|
||||
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
|
||||
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
|
||||
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
|
||||
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
|
||||
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
|
||||
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
|
||||
int (*busy_timeout)(sqlite3*,int ms);
|
||||
int (*changes)(sqlite3*);
|
||||
int (*close)(sqlite3*);
|
||||
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const char*));
|
||||
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const void*));
|
||||
const void * (*column_blob)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_count)(sqlite3_stmt*pStmt);
|
||||
const char * (*column_database_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_database_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_decltype)(sqlite3_stmt*,int i);
|
||||
const void * (*column_decltype16)(sqlite3_stmt*,int);
|
||||
double (*column_double)(sqlite3_stmt*,int iCol);
|
||||
int (*column_int)(sqlite3_stmt*,int iCol);
|
||||
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
|
||||
const char * (*column_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_origin_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_origin_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_table_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_table_name16)(sqlite3_stmt*,int);
|
||||
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
|
||||
const void * (*column_text16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_type)(sqlite3_stmt*,int iCol);
|
||||
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
|
||||
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
|
||||
int (*complete)(const char*sql);
|
||||
int (*complete16)(const void*sql);
|
||||
int (*create_collation)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_collation16)(sqlite3*,const void*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_function16)(sqlite3*,const void*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
|
||||
int (*data_count)(sqlite3_stmt*pStmt);
|
||||
sqlite3 * (*db_handle)(sqlite3_stmt*);
|
||||
int (*declare_vtab)(sqlite3*,const char*);
|
||||
int (*enable_shared_cache)(int);
|
||||
int (*errcode)(sqlite3*db);
|
||||
const char * (*errmsg)(sqlite3*);
|
||||
const void * (*errmsg16)(sqlite3*);
|
||||
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
|
||||
int (*expired)(sqlite3_stmt*);
|
||||
int (*finalize)(sqlite3_stmt*pStmt);
|
||||
void (*free)(void*);
|
||||
void (*free_table)(char**result);
|
||||
int (*get_autocommit)(sqlite3*);
|
||||
void * (*get_auxdata)(sqlite3_context*,int);
|
||||
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
|
||||
int (*global_recover)(void);
|
||||
void (*interruptx)(sqlite3*);
|
||||
sqlite_int64 (*last_insert_rowid)(sqlite3*);
|
||||
const char * (*libversion)(void);
|
||||
int (*libversion_number)(void);
|
||||
void *(*malloc)(int);
|
||||
char * (*mprintf)(const char*,...);
|
||||
int (*open)(const char*,sqlite3**);
|
||||
int (*open16)(const void*,sqlite3**);
|
||||
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
|
||||
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
|
||||
void *(*realloc)(void*,int);
|
||||
int (*reset)(sqlite3_stmt*pStmt);
|
||||
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_double)(sqlite3_context*,double);
|
||||
void (*result_error)(sqlite3_context*,const char*,int);
|
||||
void (*result_error16)(sqlite3_context*,const void*,int);
|
||||
void (*result_int)(sqlite3_context*,int);
|
||||
void (*result_int64)(sqlite3_context*,sqlite_int64);
|
||||
void (*result_null)(sqlite3_context*);
|
||||
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
|
||||
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_value)(sqlite3_context*,sqlite3_value*);
|
||||
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
|
||||
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
||||
const char*,const char*),void*);
|
||||
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
||||
char * (*xsnprintf)(int,char*,const char*,...);
|
||||
int (*step)(sqlite3_stmt*);
|
||||
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
||||
char const**,char const**,int*,int*,int*);
|
||||
void (*thread_cleanup)(void);
|
||||
int (*total_changes)(sqlite3*);
|
||||
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
|
||||
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
|
||||
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
|
||||
sqlite_int64),void*);
|
||||
void * (*user_data)(sqlite3_context*);
|
||||
const void * (*value_blob)(sqlite3_value*);
|
||||
int (*value_bytes)(sqlite3_value*);
|
||||
int (*value_bytes16)(sqlite3_value*);
|
||||
double (*value_double)(sqlite3_value*);
|
||||
int (*value_int)(sqlite3_value*);
|
||||
sqlite_int64 (*value_int64)(sqlite3_value*);
|
||||
int (*value_numeric_type)(sqlite3_value*);
|
||||
const unsigned char * (*value_text)(sqlite3_value*);
|
||||
const void * (*value_text16)(sqlite3_value*);
|
||||
const void * (*value_text16be)(sqlite3_value*);
|
||||
const void * (*value_text16le)(sqlite3_value*);
|
||||
int (*value_type)(sqlite3_value*);
|
||||
char *(*vmprintf)(const char*,va_list);
|
||||
/* Added ??? */
|
||||
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
|
||||
/* Added by 3.3.13 */
|
||||
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
int (*clear_bindings)(sqlite3_stmt*);
|
||||
/* Added by 3.4.1 */
|
||||
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
|
||||
void (*xDestroy)(void *));
|
||||
/* Added by 3.5.0 */
|
||||
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
|
||||
int (*blob_bytes)(sqlite3_blob*);
|
||||
int (*blob_close)(sqlite3_blob*);
|
||||
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
|
||||
int,sqlite3_blob**);
|
||||
int (*blob_read)(sqlite3_blob*,void*,int,int);
|
||||
int (*blob_write)(sqlite3_blob*,const void*,int,int);
|
||||
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*),
|
||||
void(*)(void*));
|
||||
int (*file_control)(sqlite3*,const char*,int,void*);
|
||||
sqlite3_int64 (*memory_highwater)(int);
|
||||
sqlite3_int64 (*memory_used)(void);
|
||||
sqlite3_mutex *(*mutex_alloc)(int);
|
||||
void (*mutex_enter)(sqlite3_mutex*);
|
||||
void (*mutex_free)(sqlite3_mutex*);
|
||||
void (*mutex_leave)(sqlite3_mutex*);
|
||||
int (*mutex_try)(sqlite3_mutex*);
|
||||
int (*open_v2)(const char*,sqlite3**,int,const char*);
|
||||
int (*release_memory)(int);
|
||||
void (*result_error_nomem)(sqlite3_context*);
|
||||
void (*result_error_toobig)(sqlite3_context*);
|
||||
int (*sleep)(int);
|
||||
void (*soft_heap_limit)(int);
|
||||
sqlite3_vfs *(*vfs_find)(const char*);
|
||||
int (*vfs_register)(sqlite3_vfs*,int);
|
||||
int (*vfs_unregister)(sqlite3_vfs*);
|
||||
int (*xthreadsafe)(void);
|
||||
void (*result_zeroblob)(sqlite3_context*,int);
|
||||
void (*result_error_code)(sqlite3_context*,int);
|
||||
int (*test_control)(int, ...);
|
||||
void (*randomness)(int,void*);
|
||||
sqlite3 *(*context_db_handle)(sqlite3_context*);
|
||||
int (*extended_result_codes)(sqlite3*,int);
|
||||
int (*limit)(sqlite3*,int,int);
|
||||
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
|
||||
const char *(*sql)(sqlite3_stmt*);
|
||||
int (*status)(int,int*,int*,int);
|
||||
int (*backup_finish)(sqlite3_backup*);
|
||||
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
|
||||
int (*backup_pagecount)(sqlite3_backup*);
|
||||
int (*backup_remaining)(sqlite3_backup*);
|
||||
int (*backup_step)(sqlite3_backup*,int);
|
||||
const char *(*compileoption_get)(int);
|
||||
int (*compileoption_used)(const char*);
|
||||
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void(*xDestroy)(void*));
|
||||
int (*db_config)(sqlite3*,int,...);
|
||||
sqlite3_mutex *(*db_mutex)(sqlite3*);
|
||||
int (*db_status)(sqlite3*,int,int*,int*,int);
|
||||
int (*extended_errcode)(sqlite3*);
|
||||
void (*log)(int,const char*,...);
|
||||
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
|
||||
const char *(*sourceid)(void);
|
||||
int (*stmt_status)(sqlite3_stmt*,int,int);
|
||||
int (*strnicmp)(const char*,const char*,int);
|
||||
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
|
||||
int (*wal_autocheckpoint)(sqlite3*,int);
|
||||
int (*wal_checkpoint)(sqlite3*,const char*);
|
||||
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
|
||||
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
|
||||
int (*vtab_config)(sqlite3*,int op,...);
|
||||
int (*vtab_on_conflict)(sqlite3*);
|
||||
/* Version 3.7.16 and later */
|
||||
int (*close_v2)(sqlite3*);
|
||||
const char *(*db_filename)(sqlite3*,const char*);
|
||||
int (*db_readonly)(sqlite3*,const char*);
|
||||
int (*db_release_memory)(sqlite3*);
|
||||
const char *(*errstr)(int);
|
||||
int (*stmt_busy)(sqlite3_stmt*);
|
||||
int (*stmt_readonly)(sqlite3_stmt*);
|
||||
int (*stricmp)(const char*,const char*);
|
||||
int (*uri_boolean)(const char*,const char*,int);
|
||||
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
|
||||
const char *(*uri_parameter)(const char*,const char*);
|
||||
char *(*xvsnprintf)(int,char*,const char*,va_list);
|
||||
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
|
||||
/* Version 3.8.7 and later */
|
||||
int (*auto_extension)(void(*)(void));
|
||||
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
|
||||
void(*)(void*),unsigned char);
|
||||
int (*cancel_auto_extension)(void(*)(void));
|
||||
int (*load_extension)(sqlite3*,const char*,const char*,char**);
|
||||
void *(*malloc64)(sqlite3_uint64);
|
||||
sqlite3_uint64 (*msize)(void*);
|
||||
void *(*realloc64)(void*,sqlite3_uint64);
|
||||
void (*reset_auto_extension)(void);
|
||||
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
|
||||
void(*)(void*), unsigned char);
|
||||
int (*strglob)(const char*,const char*);
|
||||
/* Version 3.8.11 and later */
|
||||
sqlite3_value *(*value_dup)(const sqlite3_value*);
|
||||
void (*value_free)(sqlite3_value*);
|
||||
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
|
||||
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
|
||||
/* Version 3.9.0 and later */
|
||||
unsigned int (*value_subtype)(sqlite3_value*);
|
||||
void (*result_subtype)(sqlite3_context*,unsigned int);
|
||||
/* Version 3.10.0 and later */
|
||||
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
int (*strlike)(const char*,const char*,unsigned int);
|
||||
int (*db_cacheflush)(sqlite3*);
|
||||
/* Version 3.12.0 and later */
|
||||
int (*system_errno)(sqlite3*);
|
||||
/* Version 3.14.0 and later */
|
||||
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
|
||||
char *(*expanded_sql)(sqlite3_stmt*);
|
||||
/* Version 3.18.0 and later */
|
||||
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
|
||||
/* Version 3.20.0 and later */
|
||||
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
|
||||
sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
|
||||
sqlite3_stmt**,const void**);
|
||||
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
|
||||
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
|
||||
void *(*value_pointer)(sqlite3_value*,const char*);
|
||||
int (*vtab_nochange)(sqlite3_context*);
|
||||
int (*value_nochange)(sqlite3_value*);
|
||||
const char *(*vtab_collation)(sqlite3_index_info*,int);
|
||||
/* Version 3.24.0 and later */
|
||||
int (*keyword_count)(void);
|
||||
int (*keyword_name)(int,const char**,int*);
|
||||
int (*keyword_check)(const char*,int);
|
||||
sqlite3_str *(*str_new)(sqlite3*);
|
||||
char *(*str_finish)(sqlite3_str*);
|
||||
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
|
||||
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
|
||||
void (*str_append)(sqlite3_str*, const char *zIn, int N);
|
||||
void (*str_appendall)(sqlite3_str*, const char *zIn);
|
||||
void (*str_appendchar)(sqlite3_str*, int N, char C);
|
||||
void (*str_reset)(sqlite3_str*);
|
||||
int (*str_errcode)(sqlite3_str*);
|
||||
int (*str_length)(sqlite3_str*);
|
||||
char *(*str_value)(sqlite3_str*);
|
||||
/* Version 3.25.0 and later */
|
||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*));
|
||||
/* Version 3.26.0 and later */
|
||||
const char *(*normalized_sql)(sqlite3_stmt*);
|
||||
/* Version 3.28.0 and later */
|
||||
int (*stmt_isexplain)(sqlite3_stmt*);
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
/* Version 3.31.0 and later */
|
||||
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
|
||||
const char *(*uri_key)(const char*,int);
|
||||
const char *(*filename_database)(const char*);
|
||||
const char *(*filename_journal)(const char*);
|
||||
const char *(*filename_wal)(const char*);
|
||||
/* Version 3.32.0 and later */
|
||||
const char *(*create_filename)(const char*,const char*,const char*,
|
||||
int,const char**);
|
||||
void (*free_filename)(const char*);
|
||||
sqlite3_file *(*database_file_object)(const char*);
|
||||
/* Version 3.34.0 and later */
|
||||
int (*txn_state)(sqlite3*,const char*);
|
||||
/* Version 3.36.1 and later */
|
||||
sqlite3_int64 (*changes64)(sqlite3*);
|
||||
sqlite3_int64 (*total_changes64)(sqlite3*);
|
||||
/* Version 3.37.0 and later */
|
||||
int (*autovacuum_pages)(sqlite3*,
|
||||
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
|
||||
void*, void(*)(void*));
|
||||
/* Version 3.38.0 and later */
|
||||
int (*error_offset)(sqlite3*);
|
||||
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
|
||||
int (*vtab_distinct)(sqlite3_index_info*);
|
||||
int (*vtab_in)(sqlite3_index_info*,int,int);
|
||||
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
|
||||
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
|
||||
/* Version 3.39.0 and later */
|
||||
int (*deserialize)(sqlite3*,const char*,unsigned char*,
|
||||
sqlite3_int64,sqlite3_int64,unsigned);
|
||||
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
|
||||
unsigned int);
|
||||
const char *(*db_name)(sqlite3*,int);
|
||||
/* Version 3.40.0 and later */
|
||||
int (*value_encoding)(sqlite3_value*);
|
||||
/* Version 3.41.0 and later */
|
||||
int (*is_interrupted)(sqlite3*);
|
||||
/* Version 3.43.0 and later */
|
||||
int (*stmt_explain)(sqlite3_stmt*,int);
|
||||
/* Version 3.44.0 and later */
|
||||
void *(*get_clientdata)(sqlite3*,const char*);
|
||||
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
|
||||
};
|
||||
|
||||
/*
|
||||
** This is the function signature used for all extension entry points. It
|
||||
** is also defined in the file "loadext.c".
|
||||
*/
|
||||
typedef int (*sqlite3_loadext_entry)(
|
||||
sqlite3 *db, /* Handle to the database. */
|
||||
char **pzErrMsg, /* Used to set error string on failure. */
|
||||
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
|
||||
);
|
||||
|
||||
/*
|
||||
** The following macros redefine the API routines so that they are
|
||||
** redirected through the global sqlite3_api structure.
|
||||
**
|
||||
** This header file is also used by the loadext.c source file
|
||||
** (part of the main SQLite library - not an extension) so that
|
||||
** it can get access to the sqlite3_api_routines structure
|
||||
** definition. But the main library does not want to redefine
|
||||
** the API. So the redefinition macros are only valid if the
|
||||
** SQLITE_CORE macros is undefined.
|
||||
*/
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
|
||||
#endif
|
||||
#define sqlite3_bind_blob sqlite3_api->bind_blob
|
||||
#define sqlite3_bind_double sqlite3_api->bind_double
|
||||
#define sqlite3_bind_int sqlite3_api->bind_int
|
||||
#define sqlite3_bind_int64 sqlite3_api->bind_int64
|
||||
#define sqlite3_bind_null sqlite3_api->bind_null
|
||||
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
|
||||
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
|
||||
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
|
||||
#define sqlite3_bind_text sqlite3_api->bind_text
|
||||
#define sqlite3_bind_text16 sqlite3_api->bind_text16
|
||||
#define sqlite3_bind_value sqlite3_api->bind_value
|
||||
#define sqlite3_busy_handler sqlite3_api->busy_handler
|
||||
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
|
||||
#define sqlite3_changes sqlite3_api->changes
|
||||
#define sqlite3_close sqlite3_api->close
|
||||
#define sqlite3_collation_needed sqlite3_api->collation_needed
|
||||
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
|
||||
#define sqlite3_column_blob sqlite3_api->column_blob
|
||||
#define sqlite3_column_bytes sqlite3_api->column_bytes
|
||||
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
|
||||
#define sqlite3_column_count sqlite3_api->column_count
|
||||
#define sqlite3_column_database_name sqlite3_api->column_database_name
|
||||
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
|
||||
#define sqlite3_column_decltype sqlite3_api->column_decltype
|
||||
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
|
||||
#define sqlite3_column_double sqlite3_api->column_double
|
||||
#define sqlite3_column_int sqlite3_api->column_int
|
||||
#define sqlite3_column_int64 sqlite3_api->column_int64
|
||||
#define sqlite3_column_name sqlite3_api->column_name
|
||||
#define sqlite3_column_name16 sqlite3_api->column_name16
|
||||
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
|
||||
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
|
||||
#define sqlite3_column_table_name sqlite3_api->column_table_name
|
||||
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
|
||||
#define sqlite3_column_text sqlite3_api->column_text
|
||||
#define sqlite3_column_text16 sqlite3_api->column_text16
|
||||
#define sqlite3_column_type sqlite3_api->column_type
|
||||
#define sqlite3_column_value sqlite3_api->column_value
|
||||
#define sqlite3_commit_hook sqlite3_api->commit_hook
|
||||
#define sqlite3_complete sqlite3_api->complete
|
||||
#define sqlite3_complete16 sqlite3_api->complete16
|
||||
#define sqlite3_create_collation sqlite3_api->create_collation
|
||||
#define sqlite3_create_collation16 sqlite3_api->create_collation16
|
||||
#define sqlite3_create_function sqlite3_api->create_function
|
||||
#define sqlite3_create_function16 sqlite3_api->create_function16
|
||||
#define sqlite3_create_module sqlite3_api->create_module
|
||||
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
|
||||
#define sqlite3_data_count sqlite3_api->data_count
|
||||
#define sqlite3_db_handle sqlite3_api->db_handle
|
||||
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
|
||||
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
|
||||
#define sqlite3_errcode sqlite3_api->errcode
|
||||
#define sqlite3_errmsg sqlite3_api->errmsg
|
||||
#define sqlite3_errmsg16 sqlite3_api->errmsg16
|
||||
#define sqlite3_exec sqlite3_api->exec
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_expired sqlite3_api->expired
|
||||
#endif
|
||||
#define sqlite3_finalize sqlite3_api->finalize
|
||||
#define sqlite3_free sqlite3_api->free
|
||||
#define sqlite3_free_table sqlite3_api->free_table
|
||||
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
|
||||
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
|
||||
#define sqlite3_get_table sqlite3_api->get_table
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_global_recover sqlite3_api->global_recover
|
||||
#endif
|
||||
#define sqlite3_interrupt sqlite3_api->interruptx
|
||||
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
|
||||
#define sqlite3_libversion sqlite3_api->libversion
|
||||
#define sqlite3_libversion_number sqlite3_api->libversion_number
|
||||
#define sqlite3_malloc sqlite3_api->malloc
|
||||
#define sqlite3_mprintf sqlite3_api->mprintf
|
||||
#define sqlite3_open sqlite3_api->open
|
||||
#define sqlite3_open16 sqlite3_api->open16
|
||||
#define sqlite3_prepare sqlite3_api->prepare
|
||||
#define sqlite3_prepare16 sqlite3_api->prepare16
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_profile sqlite3_api->profile
|
||||
#define sqlite3_progress_handler sqlite3_api->progress_handler
|
||||
#define sqlite3_realloc sqlite3_api->realloc
|
||||
#define sqlite3_reset sqlite3_api->reset
|
||||
#define sqlite3_result_blob sqlite3_api->result_blob
|
||||
#define sqlite3_result_double sqlite3_api->result_double
|
||||
#define sqlite3_result_error sqlite3_api->result_error
|
||||
#define sqlite3_result_error16 sqlite3_api->result_error16
|
||||
#define sqlite3_result_int sqlite3_api->result_int
|
||||
#define sqlite3_result_int64 sqlite3_api->result_int64
|
||||
#define sqlite3_result_null sqlite3_api->result_null
|
||||
#define sqlite3_result_text sqlite3_api->result_text
|
||||
#define sqlite3_result_text16 sqlite3_api->result_text16
|
||||
#define sqlite3_result_text16be sqlite3_api->result_text16be
|
||||
#define sqlite3_result_text16le sqlite3_api->result_text16le
|
||||
#define sqlite3_result_value sqlite3_api->result_value
|
||||
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
|
||||
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
|
||||
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
|
||||
#define sqlite3_snprintf sqlite3_api->xsnprintf
|
||||
#define sqlite3_step sqlite3_api->step
|
||||
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
|
||||
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
|
||||
#define sqlite3_total_changes sqlite3_api->total_changes
|
||||
#define sqlite3_trace sqlite3_api->trace
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
|
||||
#endif
|
||||
#define sqlite3_update_hook sqlite3_api->update_hook
|
||||
#define sqlite3_user_data sqlite3_api->user_data
|
||||
#define sqlite3_value_blob sqlite3_api->value_blob
|
||||
#define sqlite3_value_bytes sqlite3_api->value_bytes
|
||||
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
|
||||
#define sqlite3_value_double sqlite3_api->value_double
|
||||
#define sqlite3_value_int sqlite3_api->value_int
|
||||
#define sqlite3_value_int64 sqlite3_api->value_int64
|
||||
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
|
||||
#define sqlite3_value_text sqlite3_api->value_text
|
||||
#define sqlite3_value_text16 sqlite3_api->value_text16
|
||||
#define sqlite3_value_text16be sqlite3_api->value_text16be
|
||||
#define sqlite3_value_text16le sqlite3_api->value_text16le
|
||||
#define sqlite3_value_type sqlite3_api->value_type
|
||||
#define sqlite3_vmprintf sqlite3_api->vmprintf
|
||||
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_overload_function sqlite3_api->overload_function
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
|
||||
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
|
||||
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
|
||||
#define sqlite3_blob_close sqlite3_api->blob_close
|
||||
#define sqlite3_blob_open sqlite3_api->blob_open
|
||||
#define sqlite3_blob_read sqlite3_api->blob_read
|
||||
#define sqlite3_blob_write sqlite3_api->blob_write
|
||||
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
|
||||
#define sqlite3_file_control sqlite3_api->file_control
|
||||
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
|
||||
#define sqlite3_memory_used sqlite3_api->memory_used
|
||||
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
|
||||
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
|
||||
#define sqlite3_mutex_free sqlite3_api->mutex_free
|
||||
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
|
||||
#define sqlite3_mutex_try sqlite3_api->mutex_try
|
||||
#define sqlite3_open_v2 sqlite3_api->open_v2
|
||||
#define sqlite3_release_memory sqlite3_api->release_memory
|
||||
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
|
||||
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
|
||||
#define sqlite3_sleep sqlite3_api->sleep
|
||||
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
|
||||
#define sqlite3_vfs_find sqlite3_api->vfs_find
|
||||
#define sqlite3_vfs_register sqlite3_api->vfs_register
|
||||
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
|
||||
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
|
||||
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
|
||||
#define sqlite3_result_error_code sqlite3_api->result_error_code
|
||||
#define sqlite3_test_control sqlite3_api->test_control
|
||||
#define sqlite3_randomness sqlite3_api->randomness
|
||||
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
|
||||
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
|
||||
#define sqlite3_limit sqlite3_api->limit
|
||||
#define sqlite3_next_stmt sqlite3_api->next_stmt
|
||||
#define sqlite3_sql sqlite3_api->sql
|
||||
#define sqlite3_status sqlite3_api->status
|
||||
#define sqlite3_backup_finish sqlite3_api->backup_finish
|
||||
#define sqlite3_backup_init sqlite3_api->backup_init
|
||||
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
|
||||
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
|
||||
#define sqlite3_backup_step sqlite3_api->backup_step
|
||||
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
|
||||
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
|
||||
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
|
||||
#define sqlite3_db_config sqlite3_api->db_config
|
||||
#define sqlite3_db_mutex sqlite3_api->db_mutex
|
||||
#define sqlite3_db_status sqlite3_api->db_status
|
||||
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
|
||||
#define sqlite3_log sqlite3_api->log
|
||||
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
|
||||
#define sqlite3_sourceid sqlite3_api->sourceid
|
||||
#define sqlite3_stmt_status sqlite3_api->stmt_status
|
||||
#define sqlite3_strnicmp sqlite3_api->strnicmp
|
||||
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
|
||||
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
|
||||
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
|
||||
#define sqlite3_wal_hook sqlite3_api->wal_hook
|
||||
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
|
||||
#define sqlite3_vtab_config sqlite3_api->vtab_config
|
||||
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
|
||||
/* Version 3.7.16 and later */
|
||||
#define sqlite3_close_v2 sqlite3_api->close_v2
|
||||
#define sqlite3_db_filename sqlite3_api->db_filename
|
||||
#define sqlite3_db_readonly sqlite3_api->db_readonly
|
||||
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
|
||||
#define sqlite3_errstr sqlite3_api->errstr
|
||||
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
|
||||
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
|
||||
#define sqlite3_stricmp sqlite3_api->stricmp
|
||||
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
|
||||
#define sqlite3_uri_int64 sqlite3_api->uri_int64
|
||||
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
|
||||
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
|
||||
/* Version 3.8.7 and later */
|
||||
#define sqlite3_auto_extension sqlite3_api->auto_extension
|
||||
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
|
||||
#define sqlite3_bind_text64 sqlite3_api->bind_text64
|
||||
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
|
||||
#define sqlite3_load_extension sqlite3_api->load_extension
|
||||
#define sqlite3_malloc64 sqlite3_api->malloc64
|
||||
#define sqlite3_msize sqlite3_api->msize
|
||||
#define sqlite3_realloc64 sqlite3_api->realloc64
|
||||
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
|
||||
#define sqlite3_result_blob64 sqlite3_api->result_blob64
|
||||
#define sqlite3_result_text64 sqlite3_api->result_text64
|
||||
#define sqlite3_strglob sqlite3_api->strglob
|
||||
/* Version 3.8.11 and later */
|
||||
#define sqlite3_value_dup sqlite3_api->value_dup
|
||||
#define sqlite3_value_free sqlite3_api->value_free
|
||||
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
|
||||
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
|
||||
/* Version 3.9.0 and later */
|
||||
#define sqlite3_value_subtype sqlite3_api->value_subtype
|
||||
#define sqlite3_result_subtype sqlite3_api->result_subtype
|
||||
/* Version 3.10.0 and later */
|
||||
#define sqlite3_status64 sqlite3_api->status64
|
||||
#define sqlite3_strlike sqlite3_api->strlike
|
||||
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
|
||||
/* Version 3.12.0 and later */
|
||||
#define sqlite3_system_errno sqlite3_api->system_errno
|
||||
/* Version 3.14.0 and later */
|
||||
#define sqlite3_trace_v2 sqlite3_api->trace_v2
|
||||
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
|
||||
/* Version 3.18.0 and later */
|
||||
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
|
||||
/* Version 3.20.0 and later */
|
||||
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
|
||||
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
|
||||
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
|
||||
#define sqlite3_result_pointer sqlite3_api->result_pointer
|
||||
#define sqlite3_value_pointer sqlite3_api->value_pointer
|
||||
/* Version 3.22.0 and later */
|
||||
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
|
||||
#define sqlite3_value_nochange sqlite3_api->value_nochange
|
||||
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
|
||||
/* Version 3.24.0 and later */
|
||||
#define sqlite3_keyword_count sqlite3_api->keyword_count
|
||||
#define sqlite3_keyword_name sqlite3_api->keyword_name
|
||||
#define sqlite3_keyword_check sqlite3_api->keyword_check
|
||||
#define sqlite3_str_new sqlite3_api->str_new
|
||||
#define sqlite3_str_finish sqlite3_api->str_finish
|
||||
#define sqlite3_str_appendf sqlite3_api->str_appendf
|
||||
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
|
||||
#define sqlite3_str_append sqlite3_api->str_append
|
||||
#define sqlite3_str_appendall sqlite3_api->str_appendall
|
||||
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
|
||||
#define sqlite3_str_reset sqlite3_api->str_reset
|
||||
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
||||
#define sqlite3_str_length sqlite3_api->str_length
|
||||
#define sqlite3_str_value sqlite3_api->str_value
|
||||
/* Version 3.25.0 and later */
|
||||
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
||||
/* Version 3.26.0 and later */
|
||||
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
|
||||
/* Version 3.28.0 and later */
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->value_frombind
|
||||
/* Version 3.30.0 and later */
|
||||
#define sqlite3_drop_modules sqlite3_api->drop_modules
|
||||
/* Version 3.31.0 and later */
|
||||
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
|
||||
#define sqlite3_uri_key sqlite3_api->uri_key
|
||||
#define sqlite3_filename_database sqlite3_api->filename_database
|
||||
#define sqlite3_filename_journal sqlite3_api->filename_journal
|
||||
#define sqlite3_filename_wal sqlite3_api->filename_wal
|
||||
/* Version 3.32.0 and later */
|
||||
#define sqlite3_create_filename sqlite3_api->create_filename
|
||||
#define sqlite3_free_filename sqlite3_api->free_filename
|
||||
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||
/* Version 3.34.0 and later */
|
||||
#define sqlite3_txn_state sqlite3_api->txn_state
|
||||
/* Version 3.36.1 and later */
|
||||
#define sqlite3_changes64 sqlite3_api->changes64
|
||||
#define sqlite3_total_changes64 sqlite3_api->total_changes64
|
||||
/* Version 3.37.0 and later */
|
||||
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
|
||||
/* Version 3.38.0 and later */
|
||||
#define sqlite3_error_offset sqlite3_api->error_offset
|
||||
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
|
||||
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
|
||||
#define sqlite3_vtab_in sqlite3_api->vtab_in
|
||||
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
|
||||
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
|
||||
/* Version 3.39.0 and later */
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
#define sqlite3_deserialize sqlite3_api->deserialize
|
||||
#define sqlite3_serialize sqlite3_api->serialize
|
||||
#endif
|
||||
#define sqlite3_db_name sqlite3_api->db_name
|
||||
/* Version 3.40.0 and later */
|
||||
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||
/* Version 3.41.0 and later */
|
||||
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
|
||||
/* Version 3.43.0 and later */
|
||||
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
|
||||
/* Version 3.44.0 and later */
|
||||
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
|
||||
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
/* This case when the file really is being compiled as a loadable
|
||||
** extension */
|
||||
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
|
||||
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
|
||||
# define SQLITE_EXTENSION_INIT3 \
|
||||
extern const sqlite3_api_routines *sqlite3_api;
|
||||
#else
|
||||
/* This case when the file is being statically linked into the
|
||||
** application */
|
||||
# define SQLITE_EXTENSION_INIT1 /*no-op*/
|
||||
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE3EXT_H */
|
||||
@@ -0,0 +1,953 @@
|
||||
#ifndef SYSTEMDATA_H
|
||||
#define SYSTEMDATA_H
|
||||
#include "pmSysvariable.h"
|
||||
#include "sqlit3/SQLite.h"
|
||||
#include <set>
|
||||
#include <mutex>
|
||||
#define DEBUFG
|
||||
class SystemData
|
||||
{
|
||||
private:
|
||||
SQLite* m_db;
|
||||
std::set<unsigned int> sysFaultCodes;
|
||||
mutable std::mutex sysFaultCodesMutex;
|
||||
public:
|
||||
/**
|
||||
* @brief 向系统故障码集合中插入一个故障码
|
||||
* @param faultCode 要插入的故障码
|
||||
*/
|
||||
void insertFaultCode(unsigned int faultCode) {
|
||||
std::lock_guard<std::mutex> lock(sysFaultCodesMutex);
|
||||
sysFaultCodes.insert(faultCode);
|
||||
}
|
||||
/**
|
||||
* @brief 从系统故障码集合中消除一个故障码
|
||||
* @param faultCode 要消除的故障码
|
||||
*/
|
||||
void eraseFaultCode(unsigned int faultCode) {
|
||||
std::lock_guard<std::mutex> lock(sysFaultCodesMutex);
|
||||
sysFaultCodes.erase(faultCode);
|
||||
}
|
||||
/**
|
||||
* @brief 获取系统当前的故障等级
|
||||
* @return uint8_t 故障等级,00H-无故障, 10H-一级, 20H-二级, 30H-三级, 40H-四级
|
||||
*/
|
||||
uint8_t getFaultCodeLevel() const {
|
||||
uint8_t maxLevel = 0;
|
||||
// 遍历 sysFaultCodes 集合中的每个故障码
|
||||
for (auto code : sysFaultCodes) {
|
||||
// 提取0xabcd中的b位 (右移8位后取低4位)
|
||||
uint8_t level = (code >> 8) & 0xF;
|
||||
if (level > maxLevel) {
|
||||
maxLevel = level;
|
||||
}
|
||||
}
|
||||
return maxLevel;
|
||||
}
|
||||
/**
|
||||
* @brief 获取系统当前的故障码集合
|
||||
* @return std::set<unsigned int>& 系统当前的故障码集合
|
||||
*/
|
||||
const std::set<unsigned int>& getFaultCode() const {
|
||||
return sysFaultCodes;
|
||||
}
|
||||
//燃料电池系统参数
|
||||
uint8_t fc_mode; // 燃料电池系统运行模式:00H-无效, 01H-调试, 02H-自动, 03H-补给
|
||||
uint8_t fc_status; // 燃料电池状态:00H-无效, 01H-初始化, ..., 0DH-维护完成
|
||||
uint8_t fc_fault_level; // 燃料电池故障等级:00H-无故障, 10H-一级, 20H-二级, 30H-三级, 40H-四级
|
||||
|
||||
//功率和时间参数
|
||||
float output_power_limit; // 系统输出功率限制值,单位:W
|
||||
float total_generation_time; // 系统累计发电时间,单位:0.1小时
|
||||
float total_generation_power; // 系统累计发电总功率,单位:W
|
||||
|
||||
//故障信息
|
||||
uint16_t fc_fault_level_1; // 一级故障位
|
||||
uint16_t fc_fault_level_2; // 二级故障位
|
||||
uint16_t fc_fault_level_3; // 三级故障位
|
||||
uint16_t fc_fault_level_4; // 四级故障位
|
||||
|
||||
//燃料容量
|
||||
float hydrogen_capacity; // 储氢罐剩余容量百分比,单位:%
|
||||
float liquid_oxygen_capacity; // 液氧罐剩余容量百分比,单位:%
|
||||
|
||||
//温度压力参数
|
||||
float palladium_temp; // 钯膜最高温度,单位:℃
|
||||
float main_pipe_pressure; // 主水路压力,单位:0.01kPa
|
||||
float aux_pipe_pressure; // 辅水路压力,单位:0.01kPa
|
||||
|
||||
//舱室环境参数
|
||||
float cabin_pressure1; // 舱室1压力,单位:0.01kPa
|
||||
float cabin_pressure2; // 舱室2压力,单位:0.01kPa
|
||||
float cabin_temp1; // 舱室1温度,单位:0.01℃
|
||||
float cabin_temp2; // 舱室2温度,单位:0.01℃
|
||||
float cabin_humidity1; // 舱室1湿度,单位:0.01%RH
|
||||
float cabin_humidity2; // 舱室2湿度,单位:0.01%RH
|
||||
|
||||
//火焰探测器
|
||||
uint8_t flame_detector1; // 火焰探测器1状态:00H-无效, 01H-报警, 02H-故障
|
||||
uint8_t flame_detector2; // 火焰探测器2状态:00H-无效, 01H-报警, 02H-故障
|
||||
|
||||
//气体浓度
|
||||
float h2_concentration1; // 舱室H2浓度1,单位:0.01% LEL
|
||||
float h2_concentration2; // 舱室H2浓度2,单位:0.01% LEL
|
||||
float h2_concentration3; // 舱室H2浓度3,单位:0.01% LEL
|
||||
float o2_concentration1; // 舱室O2浓度1,单位:0.01% LEL
|
||||
float o2_concentration2; // 舱室O2浓度2,单位:0.01% LEL
|
||||
float ch3oh_concentration1; // 舱室甲醇气体浓度1,单位:0.01% LEL
|
||||
float ch3oh_concentration2; // 舱室甲醇气体浓度2,单位:0.01% LEL
|
||||
|
||||
//保留字段
|
||||
float reserved1[10]; // 保留字段
|
||||
float cabin_ox_concentration; // 仪表舱内氧气浓度,单位:0.1%
|
||||
float cabin_temperature; // 仪表舱内温度,单位:0.1℃
|
||||
float cabin_humidity; // 仪表舱内湿度,单位:0.1%RH
|
||||
float cabin_pressure; // 仪表舱内大气压,单位:0.2kPa
|
||||
|
||||
//动力舱参数
|
||||
float power_cabin_ox_concentration; // 动力舱内氧气浓度,单位:0.1%
|
||||
float power_cabin_temperature; // 动力舱内温度,单位:0.1℃
|
||||
float power_cabin_humidity; // 动力舱内湿度,单位:0.1%RH
|
||||
float power_cabin_pressure; // 动力舱内大气压,单位:0.2kPa
|
||||
uint8_t reserved2[2]; // 保留字段
|
||||
|
||||
//电池报警标志
|
||||
uint8_t dyn_alarm_flag[6]; // 动力锂电池报警标志
|
||||
uint8_t ins_alarm_flag[6]; // 仪表锂电池报警标志
|
||||
|
||||
//继电器状态
|
||||
uint8_t ins_relay_status1; // 仪表电池继电器状态
|
||||
uint8_t ins_relay_status2; // 仪表电池预充继电器和负极继电器状态
|
||||
uint8_t dyn_relay_status1; // 动力电池正极与充电继电器状态
|
||||
uint8_t dyn_relay_status2; // 动力电池预充与负极继电器状态
|
||||
|
||||
//仪表电池继电器状态
|
||||
uint8_t ins_pos_relay_status; // 仪表电池正极继电器状态 (X0H:无效 X1H:接通 X2H:断开)
|
||||
uint8_t ins_charge_relay_status; // 仪表电池充电继电器状态 (0XH:无效 1XH:接通 2XH:断开)
|
||||
uint8_t ins_precharge_relay_status; // 仪表电池预充继电器状态 (X0H:无效 X1H:接通 X2H:断开)
|
||||
uint8_t ins_neg_relay_status; // 仪表电池负极继电器状态 (0XH:无效 1XH:接通 2XH:断开)
|
||||
|
||||
//动力电池继电器状态
|
||||
uint8_t dyn_pos_relay_status; // 动力电池正极继电器状态 (X0H:无效 X1H:接通 X2H:断开)
|
||||
uint8_t dyn_charge_relay_status; // 动力电池充电继电器状态 (0XH:无效 1XH:接通 2XH:断开)
|
||||
uint8_t dyn_precharge_relay_status; // 动力电池预充继电器状态 (X0H:无效 X1H:接通 X2H:断开)
|
||||
uint8_t dyn_neg_relay_status; // 动力电池负极继电器状态 (0XH:无效 1XH:接通 2XH:断开)
|
||||
|
||||
//电池功率参数
|
||||
float ins_max_discharge_power; // 仪表电池最大允许放电功率,单位:0.05kW
|
||||
float dyn_max_discharge_power; // 动力电池最大允许放电功率,单位:0.05kW
|
||||
|
||||
//电池SOC
|
||||
int ins_soc; // 仪表锂电池荷电状态SOC,范围:0~100
|
||||
int dyn_soc; // 动力锂电池荷电状态SOC,范围:0~100
|
||||
|
||||
//电池能量
|
||||
float ins_total_energy; // 仪表电池总能量,单位:0.1kWh
|
||||
float dyn_total_energy; // 动力电池总能量,单位:0.1kWh
|
||||
|
||||
//电池输入功率
|
||||
float ins_power_input; // 仪表电池输入功率,单位:0.1kW
|
||||
float dyn_power_input; // 动力电池输入功率,单位:0.1kW
|
||||
|
||||
//电池充放电状态
|
||||
uint8_t ins_charge_status; // 仪表电池充放电状态:00H-无效,10H-充电,20H-放电
|
||||
uint8_t dyn_charge_status; // 动力电池充放电状态:00H-无效,10H-充电,20H-放电
|
||||
|
||||
//电池电压电流
|
||||
float ins_voltage_link; // 仪表电池LINK端电压,单位:0.01V
|
||||
float ins_voltage_pack; // 仪表电池PACK端电压,单位:0.01V
|
||||
float ins_current; // 仪表电池电流,单位:0.01A
|
||||
float ins_resistance_pos; // 仪表电池正极绝缘电阻,单位:kΩ
|
||||
float ins_resistance_neg; // 仪表电池负极绝缘电阻,单位:kΩ
|
||||
float dyn_voltage_link; // 动力电池LINK端电压,单位:0.01V
|
||||
float dyn_voltage_pack; // 动力电池PACK端电压,单位:0.01V
|
||||
float dyn_current; // 动力电池电流,单位:0.05A
|
||||
float dyn_resistance_pos; // 动力电池正极绝缘电阻,单位:kΩ
|
||||
float dyn_resistance_neg; // 动力电池负极绝缘电阻,单位:kΩ
|
||||
|
||||
//紧急状态
|
||||
uint8_t ins_emergency_status; // 仪表电池紧急状态
|
||||
uint8_t dyn_emergency_status; // 动力电池紧急状态
|
||||
|
||||
//保留字段
|
||||
uint8_t reserved3[2]; // 保留字段
|
||||
float ins_soc_threshold1; // 仪表电池1 SOC门限
|
||||
float ins_soc_threshold2; // 仪表电池2 SOC门限
|
||||
float ins_soc_threshold3; // 仪表电池3 SOC门限
|
||||
float dyn_soc_threshold1; // 动力电池1 SOC门限
|
||||
float dyn_soc_threshold2; // 动力电池2 SOC门限
|
||||
float dyn_soc_threshold3; // 动力电池3 SOC门限
|
||||
float ins_power_limit1; // 仪表电池1功率限制值
|
||||
float ins_power_limit2; // 仪表电池2功率限制值
|
||||
float dyn_power_limit1; // 动力电池1功率限制值
|
||||
float dyn_power_limit2; // 动力电池2功率限制值
|
||||
|
||||
//设备在线状态
|
||||
uint32_t device_online_flag1; // 设备在线状态标志1
|
||||
uint32_t device_online_flag2; // 设备在线状态标志2
|
||||
|
||||
//其他锂电池状态
|
||||
uint8_t dyn_charge_level; // 动力电池充电状态:01H-1级(不限), 02H-2级(限功率), 03H-3级(关闭)
|
||||
uint8_t dyn_water_leak_status; // 动力漏水状态:0XH-正常, 1XH-异常漏水
|
||||
uint8_t ins_water_leak_dcdc_status; // 仪表漏水状态与DCDC状态:低4位-漏水状态(0XH正常,1XH异常),高4位-DCDC状态(X0H正常,X1H故障)
|
||||
uint8_t reserved4;
|
||||
|
||||
unsigned char water_leak_status_from_insbat; // 仪表漏水状态
|
||||
unsigned char water_leak_status_from_dynbat; // 动力漏水状态
|
||||
unsigned char dcdc_status_from_insbat; // 仪表DCDC状态
|
||||
|
||||
//保留字段
|
||||
// uint32_t reserved4; // 保留字段
|
||||
uint32_t heartbeat; // 主机心跳计数器
|
||||
|
||||
//锂电池故障字段
|
||||
unsigned char powfaultCode;
|
||||
unsigned char insfaultCode;
|
||||
|
||||
|
||||
//应急电池
|
||||
double emergency_battery1_voltage; // 应急电池1总电压 [V]
|
||||
double emergency_battery1_current; // 应急电池1总电流 [A]
|
||||
double emergency_battery1_max_temp; // 应急电池1最高温度 [°C]
|
||||
uint16_t emergency_battery1_fault_word; // 应急电池1故障字
|
||||
double emergency_battery2_voltage; // 应急电池2总电压 [V]
|
||||
double emergency_battery2_current; // 应急电池2总电流 [A]
|
||||
double emergency_battery2_max_temp; // 应急电池2最高温度 [°C]
|
||||
uint16_t emergency_battery2_fault_word; // 应急电池2故障字
|
||||
|
||||
// MOOSD 状态
|
||||
bool moosd_status;
|
||||
//配电系统状态
|
||||
//DC/DC状态字
|
||||
struct DcdcStatus
|
||||
{
|
||||
// DC/DC5故障字低
|
||||
union {
|
||||
unsigned char lowFaultWord;
|
||||
struct {
|
||||
bool overTemperatureShutdown : 1; // Bit0: DC/DC模块过温关机
|
||||
bool outputOverCurrent : 1; // Bit1: 输出过流
|
||||
bool outputOverVoltage : 1; // Bit2: 输出过压
|
||||
bool outputUnderVoltage : 1; // Bit3: 输出欠压
|
||||
bool inputOverVoltage : 1; // Bit4: 输入过压
|
||||
bool inputUnderVoltage : 1; // Bit5: 输入欠压
|
||||
bool outputShortCircuit : 1; // Bit6: 输出短路保护
|
||||
bool internalFault : 1; // Bit7: 内部故障
|
||||
};
|
||||
};
|
||||
// DC/DC5故障字高
|
||||
union {
|
||||
unsigned char highFaultWord;
|
||||
struct {
|
||||
bool communicationFault : 1; // Bit0: 通讯故障报警
|
||||
bool workingStatus : 1; // Bit1: 工作状态(1:启动, 0:关闭)
|
||||
bool coolingPump1Fault : 1; // Bit2: 冷却泵1故障
|
||||
bool coolingPump2Fault : 1; // Bit3: 冷却泵2故障
|
||||
bool coolingWaterLeak : 1; // Bit4: 冷却水泄露
|
||||
bool coolingPump1Running : 1; // Bit5: 冷却泵1运行状态
|
||||
bool coolingPump2Running : 1; // Bit6: 冷却泵2运行状态
|
||||
bool reserved : 1; // Bit7: 保留位
|
||||
};
|
||||
};
|
||||
|
||||
// 构造函数,初始化所有状态为正常
|
||||
DcdcStatus() : lowFaultWord(0x00), highFaultWord(0x00) {}
|
||||
} m_dcdcStatus;
|
||||
|
||||
|
||||
//动力母线状态
|
||||
struct POWER_BUS_STATUS
|
||||
{
|
||||
// 5: 燃料电池断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char fuelCellCircuitBreaker;
|
||||
// 6: 动力锂电池断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char powerLithiumBatteryCircuitBreaker;
|
||||
// 7: 推进电机断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char propulsionMotorCircuitBreaker;
|
||||
// 8: 锂电池组仪表断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char lithiumBatteryGroupInstrumentCircuitBreaker;
|
||||
// 9: DC/DC5模块断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char dcDc5ModuleCircuitBreaker;
|
||||
// 10: 艏部高压配电箱断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char bowHighVoltageDistributionBoxCircuitBreaker;
|
||||
// 11: 艉部FT装置4/5断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char sternFTDevice45CircuitBreaker;
|
||||
// 12: 艉舵开关1断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char sternRudderSwitch1CircuitBreaker;
|
||||
// 13: 艉舵开关2断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char sternRudderSwitch2CircuitBreaker;
|
||||
// 14: FB预留断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char fbReservedCircuitBreaker;
|
||||
// 15: TYZ预留断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char tyzReservedCircuitBreaker;
|
||||
// 16: 预留断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char reservedCircuitBreaker;
|
||||
// 17: DC/DC5模块状态 0 未运行;1 运行;2 DC/DC模块过温关机;3 输出过流;4 输出过压;5 输出欠压;6 输入过压;7 输入欠压;8 输出短路保护;9 内部故障
|
||||
unsigned char dcDcModuleStatus;
|
||||
// 18:冷却系统状态 0 未运行 1 运行 2 冷却泵1故障 3 冷却泵2故障 4 冷却水泄露
|
||||
unsigned char coolingSystemStatus;
|
||||
// 19: 动力母排绝缘状态 0 正常 1 绝缘低
|
||||
unsigned char powerBusInsulationStatus;
|
||||
// 20: A汇流排绝缘状态 0 正常 1 绝缘低
|
||||
unsigned char aBusInsulationStatus;
|
||||
// 21: 仪表电源状态 0 正常 1 故障
|
||||
unsigned char meterPowerLossSignal;
|
||||
// 22: 应急电源状态 0 正常 1 故障
|
||||
unsigned char emergencyPowerLossSignal;
|
||||
// 22: dc/dc温度
|
||||
float dcDcTemperature;
|
||||
// 23: 动力汇流排电压
|
||||
float powerBusVoltage;
|
||||
// 24: DC/DC5模块电流
|
||||
float dcDc5ModuleCurrent;
|
||||
// 25: 动力汇流排电流
|
||||
float powerBusCurrent;
|
||||
// 26: A汇流排电压
|
||||
float busbarAVoltage;
|
||||
// 27: 推进电机控制箱电流
|
||||
float propulsionMotorControlBoxCurrent;
|
||||
// 28: A汇流排电流
|
||||
float busbarACurrent;
|
||||
// 29: 锂电池组(仪表)电流
|
||||
float lithiumBatteryGroupMeterCurrent;
|
||||
// 30: 艏部高压配电箱电流
|
||||
float bowHighVoltageDistributionBoxCurrent;
|
||||
// 31: 艉部FT装置4/5电流
|
||||
float sternFTDevice45Current;
|
||||
// 32: TYZ预留开关电流
|
||||
float tyzReservedSwitchCurrent;
|
||||
// 33: 艉舵开关1电流
|
||||
float sternRudderSwitch1Current;
|
||||
// 34: 预留电流
|
||||
float reservedCurrent1; // 改为 reservedCurrent1 以避免重名
|
||||
// 35: 艉舵开关2电流
|
||||
float sternRudderSwitch2Current;
|
||||
// 36: 预留电流2
|
||||
float reservedCurrent2; // 改为 reservedCurrent2 以避免重名
|
||||
// 37: FB预留电流
|
||||
float fbReservedSwitchCurrent;
|
||||
// 38: 预留电流3
|
||||
float reservedCurrent3; // 改为 reservedCurrent3 以避免重名
|
||||
// 39: 冷却水压力
|
||||
float coolWaterPressure;
|
||||
}power_bus_status;
|
||||
|
||||
struct POWER_A_BUS_STATUS
|
||||
{
|
||||
//动力汇流排状态
|
||||
//5. 艏部FT装置1/2/3断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char bowFTDevice123CircuitBreaker;
|
||||
//6. 启闭机构断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char actuatorCircuitBreaker;
|
||||
//7. 桅杆舵机控制箱断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char mastSteeringGearControlBoxCircuitBreaker;
|
||||
//8. XCZ断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char xczCircuitBreaker;
|
||||
//9. 艏舵控制箱断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char bowRudderControlBoxCircuitBreaker;
|
||||
//10. 敞水盖启动电缸断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char openWaterCoverStartCylinderCircuitBreaker;
|
||||
//11. 仪表电源失电信号 0 正常 1 故障
|
||||
unsigned char instrumentPowerFailureSignal;
|
||||
//12. 应急电源失电信号 0 正常 1 故障
|
||||
unsigned char emergencyPowerFailureSignal;
|
||||
//13. 浸水报警 0 无 1 有
|
||||
unsigned char waterIngressionAlarm;
|
||||
//14. 汇流排B电压
|
||||
float busbarBVoltage;
|
||||
//15. 汇流排B电流
|
||||
float busbarBCurrent;
|
||||
//16. 艏部FT装置1/2/3电流
|
||||
float bowFTDevice123Current;
|
||||
//17. 启闭机构电流
|
||||
float actuatorCurrent;
|
||||
//18. 桅杆舵机控制箱电流
|
||||
float mastSteeringGearControlBoxCurrent;
|
||||
//19. XCZ电流
|
||||
float xczCurrent;
|
||||
//20. 艏舵控制箱电流
|
||||
float bowRudderControlBoxCurrent;
|
||||
//21. 敞水盖启动电缸电流
|
||||
float openWaterCoverStartCylinderCurrent;
|
||||
} power_a_bus_status;
|
||||
|
||||
//仪表主母线状态
|
||||
struct INSTRUMENT_MAIN_BUS_STATUS
|
||||
{
|
||||
//5. 锂电池组(仪表)断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char lithiumBatteryGroupInstrumentCircuitBreaker;
|
||||
//6. 艏部低压配电箱断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char bowLowVoltageDistributionBoxCircuitBreaker;
|
||||
//7. UNIT4仪表DC48V断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char unit4InstrumentDC48VCircuitBreaker;
|
||||
//8. DC-C1直流配电板断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char dcC1DCDistributionPanelCircuitBreaker;
|
||||
//9. 预留断路器1 0 断开 1 闭合 2 故障
|
||||
unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀
|
||||
//10. 预留断路器2 0 断开 1 闭合 2 故障
|
||||
unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀
|
||||
//11. 应急锂电池组2断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char emergencyLithiumBatteryGroup2CircuitBreaker;
|
||||
//12. 仪表电源失电信号 0 正常 1 故障
|
||||
unsigned char instrumentPowerFailureSignal;
|
||||
//13. 应急电源失电信号 0 正常 1 故障
|
||||
unsigned char emergencyPowerFailureSignal;
|
||||
//14. 仪表汇流排绝缘低 0 正常 1 绝缘低
|
||||
unsigned char instrumentBusbarInsulationLow;
|
||||
//15. 仪表母排电压
|
||||
float instrumentBusbarVoltage;
|
||||
//16. 艏部低压配电箱电流
|
||||
float bowLowVoltageDistributionBoxCurrent;
|
||||
//17. DC-C1(直流配电板1)仪表DC48V电流
|
||||
float dcC1InstrumentDC48VCurrent;
|
||||
//18. 预留电流
|
||||
float reservedCurrent1; // 为了区分,添加了数字后缀
|
||||
//19. 应急锂电池组2电流
|
||||
float emergencyLithiumBatteryGroup2Current;
|
||||
//20. 锂电池组(仪表)电流
|
||||
float lithiumBatteryGroupInstrumentCurrent;
|
||||
//21. UNIT4仪表DC48V电流
|
||||
float unit4InstrumentDC48VCurrent;
|
||||
//22. Ushort 预留电流
|
||||
float reservedCurrent2; // 为了区分,添加了数字后缀
|
||||
//23. 应急2汇流排电压
|
||||
float emergency2BusbarVoltage;
|
||||
//24. 复合能源管控系统应急DC48V电流
|
||||
float compositeEnergyManagementSystemEmergencyDC48VCurrent;
|
||||
//25. 燃料电池安全系统应急DC48V电流
|
||||
float fuelCellSecuritySystemEmergencyDC48VCurrent;
|
||||
//26. PLC控制电源电流
|
||||
float plcControlPowerCurrent;
|
||||
} instrument_main_bus_status;
|
||||
|
||||
//仪表汇流排状态
|
||||
struct INSTRUMENT_BUS_STATUS
|
||||
{
|
||||
//5. UNIT1断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char unit1CircuitBreaker;
|
||||
//6. UNIT2断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char unit2CircuitBreaker;
|
||||
//7. UNIT3断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char unit3CircuitBreaker;
|
||||
//8. UNIT5断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char unit5CircuitBreaker;
|
||||
//9. 艏部PZ装置断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char bowPZDeviceCircuitBreaker;
|
||||
//10. 预留断路器1 0 断开 1 闭合 2 故障
|
||||
unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀
|
||||
//11. 预留断路器2 0 断开 1 闭合 2 故障
|
||||
unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀
|
||||
//12. 应急锂电池组1断路器 0 断开 1 闭合 2 故障
|
||||
unsigned char emergencyLithiumBatteryGroup1CircuitBreaker;
|
||||
//13. 仪表电源失电信号 0 正常 1 故障
|
||||
unsigned char powerFailureSignal;
|
||||
//14. 应急电源失电信号 0 正常 1 故障
|
||||
unsigned char emergencyPowerFailureSignal;
|
||||
//15. 浸水报警 0 无 1 有
|
||||
unsigned char waterIngressionAlarm;
|
||||
//16. 仪表母排电压
|
||||
float instrumentBusbarVoltage;
|
||||
//17. 仪表母排电流
|
||||
float instrumentBusbarCurrent;
|
||||
//18. UNIT1电流
|
||||
float unit1Current;
|
||||
//19. UNIT2电流
|
||||
float unit2Current;
|
||||
//20. UNIT3电流
|
||||
float unit3Current;
|
||||
//21. UNIT5电流
|
||||
float unit5Current;
|
||||
//22. 艏部PZ装置电流
|
||||
float bowPZDeviceCurrent;
|
||||
//23. 应急锂电池组1电流
|
||||
float emergencyLithiumBatteryGroup1Current;
|
||||
//24. 应急1汇流排电压
|
||||
float emergency1BusbarVoltage;
|
||||
} instrument_bus_status;
|
||||
|
||||
struct COMMON_STATUS
|
||||
{
|
||||
//超时状态
|
||||
bool isTimeout;
|
||||
//最后更新时间
|
||||
double lastUpdateTime;
|
||||
};
|
||||
|
||||
struct DeviceCommonStatus
|
||||
{
|
||||
COMMON_STATUS ccu_status;
|
||||
COMMON_STATUS dis_hv_c1;
|
||||
COMMON_STATUS dis_hv_c2;
|
||||
COMMON_STATUS dis_lv_c1;
|
||||
COMMON_STATUS dis_lv_c2;
|
||||
} device_common_status;
|
||||
|
||||
struct DeviceOnlineStatus
|
||||
{
|
||||
//在线状态
|
||||
//0x00: 未上线
|
||||
//0x01: 在线
|
||||
//0x02: 上线后掉线
|
||||
uint8_t ins_online_state; //仪表锂电在线标志位
|
||||
uint8_t dyn_online_state; //动力锂电在线标志位
|
||||
uint8_t fuel_online_state; //燃电锂电在线标志位
|
||||
uint8_t high_voltage_online_state; //高压配电板在线标志位
|
||||
uint8_t low_voltage_online_state; //低压配电板在线标志位
|
||||
uint8_t composite_online_state; //复合管控主机在线标志位
|
||||
uint8_t composite_backup_online_state; //复合管控备机在线标志位
|
||||
} device_online_status;
|
||||
|
||||
enum LeakageStatus {
|
||||
LEAKAGE_BOW_EMERGENCY = 0, // 艏部应急漏水 (0x01)
|
||||
LEAKAGE_BOW_HIGH_VOLTAGE, // 艏高压漏水 (0x02)
|
||||
LEAKAGE_BOW_LOW_VOLTAGE, // 艏低压漏水 (0x04)
|
||||
LEAKAGE_FUEL_CELL, // 燃电舱漏水 (0x08)
|
||||
LEAKAGE_LI_BATTERY, // 锂电池舱漏水 (0x10)
|
||||
LEAKAGE_STERN_EMERGENCY, // 艉应急漏水 (0x20)
|
||||
LEAKAGE_FUEL_CELL_CABIN, // 燃料电池舱漏水 (0x40)
|
||||
LEAKAGE_BOW_EMERGENCY2 // 艏部应急漏水2 (0x80)
|
||||
};
|
||||
|
||||
unsigned char leakageCode = 0;
|
||||
bool leakStatus[8] = {false};
|
||||
|
||||
unsigned char generateLeakageCode() {
|
||||
unsigned char code = 0;
|
||||
if(leakStatus[LEAKAGE_BOW_EMERGENCY]) code |= 0x01;
|
||||
if(leakStatus[LEAKAGE_BOW_HIGH_VOLTAGE]) code |= 0x02;
|
||||
if(leakStatus[LEAKAGE_BOW_LOW_VOLTAGE]) code |= 0x04;
|
||||
if(leakStatus[LEAKAGE_FUEL_CELL]) code |= 0x08;
|
||||
if(leakStatus[LEAKAGE_LI_BATTERY]) code |= 0x10;
|
||||
if(leakStatus[LEAKAGE_STERN_EMERGENCY]) code |= 0x20;
|
||||
if(leakStatus[LEAKAGE_FUEL_CELL_CABIN]) code |= 0x40;
|
||||
if(leakStatus[LEAKAGE_BOW_EMERGENCY2]) code |= 0x80;
|
||||
return code;
|
||||
}
|
||||
public:
|
||||
SystemData(){
|
||||
//初始化变量全部为0
|
||||
memset(this, 0, sizeof(SystemData));
|
||||
disSysFaultCode.clear();
|
||||
sysFaultCodes.clear();
|
||||
};
|
||||
~SystemData(){};
|
||||
|
||||
void updateCommonStatus(double time_out=10){
|
||||
//更新时间
|
||||
double currentTime = MOOSTime();
|
||||
//判断是否超时
|
||||
device_common_status.ccu_status.isTimeout = abs(currentTime - device_common_status.ccu_status.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_hv_c1.isTimeout = abs(currentTime - device_common_status.dis_hv_c1.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_hv_c2.isTimeout = abs(currentTime - device_common_status.dis_hv_c2.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_lv_c1.isTimeout = abs(currentTime - device_common_status.dis_lv_c1.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_lv_c2.isTimeout = abs(currentTime - device_common_status.dis_lv_c2.lastUpdateTime) > time_out;
|
||||
};
|
||||
|
||||
void updateSystemData(ccuState data){
|
||||
|
||||
fc_mode = data.fc_mode;
|
||||
fc_status = data.fc_status;
|
||||
fc_fault_level = data.fc_fault_level;
|
||||
|
||||
//功率和时间参数
|
||||
output_power_limit = data.output_power_limit;
|
||||
total_generation_time = data.total_generation_time * 0.1;
|
||||
total_generation_power = data.total_generation_power;
|
||||
|
||||
//故障信息
|
||||
#ifdef DEBUG
|
||||
fc_fault_level_1 = data.fault_level_1;
|
||||
fc_fault_level_2 = data.fault_level_2;
|
||||
fc_fault_level_3 = data.fault_level_3;
|
||||
fc_fault_level_4 = data.fault_level_4;
|
||||
#endif
|
||||
|
||||
//燃料容量
|
||||
hydrogen_capacity = static_cast<int>(data.hydrogen_capacity);
|
||||
liquid_oxygen_capacity = static_cast<int>(data.liquid_oxygen_capacity);
|
||||
|
||||
//温度压力参数
|
||||
palladium_temp = data.palladium_temp;
|
||||
main_pipe_pressure = data.main_pipe_pressure * 0.01;
|
||||
aux_pipe_pressure = data.aux_pipe_pressure * 0.01;
|
||||
|
||||
//舱室环境参数
|
||||
cabin_pressure1 = data.cabin_pressure1 * 0.01;
|
||||
cabin_pressure2 = data.cabin_pressure2 * 0.01;
|
||||
cabin_temp1 = data.cabin_temp1 * 0.01;
|
||||
cabin_temp2 = data.cabin_temp2 * 0.01;
|
||||
cabin_humidity1 = data.cabin_humidity1 * 0.01;
|
||||
cabin_humidity2 = data.cabin_humidity2 * 0.01;
|
||||
|
||||
//火焰探测器
|
||||
flame_detector1 = data.flame_detector1;
|
||||
flame_detector2 = data.flame_detector2;
|
||||
|
||||
//气体浓度
|
||||
h2_concentration1 = data.h2_concentration1 * 0.01;
|
||||
h2_concentration2 = data.h2_concentration2 * 0.01;
|
||||
h2_concentration3 = data.h2_concentration3 * 0.01;
|
||||
o2_concentration1 = data.o2_concentration1 * 0.01;
|
||||
o2_concentration2 = data.o2_concentration2 * 0.01;
|
||||
ch3oh_concentration1 = data.ch3oh_concentration1 * 0.01;
|
||||
ch3oh_concentration2 = data.ch3oh_concentration2 * 0.01;
|
||||
|
||||
//保留字段
|
||||
for(int i=0; i<10; i++) {
|
||||
reserved1[i] = data.reserved1[i];
|
||||
}
|
||||
|
||||
//仪表舱参数
|
||||
cabin_ox_concentration = data.cabin_ox_concentration * 0.1;
|
||||
cabin_temperature = static_cast<int16_t>(data.cabin_temperature) * 0.1;
|
||||
cabin_humidity = data.cabin_humidity * 0.1;
|
||||
cabin_pressure = data.cabin_pressure * 0.2;
|
||||
|
||||
//动力舱参数
|
||||
power_cabin_ox_concentration = data.power_cabin_ox_concentration * 0.1;
|
||||
power_cabin_temperature = static_cast<int16_t>(data.power_cabin_temperature) * 0.1;
|
||||
power_cabin_humidity = data.power_cabin_humidity * 0.1;
|
||||
power_cabin_pressure = data.power_cabin_pressure * 0.2;
|
||||
|
||||
//电池报警标志
|
||||
for(int i=0; i<6; i++) {
|
||||
dyn_alarm_flag[i] = data.dyn_alarm_flag[i];
|
||||
ins_alarm_flag[i] = data.ins_alarm_flag[i];
|
||||
}
|
||||
|
||||
//继电器状态
|
||||
ins_relay_status1 = data.ins_relay_status1;
|
||||
ins_relay_status2 = data.ins_relay_status2;
|
||||
dyn_relay_status1 = data.dyn_relay_status1;
|
||||
dyn_relay_status2 = data.dyn_relay_status2;
|
||||
|
||||
//继电器状态
|
||||
ins_pos_relay_status = (data.ins_relay_status1 ) & 0x0F; // 取高4位作为正极继电器状态
|
||||
ins_charge_relay_status = ( data.ins_relay_status1 >> 4)& 0x0F; // 取低4位作为充电继电器状态
|
||||
ins_precharge_relay_status = (data.ins_relay_status2 ) & 0x0F; // 取高4位作为预充继电器状态
|
||||
ins_neg_relay_status = (data.ins_relay_status2 >> 4) & 0x0F; // 取低4位作为负极继电器状态
|
||||
|
||||
dyn_pos_relay_status = (data.dyn_relay_status1 ) & 0x0F; // 取高4位作为正极继电器状态
|
||||
dyn_charge_relay_status = (data.dyn_relay_status1 >> 4) & 0x0F; // 取低4位作为充电继电器状态
|
||||
dyn_precharge_relay_status = (data.dyn_relay_status2) & 0x0F; // 取高4位作为预充继电器状态
|
||||
dyn_neg_relay_status = (data.dyn_relay_status2 >> 4) & 0x0F; // 取低4位作为负极继电器状态
|
||||
|
||||
//电池功率参数
|
||||
ins_max_discharge_power = data.ins_max_discharge_power * 0.05;
|
||||
dyn_max_discharge_power = data.dyn_max_discharge_power * 0.05;
|
||||
|
||||
//电池SOC
|
||||
ins_soc = static_cast<int>(data.ins_soc);
|
||||
dyn_soc = static_cast<int>(data.dyn_soc);
|
||||
|
||||
//电池能量
|
||||
ins_total_energy = data.ins_total_energy * 0.1;
|
||||
dyn_total_energy = data.dyn_total_energy * 0.1;
|
||||
|
||||
//电池输入功率
|
||||
ins_power_input = data.ins_power_input ;
|
||||
dyn_power_input = data.dyn_power_input ;
|
||||
|
||||
//电池充放电状态
|
||||
ins_charge_status = data.ins_charge_status;
|
||||
dyn_charge_status = data.dyn_charge_status;
|
||||
|
||||
//电池电压电流
|
||||
ins_voltage_link = data.ins_voltage_link * 0.1;
|
||||
ins_voltage_pack = data.ins_voltage_pack * 0.1;
|
||||
ins_current = static_cast<int16_t>(data.ins_current) * 0.05;
|
||||
ins_resistance_pos = data.ins_resistance_pos;
|
||||
ins_resistance_neg = data.ins_resistance_neg;
|
||||
dyn_voltage_link = data.dyn_voltage_link * 0.1;
|
||||
dyn_voltage_pack = data.dyn_voltage_pack * 0.1;
|
||||
dyn_current = static_cast<int16_t>(data.dyn_current) * 0.05;
|
||||
dyn_resistance_pos = data.dyn_resistance_pos;
|
||||
dyn_resistance_neg = data.dyn_resistance_neg;
|
||||
|
||||
//紧急状态
|
||||
ins_emergency_status = data.ins_emergency_status;
|
||||
dyn_emergency_status = data.dyn_emergency_status;
|
||||
|
||||
//保留字段
|
||||
for(int i=0; i<2; i++) {
|
||||
reserved2[i] = data.reserved2[i];
|
||||
}
|
||||
|
||||
//SOC门限值
|
||||
ins_soc_threshold1 = data.ins_soc_threshold1;
|
||||
ins_soc_threshold2 = data.ins_soc_threshold2;
|
||||
ins_soc_threshold3 = data.ins_soc_threshold3;
|
||||
|
||||
//功率限制值
|
||||
ins_power_limit1 = data.ins_power_limit1;
|
||||
ins_power_limit2 = data.ins_power_limit2;
|
||||
|
||||
//设备在线状态
|
||||
device_online_flag1 = data.device_online_flag1;
|
||||
device_online_flag2 = data.device_online_flag2;
|
||||
|
||||
//更新设备在线状态
|
||||
device_online_status.ins_online_state = (data.device_online_flag1 >> 0) & 0xFF; // byte0:仪表锂电在线标志位
|
||||
device_online_status.dyn_online_state = (data.device_online_flag1 >> 8) & 0xFF; // byte1:动力锂电在线标志位
|
||||
device_online_status.fuel_online_state = (data.device_online_flag1 >> 16) & 0xFF; // byte2:燃电锂电在线标志位
|
||||
device_online_status.high_voltage_online_state = (data.device_online_flag1 >> 24) & 0xFF; // byte3:高压配电板在线标志位
|
||||
|
||||
device_online_status.low_voltage_online_state = (data.device_online_flag2 >> 0) & 0xFF; // byte0:低压配电板在线标志位
|
||||
device_online_status.composite_online_state = (data.device_online_flag2 >> 8) & 0xFF; // byte1:复合管控主机在线标志位
|
||||
device_online_status.composite_backup_online_state = (data.device_online_flag2 >> 16) & 0xFF; // byte2:复合管控备机在线标志位
|
||||
|
||||
// 更新锂电池其他状态
|
||||
dyn_water_leak_status = data.dyn_water_leak_status;
|
||||
ins_water_leak_dcdc_status = data.ins_water_leak_dcdc_status;
|
||||
|
||||
dyn_charge_level = data.dyn_charge_level; //01H:1级(不限)02H:2级(限功率)03H:3级(关闭)
|
||||
water_leak_status_from_insbat = ( data.ins_water_leak_dcdc_status >> 4) & 0x0F; // 00 正常,01 异常漏水
|
||||
water_leak_status_from_dynbat = (data.dyn_water_leak_status >> 4) & 0x0F; // 00 正常,01 异常漏水
|
||||
dcdc_status_from_insbat = (data.ins_water_leak_dcdc_status) & 0x0F; // 00 正常,01 故障
|
||||
//更新漏水状态
|
||||
if(water_leak_status_from_insbat == 0x01)
|
||||
{
|
||||
leakStatus[LEAKAGE_LI_BATTERY] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
leakStatus[LEAKAGE_LI_BATTERY] = false;
|
||||
}
|
||||
if(water_leak_status_from_dynbat == 0x01)
|
||||
{
|
||||
leakStatus[LEAKAGE_LI_BATTERY] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
leakStatus[LEAKAGE_LI_BATTERY] = false;
|
||||
}
|
||||
//应急电池
|
||||
emergency_battery1_voltage = data.emergency_battery1_voltage * 0.1;
|
||||
emergency_battery1_current = data.emergency_battery1_current * 0.05;
|
||||
emergency_battery1_max_temp = data.emergency_battery1_max_temp * 0.1;
|
||||
emergency_battery1_fault_word = data.emergency_battery1_fault_word;
|
||||
emergency_battery2_voltage = data.emergency_battery2_voltage * 0.1;
|
||||
emergency_battery2_current = data.emergency_battery2_current * 0.05;
|
||||
emergency_battery2_max_temp = data.emergency_battery2_max_temp * 0.1;
|
||||
emergency_battery2_fault_word = data.emergency_battery2_fault_word;
|
||||
//心跳计数器
|
||||
heartbeat = data.heartbeat;
|
||||
}
|
||||
std::set<unsigned int> disSysFaultCode;
|
||||
mutable std::mutex faultCodeMutex;
|
||||
void updateBreakerFault(unsigned char& breakerStatus, unsigned char rawStatus, unsigned int faultCode)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(faultCodeMutex);
|
||||
unsigned char newStatus = rawStatus == 0x55 ? 1 : (rawStatus == 0xAA ? 0 : 2);
|
||||
breakerStatus = newStatus; // 保证状态更新也是原子的
|
||||
|
||||
if(newStatus == 2) {
|
||||
disSysFaultCode.insert(faultCode);
|
||||
} else {
|
||||
disSysFaultCode.erase(faultCode);
|
||||
}
|
||||
}
|
||||
void updateBreakerFault(unsigned char& breakerStatus, unsigned char rawStatus)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(faultCodeMutex);
|
||||
unsigned char newStatus = rawStatus == 0x55 ? 1 : (rawStatus == 0xAA ? 0 : 2);
|
||||
breakerStatus = newStatus; // 保证状态更新也是原子的
|
||||
}
|
||||
void updateSystemData(disHighVolBusState data){
|
||||
updateBreakerFault(power_bus_status.fuelCellCircuitBreaker, data.fuelCellCircuitBreaker, 1);
|
||||
updateBreakerFault(power_bus_status.powerLithiumBatteryCircuitBreaker, data.powerLithiumBatteryCircuitBreaker, 2);
|
||||
updateBreakerFault(power_bus_status.propulsionMotorCircuitBreaker, data.propulsionMotorCircuitBreaker, 3);
|
||||
updateBreakerFault(power_bus_status.lithiumBatteryGroupInstrumentCircuitBreaker, data.lithiumBatteryGroupInstrumentCircuitBreaker, 4);
|
||||
updateBreakerFault(power_bus_status.dcDc5ModuleCircuitBreaker, data.dcDc5ModuleCircuitBreaker, 5);
|
||||
updateBreakerFault(power_bus_status.bowHighVoltageDistributionBoxCircuitBreaker, data.bowHighVoltageDistributionBoxCircuitBreaker, 6);
|
||||
updateBreakerFault(power_bus_status.sternFTDevice45CircuitBreaker, data.sternFTDevice45CircuitBreaker, 7);
|
||||
updateBreakerFault(power_bus_status.sternRudderSwitch1CircuitBreaker, data.sternRudderSwitch1CircuitBreaker, 8);
|
||||
updateBreakerFault(power_bus_status.sternRudderSwitch2CircuitBreaker, data.sternRudderSwitch2CircuitBreaker, 9);
|
||||
updateBreakerFault(power_bus_status.fbReservedCircuitBreaker, data.fbReservedCircuitBreaker);
|
||||
updateBreakerFault(power_bus_status.tyzReservedCircuitBreaker, data.tyzReservedCircuitBreaker);
|
||||
updateBreakerFault(power_bus_status.reservedCircuitBreaker, data.reservedCircuitBreaker);
|
||||
//模块状态
|
||||
power_bus_status.dcDcModuleStatus = data.dcDcFaultWord1;
|
||||
power_bus_status.coolingSystemStatus = data.dcDcFaultWord2;
|
||||
|
||||
m_dcdcStatus.lowFaultWord = data.dcDcFaultWord1;
|
||||
m_dcdcStatus.highFaultWord = data.dcDcFaultWord2;
|
||||
|
||||
//绝缘状态
|
||||
power_bus_status.powerBusInsulationStatus = data.powerBusInsulationStatus == 0x55 ? 0 : 1;
|
||||
// if(power_bus_status.powerBusInsulationStatus == 1) disSysFaultCode.insert(34); else disSysFaultCode.erase(34);
|
||||
|
||||
power_bus_status.aBusInsulationStatus = data.aBusInsulationStatus == 0x55 ? 0 : 1;
|
||||
// if(power_bus_status.aBusInsulationStatus == 1) disSysFaultCode.insert(35); else disSysFaultCode.erase(35);
|
||||
|
||||
//电源状态
|
||||
power_bus_status.meterPowerLossSignal = data.meterPowerLossSignal == 0x55 ? 0 : 1;
|
||||
// if(power_bus_status.meterPowerLossSignal == 1) disSysFaultCode.insert(36); else disSysFaultCode.erase(36);
|
||||
|
||||
power_bus_status.emergencyPowerLossSignal = data.emergencyPowerLossSignal == 0x55 ? 0 : 1;
|
||||
|
||||
// if(power_bus_status.emergencyPowerLossSignal == 1) disSysFaultCode.insert(37); else disSysFaultCode.erase(37);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(faultCodeMutex);
|
||||
if(power_bus_status.emergencyPowerLossSignal == 1) disSysFaultCode.insert(37); else disSysFaultCode.erase(37);
|
||||
if(power_bus_status.meterPowerLossSignal == 1) disSysFaultCode.insert(36); else disSysFaultCode.erase(36);
|
||||
if(power_bus_status.aBusInsulationStatus == 1) disSysFaultCode.insert(35); else disSysFaultCode.erase(35);
|
||||
if(power_bus_status.powerBusInsulationStatus == 1) disSysFaultCode.insert(34); else disSysFaultCode.erase(34);
|
||||
}
|
||||
|
||||
//温度
|
||||
power_bus_status.dcDcTemperature = data.dcDcTemperature-40;
|
||||
|
||||
//电压电流参数
|
||||
power_bus_status.powerBusVoltage = data.powerBusVoltage * 0.1;
|
||||
power_bus_status.dcDc5ModuleCurrent = data.dcDc5ModuleCurrent * 0.1;
|
||||
power_bus_status.powerBusCurrent = data.powerBusCurrent * 0.1;
|
||||
power_bus_status.busbarAVoltage = data.busbarAVoltage * 0.1;
|
||||
power_bus_status.propulsionMotorControlBoxCurrent = data.propulsionMotorControlBoxCurrent * 0.1;
|
||||
power_bus_status.busbarACurrent = data.busbarACurrent * 0.1;
|
||||
power_bus_status.lithiumBatteryGroupMeterCurrent = data.lithiumBatteryGroupMeterCurrent * 0.1;
|
||||
power_bus_status.bowHighVoltageDistributionBoxCurrent = data.bowHighVoltageDistributionBoxCurrent * 0.1;
|
||||
power_bus_status.sternFTDevice45Current = data.sternFTDevice45Current * 0.1;
|
||||
power_bus_status.tyzReservedSwitchCurrent = data.tyzReservedSwitchCurrent * 0.1;
|
||||
power_bus_status.sternRudderSwitch1Current = data.sternRudderSwitch1Current * 0.1;
|
||||
power_bus_status.reservedCurrent1 = data.reservedCurrent1 * 0.1;
|
||||
power_bus_status.sternRudderSwitch2Current = data.sternRudderSwitch2Current * 0.1;
|
||||
power_bus_status.reservedCurrent2 = data.reservedCurrent2 * 0.1;
|
||||
power_bus_status.fbReservedSwitchCurrent = data.fbReservedSwitchCurrent * 0.1;
|
||||
power_bus_status.reservedCurrent3 = data.reservedCurrent3 * 0.1;
|
||||
|
||||
//冷却水压力
|
||||
power_bus_status.coolWaterPressure = data.coolWaterPressure * 0.1;
|
||||
};
|
||||
void updateSystemData(disHighAVolBusState data){
|
||||
//断路器状态 (0x55 1 0xAA 0 0x5A 2)
|
||||
updateBreakerFault(power_a_bus_status.bowFTDevice123CircuitBreaker, data.bowFTDevice123CircuitBreaker, 13);
|
||||
updateBreakerFault(power_a_bus_status.actuatorCircuitBreaker, data.actuatorCircuitBreaker, 14);
|
||||
updateBreakerFault(power_a_bus_status.mastSteeringGearControlBoxCircuitBreaker, data.mastSteeringGearControlBoxCircuitBreaker, 15);
|
||||
updateBreakerFault(power_a_bus_status.xczCircuitBreaker, data.xczCircuitBreaker, 16);
|
||||
updateBreakerFault(power_a_bus_status.bowRudderControlBoxCircuitBreaker, data.bowRudderControlBoxCircuitBreaker, 17);
|
||||
updateBreakerFault(power_a_bus_status.openWaterCoverStartCylinderCircuitBreaker, data.openWaterCoverStartCylinderCircuitBreaker, 18);
|
||||
|
||||
//电源状态
|
||||
power_a_bus_status.instrumentPowerFailureSignal = data.instrumentPowerFailureSignal == 0x55 ? 0 : 1;
|
||||
// if(power_a_bus_status.instrumentPowerFailureSignal == 1) disSysFaultCode.insert(38); else disSysFaultCode.erase(38);
|
||||
|
||||
power_a_bus_status.emergencyPowerFailureSignal = data.emergencyPowerFailureSignal == 0x55 ? 0 : 1;
|
||||
// if(power_a_bus_status.emergencyPowerFailureSignal == 1) disSysFaultCode.insert(39); else disSysFaultCode.erase(39);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(faultCodeMutex);
|
||||
if(power_a_bus_status.emergencyPowerFailureSignal == 1) disSysFaultCode.insert(39); else disSysFaultCode.erase(39);
|
||||
if(power_a_bus_status.instrumentPowerFailureSignal == 1) disSysFaultCode.insert(38); else disSysFaultCode.erase(38);
|
||||
}
|
||||
|
||||
//浸水报警
|
||||
power_a_bus_status.waterIngressionAlarm = data.waterIngressionAlarm == 0x55 ? 0 : 1;
|
||||
//更新漏水状态
|
||||
if(power_a_bus_status.waterIngressionAlarm == 1)
|
||||
{
|
||||
leakStatus[LEAKAGE_BOW_HIGH_VOLTAGE] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
leakStatus[LEAKAGE_BOW_HIGH_VOLTAGE] = false;
|
||||
}
|
||||
|
||||
|
||||
//电压电流参数
|
||||
power_a_bus_status.busbarBVoltage = data.busbarBVoltage * 0.1;
|
||||
power_a_bus_status.busbarBCurrent = data.busbarBCurrent * 0.1;
|
||||
power_a_bus_status.bowFTDevice123Current = data.bowFTDevice123Current * 0.1;
|
||||
power_a_bus_status.actuatorCurrent = data.actuatorCurrent * 0.1;
|
||||
power_a_bus_status.mastSteeringGearControlBoxCurrent = data.mastSteeringGearControlBoxCurrent * 0.1;
|
||||
power_a_bus_status.xczCurrent = data.xczCurrent * 0.1;
|
||||
power_a_bus_status.bowRudderControlBoxCurrent = data.bowRudderControlBoxCurrent * 0.1;
|
||||
power_a_bus_status.openWaterCoverStartCylinderCurrent = data.openWaterCoverStartCylinderCurrent * 0.1;
|
||||
};
|
||||
void updateSystemData(disLowMainBusState data){
|
||||
//断路器状态 (0x55 1 0xAA 0 0x5A 2)
|
||||
updateBreakerFault(instrument_main_bus_status.lithiumBatteryGroupInstrumentCircuitBreaker, data.lithiumBatteryGroupInstrumentCircuitBreaker, 19);
|
||||
updateBreakerFault(instrument_main_bus_status.bowLowVoltageDistributionBoxCircuitBreaker,data.bowLowVoltageDistributionBoxCircuitBreaker, 20);
|
||||
updateBreakerFault(instrument_main_bus_status.unit4InstrumentDC48VCircuitBreaker,data.unit4InstrumentDC48VCircuitBreaker, 21);
|
||||
updateBreakerFault(instrument_main_bus_status.dcC1DCDistributionPanelCircuitBreaker, data.dcC1DCDistributionPanelCircuitBreaker, 22);
|
||||
updateBreakerFault(instrument_main_bus_status.reservedCircuitBreaker1, data.reservedCircuitBreaker1);
|
||||
updateBreakerFault(instrument_main_bus_status.reservedCircuitBreaker2, data.reservedCircuitBreaker2);
|
||||
updateBreakerFault(instrument_main_bus_status.emergencyLithiumBatteryGroup2CircuitBreaker, data.emergencyLithiumBatteryGroup2CircuitBreaker, 25);
|
||||
|
||||
//电源状态
|
||||
instrument_main_bus_status.instrumentPowerFailureSignal = data.instrumentPowerFailureSignal == 0x55 ? 0 : 1;
|
||||
// if(instrument_main_bus_status.instrumentPowerFailureSignal == 1) disSysFaultCode.insert(40); else disSysFaultCode.erase(41);
|
||||
|
||||
instrument_main_bus_status.emergencyPowerFailureSignal = data.emergencyPowerFailureSignal == 0x55 ? 0 : 1;
|
||||
// if(instrument_main_bus_status.emergencyPowerFailureSignal == 1) disSysFaultCode.insert(41); else disSysFaultCode.erase(42);
|
||||
|
||||
//绝缘状态
|
||||
instrument_main_bus_status.instrumentBusbarInsulationLow = data.instrumentBusbarInsulationLow == 0x55 ? 0 : 1;
|
||||
// if(instrument_main_bus_status.instrumentBusbarInsulationLow == 1) disSysFaultCode.insert(42); else disSysFaultCode.erase(43);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(faultCodeMutex);
|
||||
if(instrument_main_bus_status.instrumentPowerFailureSignal == 1) disSysFaultCode.insert(41); else disSysFaultCode.erase(41);
|
||||
if(instrument_main_bus_status.emergencyPowerFailureSignal == 1) disSysFaultCode.insert(42); else disSysFaultCode.erase(42);
|
||||
if(instrument_main_bus_status.instrumentBusbarInsulationLow == 1) disSysFaultCode.insert(43); else disSysFaultCode.erase(43);
|
||||
}
|
||||
|
||||
//电压电流参数
|
||||
instrument_main_bus_status.instrumentBusbarVoltage = data.instrumentBusbarVoltage * 0.1;
|
||||
instrument_main_bus_status.bowLowVoltageDistributionBoxCurrent = data.bowLowVoltageDistributionBoxCurrent * 0.1;
|
||||
instrument_main_bus_status.dcC1InstrumentDC48VCurrent = data.dcC1InstrumentDC48VCurrent * 0.1;
|
||||
instrument_main_bus_status.reservedCurrent1 = data.reservedCurrent1 * 0.1;
|
||||
instrument_main_bus_status.emergencyLithiumBatteryGroup2Current = data.emergencyLithiumBatteryGroup2Current * 0.1;
|
||||
instrument_main_bus_status.lithiumBatteryGroupInstrumentCurrent = data.lithiumBatteryGroupInstrumentCurrent * 0.1;
|
||||
instrument_main_bus_status.unit4InstrumentDC48VCurrent = data.unit4InstrumentDC48VCurrent * 0.1;
|
||||
instrument_main_bus_status.reservedCurrent2 = data.reservedCurrent2 * 0.1;
|
||||
instrument_main_bus_status.emergency2BusbarVoltage = data.emergency2BusbarVoltage * 0.1;
|
||||
instrument_main_bus_status.compositeEnergyManagementSystemEmergencyDC48VCurrent = data.compositeEnergyManagementSystemEmergencyDC48VCurrent * 0.1;
|
||||
instrument_main_bus_status.fuelCellSecuritySystemEmergencyDC48VCurrent = data.fuelCellSecuritySystemEmergencyDC48VCurrent * 0.1;
|
||||
instrument_main_bus_status.plcControlPowerCurrent = data.plcControlPowerCurrent * 0.1;
|
||||
}
|
||||
void updateSystemData(disLowBusState data){
|
||||
//断路器状态 (0x55 1 0xAA 0 0x5A 2)
|
||||
updateBreakerFault(instrument_bus_status.unit1CircuitBreaker, data.unit1CircuitBreaker, 26);
|
||||
updateBreakerFault(instrument_bus_status.unit2CircuitBreaker, data.unit2CircuitBreaker, 27);
|
||||
updateBreakerFault(instrument_bus_status.unit3CircuitBreaker, data.unit3CircuitBreaker, 28);
|
||||
updateBreakerFault(instrument_bus_status.unit5CircuitBreaker, data.unit5CircuitBreaker, 29);
|
||||
updateBreakerFault(instrument_bus_status.bowPZDeviceCircuitBreaker, data.bowPZDeviceCircuitBreaker);
|
||||
updateBreakerFault(instrument_bus_status.reservedCircuitBreaker1, data.reservedCircuitBreaker1);
|
||||
updateBreakerFault(instrument_bus_status.reservedCircuitBreaker2, data.reservedCircuitBreaker2);
|
||||
updateBreakerFault(instrument_bus_status.emergencyLithiumBatteryGroup1CircuitBreaker, data.emergencyLithiumBatteryGroup1CircuitBreaker, 33);
|
||||
|
||||
//电源状态
|
||||
instrument_bus_status.powerFailureSignal = data.powerFailureSignal == 0x55 ? 0 : 1;
|
||||
// if(instrument_bus_status.powerFailureSignal == 1) disSysFaultCode.insert(44); else disSysFaultCode.erase(44);
|
||||
|
||||
instrument_bus_status.emergencyPowerFailureSignal = data.emergencyPowerFailureSignal == 0x55 ? 0 : 1;
|
||||
// if(instrument_bus_status.emergencyPowerFailureSignal == 1) disSysFaultCode.insert(45); else disSysFaultCode.erase(45);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(faultCodeMutex);
|
||||
if(instrument_bus_status.emergencyPowerFailureSignal == 1) disSysFaultCode.insert(45); else disSysFaultCode.erase(45);
|
||||
if(instrument_bus_status.powerFailureSignal == 1) disSysFaultCode.insert(44); else disSysFaultCode.erase(44);
|
||||
}
|
||||
|
||||
//浸水报警
|
||||
instrument_bus_status.waterIngressionAlarm = data.waterIngressionAlarm == 0x55 ? 0 : 1;
|
||||
//更新漏水状态
|
||||
if(instrument_bus_status.waterIngressionAlarm == 1)
|
||||
{
|
||||
leakStatus[LEAKAGE_BOW_LOW_VOLTAGE] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
leakStatus[LEAKAGE_BOW_LOW_VOLTAGE] = false;
|
||||
}
|
||||
//电压电流参数
|
||||
instrument_bus_status.instrumentBusbarVoltage = data.instrumentBusbarVoltage * 0.1;
|
||||
instrument_bus_status.instrumentBusbarCurrent = data.instrumentBusbarCurrent * 0.1;
|
||||
instrument_bus_status.unit1Current = data.unit1Current * 0.1;
|
||||
instrument_bus_status.unit2Current = data.unit2Current * 0.1;
|
||||
instrument_bus_status.unit3Current = data.unit3Current * 0.1;
|
||||
instrument_bus_status.unit5Current = data.unit5Current * 0.1;
|
||||
instrument_bus_status.bowPZDeviceCurrent = data.bowPZDeviceCurrent * 0.1;
|
||||
instrument_bus_status.emergencyLithiumBatteryGroup1Current = data.emergencyLithiumBatteryGroup1Current * 0.1;
|
||||
instrument_bus_status.emergency1BusbarVoltage = data.emergency1BusbarVoltage * 0.1;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,139 @@
|
||||
#ifndef CCUUDPMSG__H
|
||||
#define CCUUDPMSG__H
|
||||
#include "../pmSysvariable.h"
|
||||
|
||||
#define CCU_UDPMSG_START1 0x20
|
||||
#define CCU_UDPMSG_START2 0x20
|
||||
|
||||
#define DIS_MSG_HEAD1 0x40
|
||||
#define DIS_MSG_HEAD2 0x40
|
||||
|
||||
#define CCU_CMD_ID 0x0040
|
||||
#define CCU_SET_PARM_ID 0x0041
|
||||
#define CCU_STATE_FB_ID 0x0051
|
||||
#define CCU_SET_PARM_FB_ID 0x0040
|
||||
|
||||
#define DIS_HVBUS_FB_ID 0x0005
|
||||
#define DIS_HVBUSA_FB_ID 0x0006
|
||||
#define DIS_HVBUSB_FB_ID 0x0007
|
||||
#define DIS_LVBUS_FB_ID 0x0008
|
||||
|
||||
#define DIS_HVBUS_CMD_ID 0x0001
|
||||
#define DIS_HVBUSA_CMD_ID 0x0002
|
||||
#define DIS_HVBUSB_CMD_ID 0x0003
|
||||
#define DIS_LVBUS_CMD_ID 0x0004
|
||||
|
||||
#define DIS_BREAKER_ON 0x55
|
||||
#define DIS_BREAKER_OFF 0xAA
|
||||
#define DIS_FAULTOFF 0x5A
|
||||
|
||||
typedef unsigned int Checksum;
|
||||
typedef unsigned char cChecksum;
|
||||
|
||||
#pragma pack (1)
|
||||
typedef struct {
|
||||
unsigned char start1;
|
||||
unsigned char start2;
|
||||
unsigned short id;
|
||||
unsigned short length;
|
||||
} m_header;
|
||||
|
||||
typedef struct {
|
||||
unsigned short year;
|
||||
unsigned char month;
|
||||
unsigned char day;
|
||||
unsigned char hour;
|
||||
unsigned char minute;
|
||||
unsigned char second;
|
||||
unsigned char milliseconds; //每10毫秒
|
||||
} m_date;
|
||||
// 复合管控器操作指令
|
||||
typedef struct {
|
||||
m_header header;
|
||||
m_date date;
|
||||
ccuColCmd cmd;
|
||||
Checksum checkCode;
|
||||
} msg_CcuColCmdMsg;
|
||||
|
||||
// 复合管控器参数设定指令
|
||||
typedef struct {
|
||||
m_header header;
|
||||
ccuSetParmCmd cmd;
|
||||
Checksum checkCode;
|
||||
} msg_CcuSetParmMsg;
|
||||
|
||||
// 配电指令
|
||||
typedef struct
|
||||
{
|
||||
m_header header;
|
||||
disHighVolBusCmd data;
|
||||
cChecksum checkCode;
|
||||
}msg_disHVBCmd;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
m_header header;
|
||||
disHighAVolBusCmd data;
|
||||
cChecksum checkCode;
|
||||
}msg_disHVBACmd;
|
||||
|
||||
typedef struct msg_disHVBBCmd
|
||||
{
|
||||
m_header header;
|
||||
disHighBVolBusCmd data;
|
||||
cChecksum checkCode;
|
||||
}msg_disLVMBCmd;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
m_header header;
|
||||
disLowBusCmd data;
|
||||
cChecksum checkCode;
|
||||
}msg_disLVBCmd;
|
||||
|
||||
|
||||
// 复合管控参数设定反馈指令
|
||||
typedef struct {
|
||||
m_header header;
|
||||
unsigned char flag;
|
||||
unsigned char failureCode;
|
||||
Checksum checkCode;
|
||||
} msg_CcuSetParmFbMsg;
|
||||
|
||||
// 复合管控状态反馈
|
||||
typedef struct {
|
||||
m_header header;
|
||||
ccuState data;
|
||||
Checksum checkCode;
|
||||
} msg_CcuStateFbMsg;
|
||||
|
||||
//高压母线配电反馈
|
||||
typedef struct {
|
||||
m_header header;
|
||||
disHighVolBusState data;
|
||||
cChecksum checkCode;
|
||||
} msg_disHighVolBusFbMsg;
|
||||
|
||||
// 高压母线A配电反馈
|
||||
typedef struct {
|
||||
m_header header;
|
||||
disHighAVolBusState data;
|
||||
cChecksum checkCode;
|
||||
} msg_disHighAVolBusFbMsg;
|
||||
|
||||
// 仪表母线配电反馈
|
||||
typedef struct {
|
||||
m_header header;
|
||||
disLowMainBusState data;
|
||||
cChecksum checkCode;
|
||||
} msg_disLowMainBusFbMsg;
|
||||
|
||||
//仪表汇流排配电反馈
|
||||
typedef struct {
|
||||
m_header header;
|
||||
disLowBusState data;
|
||||
cChecksum checkCode;
|
||||
} msg_disLowBusFbMsg;
|
||||
|
||||
#pragma pack ()
|
||||
#endif
|
||||
@@ -0,0 +1,627 @@
|
||||
#include "udpComm.h"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
udpComm::udpComm()
|
||||
{
|
||||
udpScoket = nullptr;
|
||||
ccuHost = "";
|
||||
ccuPort = 0;
|
||||
}
|
||||
|
||||
udpComm::~udpComm() {
|
||||
if (udpScoket) {
|
||||
delete udpScoket;
|
||||
udpScoket = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Checksum udpComm::calculateChecksum(const unsigned char* data, int size)
|
||||
{
|
||||
Checksum checksum = 0;
|
||||
int size_data = size - sizeof(Checksum);
|
||||
for (int i = 0; i < size_data; i++) {
|
||||
checksum += data[i];
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
Checksum udpComm::calculateChecksum(const unsigned char* data, int dataSize, int checkSize)
|
||||
{
|
||||
Checksum checksum = 0;
|
||||
int size_data = dataSize - checkSize;
|
||||
for (int i = 0; i < size_data; i++) {
|
||||
checksum += data[i];
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
bool udpComm::getMsgId(char *m,unsigned short &id)
|
||||
{
|
||||
m_header h;
|
||||
h = *reinterpret_cast<m_header *>(m);
|
||||
// 判断消息是否有效
|
||||
if (h.start1== DIS_MSG_HEAD1 && h.start2==DIS_MSG_HEAD2)
|
||||
{
|
||||
id = h.id;
|
||||
return true;
|
||||
}
|
||||
else if (h.start1==CCU_UDPMSG_START1 && h.start2==CCU_UDPMSG_START2)
|
||||
{
|
||||
id = h.id;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
// sError.push_back("Msg Header errar");
|
||||
// LOG_F(ERROR, "Msg Header errar start1: %d, start2: %d", h.start1, h.start2);
|
||||
return false;
|
||||
}
|
||||
bool udpComm::getMsgFromBuff(char *m, msg_CcuStateFbMsg &s) {
|
||||
Checksum sum;
|
||||
msg_CcuStateFbMsg *p;
|
||||
p = reinterpret_cast<msg_CcuStateFbMsg *>(m);
|
||||
sum = calculateChecksum((unsigned char*)m, sizeof(msg_CcuStateFbMsg));
|
||||
|
||||
if (sum != p->checkCode) {
|
||||
sError.push_back("CcuStat Msg Check error");
|
||||
return false;
|
||||
}
|
||||
s = *p;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::getMsgFromBuff(char *m, msg_CcuSetParmFbMsg &s)
|
||||
{
|
||||
Checksum sum;
|
||||
msg_CcuSetParmFbMsg *p;
|
||||
p = reinterpret_cast<msg_CcuSetParmFbMsg *>(m);
|
||||
sum = calculateChecksum((unsigned char*)m, sizeof(msg_CcuSetParmFbMsg));
|
||||
|
||||
if (sum!= p->checkCode) {
|
||||
sError.push_back("CcuSetParm Msg Check error");
|
||||
return false;
|
||||
}
|
||||
|
||||
s = *p;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::getMsgFromBuff(char *m, msg_disHighVolBusFbMsg &s)
|
||||
{
|
||||
cChecksum sum;
|
||||
msg_disHighVolBusFbMsg *p;
|
||||
p = reinterpret_cast<msg_disHighVolBusFbMsg *>(m);
|
||||
sum = calculateChecksum((unsigned char*)m, sizeof(msg_disHighVolBusFbMsg), sizeof(cChecksum)) & 0xFF;
|
||||
if (sum != p->checkCode) {
|
||||
sError.push_back("DisSys HVBus Msg Check error");
|
||||
LOG_F(ERROR, "DisSys HVBus Msg Check error sum: %d, source checkCode: %d", sum, p->checkCode);
|
||||
return false;
|
||||
}
|
||||
s = *p;
|
||||
// cout << s.data.busbarAVoltage << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::getMsgFromBuff(char *m, msg_disHighAVolBusFbMsg &s)
|
||||
{
|
||||
cChecksum sum;
|
||||
msg_disHighAVolBusFbMsg *p;
|
||||
p = reinterpret_cast<msg_disHighAVolBusFbMsg *>(m);
|
||||
sum = calculateChecksum((unsigned char*)m, sizeof(msg_disHighAVolBusFbMsg), sizeof(cChecksum)) & 0xFF;
|
||||
if (sum!= p->checkCode) {
|
||||
sError.push_back("DisSys HVABus Msg Check error");
|
||||
LOG_F(ERROR, "DisSys HVABus Msg Check error sum: %d, source checkCode: %d", sum, p->checkCode);
|
||||
return false;
|
||||
}
|
||||
s = *p;
|
||||
return true;
|
||||
}
|
||||
bool udpComm::getMsgFromBuff(char *m, msg_disLowMainBusFbMsg &s)
|
||||
{
|
||||
cChecksum sum;
|
||||
msg_disLowMainBusFbMsg *p;
|
||||
p = reinterpret_cast<msg_disLowMainBusFbMsg *>(m);
|
||||
sum = calculateChecksum((unsigned char*)m, sizeof(msg_disLowMainBusFbMsg), sizeof(cChecksum)) & 0xFF;
|
||||
if (sum!= p->checkCode) {
|
||||
sError.push_back("DisSys HVBBus Msg Check error");
|
||||
LOG_F(ERROR, "DisSys HVBBus Msg Check error sum: %d, source checkCode: %d", sum, p->checkCode);
|
||||
return false;
|
||||
}
|
||||
s = *p;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::getMsgFromBuff(char *m, msg_disLowBusFbMsg &s)
|
||||
{
|
||||
cChecksum sum;
|
||||
msg_disLowBusFbMsg *p;
|
||||
p = reinterpret_cast<msg_disLowBusFbMsg *>(m);
|
||||
sum = calculateChecksum((unsigned char*)m, sizeof(msg_disLowBusFbMsg), sizeof(cChecksum)) & 0xFF;
|
||||
if (sum!= p->checkCode) {
|
||||
sError.push_back("DisSys LVBus Msg Check error");
|
||||
LOG_F(ERROR, "DisSys LVBus Msg Check error sum: %d, source checkCode: %d", sum, p->checkCode);
|
||||
return false;
|
||||
}
|
||||
s = *p;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::pushMsgToQueue(unsigned char *m)
|
||||
{
|
||||
if(m==NULL)
|
||||
{
|
||||
// sError.push_back("pushMsgToQueue faile,Msg is NULL");
|
||||
LOG_F(ERROR, "pushMsgToQueue faile,Msg is NULL m: %p", m);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char* Buff = m;
|
||||
//消息头鉴定
|
||||
char *header = new char[sizeof(m_header)];
|
||||
unsigned short id;
|
||||
memcpy(header,Buff,sizeof(m_header));
|
||||
if(!getMsgId(header,id))
|
||||
{
|
||||
// sError.push_back("pushMsgToQueue faile,Msg ID error");
|
||||
// LOG_F(INFO, "pushMsgToQueue faile,Msg ID error header: %p", header);
|
||||
delete []header;
|
||||
return false;
|
||||
}
|
||||
delete []header;
|
||||
//输入消息
|
||||
switch (id)
|
||||
{
|
||||
case CCU_STATE_FB_ID: //CCU_STATE_FB 0x0051
|
||||
{
|
||||
msg_CcuStateFbMsg s;
|
||||
if(getMsgFromBuff((char *)Buff,s))
|
||||
{
|
||||
if(m_qReceiveCcuStateBuffer.size()<QUENUE_SIZE)
|
||||
{
|
||||
double time = MOOSTime();
|
||||
m_qReceiveCcuStateBuffer.push(std::make_pair(time, s));
|
||||
}
|
||||
else
|
||||
{
|
||||
// sError.push_back("pushMsgToQueue faile,CcuState buffer is full");
|
||||
LOG_F(INFO, "pushMsgToQueue faile,CcuState buffer is full");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CCU_SET_PARM_FB_ID: //CCU_SET_PARM_FB 0x0040
|
||||
{
|
||||
msg_CcuSetParmFbMsg s;
|
||||
if(getMsgFromBuff((char *)Buff,s))
|
||||
{
|
||||
if(m_qReceiveCcuSetParmBuffer.size()<QUENUE_SIZE)
|
||||
{
|
||||
double time = MOOSTime();
|
||||
m_qReceiveCcuSetParmBuffer.push(std::make_pair(time, s));
|
||||
}
|
||||
else
|
||||
{
|
||||
// sError.push_back("pushMsgToQueue faile,CcuSetParm buffer is full");
|
||||
LOG_F(INFO, "pushMsgToQueue faile,CcuSetParm buffer is full");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIS_HVBUS_FB_ID: //DIS_HVBUS_FB 0x0020
|
||||
{
|
||||
msg_disHighVolBusFbMsg s;
|
||||
if(getMsgFromBuff((char *)Buff,s))
|
||||
{
|
||||
if(m_qReceiveDisHighVolBusBuffer.size()<QUENUE_SIZE)
|
||||
{
|
||||
double time = MOOSTime();
|
||||
m_qReceiveDisHighVolBusBuffer.push(std::make_pair(time, s));
|
||||
}
|
||||
else
|
||||
{
|
||||
// sError.push_back("pushMsgToQueue faile,DisSysHVBus buffer is full");
|
||||
LOG_F(INFO, "pushMsgToQueue faile,DisSysHVBus buffer is full");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIS_HVBUSA_FB_ID: //DIS_HVBUSA_FB 0x0006
|
||||
{
|
||||
msg_disHighAVolBusFbMsg s;
|
||||
if(getMsgFromBuff((char *)Buff,s))
|
||||
{
|
||||
if(m_qReceiveDisHighAVolBusBuffer.size()<QUENUE_SIZE)
|
||||
{
|
||||
double time = MOOSTime();
|
||||
m_qReceiveDisHighAVolBusBuffer.push(std::make_pair(time, s));
|
||||
}
|
||||
else
|
||||
{
|
||||
// sError.push_back("pushMsgToQueue faile,DisSysHVABus buffer is full");
|
||||
LOG_F(INFO, "pushMsgToQueue faile,DisSysHVABus buffer is full");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIS_HVBUSB_FB_ID: //DIS_HVBUSB_FB 0x0007
|
||||
{
|
||||
msg_disLowMainBusFbMsg s;
|
||||
if(getMsgFromBuff((char *)Buff,s))
|
||||
{
|
||||
if(m_qReceiveDisHighBVolBusBuffer.size()<QUENUE_SIZE)
|
||||
{
|
||||
double time = MOOSTime();
|
||||
m_qReceiveDisHighBVolBusBuffer.push(std::make_pair(time, s));
|
||||
}
|
||||
else
|
||||
{
|
||||
// sError.push_back("pushMsgToQueue faile,DisSysHVBBus buffer is full");
|
||||
LOG_F(INFO, "pushMsgToQueue faile,DisSysHVBBus buffer is full");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIS_LVBUS_FB_ID: //DIS_LVBUS_FB 0x0008
|
||||
{
|
||||
msg_disLowBusFbMsg s;
|
||||
if(getMsgFromBuff((char *)Buff,s))
|
||||
{
|
||||
if(m_qReceiveDisLowBusBuffer.size()<QUENUE_SIZE)
|
||||
{
|
||||
double time = MOOSTime();
|
||||
m_qReceiveDisLowBusBuffer.push(std::make_pair(time, s));
|
||||
}
|
||||
else
|
||||
{
|
||||
// sError.push_back("pushMsgToQueue faile,DisSysLVBus buffer is full");
|
||||
LOG_F(INFO, "pushMsgToQueue faile,DisSysLVBus buffer is full");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool udpComm::clearMsgQueue()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexCcuState);
|
||||
while(!m_qReceiveCcuStateBuffer.empty())
|
||||
m_qReceiveCcuStateBuffer.pop();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexCcuSetParm);
|
||||
while(!m_qReceiveCcuSetParmBuffer.empty())
|
||||
m_qReceiveCcuSetParmBuffer.pop();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexDisHighVolBus);
|
||||
while(!m_qReceiveDisHighVolBusBuffer.empty())
|
||||
m_qReceiveDisHighVolBusBuffer.pop();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexDisHighAVolBus);
|
||||
while(!m_qReceiveDisHighAVolBusBuffer.empty())
|
||||
m_qReceiveDisHighAVolBusBuffer.pop();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexDisHighBVolBus);
|
||||
while(!m_qReceiveDisHighBVolBusBuffer.empty())
|
||||
m_qReceiveDisHighBVolBusBuffer.pop();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexDisLowBus);
|
||||
while(!m_qReceiveDisLowBusBuffer.empty())
|
||||
m_qReceiveDisLowBusBuffer.pop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool udpComm::popMsgFormQueue(double &time,msg_CcuStateFbMsg &m)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexCcuState);
|
||||
if(m_qReceiveCcuStateBuffer.empty())
|
||||
return false;
|
||||
time = m_qReceiveCcuStateBuffer.front().first;
|
||||
m = m_qReceiveCcuStateBuffer.front().second;
|
||||
m_qReceiveCcuStateBuffer.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::popMsgFormQueue(double &time,msg_CcuSetParmFbMsg &m)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexCcuSetParm);
|
||||
if(m_qReceiveCcuSetParmBuffer.empty())
|
||||
return false;
|
||||
time = m_qReceiveCcuSetParmBuffer.front().first;
|
||||
m = m_qReceiveCcuSetParmBuffer.front().second;
|
||||
m_qReceiveCcuSetParmBuffer.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::popMsgFormQueue(double &time,msg_disHighVolBusFbMsg &m)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexDisHighVolBus);
|
||||
if(m_qReceiveDisHighVolBusBuffer.empty())
|
||||
return false;
|
||||
time = m_qReceiveDisHighVolBusBuffer.front().first;
|
||||
m = m_qReceiveDisHighVolBusBuffer.front().second;
|
||||
m_qReceiveDisHighVolBusBuffer.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::popMsgFormQueue(double &time,msg_disHighAVolBusFbMsg &m)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexDisHighAVolBus);
|
||||
if(m_qReceiveDisHighAVolBusBuffer.empty())
|
||||
return false;
|
||||
time = m_qReceiveDisHighAVolBusBuffer.front().first;
|
||||
m = m_qReceiveDisHighAVolBusBuffer.front().second;
|
||||
m_qReceiveDisHighAVolBusBuffer.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::popMsgFormQueue(double &time,msg_disLowMainBusFbMsg &m)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexDisHighBVolBus);
|
||||
if(m_qReceiveDisHighBVolBusBuffer.empty())
|
||||
return false;
|
||||
time = m_qReceiveDisHighBVolBusBuffer.front().first;
|
||||
m = m_qReceiveDisHighBVolBusBuffer.front().second;
|
||||
m_qReceiveDisHighBVolBusBuffer.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::popMsgFormQueue(double &time,msg_disLowBusFbMsg &m)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutexDisLowBus);
|
||||
if(m_qReceiveDisLowBusBuffer.empty())
|
||||
return false;
|
||||
time = m_qReceiveDisLowBusBuffer.front().first;
|
||||
m = m_qReceiveDisLowBusBuffer.front().second;
|
||||
m_qReceiveDisLowBusBuffer.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool udpComm::sendDisSysCmd(const disHighVolBusCmd cmd)
|
||||
{
|
||||
unsigned char* msgBuf;
|
||||
cChecksum cc;
|
||||
msg_disHVBCmd* msg = new msg_disHVBCmd;
|
||||
msg->header.id = DIS_HVBUS_CMD_ID;
|
||||
msg->header.start1 = DIS_MSG_HEAD1;
|
||||
msg->header.start2 = DIS_MSG_HEAD2;
|
||||
//TODO : 阈字节长度固定了,后续会修改
|
||||
msg->header.length = 18;
|
||||
// msg->header.length = sizeof(disHighVolBusCmd);
|
||||
msg->data = cmd;
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBCmd),sizeof(cChecksum));
|
||||
msg->checkCode = cc;
|
||||
try
|
||||
{
|
||||
sendMsg(msgBuf,sizeof(msg_disHVBCmd));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
delete msg;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::sendDisSysCmd(const disHighAVolBusCmd cmd)
|
||||
{
|
||||
unsigned char* msgBuf;
|
||||
cChecksum cc;
|
||||
msg_disHVBACmd* msg = new msg_disHVBACmd;
|
||||
msg->header.id = DIS_HVBUSA_CMD_ID;
|
||||
msg->header.start1 = DIS_MSG_HEAD1;
|
||||
msg->header.start2 = DIS_MSG_HEAD2;
|
||||
//TODO : 阈字节长度固定了,后续会修改
|
||||
msg->header.length = 6;
|
||||
// msg->header.length = sizeof(disHighAVolBusCmd);
|
||||
msg->data = cmd;
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBACmd),sizeof(cChecksum));
|
||||
msg->checkCode = cc;
|
||||
try
|
||||
{
|
||||
sendMsg(msgBuf,sizeof(msg_disHVBACmd));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
delete msg;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::sendDisSysCmd(const disHighBVolBusCmd cmd)
|
||||
{
|
||||
unsigned char* msgBuf;
|
||||
cChecksum cc;
|
||||
msg_disHVBBCmd* msg = new msg_disHVBBCmd;
|
||||
msg->header.id = DIS_HVBUSB_CMD_ID;
|
||||
msg->header.start1 = DIS_MSG_HEAD1;
|
||||
msg->header.start2 = DIS_MSG_HEAD2;
|
||||
//TODO : 阈字节长度固定了,后续会修改
|
||||
msg->header.length = 8;
|
||||
// msg->header.length = sizeof(disHighBVolBusCmd);
|
||||
msg->data = cmd;
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBBCmd),sizeof(cChecksum));
|
||||
msg->checkCode = cc;
|
||||
try
|
||||
{
|
||||
// cout << "=========" <<(int)sizeof(msg_disHVBBCmd) << endl;
|
||||
sendMsg(msgBuf,sizeof(msg_disHVBBCmd));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
delete msg;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::sendDisSysCmd(const disLowBusCmd cmd)
|
||||
{
|
||||
unsigned char* msgBuf;
|
||||
cChecksum cc;
|
||||
msg_disLVBCmd* msg = new msg_disLVBCmd;
|
||||
msg->header.id = DIS_LVBUS_CMD_ID;
|
||||
msg->header.start1 = DIS_MSG_HEAD1;
|
||||
msg->header.start2 = DIS_MSG_HEAD2;
|
||||
//TODO : 阈字节长度固定了,后续会修改
|
||||
msg->header.length = 8;
|
||||
// msg->header.length = sizeof(disLowBusCmd);
|
||||
msg->data = cmd;
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_disLVBCmd),sizeof(cChecksum));
|
||||
// msg->checkCode = static_cast<cChecksum>(cc & 0xFF);
|
||||
msg->checkCode = cc;
|
||||
cout << "cc======disLowBusCmd=============================" << (int) msg->checkCode << endl;
|
||||
try
|
||||
{
|
||||
sendMsg(msgBuf,sizeof(msg_disLVBCmd));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
delete msg;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::sendCcuColCmd(const ccuColCmd cmd)
|
||||
{
|
||||
unsigned char* msgBuf;
|
||||
Checksum cc;
|
||||
msg_CcuColCmdMsg* msg = new msg_CcuColCmdMsg();
|
||||
memset(msg, 0, sizeof(msg_CcuColCmdMsg)); // 初始化所有字段为0
|
||||
|
||||
msg->header.id = CCU_CMD_ID;
|
||||
msg->header.start1 = CCU_UDPMSG_START1;
|
||||
msg->header.start2 = CCU_UDPMSG_START2;
|
||||
msg->header.length = sizeof(ccuColCmd);
|
||||
|
||||
// 确保日期获取成功
|
||||
if(!getDate(msg->date.year,msg->date.month,msg->date.day,
|
||||
msg->date.hour,msg->date.minute,msg->date.second,msg->date.milliseconds)) {
|
||||
LOG_F(ERROR, "Failed to get current date/time");
|
||||
delete msg;
|
||||
return false;
|
||||
}
|
||||
|
||||
msg->cmd = cmd;
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_CcuColCmdMsg));
|
||||
msg->checkCode = static_cast<cChecksum>(cc & 0xFF);
|
||||
|
||||
bool sendResult = false;
|
||||
try {
|
||||
sendResult = sendMsg(msgBuf,sizeof(msg_CcuColCmdMsg));
|
||||
if (!sendResult) {
|
||||
LOG_F(ERROR, "Failed to send CCU command");
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
LOG_F(ERROR, "Exception in sendCcuColCmd: %s", e.what());
|
||||
}
|
||||
|
||||
delete msg;
|
||||
return sendResult;
|
||||
}
|
||||
bool udpComm::sendCcuSetParmCmd(const ccuSetParmCmd cmd)
|
||||
{
|
||||
unsigned char* msgBuf;
|
||||
Checksum cc;
|
||||
msg_CcuSetParmMsg* msg = new msg_CcuSetParmMsg;
|
||||
msg->header.id = CCU_SET_PARM_ID;
|
||||
msg->header.start1 = CCU_UDPMSG_START1;
|
||||
msg->header.start2 = CCU_UDPMSG_START2;
|
||||
msg->header.length = sizeof(ccuSetParmCmd);
|
||||
msg->cmd = cmd;
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_CcuSetParmMsg));
|
||||
msg->checkCode = static_cast<cChecksum>(cc & 0xFF);
|
||||
try
|
||||
{
|
||||
sendMsg(msgBuf,sizeof(msg_CcuSetParmMsg));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
delete msg;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpComm::getDate(unsigned short &year, unsigned char &month, unsigned char &day, unsigned char &hour, unsigned char &minute, unsigned char &second, unsigned char &milliseconds) {
|
||||
// 获取当前时间
|
||||
std::time_t now = std::time(nullptr);
|
||||
if (now == -1) {
|
||||
return false; // 获取时间失败
|
||||
}
|
||||
|
||||
// 转换为本地时间
|
||||
std::tm *localTime = std::localtime(&now);
|
||||
if (!localTime) {
|
||||
return false; // 转换失败
|
||||
}
|
||||
|
||||
// 获取年、月、日、时、分、秒
|
||||
year = localTime->tm_year + 1900; // tm_year 是从 1900 年开始的
|
||||
month = localTime->tm_mon + 1; // tm_mon 是从 0 开始的,0 对应 1 月
|
||||
day = localTime->tm_mday;
|
||||
hour = localTime->tm_hour;
|
||||
minute = localTime->tm_min;
|
||||
second = localTime->tm_sec;
|
||||
|
||||
// 获取毫秒,使用 std::chrono
|
||||
auto now_ms = std::chrono::system_clock::now();
|
||||
auto duration = now_ms.time_since_epoch();
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() % 1000; // 取毫秒部分
|
||||
ms = ms/10;
|
||||
milliseconds = static_cast<unsigned char>(ms);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
#ifndef UDPCOMM__H
|
||||
#define UDPCOMM__H
|
||||
#define UNIX
|
||||
|
||||
#include "ccuUdpMsg.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <string.h>
|
||||
#include "MOOS/libMOOS/Utils/MOOSUtilityFunctions.h"
|
||||
#include "MOOS/libMOOS/Comms/XPCUdpSocket.h"
|
||||
#include <ctime>
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include "../logc/loguru.hpp"
|
||||
using namespace std;
|
||||
#define QUENUE_SIZE 100
|
||||
|
||||
class udpComm {
|
||||
public:
|
||||
udpComm();
|
||||
~udpComm();
|
||||
XPCUdpSocket *udpScoket;
|
||||
string ccuHost;
|
||||
long int ccuPort;
|
||||
|
||||
bool pushMsgToQueue(unsigned char *m);
|
||||
bool clearMsgQueue();
|
||||
|
||||
bool getMsgFromBuff(char *m, msg_CcuStateFbMsg &s);
|
||||
bool getMsgFromBuff(char *m, msg_CcuSetParmFbMsg &s);
|
||||
bool getMsgFromBuff(char *m, msg_disHighVolBusFbMsg &s);
|
||||
bool getMsgFromBuff(char *m, msg_disHighAVolBusFbMsg &s);
|
||||
bool getMsgFromBuff(char *m, msg_disLowMainBusFbMsg &s);
|
||||
bool getMsgFromBuff(char *m, msg_disLowBusFbMsg &s);
|
||||
|
||||
bool popMsgFormQueue(double &time,msg_CcuStateFbMsg &m);
|
||||
bool popMsgFormQueue(double &time,msg_CcuSetParmFbMsg &m);
|
||||
bool popMsgFormQueue(double &time,msg_disHighVolBusFbMsg &m);
|
||||
bool popMsgFormQueue(double &time,msg_disHighAVolBusFbMsg &m);
|
||||
bool popMsgFormQueue(double &time,msg_disLowMainBusFbMsg &m);
|
||||
bool popMsgFormQueue(double &time,msg_disLowBusFbMsg &m);
|
||||
|
||||
bool sendCcuColCmd(const ccuColCmd cmd);
|
||||
bool sendCcuSetParmCmd(const ccuSetParmCmd cmd);
|
||||
|
||||
bool sendDisSysCmd(const disHighVolBusCmd cmd);
|
||||
bool sendDisSysCmd(const disHighAVolBusCmd cmd);
|
||||
bool sendDisSysCmd(const disHighBVolBusCmd cmd);
|
||||
bool sendDisSysCmd(const disLowBusCmd cmd);
|
||||
bool sendMsg(const unsigned char* msg, unsigned int size) {
|
||||
if (!udpScoket) {
|
||||
LOG_F(ERROR, "UDP socket is null in sendMsg");
|
||||
return false;
|
||||
}
|
||||
if (!msg || size == 0) {
|
||||
LOG_F(ERROR, "Invalid message parameters in sendMsg");
|
||||
return false;
|
||||
}
|
||||
if (ccuHost.empty() || ccuPort <= 0) {
|
||||
LOG_F(ERROR, "Invalid CCU address: %s:%d", ccuHost.c_str(), ccuPort);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
udpScoket->iSendMessageTo((void*)msg, size, ccuPort, ccuHost);
|
||||
return true;
|
||||
} catch (const XPCException& e) {
|
||||
LOG_F(ERROR, "XPCException in sendMsg");
|
||||
} catch (const std::exception& e) {
|
||||
LOG_F(ERROR, "Exception in sendMsg: %s", e.what());
|
||||
} catch (...) {
|
||||
LOG_F(ERROR, "Unknown exception in sendMsg");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getMsgId(char *m,unsigned short &id);
|
||||
Checksum calculateChecksum(const unsigned char* data, int size);
|
||||
Checksum calculateChecksum(const unsigned char* data, int dataSize, int checkSize);
|
||||
|
||||
bool getDate(unsigned short &year, unsigned char &month, unsigned char &day, unsigned char &hour, unsigned char &minute, unsigned char &second, unsigned char &milliseconds);
|
||||
|
||||
std::vector<std::string> sError;
|
||||
|
||||
|
||||
std::mutex m_mutexCcuState;
|
||||
std::mutex m_mutexCcuSetParm;
|
||||
std::mutex m_mutexDisHighVolBus;
|
||||
std::mutex m_mutexDisHighAVolBus;
|
||||
std::mutex m_mutexDisHighBVolBus;
|
||||
std::mutex m_mutexDisLowBus;
|
||||
// std::queue<msgWithTime> m_qReceiveCcuStateBuffer;
|
||||
std::queue<std::pair<double,msg_CcuStateFbMsg>> m_qReceiveCcuStateBuffer;
|
||||
std::queue<std::pair<double,msg_CcuSetParmFbMsg>> m_qReceiveCcuSetParmBuffer;
|
||||
std::queue<std::pair<double,msg_disHighVolBusFbMsg>> m_qReceiveDisHighVolBusBuffer;
|
||||
std::queue<std::pair<double,msg_disHighAVolBusFbMsg>> m_qReceiveDisHighAVolBusBuffer;
|
||||
std::queue<std::pair<double,msg_disLowMainBusFbMsg>> m_qReceiveDisHighBVolBusBuffer;
|
||||
std::queue<std::pair<double,msg_disLowBusFbMsg>> m_qReceiveDisLowBusBuffer;
|
||||
|
||||
private:
|
||||
msg_CcuColCmdMsg m_ccuColCmd;
|
||||
msg_CcuSetParmMsg m_ccuSetParmCmd;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
/* json 格式 XC阵控制软件→复合能源管控系统
|
||||
{
|
||||
"xcLowVoltageAdd_int32 " : XX //命令类型:“无命令”0,“申请仪表上电”1,“申请仪表断电”2;类型:int
|
||||
"xcHighVoltageAdd_int32 " : XX, //命令类型:“无命令”0,“申请高压上电”1,“申请高压断电”2;类型:int
|
||||
}
|
||||
*/
|
||||
#ifndef UDETECT_XCVOLTAGE_CMD_H
|
||||
#define UDETECT_XCVOLTAGE_CMD_H
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class uDetect_xcVoltage_cmd
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uDetect_xcVoltage_cmd(){};
|
||||
~uDetect_xcVoltage_cmd(){};
|
||||
|
||||
int xcLowVoltageAdd_int32;
|
||||
int xcHighVoltageAdd_int32;
|
||||
|
||||
static std::string key;
|
||||
|
||||
std::string toJsonString()
|
||||
{
|
||||
Json::Value j;
|
||||
j["xcLowVoltageAdd_int32"] = xcLowVoltageAdd_int32;
|
||||
j["xcHighVoltageAdd_int32"] = xcHighVoltageAdd_int32;
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder.settings_["indentation"] = "";
|
||||
return Json::writeString(builder, j);
|
||||
}
|
||||
bool fromJsonString(std::string jsonString)
|
||||
{
|
||||
Json::CharReaderBuilder readerBuilder;
|
||||
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
|
||||
Json::Value j;
|
||||
std::string errors;
|
||||
LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
bool parsingSuccessful = reader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &j, &errors);
|
||||
if (!parsingSuccessful) {
|
||||
LOG_F(ERROR, "Failed to parse JSON: %s", errors.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (j.isMember("xcLowVoltageAdd_int32") && j.isMember("xcHighVoltageAdd_int32")) {
|
||||
xcLowVoltageAdd_int32 = j["xcLowVoltageAdd_int32"].asInt();
|
||||
xcHighVoltageAdd_int32 = j["xcHighVoltageAdd_int32"].asInt();
|
||||
return true;
|
||||
}
|
||||
LOG_F(ERROR, "JSON does not contain required fields");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
/* json 格式 XC阵控制软件→复合能源管控系统
|
||||
{
|
||||
"zdpVoltageAdd_int32 " : XX //命令类型:“无命令”0,“申请仪表上电”1,“申请仪表断电”2;类型:int
|
||||
}
|
||||
*/
|
||||
#ifndef UDETECT_ZDPVOLTAGE_CMD_H
|
||||
#define UDETECT_ZDPVOLTAGE_CMD_H
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class uDetect_zdpVoltage_cmd
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uDetect_zdpVoltage_cmd(){};
|
||||
~uDetect_zdpVoltage_cmd(){};
|
||||
|
||||
int zdpVoltageAdd_int32;
|
||||
|
||||
static std::string key;
|
||||
|
||||
std::string toJsonString()
|
||||
{
|
||||
Json::Value j;
|
||||
j["zdpVoltageAdd_int32"] = zdpVoltageAdd_int32;
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder.settings_["indentation"] = "";
|
||||
return Json::writeString(builder, j);
|
||||
}
|
||||
bool fromJsonString(std::string jsonString)
|
||||
{
|
||||
Json::CharReaderBuilder readerBuilder;
|
||||
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
|
||||
Json::Value j;
|
||||
std::string errors;
|
||||
LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
bool parsingSuccessful = reader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &j, &errors);
|
||||
if (!parsingSuccessful) {
|
||||
LOG_F(ERROR, "Failed to parse JSON: %s", errors.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (j.isMember("zdpVoltageAdd_int32")) {
|
||||
zdpVoltageAdd_int32 = j["zdpVoltageAdd_int32"].asInt();
|
||||
return true;
|
||||
}
|
||||
LOG_F(ERROR, "JSON does not contain required fields");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
//决策消息
|
||||
#ifndef UDEVICE_DEPTH_ST_H
|
||||
#define UDEVICE_DEPTH_ST_H
|
||||
#include <string>
|
||||
#include "../logc/loguru.hpp"
|
||||
#define DB_TO_PM_DEEPTH "uDevice_depth_st"
|
||||
class uDevice_depthMsg
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
std::string key = "uDevice_depth_st";
|
||||
uDevice_depthMsg(/* args */){};
|
||||
~uDevice_depthMsg(){};
|
||||
int getDepth(const std::string& msgkey, const std::string& msg){
|
||||
if (msgkey != DB_TO_PM_DEEPTH)
|
||||
{
|
||||
LOG_F(WARNING, "消息类型错误 %s", msgkey.c_str());
|
||||
return 0;
|
||||
}
|
||||
int deepth;
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(msg);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
std::cerr << "JSON解析失败: " << errs << std::endl;
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return -1;
|
||||
}
|
||||
// 检查并读取深度数组
|
||||
if (root.isMember("value_array_int32") && root["value_array_int32"].isArray()) {
|
||||
const Json::Value& array = root["value_array_int32"];
|
||||
if (array.size() >= 3) {
|
||||
// 计算三个深度值的平均值
|
||||
deepth = (array[0].asInt() + array[1].asInt() + array[2].asInt()) / 3;
|
||||
} else {
|
||||
LOG_F(WARNING, "深度数组元素不足3个");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
LOG_F(WARNING, "缺少或类型不匹配: value_array_int32");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return deepth;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,531 @@
|
||||
#ifndef UDEVICE_SECDISTSTATE_H
|
||||
#define UDEVICE_SECDISTSTATE_H
|
||||
#include <string>
|
||||
#include <json/json.h>
|
||||
#include "../driver.h"
|
||||
#include "../logc/loguru.hpp"
|
||||
#include <cstring>
|
||||
|
||||
class uDevice_secdistStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uDevice_secdistStateMsg(){};
|
||||
~uDevice_secdistStateMsg(){};
|
||||
std::string key_fb = "uDevice_secdistState_st";
|
||||
std::string key_cmd = "uPower_secdistState_cmd";
|
||||
|
||||
struct DeviceSecdistState
|
||||
{
|
||||
// UNIT1
|
||||
u_int8_t bowCover1;
|
||||
u_int8_t bowCover2;
|
||||
u_int8_t bowCover3;
|
||||
u_int8_t bowCover4;
|
||||
u_int8_t bowCover5;
|
||||
u_int8_t bowCover6;
|
||||
u_int8_t singleBeamSonar1;
|
||||
u_int8_t singleBeamSonar2;
|
||||
u_int8_t singleBeamSonar3;
|
||||
u_int8_t singleBeamSonar4;
|
||||
u_int8_t singleBeamSonar5;
|
||||
u_int8_t singleBeamSonar6;
|
||||
u_int8_t forwardSonar;
|
||||
u_int8_t depth3;
|
||||
u_int8_t soundVeloc;
|
||||
u_int8_t bowRudderServo;
|
||||
u_int8_t bowRudderDeploy;
|
||||
u_int8_t ctd1;
|
||||
u_int8_t waterInject;
|
||||
|
||||
// UNIT2
|
||||
u_int8_t sideSonar;
|
||||
u_int8_t bowWaterInet1;
|
||||
u_int8_t bowWaterInet2;
|
||||
u_int8_t bowWaterInet3;
|
||||
u_int8_t bowWaterInet4;
|
||||
u_int8_t bowWaterInet5;
|
||||
u_int8_t bowWaterInet6;
|
||||
u_int8_t bowWaterInet7;
|
||||
u_int8_t bowWaterInet8;
|
||||
u_int8_t launchControler;
|
||||
u_int8_t electSensor;
|
||||
u_int8_t lowFreqSonar;
|
||||
|
||||
// UNIT3
|
||||
u_int8_t buoyancyAdjust1;
|
||||
u_int8_t buoyancyAdjust2;
|
||||
u_int8_t buoyancyAdjust3;
|
||||
u_int8_t USBL;
|
||||
u_int8_t depth1;
|
||||
u_int8_t commDev;
|
||||
u_int8_t mastLiftingServo;
|
||||
u_int8_t DVL;
|
||||
u_int8_t ADCP;
|
||||
u_int8_t inOutLetWater1;
|
||||
u_int8_t inOutLetWater2;
|
||||
|
||||
// UNIT4
|
||||
u_int8_t singleBeamSonar7;
|
||||
u_int8_t singleBeamSonar8;
|
||||
u_int8_t buoyage;
|
||||
u_int8_t bowThrow;
|
||||
u_int8_t depth2;
|
||||
u_int8_t thruster;
|
||||
u_int8_t dragSonar;
|
||||
u_int8_t haulingMachine;
|
||||
u_int8_t buoyancyAdjust4;
|
||||
u_int8_t buoyancyAdjust5;
|
||||
u_int8_t sternRudderServo1;
|
||||
u_int8_t sternRudderServo2;
|
||||
u_int8_t sternRudderServo3;
|
||||
u_int8_t sternRudderServo4;
|
||||
u_int8_t ctd2;
|
||||
u_int8_t commDevStern;
|
||||
u_int8_t inOutLetWater3;
|
||||
|
||||
// UNIT5
|
||||
u_int8_t secINS;
|
||||
u_int8_t photoSensor;
|
||||
u_int8_t sternThrow;
|
||||
u_int8_t mainINS;
|
||||
} deviceSecdistState;
|
||||
|
||||
|
||||
|
||||
bool parseSecdistStateFromJson(DeviceSecdistState &state, const std::string &strJson){
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder readerBuilder;
|
||||
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
|
||||
std::string errors;
|
||||
|
||||
if(!reader->parse(strJson.c_str(), strJson.c_str() + strJson.length(), &root, &errors)){
|
||||
LOG_F(ERROR, "Failed to parse JSON: %s", errors.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto checkField = [&root](const std::string& field) -> bool {
|
||||
if(!root.isMember(field) || !root[field].isUInt()) {
|
||||
// std::cerr << "Missing or invalid field: " << field << std::endl;
|
||||
// LOG_F(ERROR, "Missing or invalid field: %s", field.c_str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool ok = true;
|
||||
|
||||
// UNIT1
|
||||
if(!checkField("bowCover1_uint8")) ok=false; state.bowCover1 = root["bowCover1_uint8"].asUInt();
|
||||
if(!checkField("bowCover2_uint8")) ok=false; state.bowCover2 = root["bowCover2_uint8"].asUInt();
|
||||
if(!checkField("bowCover3_uint8")) ok=false; state.bowCover3 = root["bowCover3_uint8"].asUInt();
|
||||
if(!checkField("bowCover4_uint8")) ok=false; state.bowCover4 = root["bowCover4_uint8"].asUInt();
|
||||
if(!checkField("bowCover5_uint8")) ok=false; state.bowCover5 = root["bowCover5_uint8"].asUInt();
|
||||
if(!checkField("bowCover6_uint8")) ok=false; state.bowCover6 = root["bowCover6_uint8"].asUInt();
|
||||
if(!checkField("singleBeamSonar1_uint8")) ok=false; state.singleBeamSonar1 = root["singleBeamSonar1_uint8"].asUInt();
|
||||
if(!checkField("singleBeamSonar2_uint8")) ok=false; state.singleBeamSonar2 = root["singleBeamSonar2_uint8"].asUInt();
|
||||
if(!checkField("singleBeamSonar3_uint8")) ok=false; state.singleBeamSonar3 = root["singleBeamSonar3_uint8"].asUInt();
|
||||
if(!checkField("singleBeamSonar4_uint8")) ok=false; state.singleBeamSonar4 = root["singleBeamSonar4_uint8"].asUInt();
|
||||
if(!checkField("singleBeamSonar5_uint8")) ok=false; state.singleBeamSonar5 = root["singleBeamSonar5_uint8"].asUInt();
|
||||
if(!checkField("singleBeamSonar6_uint8")) ok=false; state.singleBeamSonar6 = root["singleBeamSonar6_uint8"].asUInt();
|
||||
if(!checkField("forwardSonar_uint8")) ok=false; state.forwardSonar = root["forwardSonar_uint8"].asUInt();
|
||||
if(!checkField("depth3_uint8")) ok=false; state.depth3 = root["depth3_uint8"].asUInt();
|
||||
if(!checkField("soundVeloc_uint8")) ok=false; state.soundVeloc = root["soundVeloc_uint8"].asUInt();
|
||||
if(!checkField("bowRudderServo_uint8")) ok=false; state.bowRudderServo = root["bowRudderServo_uint8"].asUInt();
|
||||
if(!checkField("bowRudderDeploy_uint8")) ok=false; state.bowRudderDeploy = root["bowRudderDeploy_uint8"].asUInt();
|
||||
if(!checkField("ctd1_uint8")) ok=false; state.ctd1 = root["ctd1_uint8"].asUInt();
|
||||
if(!checkField("waterInject_uint8")) ok=false; state.waterInject = root["waterInject_uint8"].asUInt();
|
||||
|
||||
// UNIT2
|
||||
if(!checkField("sideSonar_uint8")) ok=false; state.sideSonar = root["sideSonar_uint8"].asUInt();
|
||||
if(!checkField("bowWaterInet1_uint8")) ok=false; state.bowWaterInet1 = root["bowWaterInet1_uint8"].asUInt();
|
||||
if(!checkField("bowWaterInet2_uint8")) ok=false; state.bowWaterInet2 = root["bowWaterInet2_uint8"].asUInt();
|
||||
if(!checkField("bowWaterInet3_uint8")) ok=false; state.bowWaterInet3 = root["bowWaterInet3_uint8"].asUInt();
|
||||
if(!checkField("bowWaterInet4_uint8")) ok=false; state.bowWaterInet4 = root["bowWaterInet4_uint8"].asUInt();
|
||||
if(!checkField("bowWaterInet5_uint8")) ok=false; state.bowWaterInet5 = root["bowWaterInet5_uint8"].asUInt();
|
||||
if(!checkField("bowWaterInet6_uint8")) ok=false; state.bowWaterInet6 = root["bowWaterInet6_uint8"].asUInt();
|
||||
if(!checkField("bowWaterInet7_uint8")) ok=false; state.bowWaterInet7 = root["bowWaterInet7_uint8"].asUInt();
|
||||
if(!checkField("bowWaterInet8_uint8")) ok=false; state.bowWaterInet8 = root["bowWaterInet8_uint8"].asUInt();
|
||||
if(!checkField("launchControler_uint8")) ok=false; state.launchControler = root["launchControler_uint8"].asUInt();
|
||||
if(!checkField("electSensor_uint8")) ok=false; state.electSensor = root["electSensor_uint8"].asUInt();
|
||||
if(!checkField("lowFreqSonar_uint8")) ok=false; state.lowFreqSonar = root["lowFreqSonar_uint8"].asUInt();
|
||||
|
||||
// UNIT3
|
||||
if(!checkField("buoyancyAdjust1_uint8")) ok=false; state.buoyancyAdjust1 = root["buoyancyAdjust1_uint8"].asUInt();
|
||||
if(!checkField("buoyancyAdjust2_uint8")) ok=false; state.buoyancyAdjust2 = root["buoyancyAdjust2_uint8"].asUInt();
|
||||
if(!checkField("buoyancyAdjust3_uint8")) ok=false; state.buoyancyAdjust3 = root["buoyancyAdjust3_uint8"].asUInt();
|
||||
if(!checkField("USBL_uint8")) ok=false; state.USBL = root["USBL_uint8"].asUInt();
|
||||
if(!checkField("depth1_uint8")) ok=false; state.depth1 = root["depth1_uint8"].asUInt();
|
||||
if(!checkField("commDev_uint8")) ok=false; state.commDev = root["commDev_uint8"].asUInt();
|
||||
if(!checkField("mastLiftingServo_uint8")) ok=false; state.mastLiftingServo = root["mastLiftingServo_uint8"].asUInt();
|
||||
if(!checkField("DVL_uint8")) ok=false; state.DVL = root["DVL_uint8"].asUInt();
|
||||
if(!checkField("ADCP_uint8")) ok=false; state.ADCP = root["ADCP_uint8"].asUInt();
|
||||
if(!checkField("inOutLetWater1_uint8")) ok=false; state.inOutLetWater1 = root["inOutLetWater1_uint8"].asUInt();
|
||||
if(!checkField("inOutLetWater2_uint8")) ok=false; state.inOutLetWater2 = root["inOutLetWater2_uint8"].asUInt();
|
||||
|
||||
// UNIT4
|
||||
if(!checkField("singleBeamSonar7_uint8")) ok=false; state.singleBeamSonar7 = root["singleBeamSonar7_uint8"].asUInt();
|
||||
if(!checkField("singleBeamSonar8_uint8")) ok=false; state.singleBeamSonar8 = root["singleBeamSonar8_uint8"].asUInt();
|
||||
if(!checkField("buoyage_uint8")) ok=false; state.buoyage = root["buoyage_uint8"].asUInt();
|
||||
if(!checkField("bowThrow_uint8")) ok=false; state.bowThrow = root["bowThrow_uint8"].asUInt();
|
||||
if(!checkField("depth2_uint8")) ok=false; state.depth2 = root["depth2_uint8"].asUInt();
|
||||
if(!checkField("thruster_uint8")) ok=false; state.thruster = root["thruster_uint8"].asUInt();
|
||||
if(!checkField("dragSonar_uint8")) ok=false; state.dragSonar = root["dragSonar_uint8"].asUInt();
|
||||
if(!checkField("haulingMachine_uint8")) ok=false; state.haulingMachine = root["haulingMachine_uint8"].asUInt();
|
||||
if(!checkField("buoyancyAdjust4_uint8")) ok=false; state.buoyancyAdjust4 = root["buoyancyAdjust4_uint8"].asUInt();
|
||||
if(!checkField("buoyancyAdjust5_uint8")) ok=false; state.buoyancyAdjust5 = root["buoyancyAdjust5_uint8"].asUInt();
|
||||
if(!checkField("sternRudderServo1_uint8")) ok=false; state.sternRudderServo1 = root["sternRudderServo1_uint8"].asUInt();
|
||||
if(!checkField("sternRudderServo2_uint8")) ok=false; state.sternRudderServo2 = root["sternRudderServo2_uint8"].asUInt();
|
||||
if(!checkField("sternRudderServo3_uint8")) ok=false; state.sternRudderServo3 = root["sternRudderServo3_uint8"].asUInt();
|
||||
if(!checkField("sternRudderServo4_uint8")) ok=false; state.sternRudderServo4 = root["sternRudderServo4_uint8"].asUInt();
|
||||
if(!checkField("ctd2_uint8")) ok=false; state.ctd2 = root["ctd2_uint8"].asUInt();
|
||||
if(!checkField("commDevStern_uint8")) ok=false; state.commDevStern = root["commDevStern_uint8"].asUInt();
|
||||
if(!checkField("inOutLetWater3_uint8")) ok=false; state.inOutLetWater3 = root["inOutLetWater3_uint8"].asUInt();
|
||||
|
||||
// UNIT5
|
||||
if(!checkField("secINS_uint8")) ok=false; state.secINS = root["secINS_uint8"].asUInt();
|
||||
if(!checkField("photoSensor_uint8")) ok=false; state.photoSensor = root["photoSensor_uint8"].asUInt();
|
||||
if(!checkField("sternThrow_uint8")) ok=false; state.sternThrow = root["sternThrow_uint8"].asUInt();
|
||||
if(!checkField("mainINS_uint8")) ok=false; state.mainINS = root["mainINS_uint8"].asUInt();
|
||||
|
||||
//不检查字段缺失
|
||||
ok = true;
|
||||
return ok;
|
||||
};
|
||||
std::string buildSecdistStateToJson(DeviceSecdistState &state){
|
||||
Json::Value root;
|
||||
|
||||
// UNIT1
|
||||
root["bowCover1_uint8"] = state.bowCover1;
|
||||
root["bowCover2_uint8"] = state.bowCover2;
|
||||
root["bowCover3_uint8"] = state.bowCover3;
|
||||
root["bowCover4_uint8"] = state.bowCover4;
|
||||
root["bowCover5_uint8"] = state.bowCover5;
|
||||
root["bowCover6_uint8"] = state.bowCover6;
|
||||
root["singleBeamSonar1_uint8"] = state.singleBeamSonar1;
|
||||
root["singleBeamSonar2_uint8"] = state.singleBeamSonar2;
|
||||
root["singleBeamSonar3_uint8"] = state.singleBeamSonar3;
|
||||
root["singleBeamSonar4_uint8"] = state.singleBeamSonar4;
|
||||
root["singleBeamSonar5_uint8"] = state.singleBeamSonar5;
|
||||
root["singleBeamSonar6_uint8"] = state.singleBeamSonar6;
|
||||
root["forwardSonar_uint8"] = state.forwardSonar;
|
||||
root["depth3_uint8"] = state.depth3;
|
||||
root["soundVeloc_uint8"] = state.soundVeloc;
|
||||
root["bowRudderServo_uint8"] = state.bowRudderServo;
|
||||
root["bowRudderDeploy_uint8"] = state.bowRudderDeploy;
|
||||
root["ctd1_uint8"] = state.ctd1;
|
||||
root["waterInject_uint8"] = state.waterInject;
|
||||
|
||||
// UNIT2
|
||||
root["sideSonar_uint8"] = state.sideSonar;
|
||||
root["bowWaterInet1_uint8"] = state.bowWaterInet1;
|
||||
root["bowWaterInet2_uint8"] = state.bowWaterInet2;
|
||||
root["bowWaterInet3_uint8"] = state.bowWaterInet3;
|
||||
root["bowWaterInet4_uint8"] = state.bowWaterInet4;
|
||||
root["bowWaterInet5_uint8"] = state.bowWaterInet5;
|
||||
root["bowWaterInet6_uint8"] = state.bowWaterInet6;
|
||||
root["bowWaterInet7_uint8"] = state.bowWaterInet7;
|
||||
root["bowWaterInet8_uint8"] = state.bowWaterInet8;
|
||||
root["launchControler_uint8"] = state.launchControler;
|
||||
root["electSensor_uint8"] = state.electSensor;
|
||||
root["lowFreqSonar_uint8"] = state.lowFreqSonar;
|
||||
|
||||
// UNIT3
|
||||
root["buoyancyAdjust1_uint8"] = state.buoyancyAdjust1;
|
||||
root["buoyancyAdjust2_uint8"] = state.buoyancyAdjust2;
|
||||
root["buoyancyAdjust3_uint8"] = state.buoyancyAdjust3;
|
||||
root["USBL_uint8"] = state.USBL;
|
||||
root["depth1_uint8"] = state.depth1;
|
||||
root["commDev_uint8"] = state.commDev;
|
||||
root["mastLiftingServo_uint8"] = state.mastLiftingServo;
|
||||
root["DVL_uint8"] = state.DVL;
|
||||
root["ADCP_uint8"] = state.ADCP;
|
||||
root["inOutLetWater1_uint8"] = state.inOutLetWater1;
|
||||
root["inOutLetWater2_uint8"] = state.inOutLetWater2;
|
||||
|
||||
// UNIT4
|
||||
root["singleBeamSonar7_uint8"] = state.singleBeamSonar7;
|
||||
root["singleBeamSonar8_uint8"] = state.singleBeamSonar8;
|
||||
root["buoyage_uint8"] = state.buoyage;
|
||||
root["bowThrow_uint8"] = state.bowThrow;
|
||||
root["depth2_uint8"] = state.depth2;
|
||||
root["thruster_uint8"] = state.thruster;
|
||||
root["dragSonar_uint8"] = state.dragSonar;
|
||||
root["haulingMachine_uint8"] = state.haulingMachine;
|
||||
root["buoyancyAdjust4_uint8"] = state.buoyancyAdjust4;
|
||||
root["buoyancyAdjust5_uint8"] = state.buoyancyAdjust5;
|
||||
root["sternRudderServo1_uint8"] = state.sternRudderServo1;
|
||||
root["sternRudderServo2_uint8"] = state.sternRudderServo2;
|
||||
root["sternRudderServo3_uint8"] = state.sternRudderServo3;
|
||||
root["sternRudderServo4_uint8"] = state.sternRudderServo4;
|
||||
root["ctd2_uint8"] = state.ctd2;
|
||||
root["commDevStern_uint8"] = state.commDevStern;
|
||||
root["inOutLetWater3_uint8"] = state.inOutLetWater3;
|
||||
|
||||
// UNIT5
|
||||
root["secINS_uint8"] = state.secINS;
|
||||
root["photoSensor_uint8"] = state.photoSensor;
|
||||
root["sternThrow_uint8"] = state.sternThrow;
|
||||
root["mainINS_uint8"] = state.mainINS;
|
||||
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder.settings_["indentation"] = ""; // 紧凑格式,无缩进
|
||||
return Json::writeString(writerBuilder, root);
|
||||
};
|
||||
|
||||
bool converFromDriverTable(DeviceSecdistState &state,const DriverTable &driver){
|
||||
// UNIT1
|
||||
state.bowCover1 = driver.bowCover1;
|
||||
state.bowCover2 = driver.bowCover2;
|
||||
state.bowCover3 = driver.bowCover3;
|
||||
state.bowCover4 = driver.bowCover4;
|
||||
state.bowCover5 = driver.bowCover5;
|
||||
state.bowCover6 = driver.bowCover6;
|
||||
state.singleBeamSonar1 = driver.singleBeamSonar1;
|
||||
state.singleBeamSonar2 = driver.singleBeamSonar2;
|
||||
state.singleBeamSonar3 = driver.singleBeamSonar3;
|
||||
state.singleBeamSonar4 = driver.singleBeamSonar4;
|
||||
state.singleBeamSonar5 = driver.singleBeamSonar5;
|
||||
state.singleBeamSonar6 = driver.singleBeamSonar6;
|
||||
state.forwardSonar = driver.forwardSonar;
|
||||
state.depth3 = driver.depth3;
|
||||
state.soundVeloc = driver.soundVeloc;
|
||||
state.bowRudderServo = driver.bowRudderServo1;
|
||||
state.bowRudderDeploy = driver.bowRudderDeploy;
|
||||
state.ctd1 = driver.ctd1;
|
||||
state.waterInject = driver.waterInject;
|
||||
|
||||
// UNIT2
|
||||
state.sideSonar = driver.sideSonar;
|
||||
state.bowWaterInet1 = driver.bowWaterInet1;
|
||||
state.bowWaterInet2 = driver.bowWaterInet2;
|
||||
state.bowWaterInet3 = driver.bowWaterInet3;
|
||||
state.bowWaterInet4 = driver.bowWaterInet4;
|
||||
state.bowWaterInet5 = driver.bowWaterInet5;
|
||||
state.bowWaterInet6 = driver.bowWaterInet6;
|
||||
state.bowWaterInet7 = driver.bowWaterInet7;
|
||||
state.bowWaterInet8 = driver.bowWaterInet8;
|
||||
state.launchControler = driver.launchControler;
|
||||
state.electSensor = driver.electSensor;
|
||||
state.lowFreqSonar = driver.lowFreqSonar;
|
||||
|
||||
// UNIT3
|
||||
state.buoyancyAdjust1 = driver.buoyancyAdjust1;
|
||||
state.buoyancyAdjust2 = driver.buoyancyAdjust2;
|
||||
state.buoyancyAdjust3 = driver.buoyancyAdjust3;
|
||||
state.USBL = driver.USBL;
|
||||
state.depth1 = driver.depth1;
|
||||
state.commDev = driver.commMast;
|
||||
state.mastLiftingServo = driver.mastLiftingServo;
|
||||
state.DVL = driver.DVL;
|
||||
state.ADCP = driver.DVL; // Assuming ADCP is same as DVL
|
||||
//出入水传感器1、2共用一个继电器
|
||||
state.inOutLetWater1 = driver.inputWaterSensor1;
|
||||
state.inOutLetWater2 = driver.inputWaterSensor1;
|
||||
// state.inOutLetWater2 = driver.inputWaterSensor2;
|
||||
|
||||
// UNIT4
|
||||
state.singleBeamSonar7 = driver.singleBeamSonar7;
|
||||
state.singleBeamSonar8 = driver.singleBeamSonar8;
|
||||
state.buoyage = driver.buoyage;
|
||||
state.bowThrow = driver.bowThrow;
|
||||
state.depth2 = driver.depth2;
|
||||
state.thruster = driver.thruster;
|
||||
state.haulingMachine = 2; // No corresponding field in DriverTable
|
||||
state.buoyancyAdjust4 = driver.buoyancyAdjust4;
|
||||
state.buoyancyAdjust5 = driver.buoyancyAdjust5;
|
||||
state.sternRudderServo1 = driver.sternRudderServo1;
|
||||
state.sternRudderServo2 = driver.sternRudderServo2;
|
||||
state.sternRudderServo3 = driver.sternRudderServo3;
|
||||
state.sternRudderServo4 = driver.sternRudderServo4;
|
||||
state.ctd2 = driver.ctd2;
|
||||
state.commDevStern = 2; // No corresponding field in DriverTable
|
||||
state.inOutLetWater3 = driver.inputWaterSensor3;
|
||||
|
||||
// UNIT5
|
||||
state.secINS = driver.ins;
|
||||
state.photoSensor = driver.photoSensor;
|
||||
state.sternThrow = driver.sternThrow;
|
||||
state.mainINS = driver.ins;
|
||||
|
||||
// 未映射字段
|
||||
// driver.overDeep1
|
||||
// driver.overDeep2
|
||||
// driver.ntp
|
||||
state.dragSonar = 2; // Assuming dragSonar is same as lowFreqSonar
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool converToDriverTable(const DeviceSecdistState &state, DriverTable &driver){
|
||||
// UNIT1
|
||||
driver.bowCover1 = state.bowCover1;
|
||||
driver.bowCover2 = state.bowCover2;
|
||||
driver.bowCover3 = state.bowCover3;
|
||||
driver.bowCover4 = state.bowCover4;
|
||||
driver.bowCover5 = state.bowCover5;
|
||||
driver.bowCover6 = state.bowCover6;
|
||||
driver.singleBeamSonar1 = state.singleBeamSonar1;
|
||||
driver.singleBeamSonar2 = state.singleBeamSonar2;
|
||||
driver.singleBeamSonar3 = state.singleBeamSonar3;
|
||||
driver.singleBeamSonar4 = state.singleBeamSonar4;
|
||||
driver.singleBeamSonar5 = state.singleBeamSonar5;
|
||||
driver.singleBeamSonar6 = state.singleBeamSonar6;
|
||||
driver.forwardSonar = state.forwardSonar;
|
||||
driver.depth3 = state.depth3;
|
||||
driver.soundVeloc = state.soundVeloc;
|
||||
driver.bowRudderServo1 = state.bowRudderServo;
|
||||
driver.bowRudderServo2 = state.bowRudderServo;
|
||||
driver.bowRudderDeploy = state.bowRudderDeploy;
|
||||
driver.ctd1 = state.ctd1;
|
||||
driver.waterInject = state.waterInject;
|
||||
|
||||
// UNIT2
|
||||
driver.sideSonar = state.sideSonar;
|
||||
driver.bowWaterInet1 = state.bowWaterInet1;
|
||||
driver.bowWaterInet2 = state.bowWaterInet2;
|
||||
driver.bowWaterInet3 = state.bowWaterInet3;
|
||||
driver.bowWaterInet4 = state.bowWaterInet4;
|
||||
driver.bowWaterInet5 = state.bowWaterInet5;
|
||||
driver.bowWaterInet6 = state.bowWaterInet6;
|
||||
driver.bowWaterInet7 = state.bowWaterInet7;
|
||||
driver.bowWaterInet8 = state.bowWaterInet8;
|
||||
driver.launchControler = state.launchControler;
|
||||
driver.electSensor = state.electSensor;
|
||||
driver.lowFreqSonar = state.lowFreqSonar;
|
||||
|
||||
// UNIT3
|
||||
driver.buoyancyAdjust1 = state.buoyancyAdjust1;
|
||||
driver.buoyancyAdjust2 = state.buoyancyAdjust2;
|
||||
driver.buoyancyAdjust3 = state.buoyancyAdjust3;
|
||||
driver.USBL = state.USBL;
|
||||
driver.depth1 = state.depth1;
|
||||
driver.commMast = state.commDev;
|
||||
driver.ntp = 1;
|
||||
driver.mastLiftingServo = state.mastLiftingServo;
|
||||
driver.DVL = state.DVL;
|
||||
driver.inputWaterSensor1 = state.inOutLetWater1;
|
||||
driver.inputWaterSensor2 = state.inOutLetWater2;
|
||||
driver.overDeep1 = (state.depth1 == 1) ? 1 : 0;
|
||||
driver.overDeep2 = (state.depth2 == 1 || state.depth3 == 1) ? 1 : 0;
|
||||
|
||||
// UNIT4
|
||||
driver.singleBeamSonar7 = state.singleBeamSonar7;
|
||||
driver.singleBeamSonar8 = state.singleBeamSonar8;
|
||||
driver.buoyage = state.buoyage;
|
||||
driver.bowThrow = state.bowThrow;
|
||||
driver.depth2 = state.depth2;
|
||||
driver.thruster = state.thruster;
|
||||
driver.buoyancyAdjust4 = state.buoyancyAdjust4;
|
||||
driver.buoyancyAdjust5 = state.buoyancyAdjust5;
|
||||
driver.sternRudderServo1 = state.sternRudderServo1;
|
||||
driver.sternRudderServo2 = state.sternRudderServo2;
|
||||
driver.sternRudderServo3 = state.sternRudderServo3;
|
||||
driver.sternRudderServo4 = state.sternRudderServo4;
|
||||
driver.ctd2 = state.ctd2;
|
||||
driver.inputWaterSensor3 = state.inOutLetWater3;
|
||||
|
||||
// UNIT5
|
||||
driver.ins = state.secINS | state.mainINS;
|
||||
driver.photoSensor = state.photoSensor;
|
||||
driver.sternThrow = state.sternThrow;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string buildMsg(DriverTable &driver){
|
||||
DeviceSecdistState s;
|
||||
converFromDriverTable(s,driver);
|
||||
// std::cout << (int)s.depth1 << std::endl;
|
||||
// std::cout << buildSecdistStateToJson(s) << std::endl;
|
||||
return buildSecdistStateToJson(s);
|
||||
};
|
||||
|
||||
bool parseMsg(const std::string &strJson,DriverTable &driver){
|
||||
DeviceSecdistState s;
|
||||
if(!parseSecdistStateFromJson(s,strJson)){
|
||||
LOG_F(WARNING, "parseSecdistStateFromJson failed");
|
||||
return false;
|
||||
}
|
||||
converToDriverTable(s,driver);
|
||||
return true;
|
||||
};
|
||||
|
||||
std::string buildMsg(DriverTable driver, DriverTable driver_state){
|
||||
DeviceSecdistState s;
|
||||
DriverTable driverCopy = driver;
|
||||
for (size_t i = 0; i < sizeof(DriverTable); ++i) {
|
||||
unsigned char* driverCopyPtr = reinterpret_cast<unsigned char*>(&driverCopy) + i;
|
||||
unsigned char* statePtr = reinterpret_cast<unsigned char*>(&driver_state) + i;
|
||||
if (*driverCopyPtr == *statePtr) {
|
||||
*driverCopyPtr = 2;
|
||||
}
|
||||
}
|
||||
converFromDriverTable(s, driverCopy);
|
||||
// std::cout << (int)s.depth1 << std::endl;
|
||||
// std::cout << buildSecdistStateToJson(s) << std::endl;
|
||||
return buildSecdistStateToJson(s);
|
||||
};
|
||||
|
||||
std::string buildMsg(DriverTable driver, DriverTable driver_state, unsigned int nCheck){
|
||||
static size_t callCount = 0; // 静态变量,记录函数调用次数
|
||||
DeviceSecdistState s;
|
||||
DriverTable driverCopy = driver;
|
||||
if (nCheck > 0 && callCount % nCheck == 0)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(DriverTable); ++i) {
|
||||
unsigned char* driverCopyPtr = reinterpret_cast<unsigned char*>(&driverCopy) + i;
|
||||
unsigned char* statePtr = reinterpret_cast<unsigned char*>(&driver_state) + i;
|
||||
if (*driverCopyPtr == *statePtr) {
|
||||
*driverCopyPtr = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
memset(&driverCopy, 2, sizeof(DriverTable));
|
||||
}
|
||||
callCount ++;
|
||||
converFromDriverTable(s, driverCopy);
|
||||
// std::cout << (int)s.depth1 << std::endl;
|
||||
// std::cout << buildSecdistStateToJson(s) << std::endl;
|
||||
return buildSecdistStateToJson(s);
|
||||
};
|
||||
|
||||
static DriverTable fault_state;
|
||||
std::string buildMsg(DriverTable driver, DriverTable driver_state, DriverTable &driver_fault_state){
|
||||
static size_t f_callCount = 0; // 静态变量,记录函数调用次数
|
||||
unsigned int nCheck = 10;
|
||||
DeviceSecdistState s;
|
||||
DriverTable driverCopy = driver;
|
||||
for (size_t i = 0; i < sizeof(DriverTable); ++i)
|
||||
{
|
||||
unsigned char* driverCopyPtr = reinterpret_cast<unsigned char*>(&driverCopy) + i;
|
||||
unsigned char* statePtr = reinterpret_cast<unsigned char*>(&driver_state) + i;
|
||||
unsigned char* faultStatePtr = reinterpret_cast<unsigned char*>(&driver_fault_state) + i;
|
||||
unsigned char* faultState = reinterpret_cast<unsigned char*>(&fault_state) + i;
|
||||
if (*driverCopyPtr == *statePtr)
|
||||
{
|
||||
*driverCopyPtr = 2;
|
||||
*faultStatePtr = 0;
|
||||
*faultState = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*faultState = *faultState + 1;
|
||||
if(*faultState >= 5)
|
||||
{
|
||||
//只有开启失败才计入故障
|
||||
if(*driverCopyPtr == 1)
|
||||
*faultStatePtr = 1;
|
||||
*faultState = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
f_callCount ++;
|
||||
converFromDriverTable(s, driverCopy);
|
||||
return buildSecdistStateToJson(s);
|
||||
};
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
{
|
||||
"rpm int16": "xxx", // 实际转速,类型:int16_t
|
||||
"voltage_uint16": "xxx", // 电压,类型:uint16_t,单位 V
|
||||
"current_uint16": "xxx", // 电流,类型:uint16_t,单位 A
|
||||
"ctrlTemp_uint16": "xxx", // 控制器温度,类型:uint16_t,单位 °C
|
||||
"motorTemp_uint16": "xxx", // 电机温度,类型:uint16_t,单位 °C
|
||||
"motorTorque_uint16": "xxx", // 电机扭矩,类型:uint16_t,单位 N・m
|
||||
"maxTorque_uint16": "xxx", // 电机最大扭矩,类型:uint16_t,单位 N・m,电机使能时该字段非零,无使能地址报警,含使能整标标识字,00 无故障,按位常量零
|
||||
"error_int64": "xxx" // 见表 [1],类型:int64_t
|
||||
}
|
||||
*/
|
||||
#ifndef UDEVICE_THRUSTER_ST_H
|
||||
#define UDEVICE_THRUSTER_ST_H
|
||||
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
class uDevice_thruster_st
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uDevice_thruster_st(){};
|
||||
~uDevice_thruster_st(){};
|
||||
|
||||
int16_t rpm_int16;
|
||||
uint16_t voltage_uint16;
|
||||
uint16_t current_uint16;
|
||||
uint16_t ctrlTemp_uint16;
|
||||
uint16_t motorTemp_uint16;
|
||||
uint16_t motorTorque_uint16;
|
||||
uint16_t maxTorque_uint16;
|
||||
int64_t error_int64;
|
||||
|
||||
static std::string key;
|
||||
|
||||
std::string toJsonString()
|
||||
{
|
||||
Json::Value j;
|
||||
j["rpm_int16"] = rpm_int16;
|
||||
j["voltage_uint16"] = voltage_uint16;
|
||||
j["current_uint16"] = current_uint16;
|
||||
j["ctrlTemp_uint16"] = ctrlTemp_uint16;
|
||||
j["motorTemp_uint16"] = motorTemp_uint16;
|
||||
j["motorTorque_uint16"] = motorTorque_uint16;
|
||||
j["maxTorque_uint16"] = maxTorque_uint16;
|
||||
j["error_int64"] = static_cast<Json::Int64>(error_int64);
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder.settings_["indentation"] = "";
|
||||
return Json::writeString(builder, j);
|
||||
}
|
||||
|
||||
bool fromJsonString(std::string jsonString)
|
||||
{
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(jsonString);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提取rpm_int16
|
||||
if (root.isMember("rpm_int16") && root["rpm_int16"].isInt()) {
|
||||
rpm_int16 = root["rpm_int16"].asInt();
|
||||
// LOG_F(INFO, "rpm_int16: %d", rpm_int16);
|
||||
}
|
||||
|
||||
// 提取voltage_uint16
|
||||
if (root.isMember("voltage_uint16") && root["voltage_uint16"].isUInt()) {
|
||||
voltage_uint16 = root["voltage_uint16"].asUInt();
|
||||
// LOG_F(INFO, "voltage_uint16: %u", voltage_uint16);
|
||||
}
|
||||
|
||||
// 提取current_uint16
|
||||
if (root.isMember("current_uint16") && root["current_uint16"].isUInt()) {
|
||||
current_uint16 = root["current_uint16"].asUInt();
|
||||
// LOG_F(INFO, "current_uint16: %u", current_uint16);
|
||||
}
|
||||
|
||||
// 提取ctrlTemp_uint16
|
||||
if (root.isMember("ctrlTemp_uint16") && root["ctrlTemp_uint16"].isUInt()) {
|
||||
ctrlTemp_uint16 = root["ctrlTemp_uint16"].asUInt();
|
||||
// LOG_F(INFO, "ctrlTemp_uint16: %u", ctrlTemp_uint16);
|
||||
}
|
||||
|
||||
// 提取motorTemp_uint16
|
||||
if (root.isMember("motorTemp_uint16") && root["motorTemp_uint16"].isUInt()) {
|
||||
motorTemp_uint16 = root["motorTemp_uint16"].asUInt();
|
||||
// LOG_F(INFO, "motorTemp_uint16: %u", motorTemp_uint16);
|
||||
}
|
||||
|
||||
// 提取motorTorque_uint16
|
||||
if (root.isMember("motorTorque_uint16") && root["motorTorque_uint16"].isUInt()) {
|
||||
motorTorque_uint16 = root["motorTorque_uint16"].asUInt();
|
||||
// LOG_F(INFO, "motorTorque_uint16: %u", motorTorque_uint16);
|
||||
}
|
||||
|
||||
// 提取maxTorque_uint16
|
||||
if (root.isMember("maxTorque_uint16") && root["maxTorque_uint16"].isUInt()) {
|
||||
maxTorque_uint16 = root["maxTorque_uint16"].asUInt();
|
||||
// LOG_F(INFO, "maxTorque_uint16: %u", maxTorque_uint16);
|
||||
}
|
||||
|
||||
// 提取error_int64
|
||||
if (root.isMember("error_int64") && root["error_int64"].isInt64()) {
|
||||
error_int64 = root["error_int64"].asInt64();
|
||||
// LOG_F(INFO, "error_int64: %lld", error_int64);
|
||||
}
|
||||
|
||||
// LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef UEXTERNCOMM_SETDEVICESWITCH_CMD_H
|
||||
#define UEXTERNCOMM_SETDEVICESWITCH_CMD_H
|
||||
#include <string>
|
||||
|
||||
class uExternComm_setDeviceSwitchMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
std::string key = "uExternComm_setDeviceSwitch_cmd";
|
||||
|
||||
uExternComm_setDeviceSwitchMsg(/* args */){};
|
||||
~uExternComm_setDeviceSwitchMsg(){};
|
||||
DeviceSwitchCmd getSetDevSwitch(const std::string& key, const std::string& msg)
|
||||
{
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
DeviceSwitchCmd cmd{};
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(msg);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
cmd.id = -1;
|
||||
}
|
||||
|
||||
// 检查并读取设备开关状态
|
||||
if (root.isMember("id_uint8") && root["id_uint8"].isUInt()) {
|
||||
cmd.id = root["id_uint8"].asUInt();
|
||||
} else {
|
||||
cmd.id = -1;
|
||||
LOG_F(WARNING, "缺少或类型不匹配: id_uint8");
|
||||
}
|
||||
if (root.isMember("cmd_uint8") && root["cmd_uint8"].isUInt()) {
|
||||
cmd.cmd = root["cmd_uint8"].asUInt();
|
||||
} else {
|
||||
LOG_F(WARNING, "缺少或类型不匹配: state_bool");
|
||||
}
|
||||
return cmd;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef UEXTERCOMM_SETOPCONDITION_CMD_H
|
||||
#define UEXTERCOMM_SETOPCONDITION_CMD_H
|
||||
#include <string>
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
//外部通信消息
|
||||
#define DB_TO_PM_SETOPCONDITION "uExternComm_setOpCondition_cmd"
|
||||
|
||||
class uExternComm_setOpConditionMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
std::string key = "uExternComm_setOpCondition_cmd";
|
||||
uExternComm_setOpConditionMsg(/* args */){};
|
||||
~uExternComm_setOpConditionMsg(){};
|
||||
|
||||
int getSetOpCondition(const std::string& key, const std::string& msg)
|
||||
{
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(msg);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 检查并读取操作条件
|
||||
if (root.isMember("state_uint8") && root["state_uint8"].isUInt()) {
|
||||
return root["state_uint8"].asUInt();
|
||||
LOG_F(INFO, "上位机指令:opCondition: %d", root["state_uint8"].asUInt());
|
||||
} else {
|
||||
LOG_F(WARNING, "缺少或类型不匹配: opCondition");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef UEXTERCOMM_SETOPMODE_CMD_H
|
||||
#define UEXTERCOMM_SETOPMODE_CMD_H
|
||||
#include <string>
|
||||
#include "../logc/loguru.hpp"
|
||||
|
||||
//外部通信消息
|
||||
#define DB_TO_PM_SETOPMODE "uExternComm_setOpMode_cmd"
|
||||
|
||||
class uExternComm_setOpModeMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
std::string key = "uExternComm_setOpMode_cmd";
|
||||
uExternComm_setOpModeMsg(/* args */){};
|
||||
~uExternComm_setOpModeMsg(){};
|
||||
|
||||
int getSetOpMode(const std::string& msgkey, const std::string& msg){
|
||||
if (msgkey!= key)
|
||||
{
|
||||
LOG_F(WARNING, "消息类型错误 %s", msgkey.c_str());
|
||||
return 0;
|
||||
}
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(msg);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 检查并读取操作模式
|
||||
if (root.isMember("state_uint8") && root["state_uint8"].isUInt()) {
|
||||
return root["state_uint8"].asUInt();
|
||||
} else {
|
||||
LOG_F(WARNING, "缺少或类型不匹配: opMode");
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef UEXTERNCONM_SETPMSYS_H
|
||||
#define UEXTERNCONM_SETPMSYS_H
|
||||
#include <string>
|
||||
#include "../logc/loguru.hpp"
|
||||
#define DB_TO_PM_SETPMSYS "uExternComm_setPowerSystem_cmd"
|
||||
class uExternComm_setPowerSystemMsg
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
std::string key = "uExternComm_setPowerSystem_cmd";
|
||||
uExternComm_setPowerSystemMsg(/* args */){};
|
||||
~uExternComm_setPowerSystemMsg(){};
|
||||
|
||||
int getSetPMSys(const std::string& key, const std::string& msg)
|
||||
{
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(msg);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
std::cerr << "JSON解析失败: " << errs << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 检查并读取电源系统设置
|
||||
if (root.isMember("powerCmd_uint8") && root["powerCmd_uint8"].isUInt()) {
|
||||
return root["powerCmd_uint8"].asUInt();
|
||||
} else {
|
||||
LOG_F(WARNING, "缺少或类型不匹配: powerCmd_uint8");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
{
|
||||
"rpm_int16": "xx", // 期望转速;单位:rpm;类型 int16_t
|
||||
"enable_int16": "xx" // 使能指令,1 - 使能,0 - 去使能。类型 int16_t
|
||||
}
|
||||
*/
|
||||
#ifndef UEXTERNCOMM_SETTHRUSTSPEED_CMD_H
|
||||
#define UEXTERNCOMM_SETTHRUSTSPEED_CMD_H
|
||||
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
class uExternComm_setThrustSpeed_cmd
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uExternComm_setThrustSpeed_cmd(){};
|
||||
~uExternComm_setThrustSpeed_cmd(){};
|
||||
|
||||
int16_t rpm_int16;
|
||||
int16_t enable_int16;
|
||||
|
||||
static std::string key;
|
||||
|
||||
std::string toJsonString()
|
||||
{
|
||||
Json::Value j;
|
||||
j["rpm_int16"] = rpm_int16;
|
||||
j["enable_int16"] = enable_int16;
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder.settings_["indentation"] = "";
|
||||
return Json::writeString(builder, j);
|
||||
}
|
||||
|
||||
bool fromJsonString(std::string jsonString)
|
||||
{
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(jsonString);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提取rpm_int16
|
||||
if (root.isMember("rpm_int16") && root["rpm_int16"].isInt()) {
|
||||
rpm_int16 = root["rpm_int16"].asInt();
|
||||
// LOG_F(INFO, "rpm_int16: %d", rpm_int16);
|
||||
}
|
||||
|
||||
// 提取enable_int16
|
||||
if (root.isMember("enable_int16") && root["enable_int16"].isInt()) {
|
||||
enable_int16 = root["enable_int16"].asInt();
|
||||
// LOG_F(INFO, "enable_int16: %d", enable_int16);
|
||||
}
|
||||
|
||||
// LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef UPLAN_PLANSTOP_CMD_H
|
||||
#define UPLAN_PLANSTOP_CMD_H
|
||||
#include <string>
|
||||
#include "../logc/loguru.hpp"
|
||||
#define DB_TO_PM_TASKSTOP "uPlan_planStop_st"
|
||||
class uPlan_planStopMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
std::string key = "uPlan_planStop_st";
|
||||
uPlan_planStopMsg(/* args */){};
|
||||
~uPlan_planStopMsg(){};
|
||||
bool getTaskStop(const std::string& key, const std::string& msg) {
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(msg);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查op_int32字段
|
||||
if (root.isMember("op_int32") && root["op_int32"].isInt()) {
|
||||
return root["op_int32"].asInt() == 1;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef UPPERCOMMMANAGER_H
|
||||
#define UPPERCOMMMANAGER_H
|
||||
#include <string>
|
||||
#include "../pmSysvariable.h"
|
||||
#include "../logc/loguru.hpp"
|
||||
//决策消息
|
||||
#define DB_TO_PM_MISSION "uPlan_taskStart_st"
|
||||
|
||||
class uPlan_taskStartMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
std::string key = "uPlan_taskStart_st";
|
||||
uPlan_taskStartMsg(/* args */){};
|
||||
~uPlan_taskStartMsg(){};
|
||||
|
||||
MissionState getMission(const std::string& key, const std::string& msg) {
|
||||
MissionState mission{};
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(msg);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
std::cerr << "JSON解析失败: " << errs << std::endl;
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return mission;
|
||||
}
|
||||
|
||||
// 提取taskType_str
|
||||
if (root.isMember("taskType_str") && root["taskType_str"].isString()) {
|
||||
mission.type = TaskType::fromString(root["taskType_str"].asString());
|
||||
LOG_F(INFO, "taskType: %d", mission.type, root["taskType_str"].asString());
|
||||
}
|
||||
|
||||
// 提取balanceEnabled_bool
|
||||
if (root.isMember("balanceEnabled_bool") && root["balanceEnabled_bool"].isBool()) {
|
||||
mission.enableBuoyancyAdjustment = root["balanceEnabled_bool"].asBool();
|
||||
LOG_F(INFO, "balanceEnabled_bool: %d", mission.enableBuoyancyAdjustment);
|
||||
}
|
||||
|
||||
// 提取bowRudderUnfold_bool
|
||||
if (root.isMember("bowRudderUnfold_bool") && root["bowRudderUnfold_bool"].isBool()) {
|
||||
mission.enableBowRudder = root["bowRudderUnfold_bool"].asBool();
|
||||
LOG_F(INFO, "bowRudderUnfold_bool: %d", mission.enableBowRudder);
|
||||
}
|
||||
|
||||
|
||||
return mission;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifndef U_POWER_CURRENTSTATE_ST_H
|
||||
#define U_POWER_CURRENTSTATE_ST_H
|
||||
#include "../driver.h"
|
||||
#include "string"
|
||||
#include "json/json.h"
|
||||
#include <bitset>
|
||||
|
||||
class uPower_currentStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uPower_currentStateMsg() {
|
||||
memset(&state, 0, sizeof(state));
|
||||
};
|
||||
~uPower_currentStateMsg() {};
|
||||
std::string key = "uPower_currentState_st";
|
||||
|
||||
pmState state;
|
||||
std::string buildMsg(pmState state)
|
||||
{
|
||||
// 状态赋值
|
||||
Json::Value currentBusState;
|
||||
currentBusState["HVBpowerBusVol_uint16"] = state.bus1State.powerBusVoltage;
|
||||
currentBusState["HVBdcDc5Cur_uint16"] = state.bus1State.dcDc5ModuleCurrent;
|
||||
currentBusState["HVBpowerBusCur_uint16"] = state.bus1State.powerBusCurrent;
|
||||
currentBusState["HVBbusAVol_uint16"] = state.bus1State.busbarAVoltage;
|
||||
currentBusState["HVBmotorCur_uint16"] = state.bus1State.propulsionMotorControlBoxCurrent;
|
||||
currentBusState["HVBbusACur_uint16"] = state.bus1State.busbarACurrent;
|
||||
currentBusState["HVBbatGroupCur_uint16"] = state.bus1State.lithiumBatteryGroupMeterCurrent;
|
||||
currentBusState["HVBbowHVolDisBoxCur_uint16"] = state.bus1State.bowHighVoltageDistributionBoxCurrent;
|
||||
currentBusState["HVBFTDev45Cur_uint16"] = state.bus1State.sternFTDevice45Current;
|
||||
currentBusState["HVBtyzCur_uint16"] = state.bus1State.tyzReservedSwitchCurrent;
|
||||
currentBusState["HVBsternRud1Cur_uint16"] = state.bus1State.sternRudderSwitch1Current;
|
||||
currentBusState["HVBreservedCur1_uint16"] = state.bus1State.reservedCurrent1;
|
||||
currentBusState["HVBsternRud2Cur_uint16"] = state.bus1State.sternRudderSwitch2Current;
|
||||
currentBusState["HVBreservedCur2_uint16"] = state.bus1State.reservedCurrent2;
|
||||
currentBusState["HVBfbCur_uint16"] = state.bus1State.fbReservedSwitchCurrent;
|
||||
currentBusState["HVBreservedCur3_uint16"] = state.bus1State.reservedCurrent3;
|
||||
|
||||
currentBusState["HVABbusBVol_uint16"] = state.bus2State.busbarBVoltage;
|
||||
currentBusState["HVABbusBCur_uint16"] = state.bus2State.busbarBCurrent;
|
||||
currentBusState["HVABFTDev123Cur_uint16"] = state.bus2State.bowFTDevice123Current;
|
||||
currentBusState["HVABactCur_uint16"] = state.bus2State.actuatorCurrent;
|
||||
currentBusState["HVABmastSteGeaCur_uint16"] = state.bus2State.mastSteeringGearControlBoxCurrent;
|
||||
currentBusState["HVABxczCur_uint16"] = state.bus2State.xczCurrent;
|
||||
currentBusState["HVABbowRudCur_uint16"] = state.bus2State.bowRudderControlBoxCurrent;
|
||||
currentBusState["HVABopenWaterCur_uint16"] = state.bus2State.openWaterCoverStartCylinderCurrent;
|
||||
|
||||
currentBusState["HVBBinsBusVol_uint16"] = state.bus3State.instrumentBusbarVoltage;
|
||||
currentBusState["HVBBbowLowVolDisBoxCur_uint16"] = state.bus3State.bowLowVoltageDistributionBoxCurrent;
|
||||
currentBusState["HVBBdcC1InsCur_uint16"] = state.bus3State.dcC1InstrumentDC48VCurrent;
|
||||
currentBusState["HVBBreservedCur1_uint16"] = state.bus3State.reservedCurrent1;
|
||||
currentBusState["HVBBemerBatCur_uint16"] = state.bus3State.emergencyLithiumBatteryGroup2Current;
|
||||
currentBusState["HVBBbatInsCur_uint16"] = state.bus3State.lithiumBatteryGroupInstrumentCurrent;
|
||||
currentBusState["HVBBunit4Cur_uint16"] = state.bus3State.unit4InstrumentDC48VCurrent;
|
||||
currentBusState["HVBBreservedCur2_uint16"] = state.bus3State.reservedCurrent2;
|
||||
currentBusState["HVBBemer2BusVol_uint16"] = state.bus3State.emergency2BusbarVoltage;
|
||||
currentBusState["HVBBCCUCur_uint16"] = state.bus3State.compositeEnergyManagementSystemEmergencyDC48VCurrent;
|
||||
currentBusState["HVBBFCSSecurSysCur_uint16"] = state.bus3State.fuelCellSecuritySystemEmergencyDC48VCurrent;
|
||||
currentBusState["HVBBplcCur_uint16"] = state.bus3State.plcControlPowerCurrent;
|
||||
|
||||
currentBusState["LVBinsBusVol_uint16"] = state.bus4State.instrumentBusbarVoltage;
|
||||
currentBusState["LVBBinsBusCur_uint16"] = state.bus4State.instrumentBusbarCurrent;
|
||||
currentBusState["LVBBunit1Cur_uint16"] = state.bus4State.unit1Current;
|
||||
currentBusState["LVBBunit2Cur_uint16"] = state.bus4State.unit2Current;
|
||||
currentBusState["LVBBunit3Cur_uint16"] = state.bus4State.unit3Current;
|
||||
currentBusState["LVBBunit5Cur_uint16"] = state.bus4State.unit5Current;
|
||||
currentBusState["LVBBbowPZDevCur_uint16"] = state.bus4State.bowPZDeviceCurrent;
|
||||
currentBusState["LVBBemerBatCur_uint16"] = state.bus4State.emergencyLithiumBatteryGroup1Current;
|
||||
currentBusState["LVBBemerBusVol_uint16"] = state.bus4State.emergency1BusbarVoltage;
|
||||
|
||||
// 转化为json格式
|
||||
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder.settings_["indentation"] = "";
|
||||
return Json::writeString(writerBuilder, currentBusState);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,203 @@
|
||||
#ifndef U_POWER_DISSYSSTATE_ST_H
|
||||
#define U_POWER_DISSYSSTATE_ST_H
|
||||
#include "../driver.h"
|
||||
#include "string"
|
||||
#include "json/json.h"
|
||||
#include <bitset>
|
||||
#include "../pmSysvariable.h"
|
||||
#include "../systemData.h"
|
||||
class uPower_disSysStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uPower_disSysStateMsg() {
|
||||
// state_of_bus_hv = {};
|
||||
// state_of_bus_hv_a = {};
|
||||
// state_of_bus_lv = {};
|
||||
// state_of_bus_lv_a = {};
|
||||
};
|
||||
~uPower_disSysStateMsg() {};
|
||||
std::string key = "uPower_disSysState_st";
|
||||
|
||||
struct state_of_bus_hv
|
||||
{
|
||||
// 使用 std::bitset 存储 16 位继电器状态
|
||||
std::bitset<16> relay_states;
|
||||
|
||||
// 燃料电池断路器
|
||||
void set_fuel_cell_breaker(bool state) { relay_states[0] = state; }
|
||||
// 动力锂电池断路器
|
||||
void set_power_lithium_battery_breaker(bool state) { relay_states[1] = state; }
|
||||
// 推进电机断路器
|
||||
void set_propulsion_motor_breaker(bool state) { relay_states[2] = state; }
|
||||
// 锂电池组仪表断路器
|
||||
void set_lithium_battery_meter_breaker(bool state) { relay_states[3] = state; }
|
||||
// DC/DC5模块断路器
|
||||
void set_dc_dc5_module_breaker(bool state) { relay_states[4] = state; }
|
||||
// 艏部高压配电箱断路器
|
||||
void set_bow_high_voltage_box_breaker(bool state) { relay_states[5] = state; }
|
||||
// 艉部FT装置4/5断路器
|
||||
void set_stern_ft_device_breaker(bool state) { relay_states[6] = state; }
|
||||
// 艉舵开关1断路器
|
||||
void set_stern_rudder_switch1_breaker(bool state) { relay_states[7] = state; }
|
||||
// 艉舵开关2断路器
|
||||
void set_stern_rudder_switch2_breaker(bool state) { relay_states[8] = state; }
|
||||
// FB预留断路器
|
||||
void set_fb_reserved_breaker(bool state) { relay_states[9] = state; }
|
||||
// TYZ预留断路器
|
||||
void set_tyz_reserved_breaker(bool state) { relay_states[10] = state; }
|
||||
// 预留断路器
|
||||
void set_reserved_breaker(bool state) { relay_states[11] = state; }
|
||||
// 初始化后 16 - 12 位为 0
|
||||
state_of_bus_hv() {
|
||||
relay_states.reset(12);
|
||||
relay_states.reset(13);
|
||||
relay_states.reset(14);
|
||||
relay_states.reset(15);
|
||||
}
|
||||
} m_state_of_bus_hv;
|
||||
|
||||
struct state_of_bus_hv_a
|
||||
{
|
||||
std::bitset<16> relay_states;
|
||||
// 艏部FT装置1 - 3 断路器
|
||||
void set_bow_ft_device_1_3_breaker(bool state) { relay_states[0] = state; }
|
||||
// 启闭机构断路器
|
||||
void set_opening_closing_mechanism_breaker(bool state) { relay_states[1] = state; }
|
||||
// 桅杆舵机控制箱断路器
|
||||
void set_mast_servo_control_box_breaker(bool state) { relay_states[2] = state; }
|
||||
// XCZ 断路器
|
||||
void set_xcz_breaker(bool state) { relay_states[3] = state; }
|
||||
// 艏舵控制箱断路器
|
||||
void set_bow_rudder_control_box_breaker(bool state) { relay_states[4] = state; }
|
||||
// 敞水盖启动电缸断路器
|
||||
void set_open_water_cover_actuator_breaker(bool state) { relay_states[5] = state; }
|
||||
// 初始化后 6 - 15 位为 0
|
||||
state_of_bus_hv_a() {
|
||||
for (int i = 6; i < 16; ++i) {
|
||||
relay_states.reset(i);
|
||||
}
|
||||
}
|
||||
}m_state_of_bus_hv_a;
|
||||
|
||||
struct state_of_bus_lv
|
||||
{
|
||||
std::bitset<16> relay_states;
|
||||
// 锂电池组(仪表)断路器
|
||||
void set_lithium_battery_group_meter_breaker(bool state) { relay_states[0] = state; }
|
||||
// 艏部低压配电箱断路器
|
||||
void set_bow_low_voltage_box_breaker(bool state) { relay_states[1] = state; }
|
||||
// UNIT4仪表DC48V断路器
|
||||
void set_unit4_meter_dc48v_breaker(bool state) { relay_states[2] = state; }
|
||||
// DC - C1直流配电板断路器
|
||||
void set_dc_c1_dc_distribution_board_breaker(bool state) { relay_states[3] = state; }
|
||||
// 预留断路器
|
||||
void set_reserved_breaker_1(bool state) { relay_states[4] = state; }
|
||||
// 预留断路器
|
||||
void set_reserved_breaker_2(bool state) { relay_states[5] = state; }
|
||||
// 应急锂电池组2断路器
|
||||
void set_emergency_lithium_battery_group_2_breaker(bool state) { relay_states[6] = state; }
|
||||
// 初始化后 7 - 15 位为 0
|
||||
state_of_bus_lv() {
|
||||
for (int i = 7; i < 16; ++i) {
|
||||
relay_states.reset(i);
|
||||
}
|
||||
}
|
||||
}m_state_of_bus_lv;
|
||||
|
||||
struct state_of_bus_lv_a
|
||||
{
|
||||
// 使用 std::bitset 存储 16 位继电器状态
|
||||
std::bitset<16> relay_states;
|
||||
// UNIT1断路器
|
||||
void set_unit1_breaker(bool state) { relay_states[0] = state; }
|
||||
// UNIT2断路器
|
||||
void set_unit2_breaker(bool state) { relay_states[1] = state; }
|
||||
// UNIT3断路器
|
||||
void set_unit3_breaker(bool state) { relay_states[2] = state; }
|
||||
// UNIT5断路器
|
||||
void set_unit5_breaker(bool state) { relay_states[3] = state; }
|
||||
// 艏部PZ装置断路器
|
||||
void set_bow_pz_device_breaker(bool state) { relay_states[4] = state; }
|
||||
// 预留断路器
|
||||
void set_reserved_breaker_1(bool state) { relay_states[5] = state; }
|
||||
// 预留断路器
|
||||
void set_reserved_breaker_2(bool state) { relay_states[6] = state; }
|
||||
// 应急锂电池组1断路器
|
||||
void set_emergency_lithium_battery_group_1_breaker(bool state) { relay_states[7] = state; }
|
||||
// 初始化后 8 - 15 位为 0
|
||||
state_of_bus_lv_a() {
|
||||
for (int i = 8; i < 16; ++i) {
|
||||
relay_states.reset(i);
|
||||
}
|
||||
}
|
||||
}m_state_of_bus_lv_a;
|
||||
|
||||
// std::string buildMsg(SystemData data,disSysBreakerList currentDisBreakerState)
|
||||
std::string buildMsg(const SystemData& data,disSysBreakerList currentDisBreakerState)
|
||||
{
|
||||
//构建配电系统状态报告
|
||||
Json::Value dis;
|
||||
// disBus1Breaker dis1 = currentDisBreakerState.bus1Breaker;
|
||||
m_state_of_bus_hv.set_fuel_cell_breaker((data.power_bus_status.fuelCellCircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_power_lithium_battery_breaker((data.power_bus_status.powerLithiumBatteryCircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_propulsion_motor_breaker((data.power_bus_status.propulsionMotorCircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_lithium_battery_meter_breaker((data.power_bus_status.lithiumBatteryGroupInstrumentCircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_dc_dc5_module_breaker((data.power_bus_status.dcDc5ModuleCircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_bow_high_voltage_box_breaker((data.power_bus_status.bowHighVoltageDistributionBoxCircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_stern_ft_device_breaker((data.power_bus_status.sternFTDevice45CircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_stern_rudder_switch1_breaker((data.power_bus_status.sternRudderSwitch1CircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_stern_rudder_switch2_breaker((data.power_bus_status.sternRudderSwitch2CircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_fb_reserved_breaker((data.power_bus_status.fbReservedCircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_tyz_reserved_breaker((data.power_bus_status.tyzReservedCircuitBreaker == 1));
|
||||
m_state_of_bus_hv.set_reserved_breaker((data.power_bus_status.reservedCircuitBreaker == 1));
|
||||
dis["HVolABusBreaker_uint16"] = m_state_of_bus_hv.relay_states.to_ulong();
|
||||
|
||||
|
||||
m_state_of_bus_hv_a.set_bow_ft_device_1_3_breaker((data.power_a_bus_status.bowFTDevice123CircuitBreaker == 1));
|
||||
m_state_of_bus_hv_a.set_opening_closing_mechanism_breaker((data.power_a_bus_status.actuatorCircuitBreaker == 1));
|
||||
m_state_of_bus_hv_a.set_mast_servo_control_box_breaker((data.power_a_bus_status.mastSteeringGearControlBoxCircuitBreaker == 1));
|
||||
m_state_of_bus_hv_a.set_xcz_breaker((data.power_a_bus_status.xczCircuitBreaker == 1));
|
||||
m_state_of_bus_hv_a.set_bow_rudder_control_box_breaker((data.power_a_bus_status.bowRudderControlBoxCircuitBreaker == 1));
|
||||
m_state_of_bus_hv_a.set_open_water_cover_actuator_breaker((data.power_a_bus_status.openWaterCoverStartCylinderCircuitBreaker == 1));
|
||||
dis["HVolBBusBreaker_uint16"] = m_state_of_bus_hv_a.relay_states.to_ulong();
|
||||
|
||||
m_state_of_bus_lv.set_bow_low_voltage_box_breaker((data.instrument_main_bus_status.bowLowVoltageDistributionBoxCircuitBreaker == 1));
|
||||
m_state_of_bus_lv.set_dc_c1_dc_distribution_board_breaker((data.instrument_main_bus_status.dcC1DCDistributionPanelCircuitBreaker == 1));
|
||||
m_state_of_bus_lv.set_unit4_meter_dc48v_breaker((data.instrument_main_bus_status.unit4InstrumentDC48VCircuitBreaker == 1));
|
||||
m_state_of_bus_lv.set_lithium_battery_group_meter_breaker((data.instrument_main_bus_status.lithiumBatteryGroupInstrumentCircuitBreaker == 1));
|
||||
m_state_of_bus_lv.set_emergency_lithium_battery_group_2_breaker((data.instrument_main_bus_status.emergencyLithiumBatteryGroup2CircuitBreaker == 1));
|
||||
m_state_of_bus_lv.set_reserved_breaker_1((data.instrument_main_bus_status.reservedCircuitBreaker1 == 1));
|
||||
m_state_of_bus_lv.set_reserved_breaker_2((data.instrument_main_bus_status.reservedCircuitBreaker2 == 1));
|
||||
dis["HVolBusBreaker_uint16"] = m_state_of_bus_lv.relay_states.to_ulong();
|
||||
|
||||
|
||||
m_state_of_bus_lv_a.set_unit1_breaker((data.instrument_bus_status.unit1CircuitBreaker == 1));
|
||||
m_state_of_bus_lv_a.set_unit2_breaker((data.instrument_bus_status.unit2CircuitBreaker == 1));
|
||||
m_state_of_bus_lv_a.set_unit3_breaker((data.instrument_bus_status.unit3CircuitBreaker == 1));
|
||||
m_state_of_bus_lv_a.set_unit5_breaker((data.instrument_bus_status.unit5CircuitBreaker == 1));
|
||||
m_state_of_bus_lv_a.set_bow_pz_device_breaker((data.instrument_bus_status.bowPZDeviceCircuitBreaker == 1));
|
||||
m_state_of_bus_lv_a.set_reserved_breaker_1((data.instrument_bus_status.reservedCircuitBreaker1 == 1));
|
||||
m_state_of_bus_lv_a.set_reserved_breaker_2((data.instrument_bus_status.reservedCircuitBreaker2 == 1));
|
||||
m_state_of_bus_lv_a.set_emergency_lithium_battery_group_1_breaker((data.instrument_bus_status.emergencyLithiumBatteryGroup1CircuitBreaker == 1));
|
||||
dis["LVolBusBreaker_uint16"] = m_state_of_bus_lv_a.relay_states.to_ulong();
|
||||
|
||||
//构建配电系统故障码
|
||||
Json::Value faultCodeDis_array = Json::Value(Json::arrayValue);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(data.faultCodeMutex);
|
||||
for(auto val : data.disSysFaultCode)
|
||||
{
|
||||
faultCodeDis_array.append(val);
|
||||
}
|
||||
}
|
||||
dis["faultCode_array"] = faultCodeDis_array;
|
||||
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder.settings_["indentation"] = "";
|
||||
return Json::writeString(writerBuilder, dis);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,220 @@
|
||||
#ifndef U_POWER_EQUINSSTATE_H
|
||||
#define U_POWER_EQUINSSTATE_H
|
||||
#include "../driver.h"
|
||||
#include "string"
|
||||
#include "json/json.h"
|
||||
#include <bitset>
|
||||
class uPower_equInsStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uPower_equInsStateMsg() {
|
||||
// 初始化成员变量
|
||||
//state全部初始化为0
|
||||
memset(&state, 0, sizeof(state));
|
||||
}; // 添加默认构造函数实现
|
||||
~uPower_equInsStateMsg() {}; // 添加析构函数实现
|
||||
std::string key = "uPower_equInsState_fb";
|
||||
|
||||
struct SensorState
|
||||
{
|
||||
unsigned int singleBeamSonar1 : 1; // 单波束声呐1
|
||||
unsigned int singleBeamSonar2 : 1; // 单波束声呐2
|
||||
unsigned int singleBeamSonar3 : 1; // 单波束声呐3
|
||||
unsigned int singleBeamSonar4 : 1; // 单波束声呐4
|
||||
unsigned int singleBeamSonar5 : 1; // 单波束声呐5
|
||||
unsigned int singleBeamSonar6 : 1; // 单波束声呐6
|
||||
unsigned int singleBeamSonar7 : 1; // 单波束声呐7
|
||||
unsigned int singleBeamSonar8 : 1; // 单波束声呐8
|
||||
unsigned int forwardSonar : 1; // 前视声呐
|
||||
unsigned int ctd1 : 1; // CTD1
|
||||
unsigned int ctd2 : 1; // CTD2
|
||||
unsigned int soundVelocityMeter : 1; // 声速仪
|
||||
unsigned int ntp : 1; // 深度计
|
||||
unsigned int depthMeter1 : 1; // 深度计1
|
||||
unsigned int depthMeter2 : 1; // 深度计2
|
||||
unsigned int depthMeter3 : 1; // 深度计3
|
||||
};
|
||||
struct ActuatorState
|
||||
{
|
||||
unsigned int openCloseMechanism1 : 1; // bit 0 启闭机构1
|
||||
unsigned int openCloseMechanism2 : 1; // bit 1 启闭机构2
|
||||
unsigned int openCloseMechanism3 : 1; // bit 2 启闭机构3
|
||||
unsigned int openCloseMechanism4 : 1; // bit 3 启闭机构4
|
||||
unsigned int openCloseMechanism5 : 1; // bit 4 启闭机构5
|
||||
unsigned int openCloseMechanism6 : 1; // bit 5 启闭机构6
|
||||
unsigned int reserved1 : 2; // bit 6-7 保留
|
||||
unsigned int openWaterMechanism1 : 1; // bit 8 敞水机构1
|
||||
unsigned int openWaterMechanism2 : 1; // bit 9 敞水机构2
|
||||
unsigned int openWaterMechanism3 : 1; // bit 10 敞水机构3
|
||||
unsigned int openWaterMechanism4 : 1; // bit 11 敞水机构4
|
||||
unsigned int openWaterMechanism5 : 1; // bit 12 敞水机构5
|
||||
unsigned int openWaterMechanism6 : 1; // bit 13 敞水机构6
|
||||
unsigned int openWaterMechanism7 : 1; // bit 14 敞水机构7
|
||||
unsigned int openWaterMechanism8 : 1; // bit 15 敞水机构8
|
||||
};
|
||||
|
||||
struct MotionState
|
||||
{
|
||||
unsigned int sternRudder1 : 1; // bit 0 艉部舵机1
|
||||
unsigned int sternRudder2 : 1; // bit 1 艉部舵机2
|
||||
unsigned int sternRudder3 : 1; // bit 2 艉部舵机3
|
||||
unsigned int sternRudder4 : 1; // bit 3 艉部舵机4
|
||||
unsigned int bowRudder : 1; // bit 4 艏舵电缸
|
||||
unsigned int waterInjection : 1; // bit 5 注水机构
|
||||
unsigned int propulsionMotor : 1; // bit 6 推进电机
|
||||
unsigned int buoyancyAdjust1 : 1; // bit 7 浮调机构(艏部)1
|
||||
unsigned int buoyancyAdjust2 : 1; // bit 8 浮调机构(艏部)2
|
||||
unsigned int buoyancyAdjust3 : 1; // bit 9 浮调机构(艏部)3
|
||||
unsigned int buoyancyAdjust4 : 1; // bit 10 浮调机构(艉部)4
|
||||
unsigned int buoyancyAdjust5 : 1; // bit 11 浮调机构(艉部)5
|
||||
unsigned int DVL : 1; // bit 12 DVL
|
||||
unsigned int INS : 1; // bit 13 惯导系统
|
||||
unsigned int bowRudderLeft : 1; // bit 14 艏舵左舵机
|
||||
unsigned int bowRudderRight : 1; // bit 15 艏右舵舵机
|
||||
};
|
||||
struct LoadcommState
|
||||
{
|
||||
unsigned int payloadControl : 1; // bit 0 载荷发控
|
||||
unsigned int optMast : 1; // bit 1 光电桅杆
|
||||
unsigned int emMast : 1; // bit 2 电磁桅杆
|
||||
unsigned int reserved1 : 1; // bit 3 保留
|
||||
unsigned int sideSonar : 1; // bit 4 舷侧声纳
|
||||
unsigned int towedSonar : 1; // bit 5 拖曳声纳
|
||||
unsigned int reserved2 : 2; // bit 6-7 保留
|
||||
unsigned int commMast : 1; // bit 8 通信桅杆
|
||||
unsigned int midLowFreqSonar : 1; // bit 9 中低频声呐
|
||||
unsigned int highFreqComm : 1; // bit 10 高频声通机
|
||||
unsigned int buoySystem : 1; // bit 11 浮标系统
|
||||
unsigned int commMastRudder : 1; // bit 12 通信桅杆舵机
|
||||
unsigned int optMastRudder : 1; // bit 13 光电桅杆舵机
|
||||
unsigned int emMastRudder : 1; // bit 14 电磁桅杆舵机
|
||||
unsigned int reserved3 : 1; // bit 15 保留
|
||||
};
|
||||
struct ThrowPowerState
|
||||
{
|
||||
unsigned int bowThrow : 1; // bit 0 艏部抛载
|
||||
unsigned int reserved1 : 7; // bit 1-7 保留
|
||||
unsigned int fuelCellController : 1; // bit 8 燃料电池控制器
|
||||
unsigned int instrumentPanel : 1; // bit 9 仪表配电板
|
||||
unsigned int powerPanel : 1; // bit 10 动力配电板
|
||||
unsigned int instrumentBattery : 1; // bit 11 仪表锂电池
|
||||
unsigned int powerBattery : 1; // bit 12 动力锂电
|
||||
unsigned int sternThrow : 1; // bit 13 艉部抛载
|
||||
unsigned int reserved2 : 2; // bit 14-15 保留
|
||||
};
|
||||
struct uPower_equInsState
|
||||
{
|
||||
SensorState sensorState;
|
||||
ActuatorState actuatorState;
|
||||
MotionState motionState;
|
||||
LoadcommState loadcommState;
|
||||
ThrowPowerState throwPowerState;
|
||||
} state;
|
||||
std::string buildMsg(DriverTable s)
|
||||
{
|
||||
// 按照协议格式填充数据
|
||||
|
||||
// 传感器状态赋值
|
||||
state.sensorState.singleBeamSonar1 = s.singleBeamSonar1;
|
||||
state.sensorState.singleBeamSonar2 = s.singleBeamSonar2;
|
||||
state.sensorState.singleBeamSonar3 = s.singleBeamSonar3;
|
||||
state.sensorState.singleBeamSonar4 = s.singleBeamSonar4;
|
||||
state.sensorState.singleBeamSonar5 = s.singleBeamSonar5;
|
||||
state.sensorState.singleBeamSonar6 = s.singleBeamSonar6;
|
||||
state.sensorState.singleBeamSonar7 = s.singleBeamSonar7;
|
||||
state.sensorState.singleBeamSonar8 = s.singleBeamSonar8;
|
||||
state.sensorState.forwardSonar = s.forwardSonar;
|
||||
state.sensorState.ctd1 = s.ctd1;
|
||||
state.sensorState.ctd2 = s.ctd2;
|
||||
state.sensorState.soundVelocityMeter = s.soundVeloc;
|
||||
state.sensorState.ntp = s.ntp;
|
||||
state.sensorState.depthMeter1 = s.depth1;
|
||||
state.sensorState.depthMeter2 = s.depth2;
|
||||
state.sensorState.depthMeter3 = s.depth3;
|
||||
|
||||
// 执行机构状态赋值
|
||||
state.actuatorState.openCloseMechanism1 = s.bowCover1;
|
||||
state.actuatorState.openCloseMechanism2 = s.bowCover2;
|
||||
state.actuatorState.openCloseMechanism3 = s.bowCover3;
|
||||
state.actuatorState.openCloseMechanism4 = s.bowCover4;
|
||||
state.actuatorState.openCloseMechanism5 = s.bowCover5;
|
||||
state.actuatorState.openCloseMechanism6 = s.bowCover6;
|
||||
state.actuatorState.openWaterMechanism1 = s.bowWaterInet1;
|
||||
state.actuatorState.openWaterMechanism2 = s.bowWaterInet2;
|
||||
state.actuatorState.openWaterMechanism3 = s.bowWaterInet3;
|
||||
state.actuatorState.openWaterMechanism4 = s.bowWaterInet4;
|
||||
state.actuatorState.openWaterMechanism5 = s.bowWaterInet5;
|
||||
state.actuatorState.openWaterMechanism6 = s.bowWaterInet6;
|
||||
state.actuatorState.openWaterMechanism7 = s.bowWaterInet7;
|
||||
state.actuatorState.openWaterMechanism8 = s.bowWaterInet8;
|
||||
|
||||
// 运动状态赋值
|
||||
state.motionState.sternRudder1 = s.sternRudderServo1;
|
||||
state.motionState.sternRudder2 = s.sternRudderServo2;
|
||||
state.motionState.sternRudder3 = s.sternRudderServo3;
|
||||
state.motionState.sternRudder4 = s.sternRudderServo4;
|
||||
|
||||
state.motionState.bowRudder = s.bowRudderDeploy;
|
||||
|
||||
state.motionState.waterInjection = s.waterInject;
|
||||
|
||||
state.motionState.propulsionMotor = s.thruster;
|
||||
state.motionState.buoyancyAdjust1 = s.buoyancyAdjust1;
|
||||
state.motionState.buoyancyAdjust2 = s.buoyancyAdjust2;
|
||||
state.motionState.buoyancyAdjust3 = s.buoyancyAdjust3;
|
||||
state.motionState.buoyancyAdjust4 = s.buoyancyAdjust4;
|
||||
state.motionState.buoyancyAdjust5 = s.buoyancyAdjust5;
|
||||
state.motionState.DVL = s.DVL;
|
||||
state.motionState.INS = s.ins;
|
||||
|
||||
state.motionState.bowRudderLeft = s.bowRudderServo1;
|
||||
state.motionState.bowRudderRight = s.bowRudderServo2;
|
||||
|
||||
// 负载通信状态赋值
|
||||
state.loadcommState.payloadControl = s.launchControler;
|
||||
state.loadcommState.sideSonar = s.sideSonar;
|
||||
state.loadcommState.optMast = s.photoSensor;
|
||||
state.loadcommState.emMast = s.electSensor;
|
||||
state.loadcommState.buoySystem = s.buoyage;
|
||||
state.loadcommState.commMastRudder = s.mastLiftingServo;
|
||||
state.loadcommState.optMastRudder = s.mastLiftingServo;
|
||||
state.loadcommState.emMastRudder = s.mastLiftingServo;
|
||||
state.loadcommState.highFreqComm = s.USBL;
|
||||
state.loadcommState.midLowFreqSonar = s.lowFreqSonar;
|
||||
state.loadcommState.commMast = s.commMast;
|
||||
state.loadcommState.towedSonar = 0; //拖曳声纳未安装,默认为0
|
||||
|
||||
// 抛载和电源状态赋值
|
||||
state.throwPowerState.bowThrow = s.bowThrow; // 艏部抛载
|
||||
state.throwPowerState.sternThrow = s.sternThrow; // 艉部抛载
|
||||
state.throwPowerState.fuelCellController = 1; // 燃料电池控制器 默认开启
|
||||
state.throwPowerState.instrumentPanel = 1; // 仪表配电板 默认开启
|
||||
state.throwPowerState.powerPanel = 1; // 动力配电板 默认开启
|
||||
state.throwPowerState.instrumentBattery = 1; // 仪表锂电池 默认开启
|
||||
state.throwPowerState.powerBattery = 1; // 动力锂电 默认开启
|
||||
|
||||
// 转化为json格式
|
||||
Json::Value root;
|
||||
root["sensor_int16"] = *reinterpret_cast<uint16_t*>(&state.sensorState);
|
||||
root["actuator_int16"] = *reinterpret_cast<uint16_t*>(&state.actuatorState);
|
||||
root["motion_int16"] = *reinterpret_cast<uint16_t*>(&state.motionState);
|
||||
root["loadcomm_int16"] = *reinterpret_cast<uint16_t*>(&state.loadcommState);
|
||||
root["throwpower_int16"] = *reinterpret_cast<uint16_t*>(&state.throwPowerState);
|
||||
|
||||
//以二进制形式打印
|
||||
// std::cout << "sensor_int16: " << std::bitset<16>(*reinterpret_cast<uint16_t*>(&state.sensorState)) << std::endl;
|
||||
// std::cout << "actuator_int16: " << std::bitset<16>(*reinterpret_cast<uint16_t*>(&state.actuatorState)) << std::endl;
|
||||
// std::cout << "motion_int16: " << std::bitset<16>(*reinterpret_cast<uint16_t*>(&state.motionState)) << std::endl;
|
||||
// std::cout << "loadcomm_int16: " << std::bitset<16>(*reinterpret_cast<uint16_t*>(&state.loadcommState)) << std::endl;
|
||||
// std::cout << "throwpower_int16: " << std::bitset<16>(*reinterpret_cast<uint16_t*>(&state.throwPowerState)) << std::endl;
|
||||
|
||||
// 返回json字符串
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder.settings_["indentation"] = ""; // 紧凑格式,无缩进
|
||||
return Json::writeString(writerBuilder, root);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef U_POWER_EQUSTATE_FB_H
|
||||
#define U_POWER_EQUSTATE_FB_H
|
||||
#include "../driver.h"
|
||||
#include "string"
|
||||
#include "json/json.h"
|
||||
#include <bitset>
|
||||
|
||||
class uPower_equStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uPower_equStateMsg() {
|
||||
};
|
||||
~uPower_equStateMsg() {};
|
||||
std::string key = "uPower_equState_fb";
|
||||
std::string key_cmd = "uPower_equState_cmd";
|
||||
|
||||
Driver driver;
|
||||
|
||||
std::string buildMsg(DriverTable s)
|
||||
{
|
||||
return driver.saveDriverTableToJson(&s);
|
||||
}
|
||||
|
||||
const DriverTable getEquipmentCmd(const std::string& key, const std::string& msg)
|
||||
{
|
||||
DriverTable cmd;
|
||||
if (driver.loadDriverTableFromJson(msg, cmd) < 0)
|
||||
{
|
||||
LOG_F(WARNING, "get equipment cmd error:%s", msg.c_str());
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
#ifndef U_POWER_FCSSTATE_ST_H
|
||||
#define U_POWER_FCSSTATE_ST_H
|
||||
#include "../driver.h"
|
||||
#include "string"
|
||||
#include "json/json.h"
|
||||
#include <bitset>
|
||||
#include "../systemData.h"
|
||||
class uPower_fcsStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uPower_fcsStateMsg() {
|
||||
memset(&state, 0, sizeof(state));
|
||||
};
|
||||
~uPower_fcsStateMsg() {};
|
||||
std::string key = "uPower_fcsState_st";
|
||||
|
||||
struct uPower_fcsState
|
||||
{
|
||||
unsigned int fcsStatus : 4; // 燃料电池状态
|
||||
unsigned int outputPower : 12; // 输出功率 (0-4095)
|
||||
unsigned int temperature : 8; // 温度 (0-255)
|
||||
unsigned int errorCode : 8; // 错误代码
|
||||
} state;
|
||||
|
||||
// std::string buildMsg(SystemData data)
|
||||
std::string buildMsg(const SystemData& data)
|
||||
{
|
||||
//TODO:根据最新协议修改
|
||||
Json::Value fcs;
|
||||
// suffix = getTypeName(typeid(ccustate.fcuState).name());
|
||||
// fcs["fcuState"] = ccustate.fcuState;
|
||||
fcs["backpressure1_fp32"] = data.cabin_pressure1;
|
||||
fcs["backpressure2_fp32"] = data.cabin_pressure2;
|
||||
|
||||
fcs["ch4oConcent1_fp32"] = data.ch3oh_concentration1;
|
||||
fcs["ch4oConcent2_fp32"] = data.ch3oh_concentration2;
|
||||
|
||||
fcs["ch4o_fp32"] = 0.0; // 备用
|
||||
|
||||
fcs["excTemp_fp32"] = data.palladium_temp;
|
||||
|
||||
fcs["fcuCurIns_fp32"] = 0.0; //备用
|
||||
|
||||
fcs["fcuCurPower_fp32"] = 0.0; //备用
|
||||
|
||||
fcs["fcuCur_fp32"] = 0.0; //备用
|
||||
|
||||
fcs["fcuFaultLeve_uint8"] = data.fc_fault_level;
|
||||
|
||||
fcs["fcuOutIns_fp32"] = 0.0; //备用
|
||||
|
||||
fcs["fcuOutPower_fp32"] = 0.0; //备用
|
||||
|
||||
fcs["fcuState_uint8"] = data.fc_status;
|
||||
|
||||
fcs["fcuVolIns_fp32"] = 0.0; //备用
|
||||
|
||||
fcs["fcuVolPower_fp32"] = 0.0; //备用
|
||||
|
||||
fcs["fcuVol_fp32"] = 0.0; //备用
|
||||
|
||||
fcs["h2Concent1_fp32"] = data.h2_concentration1;
|
||||
fcs["h2Concent2_fp32"] = data.h2_concentration2;
|
||||
|
||||
fcs[ "o2Concent1_fp32"] = data.o2_concentration1;
|
||||
fcs["o2Concent2_fp32"] = data.o2_concentration2;
|
||||
|
||||
fcs["o2Level_fp32"] = 0.0; //备用
|
||||
fcs["o2_fp32"] = 0.0; //备用
|
||||
fcs["powLimit_fp32"] = data.output_power_limit;
|
||||
fcs[ "powerGen_fp32"] = data.total_generation_power;
|
||||
|
||||
fcs["flameDet_uint8"] = data.flame_detector1;
|
||||
|
||||
fcs["faultCode1_uint16"] = data.fc_fault_level_1;
|
||||
fcs["faultCode2_uint16"] = data.fc_fault_level_2;
|
||||
fcs["faultCode3_uint16"] = data.fc_fault_level_3;
|
||||
fcs["faultCode4_uint16"] = data.fc_fault_level_4;
|
||||
//新增加通信状态字段
|
||||
// fcs["fcCommState_uint8"] = data.device_common_status.ccu_status.isTimeout;
|
||||
fcs["fcCommState_uint8"] = 0;
|
||||
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder.settings_["indentation"] = "";
|
||||
return Json::writeString(writerBuilder, fcs);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef U_POWER_LIBATSTATE_ST_H
|
||||
#define U_POWER_LIBATSTATE_ST_H
|
||||
#include "../driver.h"
|
||||
#include "string"
|
||||
#include "json/json.h"
|
||||
#include <bitset>
|
||||
#include "../systemData.h"
|
||||
class uPower_liBatStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uPower_liBatStateMsg() {
|
||||
};
|
||||
~uPower_liBatStateMsg() {};
|
||||
std::string key = "uPower_liBatState_st";
|
||||
|
||||
// std::string buildMsg(SystemData data)
|
||||
std::string buildMsg(const SystemData& data)
|
||||
{
|
||||
//TODO:根据最新协议修改
|
||||
Json::Value lbs;
|
||||
//构建动力锂电池状态报告
|
||||
lbs["insBatCurElect_uint16"] = data.ins_current;
|
||||
lbs["insBatLimit_uint16"] = data.ins_power_limit1;
|
||||
lbs[ "insBatSoc_uint8"] = data.ins_soc;
|
||||
lbs["insBatTotalElect_uint16"] = data.ins_total_energy;
|
||||
lbs["insChargeState_uint8"] = data.ins_charge_status;
|
||||
lbs["insCurSocHold1_uint8"] = 0; //备用
|
||||
lbs["insCurSocHold2_uint8"] = 0; //备用
|
||||
lbs["insCurSocHold3_uint8"] = 0; //备用
|
||||
lbs["insCurrent_uint16"] = data.ins_current;
|
||||
lbs[ "insLinkVol_uint16"] = data.ins_voltage_link;
|
||||
lbs["insNegRelayState_uint8"] = 0;
|
||||
lbs["insNegRes_uint16"] = data.ins_resistance_neg;
|
||||
lbs[ "insPackVol_uint16"] = data.ins_voltage_pack;
|
||||
lbs[ "insPosRelayState_uint8"] = 0;
|
||||
lbs["insPosRes_uint16"] = data.ins_resistance_pos;
|
||||
lbs["powBatCurElect_uint16"] = 0;
|
||||
lbs["powBatSoc_uint8"] = data.dyn_soc;
|
||||
lbs[ "powBatTotalElect_uint16"] = data.dyn_total_energy;
|
||||
lbs["powChargeState_uint8"] = data.dyn_charge_status;
|
||||
lbs["powCurSocHold1_uint8"] = 0; //备用
|
||||
lbs["powCurSocHold2_uint8"] = 0; //备用
|
||||
lbs["powCurSocHold3_uint8"] = 0; //备用
|
||||
lbs["powCurToInsLimit1_uint8"] = data.dyn_power_limit1;
|
||||
lbs["powCurToInsLimit2_uint8"] = data.dyn_power_limit2;
|
||||
lbs["powCur_uint16"] = data.dyn_current;
|
||||
lbs["powLinkVol_uint16"] = data.dyn_voltage_link;
|
||||
lbs["powNegRelayState_uint8"] = 0;
|
||||
lbs["powNegRes_uint16"] = data.dyn_resistance_neg;
|
||||
lbs["powPosRelayState_uint8"] = 0;
|
||||
lbs["powPosRes_uint16"] = data.dyn_resistance_pos;
|
||||
lbs["powerBatLimit_uint16"] = 0; //备用
|
||||
lbs["powerPackVol_uint16"] = data.dyn_voltage_pack;
|
||||
lbs["powFaultCode_uint8"] = data.powfaultCode;
|
||||
lbs["insFaultCode_uint8"] = data.insfaultCode;
|
||||
//新增加两个通信状态字段
|
||||
// lbs["insCommState_uint8"] = data.device_common_status.ccu_status.isTimeout;
|
||||
// lbs["powCommState_uint8"] = data.device_common_status.ccu_status.isTimeout;
|
||||
//TODO:默认屏蔽故障码
|
||||
lbs["insCommState_uint8"] = 0;
|
||||
lbs["powCommState_uint8"] = 0;
|
||||
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder.settings_["indentation"] = "";
|
||||
return Json::writeString(writerBuilder, lbs);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef U_POWER_PMSTATE_FB_H
|
||||
#define U_POWER_PMSTATE_FB_H
|
||||
#include "../driver.h"
|
||||
#include "string"
|
||||
#include "json/json.h"
|
||||
#include <bitset>
|
||||
#include "../systemData.h"
|
||||
class uPower_pmStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uPower_pmStateMsg() {
|
||||
state.workCondition = 0;
|
||||
state.currentMod = 0;
|
||||
state.powerState = 0;
|
||||
state.faultLevel = 0;
|
||||
state.faultCode.clear();
|
||||
state.soc = 0;
|
||||
state.sustainableTime = 0;
|
||||
state.m_faultNum = 0;
|
||||
state.m_leakage = 0;
|
||||
};
|
||||
~uPower_pmStateMsg() {};
|
||||
std::string key = "uPower_pmState_fb";
|
||||
|
||||
struct uPower_pmState
|
||||
{
|
||||
unsigned char workCondition;
|
||||
unsigned char currentMod;
|
||||
unsigned char powerState;
|
||||
unsigned char faultLevel;
|
||||
vector<unsigned int> faultCode;
|
||||
unsigned int soc;
|
||||
unsigned int sustainableTime;
|
||||
unsigned int m_faultNum;
|
||||
unsigned char m_leakage;
|
||||
} state;
|
||||
|
||||
std::string buildMsg(const SystemData& data)
|
||||
{
|
||||
// 状态赋值
|
||||
Json::Value pms;
|
||||
|
||||
pms["workCondition_uint8"] = state.workCondition;
|
||||
pms["currentMod_uint8"] = state.currentMod;
|
||||
pms["powerState_uint8"] = state.powerState;
|
||||
// pms["faultLevel_uint8"] = state.faultLevel;
|
||||
pms["faultLevel_uint8"] = data.getFaultCodeLevel();
|
||||
|
||||
Json::Value faultCode_array = Json::Value(Json::arrayValue);
|
||||
//TODO:屏蔽所有故障
|
||||
for(auto faultCode : data.getFaultCode())
|
||||
{
|
||||
faultCode_array.append(faultCode);
|
||||
}
|
||||
|
||||
pms["faultCode_array"] = faultCode_array;
|
||||
|
||||
pms["soc_uint16"] = state.soc;
|
||||
|
||||
pms["sustainableTime_int64"] = state.sustainableTime;
|
||||
|
||||
pms["leakage_uint8"] = state.m_leakage;
|
||||
|
||||
// 转化为json格式
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder.settings_["indentation"] = "";
|
||||
return Json::writeString(writerBuilder, pms);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef U_POWER_SYSSTATE_FB_H
|
||||
#define U_POWER_SYSSTATE_FB_H
|
||||
#include "../driver.h"
|
||||
#include "string"
|
||||
#include "json/json.h"
|
||||
#include <bitset>
|
||||
#include "../logc/loguru.hpp"
|
||||
class uPower_sysStateMsg
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uPower_sysStateMsg() {
|
||||
};
|
||||
~uPower_sysStateMsg() {};
|
||||
std::string key = "uPower_sysState_cmd";
|
||||
const MSControlCmd getMasterControlCmd(const std::string& key, const std::string& msg)
|
||||
{
|
||||
MSControlCmd cmd;
|
||||
if (parseControlCmdFromJson(cmd, msg)) {
|
||||
|
||||
return cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_F(WARNING, "get master control cmd error:%s", msg.c_str());
|
||||
}
|
||||
};
|
||||
bool parseControlCmdFromJson(MSControlCmd &cmd, const std::string &strJson)
|
||||
{
|
||||
Json::CharReaderBuilder builder;
|
||||
Json::Value root;
|
||||
std::string errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream s(strJson);
|
||||
if (!Json::parseFromStream(builder, s, &root, &errs))
|
||||
{
|
||||
std::cerr << "JSON解析失败: " << errs << std::endl;
|
||||
return false; // 解析失败
|
||||
}
|
||||
if (root.isMember("powerCMD") && root["powerCMD"].isUInt())
|
||||
{
|
||||
cmd.powerCMD = root["powerCMD"].asUInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "缺少或类型不匹配: powerCMD" << std::endl;
|
||||
return false; // 缺少或类型不匹配
|
||||
}
|
||||
|
||||
if (root.isMember("modCMD") && root["modCMD"].isUInt())
|
||||
{
|
||||
cmd.modCMD = root["modCMD"].asUInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "缺少或类型不匹配: modCMD" << std::endl;
|
||||
return false; // 缺少或类型不匹配
|
||||
}
|
||||
|
||||
if (root.isMember("workCMD") && root["workCMD"].isUInt())
|
||||
{
|
||||
cmd.workCMD = root["workCMD"].asUInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "缺少或类型不匹配: workCMD" << std::endl;
|
||||
return false; // 缺少或类型不匹配
|
||||
}
|
||||
return true; // 成功
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "uDetect_zdpVoltage_cmd.h"
|
||||
#include "uDetect_xcVoltage_cmd.h"
|
||||
#include "uDevice_thruster_st.h"
|
||||
#include "uExternComm_setThrustSpeed_cmd.h"
|
||||
|
||||
// 定义静态成员变量
|
||||
std::string uDetect_zdpVoltage_cmd::key = "uDetect_zdpVoltage_cmd";
|
||||
std::string uDetect_xcVoltage_cmd::key = "uDetect_xcVoltage_cmd";
|
||||
std::string uDevice_thruster_st::key = "uDevice_thruster_st";
|
||||
std::string uExternComm_setThrustSpeed_cmd::key = "uExternComm_setThrustSpeed_cmd";
|
||||
@@ -41,9 +41,11 @@ PowerManger::PowerManger()
|
||||
m_faultNum = 0;
|
||||
m_ticker = 0;
|
||||
m_leakage = 0;
|
||||
m_thrustRpm = 0;
|
||||
m_thrustEnable = 0;
|
||||
faultCode.clear();
|
||||
|
||||
m_skew = 2;
|
||||
m_skew = 10;
|
||||
|
||||
m_pmCurrentState = {};
|
||||
m_currentDisBreakerState = {};
|
||||
@@ -158,7 +160,6 @@ bool PowerManger::Iterate()
|
||||
CycleTriggeredEvent cycleEvent;
|
||||
PowerManagerFsm::dispatch(cycleEvent);
|
||||
faultLevel = getFaultLevel();
|
||||
// 更新系统数据
|
||||
m_systemData->updateCommonStatus();
|
||||
// m_CcuColCmd.heartbeat
|
||||
// if (m_ticker++ % 5 == 0)
|
||||
@@ -238,6 +239,8 @@ void PowerManger::registerVariables()
|
||||
|
||||
Register(uDetect_xcVoltage_cmd::key,0);
|
||||
Register(uDetect_zdpVoltage_cmd::key,0);
|
||||
Register(uDevice_thruster_st::key,0);
|
||||
// Register(uExternComm_setThrustSpeed_cmd::key,0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
*
|
||||
* Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
|
||||
*/
|
||||
/************************************************************/
|
||||
/* NAME: */
|
||||
/* ORGN: MIT, Cambridge MA */
|
||||
/* FILE: PowerManger.h */
|
||||
/* DATE: December 29th, 1963 */
|
||||
/************************************************************ /
|
||||
/* NAME: */
|
||||
/* ORGN: MIT, Cambridge MA */
|
||||
/* FILE: PowerManger.h */
|
||||
/* DATE: December 29th, 1963 */
|
||||
/************************************************************/
|
||||
|
||||
#ifndef PowerManger_HEADER
|
||||
@@ -105,6 +105,8 @@ class PowerManger : public AppCastingMOOSApp
|
||||
Driver m_driver; //设备表处理
|
||||
unsigned char m_leakage;
|
||||
std::set<unsigned int> m_faultCodes;
|
||||
int m_thrustRpm;
|
||||
int m_thrustEnable;
|
||||
// std::set<unsigned int> m_disSysFaultCodes;
|
||||
//============================Device Option================================
|
||||
std::queue<DeviceSwitchCmd> m_deviceCmdQuenue;
|
||||
|
||||
@@ -157,6 +157,8 @@ bool UpperCommManager::processUpperMsg(const string& key, const string& strJson)
|
||||
else if(key == uDetect_xcVoltage_cmd::key)
|
||||
{
|
||||
uDetect_xcVoltage_cmd xcCmd;
|
||||
xcCmd.xcHighVoltageAdd_int32 = 0;
|
||||
xcCmd.xcLowVoltageAdd_int32 = 0;
|
||||
xcCmd.fromJsonString(strJson);
|
||||
SideSonarCmd sideSonarCmd;
|
||||
sideSonarCmd.xcHighVoltageAdd = xcCmd.xcHighVoltageAdd_int32;
|
||||
@@ -175,6 +177,17 @@ bool UpperCommManager::processUpperMsg(const string& key, const string& strJson)
|
||||
PowerManagerFsm::dispatch(devCmdExt);
|
||||
LOG_F(INFO, "set dev switch success");
|
||||
return true;
|
||||
}
|
||||
else if(key == uDevice_thruster_st::key)
|
||||
{
|
||||
uDevice_thruster_st thrusterSt;
|
||||
thrusterSt.fromJsonString(strJson);
|
||||
m_pm->m_thrustRpm = thrusterSt.rpm_int16;
|
||||
if(thrusterSt.maxTorque_uint16 == 0)
|
||||
m_pm->m_thrustEnable = 0;
|
||||
else
|
||||
m_pm->m_thrustEnable = 1;
|
||||
return true;
|
||||
};
|
||||
LOG_F(WARNING, "Unknown key: %s", key.c_str());
|
||||
return false;
|
||||
@@ -184,8 +197,6 @@ void UpperCommManager::processPeriodicTasks() {
|
||||
buildSystemReport();
|
||||
std::string strJson;
|
||||
//发送当前设备状态
|
||||
//TODO: 修改设备状态
|
||||
m_pm->m_currentDriverState.ins = 1;
|
||||
strJson = m_equStateMsg.buildMsg(m_pm->m_currentDriverState);
|
||||
m_pm->sendNotification(m_equStateMsg.key, strJson);
|
||||
//发送次级配电指令 修改后的代码
|
||||
@@ -211,7 +222,8 @@ void UpperCommManager::buildSystemReport() {
|
||||
// cout << "m_pmStateMsg.state.faultCode.size():" << m_pmStateMsg.state.faultCode.size() << endl;
|
||||
m_pmStateMsg.state.soc = m_pm->soc;
|
||||
m_pmStateMsg.state.sustainableTime = m_pm->sustainableTime;
|
||||
m_pmStateMsg.state.m_leakage = m_pm->m_leakage;
|
||||
// m_pmStateMsg.state.m_leakage = m_pm->m_leakage;
|
||||
m_pmStateMsg.state.m_leakage = m_pm->m_systemData->generateLeakageCode();
|
||||
m_pmStateMsg.state.m_faultNum = m_pm->m_faultNum;
|
||||
|
||||
m_pm->sendNotification(m_pmStateMsg.key, m_pmStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "upmsg/uPower_sysState.h"
|
||||
#include "upmsg/uDetect_zdpVoltage_cmd.h"
|
||||
#include "upmsg/uDetect_xcVoltage_cmd.h"
|
||||
#include "upmsg/uDevice_thruster_st.h"
|
||||
|
||||
#define _DEBUG
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "../PowerManger.h"
|
||||
#include "../logc/loguru.hpp"
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include "MOOS/libMOOS/Utils/MOOSUtilityFunctions.h"
|
||||
#include "../faultCode.h"
|
||||
|
||||
@@ -508,9 +509,24 @@ void PowerManagerFsm::handlePropulsionMotorCmd(int id, int cmd)
|
||||
{
|
||||
if(cmd == EquipmentCommand::OFF)
|
||||
{
|
||||
//检测电机去使能状态,5秒超时
|
||||
auto startTime = std::chrono::steady_clock::now();
|
||||
while(pm->m_thrustEnable == 1)
|
||||
{
|
||||
// 检查是否超时(5秒)
|
||||
auto currentTime = std::chrono::steady_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime);
|
||||
if(elapsed.count() >= 5)
|
||||
{
|
||||
LOG_F(WARNING, "电机去使能超时(5秒)");
|
||||
return;
|
||||
}
|
||||
MOOSPause(100);
|
||||
}
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(0);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::thruster, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
|
||||
} else if(cmd == EquipmentCommand::ON)
|
||||
{
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::thruster, (unsigned char)cmd);
|
||||
@@ -523,12 +539,27 @@ void PowerManagerFsm::handlePropulsionMotorCmd(int id, int cmd)
|
||||
|
||||
if(cmd == EquipmentCommand::ON)
|
||||
{
|
||||
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, static_cast<DeviceId::Type>(id), (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(1);
|
||||
}
|
||||
else if(cmd == EquipmentCommand::OFF)
|
||||
{
|
||||
//检测电机去使能状态,5秒超时
|
||||
auto startTime = std::chrono::steady_clock::now();
|
||||
while(pm->m_thrustEnable == 1)
|
||||
{
|
||||
// 检查是否超时(5秒)
|
||||
auto currentTime = std::chrono::steady_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime);
|
||||
if(elapsed.count() >= 5)
|
||||
{
|
||||
LOG_F(WARNING, "电机去使能超时(5秒)");
|
||||
return;
|
||||
}
|
||||
MOOSPause(100);
|
||||
}
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(0);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, static_cast<DeviceId::Type>(id), (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
@@ -539,10 +570,38 @@ void PowerManagerFsm::handlePropulsionMotorCmd(int id, int cmd)
|
||||
}
|
||||
else if(cmd == EquipmentCommand::POWER_OFF)
|
||||
{
|
||||
//检测电机去使能状态,5秒超时
|
||||
auto startTime = std::chrono::steady_clock::now();
|
||||
while(pm->m_thrustEnable == 1)
|
||||
{
|
||||
// 检查是否超时(5秒)
|
||||
auto currentTime = std::chrono::steady_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime);
|
||||
if(elapsed.count() >= 5)
|
||||
{
|
||||
LOG_F(WARNING, "电机去使能超时(5秒)");
|
||||
return;
|
||||
}
|
||||
MOOSPause(100);
|
||||
}
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(0);
|
||||
}
|
||||
else if(cmd == EquipmentCommand::METER_OFF)
|
||||
{
|
||||
//检测电机去使能状态,5秒超时
|
||||
auto startTime = std::chrono::steady_clock::now();
|
||||
while(pm->m_thrustEnable == 1)
|
||||
{
|
||||
// 检查是否超时(5秒)
|
||||
auto currentTime = std::chrono::steady_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime);
|
||||
if(elapsed.count() >= 5)
|
||||
{
|
||||
LOG_F(WARNING, "电机去使能超时(5秒)");
|
||||
return;
|
||||
}
|
||||
MOOSPause(100);
|
||||
}
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, static_cast<DeviceId::Type>(id), (unsigned char)0);
|
||||
}
|
||||
else if(cmd == EquipmentCommand::METER_ON)
|
||||
@@ -1832,7 +1891,7 @@ void PowerManagerFsm::extendedNavigationFault()
|
||||
}
|
||||
|
||||
//===处理动力锂电池功率不满
|
||||
if(pm->m_systemData->ins_max_discharge_power < 500)
|
||||
if(pm->m_systemData->dyn_max_discharge_power < 500)
|
||||
{
|
||||
pm->m_systemData->insertFaultCode(0x2323);
|
||||
}
|
||||
@@ -2408,8 +2467,13 @@ void PowerManagerFsm::emergencySystemFault()
|
||||
{
|
||||
if(pm->m_subDisSysFault.bowThrow == 1)
|
||||
pm->m_systemData->insertFaultCode(0x7202);
|
||||
else
|
||||
pm->m_systemData->eraseFaultCode(0x7202);
|
||||
|
||||
if(pm->m_subDisSysFault.sternThrow == 1)
|
||||
pm->m_systemData->insertFaultCode(0x7203);
|
||||
else
|
||||
pm->m_systemData->eraseFaultCode(0x7203);
|
||||
} else if (pm->m_subDisSysFault.bowThrow == 1 && pm->m_subDisSysFault.sternThrow == 1)
|
||||
{
|
||||
pm->m_systemData->insertFaultCode(0x7302);
|
||||
@@ -2428,13 +2492,13 @@ void PowerManagerFsm::emergencySystemFault()
|
||||
pm->m_systemData->eraseFaultCode(0x7301);
|
||||
|
||||
if(pm->m_systemData->power_bus_status.emergencyPowerLossSignal || pm->m_systemData->instrument_main_bus_status.emergencyPowerFailureSignal
|
||||
|| pm->m_systemData->disSysFaultCode.find(25) != pm->m_systemData->disSysFaultCode.end())
|
||||
|| (pm->m_systemData->disSysFaultCode.find(25) != pm->m_systemData->disSysFaultCode.end()))
|
||||
pm->m_systemData->insertFaultCode(0x7306);
|
||||
else
|
||||
pm->m_systemData->eraseFaultCode(0x7306);
|
||||
|
||||
if(pm->m_systemData->power_a_bus_status.emergencyPowerFailureSignal || pm->m_systemData->instrument_bus_status.emergencyPowerFailureSignal
|
||||
|| pm->m_systemData->disSysFaultCode.find(33) != pm->m_systemData->disSysFaultCode.end())
|
||||
|| (pm->m_systemData->disSysFaultCode.find(33) != pm->m_systemData->disSysFaultCode.end()))
|
||||
pm->m_systemData->insertFaultCode(0x7307);
|
||||
else
|
||||
pm->m_systemData->eraseFaultCode(0x7307);
|
||||
@@ -2547,91 +2611,106 @@ void PowerManagerFsm::handelPowerCmd(){
|
||||
case 0:
|
||||
{
|
||||
LOG_F(INFO, "收到上位机控制指令:关机");
|
||||
//1. 关闭动力电池
|
||||
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Stop;
|
||||
MOOSPause(3);
|
||||
int count=0;
|
||||
while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02))
|
||||
{
|
||||
LOG_F(INFO,"动力锂电池下电中...");
|
||||
MOOSPause(3);
|
||||
if(count>10)
|
||||
{
|
||||
LOG_F(INFO, "动力锂电池无下电反馈");
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
LOG_F(INFO, "动力锂电池已下电");
|
||||
// MOOSPause(3);
|
||||
// int count=0;
|
||||
// while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02))
|
||||
// {
|
||||
// LOG_F(INFO,"动力锂电池下电中...");
|
||||
// MOOSPause(3);
|
||||
// if(count>10)
|
||||
// {
|
||||
// LOG_F(INFO, "动力锂电池无下电反馈");
|
||||
// break;
|
||||
// }
|
||||
// count++;
|
||||
// }
|
||||
// LOG_F(INFO, "动力锂电池已下电");
|
||||
//2. 断掉所有动力电断路器
|
||||
//2.1 断开所有艏部高压断路器
|
||||
pm->m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HVA_bowFTDevice123Circuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HVA_bowRudderControlBoxCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HVA_xczCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
//2.2 断开所有艉部高压设备断路器
|
||||
//检查电机去使能
|
||||
//检测电机去使能状态,5秒超时
|
||||
auto startTime = std::chrono::steady_clock::now();
|
||||
while(pm->m_thrustEnable == 1)
|
||||
{
|
||||
// 检查是否超时(5秒)
|
||||
auto currentTime = std::chrono::steady_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime);
|
||||
if(elapsed.count() >= 5)
|
||||
{
|
||||
LOG_F(WARNING, "电机去使能超时(5秒)");
|
||||
return;
|
||||
}
|
||||
MOOSPause(100);
|
||||
}
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_sternFt45_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_sternRudder1_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_sternRudder2_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_fbReserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_tyzReserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_reserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
|
||||
//2.3 断开仪表预留断路器
|
||||
pm->m_lowerCommManager->operate_LV_reservedCircuit1_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_LV_reservedCircuit2_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_LVA_reservedCircuit1_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_LVA_reservedCircuit2_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_LVA_bowPZDeviceCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
|
||||
//2.4 断开应急电池断路器
|
||||
pm->m_lowerCommManager->operate_LV_mergencyLithiumBatteryGroup2Circuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_LVA_mergencyLithiumBatteryGroup1Circuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
|
||||
//2.5 断开动力电断路器
|
||||
pm->m_lowerCommManager->operate_HV_bowHighVoltageBox_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5Module_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0);
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
//最后 关闭动力电池
|
||||
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Stop;
|
||||
{
|
||||
int count=0;
|
||||
while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02))
|
||||
{
|
||||
LOG_F(INFO,"动力锂电池下电中...");
|
||||
MOOSPause(3);
|
||||
MOOSPause(1000);
|
||||
if(count>10)
|
||||
{
|
||||
LOG_F(INFO, "动力锂电池无下电反馈");
|
||||
@@ -2643,7 +2722,7 @@ void PowerManagerFsm::handelPowerCmd(){
|
||||
LOG_F(INFO, "动力锂电池已下电");
|
||||
//3. 次级配电系统恢复待机
|
||||
pm->m_driver.getSTANDBYTable(&pm->m_subDisSysCmd);
|
||||
MOOSPause(30);
|
||||
MOOSPause(3000);
|
||||
//4. 执行锂电池关机指令
|
||||
pm->m_CcuColCmd.insBatCmd = BatteryCommand::Stop;
|
||||
break;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../pmSysvariable.h"
|
||||
#include "../driver.h"
|
||||
#include "../PowerManger.h"
|
||||
#include "../upmsg/uExternComm_setThrustSpeed_cmd.h"
|
||||
|
||||
|
||||
#define OVER_DEPTH 0.1
|
||||
|
||||
@@ -16,6 +16,30 @@ SQLite::SQLite(const std::string& dbPath) {
|
||||
}
|
||||
}
|
||||
|
||||
bool SQLite::checkConnection() {
|
||||
if (!m_db) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 执行一个简单的查询来检查连接是否仍然有效
|
||||
const char* sql = "SELECT 1;";
|
||||
sqlite3_stmt* stmt = nullptr;
|
||||
if (sqlite3_prepare_v2(m_db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
|
||||
LOG_F(ERROR, "数据库连接检查失败: %s", sqlite3_errmsg(m_db));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = (sqlite3_step(stmt) == SQLITE_ROW);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (!success) {
|
||||
LOG_F(ERROR, "数据库连接检查失败: 查询未返回结果");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SQLite::~SQLite()
|
||||
{
|
||||
if (m_db) sqlite3_close(m_db);
|
||||
@@ -367,10 +391,18 @@ bool SQLite::createTable()
|
||||
}
|
||||
|
||||
bool SQLite::insertData(const ccuState data) {
|
||||
std::lock_guard<std::mutex> lock(m_dbMutex);
|
||||
|
||||
if (!m_db) {
|
||||
std::cerr << "数据库未打开,无法插入数据。" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查数据库连接是否仍然有效
|
||||
if (!checkConnection()) {
|
||||
std::cerr << "数据库连接无效,无法插入数据。" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* sql = R"(
|
||||
INSERT INTO CcuState (
|
||||
@@ -840,10 +872,18 @@ bool SQLite::insertData(const disLowBusCmd cmd) {
|
||||
}
|
||||
|
||||
bool SQLite::insertData(const disHighVolBusState data) {
|
||||
std::lock_guard<std::mutex> lock(m_dbMutex);
|
||||
|
||||
if (!m_db) {
|
||||
std::cerr << "数据库未打开,无法插入数据。" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查数据库连接是否仍然有效
|
||||
if (!checkConnection()) {
|
||||
std::cerr << "数据库连接无效,无法插入数据。" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* sql = R"(
|
||||
INSERT INTO disHighVolBusState (
|
||||
@@ -945,10 +985,18 @@ bool SQLite::insertData(const disHighVolBusState data) {
|
||||
}
|
||||
|
||||
bool SQLite::insertData(const disHighAVolBusState data) {
|
||||
std::lock_guard<std::mutex> lock(m_dbMutex);
|
||||
|
||||
if (!m_db) {
|
||||
std::cerr << "数据库未打开,无法插入数据。" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查数据库连接是否仍然有效
|
||||
if (!checkConnection()) {
|
||||
std::cerr << "数据库连接无效,无法插入数据。" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* sql = R"(
|
||||
INSERT INTO disHighAVolBusState (
|
||||
|
||||
@@ -2,17 +2,25 @@
|
||||
#define SQLITE_H
|
||||
#include "sqlite3.h"
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include "../pmSysvariable.h"
|
||||
|
||||
class SQLite
|
||||
{
|
||||
private:
|
||||
sqlite3* m_db;
|
||||
std::mutex m_dbMutex;
|
||||
|
||||
bool checkConnection();
|
||||
|
||||
public:
|
||||
std::string m_dbPath;
|
||||
SQLite(const std::string& dbName);
|
||||
~SQLite();
|
||||
|
||||
// 检查数据库连接是否有效
|
||||
bool isConnected() const { return m_db != nullptr; }
|
||||
|
||||
//创建表
|
||||
bool createTable();
|
||||
bool createTable(const std::string& tableName, const std::string& columns);
|
||||
@@ -33,4 +41,4 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif // SQLITE_H
|
||||
@@ -505,7 +505,7 @@ public:
|
||||
LEAKAGE_LI_BATTERY, // 锂电池舱漏水 (0x10)
|
||||
LEAKAGE_STERN_EMERGENCY, // 艉应急漏水 (0x20)
|
||||
LEAKAGE_FUEL_CELL_CABIN, // 燃料电池舱漏水 (0x40)
|
||||
LEAKAGE_BOW_EMERGENCY2 // 艏部应急漏水2 (0x80)
|
||||
LEAKAGE_BOW_EMERGENCY2 // 艉部应急漏水 (0x80)
|
||||
};
|
||||
|
||||
unsigned char leakageCode = 0;
|
||||
@@ -704,8 +704,23 @@ public:
|
||||
water_leak_status_from_insbat = ( data.ins_water_leak_dcdc_status >> 4) & 0x0F; // 00 正常,01 异常漏水
|
||||
water_leak_status_from_dynbat = (data.dyn_water_leak_status >> 4) & 0x0F; // 00 正常,01 异常漏水
|
||||
dcdc_status_from_insbat = (data.ins_water_leak_dcdc_status) & 0x0F; // 00 正常,01 故障
|
||||
|
||||
|
||||
//更新漏水状态
|
||||
if(water_leak_status_from_insbat == 0x01)
|
||||
{
|
||||
leakStatus[LEAKAGE_LI_BATTERY] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
leakStatus[LEAKAGE_LI_BATTERY] = false;
|
||||
}
|
||||
if(water_leak_status_from_dynbat == 0x01)
|
||||
{
|
||||
leakStatus[LEAKAGE_LI_BATTERY] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
leakStatus[LEAKAGE_LI_BATTERY] = false;
|
||||
}
|
||||
//应急电池
|
||||
emergency_battery1_voltage = data.emergency_battery1_voltage * 0.1;
|
||||
emergency_battery1_current = data.emergency_battery1_current * 0.05;
|
||||
@@ -715,7 +730,6 @@ public:
|
||||
emergency_battery2_current = data.emergency_battery2_current * 0.05;
|
||||
emergency_battery2_max_temp = data.emergency_battery2_max_temp * 0.1;
|
||||
emergency_battery2_fault_word = data.emergency_battery2_fault_word;
|
||||
|
||||
//心跳计数器
|
||||
heartbeat = data.heartbeat;
|
||||
}
|
||||
@@ -827,7 +841,16 @@ public:
|
||||
}
|
||||
|
||||
//浸水报警
|
||||
power_a_bus_status.waterIngressionAlarm = data.waterIngressionAlarm;
|
||||
power_a_bus_status.waterIngressionAlarm = data.waterIngressionAlarm == 0x55 ? 0 : 1;
|
||||
//更新漏水状态
|
||||
if(power_a_bus_status.waterIngressionAlarm == 1)
|
||||
{
|
||||
leakStatus[LEAKAGE_BOW_HIGH_VOLTAGE] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
leakStatus[LEAKAGE_BOW_HIGH_VOLTAGE] = false;
|
||||
}
|
||||
|
||||
|
||||
//电压电流参数
|
||||
@@ -862,9 +885,9 @@ public:
|
||||
// if(instrument_main_bus_status.instrumentBusbarInsulationLow == 1) disSysFaultCode.insert(42); else disSysFaultCode.erase(43);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(faultCodeMutex);
|
||||
if(instrument_main_bus_status.instrumentBusbarInsulationLow == 1) disSysFaultCode.insert(42); else disSysFaultCode.erase(43);
|
||||
if(instrument_main_bus_status.emergencyPowerFailureSignal == 1) disSysFaultCode.insert(41); else disSysFaultCode.erase(42);
|
||||
if(instrument_main_bus_status.instrumentPowerFailureSignal == 1) disSysFaultCode.insert(40); else disSysFaultCode.erase(41);
|
||||
if(instrument_main_bus_status.instrumentPowerFailureSignal == 1) disSysFaultCode.insert(41); else disSysFaultCode.erase(41);
|
||||
if(instrument_main_bus_status.emergencyPowerFailureSignal == 1) disSysFaultCode.insert(42); else disSysFaultCode.erase(42);
|
||||
if(instrument_main_bus_status.instrumentBusbarInsulationLow == 1) disSysFaultCode.insert(43); else disSysFaultCode.erase(43);
|
||||
}
|
||||
|
||||
//电压电流参数
|
||||
@@ -905,8 +928,16 @@ public:
|
||||
}
|
||||
|
||||
//浸水报警
|
||||
instrument_bus_status.waterIngressionAlarm = data.waterIngressionAlarm;
|
||||
|
||||
instrument_bus_status.waterIngressionAlarm = data.waterIngressionAlarm == 0x55 ? 0 : 1;
|
||||
//更新漏水状态
|
||||
if(instrument_bus_status.waterIngressionAlarm == 1)
|
||||
{
|
||||
leakStatus[LEAKAGE_BOW_LOW_VOLTAGE] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
leakStatus[LEAKAGE_BOW_LOW_VOLTAGE] = false;
|
||||
}
|
||||
//电压电流参数
|
||||
instrument_bus_status.instrumentBusbarVoltage = data.instrumentBusbarVoltage * 0.1;
|
||||
instrument_bus_status.instrumentBusbarCurrent = data.instrumentBusbarCurrent * 0.1;
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
|
||||
Json::Value j;
|
||||
std::string errors;
|
||||
|
||||
LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
bool parsingSuccessful = reader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &j, &errors);
|
||||
if (!parsingSuccessful) {
|
||||
LOG_F(ERROR, "Failed to parse JSON: %s", errors.c_str());
|
||||
@@ -50,9 +50,6 @@ public:
|
||||
if (j.isMember("xcLowVoltageAdd_int32") && j.isMember("xcHighVoltageAdd_int32")) {
|
||||
xcLowVoltageAdd_int32 = j["xcLowVoltageAdd_int32"].asInt();
|
||||
xcHighVoltageAdd_int32 = j["xcHighVoltageAdd_int32"].asInt();
|
||||
LOG_F(INFO, "xcLowVoltageAdd_int32: %d", xcLowVoltageAdd_int32);
|
||||
LOG_F(INFO, "xcHighVoltageAdd_int32: %d", xcHighVoltageAdd_int32);
|
||||
LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
return true;
|
||||
}
|
||||
LOG_F(ERROR, "JSON does not contain required fields");
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
|
||||
Json::Value j;
|
||||
std::string errors;
|
||||
|
||||
LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
bool parsingSuccessful = reader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &j, &errors);
|
||||
if (!parsingSuccessful) {
|
||||
LOG_F(ERROR, "Failed to parse JSON: %s", errors.c_str());
|
||||
@@ -46,8 +46,6 @@ public:
|
||||
|
||||
if (j.isMember("zdpVoltageAdd_int32")) {
|
||||
zdpVoltageAdd_int32 = j["zdpVoltageAdd_int32"].asInt();
|
||||
LOG_F(INFO, "zdpVoltageAdd_int32: %d", zdpVoltageAdd_int32);
|
||||
LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
return true;
|
||||
}
|
||||
LOG_F(ERROR, "JSON does not contain required fields");
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
{
|
||||
"rpm int16": "xxx", // 实际转速,类型:int16_t
|
||||
"voltage_uint16": "xxx", // 电压,类型:uint16_t,单位 V
|
||||
"current_uint16": "xxx", // 电流,类型:uint16_t,单位 A
|
||||
"ctrlTemp_uint16": "xxx", // 控制器温度,类型:uint16_t,单位 °C
|
||||
"motorTemp_uint16": "xxx", // 电机温度,类型:uint16_t,单位 °C
|
||||
"motorTorque_uint16": "xxx", // 电机扭矩,类型:uint16_t,单位 N・m
|
||||
"maxTorque_uint16": "xxx", // 电机最大扭矩,类型:uint16_t,单位 N・m,电机使能时该字段非零,无使能地址报警,含使能整标标识字,00 无故障,按位常量零
|
||||
"error_int64": "xxx" // 见表 [1],类型:int64_t
|
||||
}
|
||||
*/
|
||||
#ifndef UDEVICE_THRUSTER_ST_H
|
||||
#define UDEVICE_THRUSTER_ST_H
|
||||
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
class uDevice_thruster_st
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uDevice_thruster_st(){};
|
||||
~uDevice_thruster_st(){};
|
||||
|
||||
int16_t rpm_int16;
|
||||
uint16_t voltage_uint16;
|
||||
uint16_t current_uint16;
|
||||
uint16_t ctrlTemp_uint16;
|
||||
uint16_t motorTemp_uint16;
|
||||
uint16_t motorTorque_uint16;
|
||||
uint16_t maxTorque_uint16;
|
||||
int64_t error_int64;
|
||||
|
||||
static std::string key;
|
||||
|
||||
std::string toJsonString()
|
||||
{
|
||||
Json::Value j;
|
||||
j["rpm_int16"] = rpm_int16;
|
||||
j["voltage_uint16"] = voltage_uint16;
|
||||
j["current_uint16"] = current_uint16;
|
||||
j["ctrlTemp_uint16"] = ctrlTemp_uint16;
|
||||
j["motorTemp_uint16"] = motorTemp_uint16;
|
||||
j["motorTorque_uint16"] = motorTorque_uint16;
|
||||
j["maxTorque_uint16"] = maxTorque_uint16;
|
||||
j["error_int64"] = static_cast<Json::Int64>(error_int64);
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder.settings_["indentation"] = "";
|
||||
return Json::writeString(builder, j);
|
||||
}
|
||||
|
||||
bool fromJsonString(std::string jsonString)
|
||||
{
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(jsonString);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提取rpm_int16
|
||||
if (root.isMember("rpm_int16") && root["rpm_int16"].isInt()) {
|
||||
rpm_int16 = root["rpm_int16"].asInt();
|
||||
// LOG_F(INFO, "rpm_int16: %d", rpm_int16);
|
||||
}
|
||||
|
||||
// 提取voltage_uint16
|
||||
if (root.isMember("voltage_uint16") && root["voltage_uint16"].isUInt()) {
|
||||
voltage_uint16 = root["voltage_uint16"].asUInt();
|
||||
// LOG_F(INFO, "voltage_uint16: %u", voltage_uint16);
|
||||
}
|
||||
|
||||
// 提取current_uint16
|
||||
if (root.isMember("current_uint16") && root["current_uint16"].isUInt()) {
|
||||
current_uint16 = root["current_uint16"].asUInt();
|
||||
// LOG_F(INFO, "current_uint16: %u", current_uint16);
|
||||
}
|
||||
|
||||
// 提取ctrlTemp_uint16
|
||||
if (root.isMember("ctrlTemp_uint16") && root["ctrlTemp_uint16"].isUInt()) {
|
||||
ctrlTemp_uint16 = root["ctrlTemp_uint16"].asUInt();
|
||||
// LOG_F(INFO, "ctrlTemp_uint16: %u", ctrlTemp_uint16);
|
||||
}
|
||||
|
||||
// 提取motorTemp_uint16
|
||||
if (root.isMember("motorTemp_uint16") && root["motorTemp_uint16"].isUInt()) {
|
||||
motorTemp_uint16 = root["motorTemp_uint16"].asUInt();
|
||||
// LOG_F(INFO, "motorTemp_uint16: %u", motorTemp_uint16);
|
||||
}
|
||||
|
||||
// 提取motorTorque_uint16
|
||||
if (root.isMember("motorTorque_uint16") && root["motorTorque_uint16"].isUInt()) {
|
||||
motorTorque_uint16 = root["motorTorque_uint16"].asUInt();
|
||||
// LOG_F(INFO, "motorTorque_uint16: %u", motorTorque_uint16);
|
||||
}
|
||||
|
||||
// 提取maxTorque_uint16
|
||||
if (root.isMember("maxTorque_uint16") && root["maxTorque_uint16"].isUInt()) {
|
||||
maxTorque_uint16 = root["maxTorque_uint16"].asUInt();
|
||||
// LOG_F(INFO, "maxTorque_uint16: %u", maxTorque_uint16);
|
||||
}
|
||||
|
||||
// 提取error_int64
|
||||
if (root.isMember("error_int64") && root["error_int64"].isInt64()) {
|
||||
error_int64 = root["error_int64"].asInt64();
|
||||
// LOG_F(INFO, "error_int64: %lld", error_int64);
|
||||
}
|
||||
|
||||
// LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
{
|
||||
"rpm_int16": "xx", // 期望转速;单位:rpm;类型 int16_t
|
||||
"enable_int16": "xx" // 使能指令,1 - 使能,0 - 去使能。类型 int16_t
|
||||
}
|
||||
*/
|
||||
#ifndef UEXTERNCOMM_SETTHRUSTSPEED_CMD_H
|
||||
#define UEXTERNCOMM_SETTHRUSTSPEED_CMD_H
|
||||
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
class uExternComm_setThrustSpeed_cmd
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uExternComm_setThrustSpeed_cmd(){};
|
||||
~uExternComm_setThrustSpeed_cmd(){};
|
||||
|
||||
int16_t rpm_int16;
|
||||
int16_t enable_int16;
|
||||
|
||||
static std::string key;
|
||||
|
||||
std::string toJsonString()
|
||||
{
|
||||
Json::Value j;
|
||||
j["rpm_int16"] = rpm_int16;
|
||||
j["enable_int16"] = enable_int16;
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder.settings_["indentation"] = "";
|
||||
return Json::writeString(builder, j);
|
||||
}
|
||||
|
||||
bool fromJsonString(std::string jsonString)
|
||||
{
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
JSONCPP_STRING errs;
|
||||
|
||||
// 解析JSON字符串
|
||||
std::istringstream stream(jsonString);
|
||||
if (!Json::parseFromStream(builder, stream, &root, &errs)) {
|
||||
LOG_F(WARNING, "JSON解析失败: %s", errs.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提取rpm_int16
|
||||
if (root.isMember("rpm_int16") && root["rpm_int16"].isInt()) {
|
||||
rpm_int16 = root["rpm_int16"].asInt();
|
||||
// LOG_F(INFO, "rpm_int16: %d", rpm_int16);
|
||||
}
|
||||
|
||||
// 提取enable_int16
|
||||
if (root.isMember("enable_int16") && root["enable_int16"].isInt()) {
|
||||
enable_int16 = root["enable_int16"].asInt();
|
||||
// LOG_F(INFO, "enable_int16: %d", enable_int16);
|
||||
}
|
||||
|
||||
// LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
m_state_of_bus_lv_a.set_reserved_breaker_1((data.instrument_bus_status.reservedCircuitBreaker1 == 1));
|
||||
m_state_of_bus_lv_a.set_reserved_breaker_2((data.instrument_bus_status.reservedCircuitBreaker2 == 1));
|
||||
m_state_of_bus_lv_a.set_emergency_lithium_battery_group_1_breaker((data.instrument_bus_status.emergencyLithiumBatteryGroup1CircuitBreaker == 1));
|
||||
dis["LVolBusBreaker_uint16"] = m_state_of_bus_lv.relay_states.to_ulong();
|
||||
dis["LVolBusBreaker_uint16"] = m_state_of_bus_lv_a.relay_states.to_ulong();
|
||||
|
||||
//构建配电系统故障码
|
||||
Json::Value faultCodeDis_array = Json::Value(Json::arrayValue);
|
||||
|
||||
@@ -129,7 +129,8 @@ public:
|
||||
state.sensorState.ctd1 = s.ctd1;
|
||||
state.sensorState.ctd2 = s.ctd2;
|
||||
state.sensorState.soundVelocityMeter = s.soundVeloc;
|
||||
state.sensorState.ntp = s.ntp;
|
||||
// state.sensorState.ntp = s.ntp;
|
||||
state.sensorState.ntp = 0;
|
||||
state.sensorState.depthMeter1 = s.depth1;
|
||||
state.sensorState.depthMeter2 = s.depth2;
|
||||
state.sensorState.depthMeter3 = s.depth3;
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
{
|
||||
//TODO:根据最新协议修改
|
||||
Json::Value lbs;
|
||||
//构建动力锂电池状态报告
|
||||
//构建锂电池状态报告
|
||||
lbs["insBatCurElect_uint16"] = data.ins_current;
|
||||
lbs["insBatLimit_uint16"] = data.ins_power_limit1;
|
||||
lbs[ "insBatSoc_uint8"] = data.ins_soc;
|
||||
@@ -61,6 +61,17 @@ public:
|
||||
//TODO:默认屏蔽故障码
|
||||
lbs["insCommState_uint8"] = 0;
|
||||
lbs["powCommState_uint8"] = 0;
|
||||
|
||||
//应急电池
|
||||
// 增加应急锂电池状态
|
||||
lbs["emergencyBattery1Voltage_int16"] = data.emergency_battery1_voltage;
|
||||
lbs["emergencyBattery1Current_int16"] = data.emergency_battery1_current;
|
||||
lbs["emergencyBattery1MaxTemp_int16"] = data.emergency_battery1_max_temp;
|
||||
lbs["emergencyBattery1FaultWord_uint16"] = data.emergency_battery1_fault_word;
|
||||
lbs["emergencyBattery2Voltage_int16"] = data.emergency_battery2_voltage;
|
||||
lbs["emergencyBattery2Current_int16"] = data.emergency_battery2_current;
|
||||
lbs["emergencyBattery2MaxTemp_int16"] = data.emergency_battery2_max_temp;
|
||||
lbs["emergencyBattery2FaultWord_uint16"] = data.emergency_battery2_fault_word;
|
||||
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder.settings_["indentation"] = "";
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#include "uDetect_zdpVoltage_cmd.h"
|
||||
#include "uDetect_xcVoltage_cmd.h"
|
||||
#include "uDevice_thruster_st.h"
|
||||
#include "uExternComm_setThrustSpeed_cmd.h"
|
||||
|
||||
// 定义静态成员变量
|
||||
std::string uDetect_zdpVoltage_cmd::key = "uDetect_zdpVoltage_cmd";
|
||||
std::string uDetect_xcVoltage_cmd::key = "uDetect_xcVoltage_cmd";
|
||||
std::string uDevice_thruster_st::key = "uDevice_thruster_st";
|
||||
std::string uExternComm_setThrustSpeed_cmd::key = "uExternComm_setThrustSpeed_cmd";
|
||||
|
||||
@@ -1765,11 +1765,11 @@ class PowerManagerApp:
|
||||
self.simulation_LowBusFbMsg.emergencyLithiumBatteryGroup1CircuitBreaker = self.simulation_LVBCmdMsg.emergencyLithiumBatteryGroup1CircuitBreaker
|
||||
|
||||
self.send_udp_command(self.simulation_HighVolBusFbMsg.pack(), self.udp_ip, self.udp_port)
|
||||
time.sleep(0.01)
|
||||
time.sleep(1)
|
||||
self.send_udp_command(self.simulation_HighAVolBusFbMsg.pack(), self.udp_ip, self.udp_port)
|
||||
time.sleep(0.01)
|
||||
time.sleep(1)
|
||||
self.send_udp_command(self.simulation_LowBusFbMsg.pack(), self.udp_ip, self.udp_port)
|
||||
time.sleep(0.01)
|
||||
time.sleep(1)
|
||||
self.send_udp_command(self.simulation_LowMainBusFbMsg.pack(), self.udp_ip, self.udp_port)
|
||||
time.sleep(1) # 1秒间隔
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 编译测试程序
|
||||
g++ -std=c++11 -I../../src/pPowerManger -I../../src/pPowerManger/sqlit3 \
|
||||
testSqlitdb.cpp ../../src/pPowerManger/sqlit3/SQLite.cpp ../../src/pPowerManger/sqlit3/sqlite3.c \
|
||||
-o testSqlitdb -lsqlite3 -lpthread
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "编译成功!"
|
||||
echo "运行测试:"
|
||||
./testSqlitdb
|
||||
else
|
||||
echo "编译失败!"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user