204 lines
7.8 KiB
C++
204 lines
7.8 KiB
C++
//=======================================================================
|
||
// 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);
|
||
}
|