修复了程序在启动时偶尔崩溃的问题

This commit is contained in:
zjk
2026-01-27 20:45:00 +08:00
parent b5ca051831
commit e5193bd7f7
9 changed files with 456 additions and 133 deletions
-9
View File
@@ -1,9 +0,0 @@
//SERVERHOST = 192.168.0.223
//SERVERPORT = 9000
ProcessConfig = pPowerManger
{
AppTick = 4
CommsTick = 4
log_level = INFO
log_file = ./logfile.log
}
Executable
+34
View File
@@ -0,0 +1,34 @@
#!/bin/bash
echo "开始测试pPowerManger程序启动稳定性..."
LOOP_COUNT=0
while true; do
LOOP_COUNT=$((LOOP_COUNT + 1))
echo "\n===== 第 $LOOP_COUNT 次循环 ====="
# 启动pPowerManger程序
echo "启动pPowerManger..."
./pPowerManger pPowerManger.moos &
PROCESS_ID=$!
# 等待5秒让程序启动
sleep 0.1
# 检查程序是否还在运行
if kill -0 $PROCESS_ID 2>/dev/null; then
echo "程序启动成功,PID: $PROCESS_ID"
# 等待2秒后关闭程序
sleep 2
echo "关闭程序..."
kill $PROCESS_ID
# 等待1秒让程序彻底关闭
sleep 0.1
else
echo "程序启动失败!"
echo "故障发生在第 $LOOP_COUNT 次循环"
exit 0.1
fi
done
Executable
+148
View File
@@ -0,0 +1,148 @@
#!/bin/bash
# 核心配置
CRASH_LOG_DIR="./crash_logs"
RUN_DURATION=2
GDB_TIMEOUT=$((RUN_DURATION + 2)) # 延长超时,确保GDB完全初始化
MAX_LOOP=0
# 强制捕获所有致命信号
CRASH_SIGNALS=("SIGSEGV" "SIGABRT" "SIGILL" "SIGFPE" "SIGBUS")
# 创建日志目录
mkdir -p ${CRASH_LOG_DIR}
rm -f ${CRASH_LOG_DIR}/* # 清空旧日志(可选)
# 清理进程函数
cleanup() {
pkill -9 gdb >/dev/null 2>&1
pkill -9 pPowerManger >/dev/null 2>&1
sleep 0.2
}
# 检查是否是真崩溃(从日志+系统日志双重验证)
is_real_crash() {
local log_file=$1
local loop=$2
# 1. 检查GDB日志中的崩溃关键字
if grep -qiE "segmentation fault|sigsegv|crash detected|backtrace" "${log_file}"; then
return 0
fi
# 2. 检查系统dmesg中的段错误记录(终极验证)
if dmesg | grep -i "pPowerManger.*segfault" | grep -i "loop_${loop}"; then
return 0
fi
return 1
}
# 打印系统级崩溃日志(dmesg)
print_system_crash_log() {
local loop=$1
echo -e "\033[33m===== 系统级崩溃日志(dmesg)=====\033[0m"
dmesg | grep -A 5 -B 2 "pPowerManger.*segfault" | tail -10
echo -e "\033[33m===================================\033[0m"
}
echo -e "🔍 启动pPowerManger稳定性测试(强制捕获段错误)\n"
echo "📂 崩溃日志目录: ${CRASH_LOG_DIR}"
echo "⏱ 程序运行时长: ${RUN_DURATION}秒"
echo "📌 捕获信号: ${CRASH_SIGNALS[*]}"
echo -e "========================================\n"
cleanup # 初始清理
LOOP_COUNT=0
while true; do
LOOP_COUNT=$((LOOP_COUNT + 1))
if [ ${MAX_LOOP} -ne 0 ] && [ ${LOOP_COUNT} -gt ${MAX_LOOP} ]; then
echo -e "\n✅ 测试完成(${MAX_LOOP}次循环无崩溃)"
cleanup
exit 0
fi
echo -e "===== 第 ${LOOP_COUNT} 次循环 ====="
CRASH_LOG="${CRASH_LOG_DIR}/crash_loop_${LOOP_COUNT}.log"
GDB_CMD="${CRASH_LOG_DIR}/gdb_cmds_${LOOP_COUNT}.gdb"
# 生成强化版GDB脚本:强制捕获所有信号,优先初始化信号处理
cat > ${GDB_CMD} << EOF
# 核心:GDB启动后先设置信号捕获,再启动程序
set args pPowerManger.moos
set timeout ${GDB_TIMEOUT}
set print pretty on
set print frame-arguments all
set logging file ${CRASH_LOG}.gdb_raw
set logging on # 开启GDB原始日志(双重保障)
# 强制捕获所有致命信号
EOF
# 为每个崩溃信号添加捕获规则(追加到GDB脚本)
for sig in "${CRASH_SIGNALS[@]}"; do
cat >> ${GDB_CMD} << EOF
handle ${sig} stop print pass nostop # 即使子线程崩溃也捕获
EOF
done
# 追加程序启动和崩溃处理逻辑
cat >> ${GDB_CMD} << EOF
# 延迟10ms启动程序,确保GDB完全初始化
sleep 0.01
run
# 崩溃后强制打印所有信息(无论是否主线程)
if \$exitcode != 0 || \$signal_number != 0
echo "\n====================================="
echo " CRASH DETECTED"
echo "====================================="
echo "Loop: ${LOOP_COUNT}"
echo "Exit code: \$exitcode"
echo "Signal: \$signal_name (\$signal_number)"
echo "====================================="
thread apply all bt full # 打印所有线程的调用栈(关键!)
info threads
info proc mappings # 打印内存映射(排查内存越界)
info locals
info registers
endif
set logging off
quit
EOF
# 核心:用nohup+GDB启动,避免输出丢失;同时记录进程ID
echo "启动程序(GDB强化模式)..."
nohup timeout ${GDB_TIMEOUT} gdb -batch -x ${GDB_CMD} ./pPowerManger > ${CRASH_LOG} 2>&1 &
GDB_PID=$!
wait ${GDB_PID} # 等待GDB执行完成
# 双重验证:检查是否真崩溃
if is_real_crash ${CRASH_LOG} ${LOOP_COUNT}; then
# 捕获到真崩溃
echo -e "\033[31m❌ 第 ${LOOP_COUNT} 次循环捕获到段错误!\033[0m"
echo -e "\033[31m📄 崩溃日志: ${CRASH_LOG}\033[0m"
print_system_crash_log ${LOOP_COUNT}
# 打印最关键的调用栈(所有线程)
echo -e "\033[31m===== 所有线程崩溃调用栈 =====\033[0m"
grep -A 50 "thread apply all bt full" ${CRASH_LOG} | grep -v "No stack frame"
echo -e "\033[31m==============================\033[0m"
cleanup
echo -e "\n🛑 测试终止,完整日志在 ${CRASH_LOG}"
exit 1
else
# 无崩溃(正常退出/启动失败)
if grep -qi "Program exited normally" ${CRASH_LOG}; then
echo "✅ 程序正常运行${RUN_DURATION}秒后退出"
else
echo "⚠️ 程序启动失败(非段错误),继续循环"
# 保留启动失败日志(方便排查)
mv ${CRASH_LOG} ${CRASH_LOG}.start_fail
fi
rm -f ${GDB_CMD} ${CRASH_LOG}.gdb_raw
fi
cleanup
echo -e "第 ${LOOP_COUNT} 次循环完成\n"
sleep 0.5
done
Executable
+61
View File
@@ -0,0 +1,61 @@
#!/bin/bash
INVOCATION_ABS_DIR=`pwd`
# 默认设为Debug模式,避免无符号编译(核心修改1)
BUILD_TYPE="Debug"
CMD_LINE_ARGS=""
#-------------------------------------------------------------------
# Part 1: Check for and handle command-line arguments
#-------------------------------------------------------------------
for ARGI; do
if [ "${ARGI}" = "--help" -o "${ARGI}" = "-h" ] ; then
printf "%s [SWITCHES] \n" $0
printf "Switches: \n"
printf " --help, -h \n"
printf " --debug, -d \n"
printf " --release, -r \n"
printf "Notes: \n"
printf " (1) All other command line args will be passed as args \n"
printf " to \"make\" when it is eventually invoked. \n"
printf " (2) For example -k will continue making when/if a failure \n"
printf " is encountered in building one of the subdirectories. \n"
printf " (3) For example -j2 will utilize a 2nd core in the build \n"
printf " if your machine has two cores. -j4 etc for quad core. \n"
exit 0;
elif [ "${ARGI}" = "--debug" -o "${ARGI}" = "-d" ] ; then
BUILD_TYPE="Debug"
elif [ "${ARGI}" = "--release" -o "${ARGI}" = "-r" ] ; then
BUILD_TYPE="Release"
else
CMD_LINE_ARGS=$CMD_LINE_ARGS" "$ARGI
fi
done
#-------------------------------------------------------------------
# Part 2: Invoke the call to make in the build directory
#-------------------------------------------------------------------
mkdir -p build
cd build
# 核心修改2:添加RK3588 ARM64编译选项+强制调试符号
# -DCMAKE_CXX_FLAGS:全局C++编译选项,适配RK3588的cortex-a76架构
# -DCMAKE_BUILD_TYPE:指定编译模式
# -DCMAKE_CXX_FLAGS_DEBUG:Debug模式强制-O0 + 完整调试符号
# -DCMAKE_CXX_FLAGS_RELEASE:Release模式保留-g(调试符号),仅优化级别-O2
cmake \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DCMAKE_CXX_FLAGS="-march=armv8-a -mtune=cortex-a76 -mstrict-align -fPIC" \
-DCMAKE_CXX_FLAGS_DEBUG="-O0 -g -ggdb" \
-DCMAKE_CXX_FLAGS_RELEASE="-O2 -g -ggdb" \
../
# 核心修改3:添加-j参数加速编译(适配RK3588多核),默认用4核(可根据板卡调整)
# 若你传了-j参数,会覆盖默认的-j4
# if [[ ! $CMD_LINE_ARGS =~ "-j" ]]; then
# CMD_LINE_ARGS="-j4 ${CMD_LINE_ARGS}"
# fi
make ${CMD_LINE_ARGS}
cd ${INVOCATION_ABS_DIR}
+103 -85
View File
@@ -189,111 +189,126 @@ bool LowerCommManager::updatePoweSystemStates(){
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); //写入数据库
if(m_udpComm->popMsgFormQueue(time, m_CcuCurrentState));
{
m_pm->m_pmCurrentState.ccustate = m_CcuCurrentState.data;
m_pm->m_db->insertData(m_pm->m_pmCurrentState.ccustate); //写入数据库
msg_CcuStateFbMsg_Update_time = time;
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.ccustate);
m_pm->m_systemData->device_common_status.ccu_status.lastUpdateTime = m_pm->m_lowerCommManager->msg_CcuStateFbMsg_Update_time;
}
//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;
if(m_udpComm->popMsgFormQueue(time, m_disHighVolBusCurrentState));
{
// 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;
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;
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus1State);
m_pm->m_systemData->device_common_status.dis_hv_c1.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighVolBusFbMsg_Update_time;
}
}
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;
if(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;
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;
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus2State);
m_pm->m_systemData->device_common_status.dis_hv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighAVolBusFbMsg_Update_time;
}
}
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;
if(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;
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;
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus3State);
m_pm->m_systemData->device_common_status.dis_lv_c1.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighBVolBusFbMsg_Update_time;
}
}
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;
if(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;
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.bus4State);
m_pm->m_systemData->device_common_status.dis_lv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disLowBusFbMsg_Update_time;
}
}
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;
}
@@ -310,18 +325,21 @@ bool LowerCommManager::listenThreadFunc()
if(nRead > 0)
{
try {
if(!m_udpComm->pushMsgToQueue(Buff))
if(m_udpComm->pushMsgToQueue(Buff))
{
//更新当前状态
if(!updatePoweSystemStates())
{
std::cerr << "Error updating power system states" << std::endl;
}
}
else
{
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;
+4 -3
View File
@@ -55,6 +55,10 @@ PowerManger::PowerManger()
m_subDisSysCmd = {};
m_subDisSysState = {};
m_subDisSysFault = {};
//初始化系统数据
m_systemData = new SystemData();
//初始化控制指令
initControlCmd();
@@ -70,9 +74,6 @@ PowerManger::PowerManger()
m_db = new SQLite("power_data.db");
m_db->createTable();
//初始化系统数据
m_systemData = new SystemData();
//初始化http服务器
m_httpServer = new HttpServer(8090);
m_httpServer->setPowerManger(this);
Binary file not shown.
+75 -27
View File
@@ -36,7 +36,7 @@ public:
uint8_t maxLevel = 0;
// 遍历 sysFaultCodes 集合中的每个故障码
for (auto code : sysFaultCodes) {
// 提取0xabcd中的b位 (右移8位后取低4位)
// 提取0xabcd中的b位
uint8_t level = (code >> 8) & 0xF;
if (level > maxLevel) {
maxLevel = level;
@@ -46,9 +46,10 @@ public:
}
/**
* @brief 获取系统当前的故障码集合
* @return std::set<unsigned int>& 系统当前的故障码集合
* @return std::set<unsigned int> 系统当前的故障码集合
*/
const std::set<unsigned int>& getFaultCode() const {
std::set<unsigned int> getFaultCode() const {
std::lock_guard<std::mutex> lock(sysFaultCodesMutex);
return sysFaultCodes;
}
//燃料电池系统参数
@@ -524,11 +525,70 @@ public:
return code;
}
public:
SystemData(){
//初始化变量全部为0
memset(this, 0, sizeof(SystemData));
disSysFaultCode.clear();
sysFaultCodes.clear();
SystemData() :
m_db(nullptr),
fc_mode(0), fc_status(0), fc_fault_level(0),
output_power_limit(0.0f), total_generation_time(0.0f), total_generation_power(0.0f),
fc_fault_level_1(0), fc_fault_level_2(0), fc_fault_level_3(0), fc_fault_level_4(0),
hydrogen_capacity(0.0f), liquid_oxygen_capacity(0.0f),
palladium_temp(0.0f), main_pipe_pressure(0.0f), aux_pipe_pressure(0.0f),
cabin_pressure1(0.0f), cabin_pressure2(0.0f), cabin_temp1(0.0f), cabin_temp2(0.0f),
cabin_humidity1(0.0f), cabin_humidity2(0.0f),
flame_detector1(0), flame_detector2(0),
h2_concentration1(0.0f), h2_concentration2(0.0f), h2_concentration3(0.0f),
o2_concentration1(0.0f), o2_concentration2(0.0f),
ch3oh_concentration1(0.0f), ch3oh_concentration2(0.0f),
cabin_ox_concentration(0.0f), cabin_temperature(0.0f), cabin_humidity(0.0f), cabin_pressure(0.0f),
power_cabin_ox_concentration(0.0f), power_cabin_temperature(0.0f), power_cabin_humidity(0.0f), power_cabin_pressure(0.0f),
ins_relay_status1(0), ins_relay_status2(0), dyn_relay_status1(0), dyn_relay_status2(0),
ins_pos_relay_status(0), ins_charge_relay_status(0), ins_precharge_relay_status(0), ins_neg_relay_status(0),
dyn_pos_relay_status(0), dyn_charge_relay_status(0), dyn_precharge_relay_status(0), dyn_neg_relay_status(0),
ins_max_discharge_power(0.0f), dyn_max_discharge_power(0.0f),
ins_soc(0), dyn_soc(0),
ins_total_energy(0.0f), dyn_total_energy(0.0f),
ins_power_input(0.0f), dyn_power_input(0.0f),
ins_charge_status(0), dyn_charge_status(0),
ins_voltage_link(0.0f), ins_voltage_pack(0.0f), ins_current(0.0f),
ins_resistance_pos(0.0f), ins_resistance_neg(0.0f),
dyn_voltage_link(0.0f), dyn_voltage_pack(0.0f), dyn_current(0.0f),
dyn_resistance_pos(0.0f), dyn_resistance_neg(0.0f),
ins_emergency_status(0), dyn_emergency_status(0),
ins_soc_threshold1(0.0f), ins_soc_threshold2(0.0f), ins_soc_threshold3(0.0f),
dyn_soc_threshold1(0.0f), dyn_soc_threshold2(0.0f), dyn_soc_threshold3(0.0f),
ins_power_limit1(0.0f), ins_power_limit2(0.0f),
dyn_power_limit1(0.0f), dyn_power_limit2(0.0f),
device_online_flag1(0), device_online_flag2(0),
dyn_charge_level(0), dyn_water_leak_status(0), ins_water_leak_dcdc_status(0), reserved4(0),
water_leak_status_from_insbat(0), water_leak_status_from_dynbat(0), dcdc_status_from_insbat(0),
heartbeat(0),
powfaultCode(0), insfaultCode(0),
emergency_battery1_voltage(0.0), emergency_battery1_current(0.0), emergency_battery1_max_temp(0.0),
emergency_battery1_fault_word(0),
emergency_battery2_voltage(0.0), emergency_battery2_current(0.0), emergency_battery2_max_temp(0.0),
emergency_battery2_fault_word(0),
moosd_status(false),
leakageCode(0)
{
// 初始化数组
for (int i = 0; i < 10; ++i) reserved1[i] = 0.0f;
for (int i = 0; i < 2; ++i) reserved2[i] = 0;
for (int i = 0; i < 6; ++i) { dyn_alarm_flag[i] = 0; ins_alarm_flag[i] = 0; }
for (int i = 0; i < 2; ++i) reserved3[i] = 0;
for (int i = 0; i < 8; ++i) leakStatus[i] = false;
// 初始化嵌套结构体(它们有自己的构造函数)
// m_dcdcStatus 有构造函数,会自动初始化
// power_bus_status 等 POD 结构体,使用 memset 局部初始化
memset(&power_bus_status, 0, sizeof(power_bus_status));
memset(&power_a_bus_status, 0, sizeof(power_a_bus_status));
memset(&instrument_main_bus_status, 0, sizeof(instrument_main_bus_status));
memset(&instrument_bus_status, 0, sizeof(instrument_bus_status));
memset(&device_common_status, 0, sizeof(device_common_status));
memset(&device_online_status, 0, sizeof(device_online_status));
// std::set 和 std::mutex 已经通过它们的默认构造函数正确初始化
// 默认构造的 std::set 已经是空的,不需要调用 clear()
// disSysFaultCode 和 sysFaultCodes 会在后续操作中被填充
};
~SystemData(){};
@@ -544,7 +604,6 @@ public:
};
void updateSystemData(ccuState data){
fc_mode = data.fc_mode;
fc_status = data.fc_status;
fc_fault_level = data.fc_fault_level;
@@ -592,10 +651,12 @@ public:
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];
//保留字段 :ccuState中的reserved1只有2个元素,但SystemData中的reserved1有10个元素
// 只复制前2个元素,其余保持原值
for(int i=0; i<2; i++) {
reserved1[i] = static_cast<float>(data.reserved1[i]);
}
// 注意:reserved1[2]到reserved1[9]保持原值(0.0f)
//仪表舱参数
cabin_ox_concentration = data.cabin_ox_concentration * 0.1;
@@ -705,15 +766,7 @@ public:
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)
if(water_leak_status_from_insbat == 0x01 || water_leak_status_from_dynbat == 0x01)
{
leakStatus[LEAKAGE_LI_BATTERY] = true;
}
@@ -775,18 +828,13 @@ public:
//绝缘状态
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);
// 所有对 disSysFaultCode 的访问都在锁保护下
{
std::lock_guard<std::mutex> lock(faultCodeMutex);
if(power_bus_status.emergencyPowerLossSignal == 1) disSysFaultCode.insert(37); else disSysFaultCode.erase(37);
+31 -9
View File
@@ -1764,15 +1764,37 @@ class PowerManagerApp:
self.simulation_LowBusFbMsg.reservedCircuitBreaker2 = self.simulation_LVBCmdMsg.reservedCircuitBreaker2
self.simulation_LowBusFbMsg.emergencyLithiumBatteryGroup1CircuitBreaker = self.simulation_LVBCmdMsg.emergencyLithiumBatteryGroup1CircuitBreaker
self.send_udp_command(self.simulation_HighVolBusFbMsg.pack(), self.udp_ip, self.udp_port)
time.sleep(1)
self.send_udp_command(self.simulation_HighAVolBusFbMsg.pack(), self.udp_ip, self.udp_port)
time.sleep(1)
self.send_udp_command(self.simulation_LowBusFbMsg.pack(), self.udp_ip, self.udp_port)
time.sleep(1)
self.send_udp_command(self.simulation_LowMainBusFbMsg.pack(), self.udp_ip, self.udp_port)
time.sleep(1) # 1秒间隔
# self.send_udp_command(self.simulation_HighVolBusFbMsg.pack(), self.udp_ip, self.udp_control_port)
# time.sleep(0.1)
# self.send_udp_command(self.simulation_HighAVolBusFbMsg.pack(), self.udp_ip, self.udp_control_port)
# time.sleep(0.1)
# self.send_udp_command(self.simulation_LowBusFbMsg.pack(), self.udp_ip, self.udp_control_port)
# time.sleep(0.1)
# self.send_udp_command(self.simulation_LowMainBusFbMsg.pack(), self.udp_ip, self.udp_control_port)
# time.sleep(0.1) # 1秒间隔
# 处理高压母线数据
packed_data = self.simulation_HighVolBusFbMsg.pack()
error_packed_data = packed_data[:-1] + b'\x00' # 修改校验位为0x00
self.send_udp_command(error_packed_data, self.udp_ip, self.udp_control_port)
# time.sleep(0.1)
# 处理高压A母线数据
packed_data = self.simulation_HighAVolBusFbMsg.pack()
error_packed_data = packed_data[:-1] + b'\x00' # 修改校验位为0x00
self.send_udp_command(error_packed_data, self.udp_ip, self.udp_control_port)
# time.sleep(0.01)
# 处理低压母线数据
packed_data = self.simulation_LowBusFbMsg.pack()
error_packed_data = packed_data[:-1] + b'\x00' # 修改校验位为0x00
self.send_udp_command(error_packed_data, self.udp_ip, self.udp_control_port)
# time.sleep(0.01)
# 处理仪表主母线数据
packed_data = self.simulation_LowMainBusFbMsg.pack()
error_packed_data = packed_data[:-1] + b'\x00' # 修改校验位为0x00
self.send_udp_command(error_packed_data, self.udp_ip, self.udp_control_port)
time.sleep(0.01) # 1秒间隔
def on_connection_changed(self, *args):
"""连接状态改变回调"""
if self.Start_Connection.get():
@@ -1899,4 +1921,4 @@ if __name__ == "__main__":
root.protocol("WM_DELETE_WINDOW", app.on_closing)
print('start')
root.mainloop()
print('end')
print('end')