Files
H100PowerManger/test/until/SystemDataTest.cpp
T

204 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//=======================================================================
// SystemDataTest: SystemData 的故障检测逻辑(断路器映射、绝缘、电源失电、
// 漏水、DCDC、继电器位提取、缩放、故障码集合、漏水位)。
// 不改动生产代码;仅链接现有 systemData.h + SQLite + MOOS。
//=======================================================================
#include <gtest/gtest.h>
#include "MOOS/libMOOS/Utils/MOOSUtilityFunctions.h" // MOOSTime (updateCommonStatus)
#include "systemData.h"
#include "faultCode.h"
TEST(SystemDataTest, BreakerMapping)
{
SystemData sd;
unsigned char status = 0;
// 0x55 = 闭合(1),无故障码
sd.updateBreakerFault(status, 0x55, 99);
EXPECT_EQ(status, 1u);
EXPECT_EQ(sd.disSysFaultCode.count(99), 0u);
// 0xAA = 断开(0),无故障码
sd.updateBreakerFault(status, 0xAA, 99);
EXPECT_EQ(status, 0u);
EXPECT_EQ(sd.disSysFaultCode.count(99), 0u);
// 0x5A = 故障脱扣(2),插入故障码
sd.updateBreakerFault(status, 0x5A, 99);
EXPECT_EQ(status, 2u);
EXPECT_EQ(sd.disSysFaultCode.count(99), 1u);
// 再次正常后擦除
sd.updateBreakerFault(status, 0x55, 99);
EXPECT_EQ(sd.disSysFaultCode.count(99), 0u);
}
TEST(SystemDataTest, HighVolBusFaultDetection)
{
SystemData sd;
disHighVolBusState s{};
// 全 0xAA(断开,正常)
s.fuelCellCircuitBreaker = 0xAA;
s.powerLithiumBatteryCircuitBreaker = 0xAA;
s.propulsionMotorCircuitBreaker = 0xAA;
s.lithiumBatteryGroupInstrumentCircuitBreaker = 0xAA;
s.dcDc5ModuleCircuitBreaker = 0xAA;
s.bowHighVoltageDistributionBoxCircuitBreaker = 0xAA;
s.sternFTDevice45CircuitBreaker = 0xAA;
s.sternRudderSwitch1CircuitBreaker = 0xAA;
s.sternRudderSwitch2CircuitBreaker = 0xAA;
s.powerBusInsulationStatus = 0x55;
s.aBusInsulationStatus = 0x55;
s.meterPowerLossSignal = 0x55;
s.emergencyPowerLossSignal = 0x55;
sd.updateSystemData(s);
EXPECT_EQ(sd.power_bus_status.fuelCellCircuitBreaker, 0u);
EXPECT_EQ(sd.disSysFaultCode.count(1), 0u);
// 燃料电断路器故障脱扣
s.fuelCellCircuitBreaker = 0x5A;
sd.updateSystemData(s);
EXPECT_EQ(sd.power_bus_status.fuelCellCircuitBreaker, 2u);
EXPECT_EQ(sd.disSysFaultCode.count(1), 1u);
// 动力锂电池闭合 + A汇流排/动力母排绝缘低 → 34/35
s.fuelCellCircuitBreaker = 0xAA;
s.powerLithiumBatteryCircuitBreaker = 0x55;
s.powerBusInsulationStatus = 0xAA;
s.aBusInsulationStatus = 0xAA;
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(34), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(35), 1u);
EXPECT_EQ(sd.power_bus_status.powerBusInsulationStatus, 1u);
EXPECT_EQ(sd.power_bus_status.aBusInsulationStatus, 1u);
// 电源失电 → 36/37
s.meterPowerLossSignal = 0xAA;
s.emergencyPowerLossSignal = 0xAA;
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(36), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(37), 1u);
// 全部恢复正常后故障码擦除
s.powerLithiumBatteryCircuitBreaker = 0xAA;
s.powerBusInsulationStatus = 0x55;
s.aBusInsulationStatus = 0x55;
s.meterPowerLossSignal = 0x55;
s.emergencyPowerLossSignal = 0x55;
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(34), 0u);
EXPECT_EQ(sd.disSysFaultCode.count(35), 0u);
EXPECT_EQ(sd.disSysFaultCode.count(36), 0u);
EXPECT_EQ(sd.disSysFaultCode.count(37), 0u);
}
TEST(SystemDataTest, HighAVolBusFaultDetection)
{
SystemData sd;
disHighAVolBusState s{};
s.actuatorCircuitBreaker = 0x5A; // 启闭机构断路器脱扣 → 14
s.xczCircuitBreaker = 0x55;
s.instrumentPowerFailureSignal = 0x55;
s.emergencyPowerFailureSignal = 0x55;
s.waterIngressionAlarm = 0x55;
sd.updateSystemData(s);
EXPECT_EQ(sd.power_a_bus_status.actuatorCircuitBreaker, 2u);
EXPECT_EQ(sd.disSysFaultCode.count(14), 1u);
s.actuatorCircuitBreaker = 0xAA;
s.instrumentPowerFailureSignal = 0xAA; // 失电 → 38
s.emergencyPowerFailureSignal = 0xAA; // 失电 → 39
s.waterIngressionAlarm = 0xAA; // 浸水 → leakStatus[BOW_HIGH_VOLTAGE]
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(14), 0u);
EXPECT_EQ(sd.disSysFaultCode.count(38), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(39), 1u);
EXPECT_TRUE(sd.leakStatus[SystemData::LEAKAGE_BOW_HIGH_VOLTAGE]);
}
TEST(SystemDataTest, LowMainBusFaultDetection)
{
SystemData sd;
disLowMainBusState s{};
s.lithiumBatteryGroupInstrumentCircuitBreaker = 0x5A; // 19
s.unit4InstrumentDC48VCircuitBreaker = 0x5A; // 21
s.instrumentPowerFailureSignal = 0xAA; // 41
s.emergencyPowerFailureSignal = 0xAA; // 42
s.instrumentBusbarInsulationLow = 0xAA; // 43
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(19), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(21), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(41), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(42), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(43), 1u);
}
TEST(SystemDataTest, LowBusFaultDetection)
{
SystemData sd;
disLowBusState s{};
s.unit1CircuitBreaker = 0x5A; // 26
s.emergencyLithiumBatteryGroup1CircuitBreaker = 0x5A; // 33
s.powerFailureSignal = 0xAA; // 44
s.emergencyPowerFailureSignal = 0xAA; // 45
s.waterIngressionAlarm = 0xAA; // leakage BOW_LOW_VOLTAGE
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(26), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(33), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(44), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(45), 1u);
EXPECT_TRUE(sd.leakStatus[SystemData::LEAKAGE_BOW_LOW_VOLTAGE]);
}
TEST(SystemDataTest, CcuStateScalingAndRelayBits)
{
SystemData sd;
ccuState c{};
c.ins_soc = 60;
c.dyn_soc = 80;
c.ins_relay_status1 = 0x12; // 高4位=1(充电), 低4位=2(正极)
c.ins_relay_status2 = 0x34;
c.ins_voltage_link = 4800; // ×0.1 = 480.0
c.ins_water_leak_dcdc_status = 0x11; // 高4位=1 漏水, 低4位=1 DCDC故障
c.dyn_water_leak_status = 0x21; // 高4位=2, 低4位=1
sd.updateSystemData(c);
EXPECT_EQ(sd.ins_soc, 60);
EXPECT_EQ(sd.dyn_soc, 80);
EXPECT_EQ(sd.ins_pos_relay_status, 2u); // 低4位
EXPECT_EQ(sd.ins_charge_relay_status, 1u); // 高4位
EXPECT_EQ(sd.ins_precharge_relay_status, 4u); // 低4位 of status2
EXPECT_EQ(sd.ins_neg_relay_status, 3u); // 高4位 of status2
EXPECT_NEAR(sd.ins_voltage_link, 480.0, 0.01);
EXPECT_EQ(sd.water_leak_status_from_insbat, 1u);
EXPECT_EQ(sd.dcdc_status_from_insbat, 1u);
EXPECT_TRUE(sd.leakStatus[SystemData::LEAKAGE_LI_BATTERY]);
}
TEST(SystemDataTest, FaultCodeSetAndLevel)
{
SystemData sd;
EXPECT_EQ(sd.getFaultCodeLevel(), 0u);
sd.insertFaultCode(0x1102); // 0x11>>... level = (0x1102>>8)&0xF = 1
EXPECT_EQ(sd.getFaultCodeLevel(), 1u);
sd.insertFaultCode(0x4402); // level = (0x4402>>8)&0xF = 4
EXPECT_EQ(sd.getFaultCodeLevel(), 4u);
sd.eraseFaultCode(0x4402);
EXPECT_EQ(sd.getFaultCodeLevel(), 1u);
auto codes = sd.getFaultCode();
EXPECT_EQ(codes.count(0x1102), 1u);
}
TEST(SystemDataTest, LeakageCodeGeneration)
{
SystemData sd;
EXPECT_EQ(sd.generateLeakageCode(), 0u);
sd.leakStatus[SystemData::LEAKAGE_BOW_EMERGENCY] = true; // 0x01
sd.leakStatus[SystemData::LEAKAGE_FUEL_CELL] = true; // 0x08
sd.leakStatus[SystemData::LEAKAGE_LI_BATTERY] = true; // 0x10
EXPECT_EQ(sd.generateLeakageCode(), 0x19u);
}
TEST(SystemDataTest, CommonStatusTimeout)
{
SystemData sd;
sd.updateCommonStatus(30.0);
// 新建 SystemData 的 lastUpdateTime=0,与当前 MOOSTime 之差远大于 30s
EXPECT_TRUE(sd.device_common_status.ccu_status.isTimeout);
}