修复:跨线程数据竞争 + 协议字段越界 + UDP 发送失败吞错

- 并发安全:PowerManger 新增 m_stateMutex,保护 m_pmCurrentState /
  m_currentDisBreakerState / m_CcuColCmd / faultCode,并封装
  addFaultCode/clearFaultCodes/getFaultCodes 访问器
- SystemData 新增跨线程读访问器(getDynVoltageLink/getPowerBusStatus/
  getDcdcStatus/getDeviceCommonStatus 等)及配电故障码集合加锁访问
- upmsg buildMsg / httpserver pushSystemData / LowerCommManager 均改为
  持锁快照,避免 listen 线程与 comm 线程撕裂读写
- 修复析构顺序:先删 httpServer 再删其他对象,避免 use-after-free
- 修复 ccuState reserved2 越界读(协议预留 2 字节,结构体仅声明 1),
  修正 coutMsg 中 SOC 门限/功率限制字段打印
- udpComm::sendDisSysCmd 不再吞掉异常,返回 sendMsg 实际结果并记录 ERROR,
  新增 SendDisSysCmdFailsWithoutSocket 单测
- 新增 fullFeeder 全类型 UDP 集成仿真器与 fetch-data/clean-data 脚本,
  .gitignore 补充 SQLite 运行期文件与 fullFeeder 二进制
This commit is contained in:
zjk
2026-08-21 11:36:19 +08:00
parent 7819ea621f
commit 12f0dee86e
20 changed files with 2406 additions and 285 deletions
+6
View File
@@ -260,6 +260,12 @@ reports/
# CI test binaries (built into bin/) # CI test binaries (built into bin/)
bin/PowerMangerTests bin/PowerMangerTests
bin/udpFeeder bin/udpFeeder
bin/fullFeeder
# SQLite runtime artifacts
*.db-shm
*.db-wal
*.db-journal
# Cross-compiled aarch64 artifacts (scripts/cross-build-local.sh) # Cross-compiled aarch64 artifacts (scripts/cross-build-local.sh)
bin/arm64/ bin/arm64/
+138
View File
@@ -0,0 +1,138 @@
#!/bin/bash
#=======================================================================
# FILE: scripts/clean-data.sh
# DESC: 清理目标板卡 (RK3588 / Ubuntu 22.04) 上的数据库与日志文件。
# 默认清理板卡运行目录 /root/work/h100/data/ 下的:
# power_data.db (+ -wal/-shm) 主机功率数据库
# feedback_data.db 反馈落盘数据库
# pPowerManger.log 主机运行日志
# 默认先停止 3 个服务再清理(避免 SQLite WAL 仍在写入)。
#
# 用法:
# ./scripts/clean-data.sh # 停服务 -> 清理 data 目录(不重启)
# ./scripts/clean-data.sh --start # 清理后重新启动 3 个服务
# ./scripts/clean-data.sh --no-stop # 不停服务直接清理(慎用)
# ./scripts/clean-data.sh --stale # 额外清理 bin/ 与 src/bin/ 下的旧 db/log
#
# 参数:
# --host <ip> 目标主机(默认 192.168.0.223)
# --user <user> 登录用户(默认 root)
# --board-dir <dir> 板卡部署根目录(默认 /root/work/h100)
# --start 清理后重启服务
# --no-stop 不停服务直接清理(慎用)
# --stale 额外清理历史遗留的 bin/、src/bin/ 下旧数据库与日志
# -h, --help 显示帮助
#
# 前置: 板卡已配免密 SSH(见 scripts/deploy.sh setup-ssh)。
#=======================================================================
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "${SCRIPT_DIR}")"
HOST="192.168.0.223"
USER="root"
BOARD_DIR="/root/work/h100"
DO_START=0
DO_STOP=1
DO_STALE=0
SERVICES=(moosdb pPowerManger pPowerMangerHost)
# 板卡 data 目录下需要清理的文件(含 SQLite WAL/SHM)
DATA_FILES=(power_data.db power_data.db-wal power_data.db-shm feedback_data.db pPowerManger.log)
# 历史遗留目录(旧部署位置),仅当 --stale 时清理
STALE_DIRS=("${BOARD_DIR}/bin" "${BOARD_DIR}/src/bin")
info() { printf '\033[1;36m[clean-data]\033[0m %s\n' "$*"; }
ok() { printf '\033[1;32m[clean-data]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[clean-data]\033[0m %s\n' "$*"; }
err() { printf '\033[1;31m[clean-data]\033[0m %s\n' "$*"; }
usage() {
sed -n '2,29p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
exit 0
}
#-------------------------------------------------------------------
# 参数解析
#-------------------------------------------------------------------
while [ $# -gt 0 ]; do
case "$1" in
--host) [ $# -ge 2 ] || { err "--host 需要参数"; exit 1; }; HOST="$2"; shift 2 ;;
--user) [ $# -ge 2 ] || { err "--user 需要参数"; exit 1; }; USER="$2"; shift 2 ;;
--board-dir) [ $# -ge 2 ] || { err "--board-dir 需要参数"; exit 1; }; BOARD_DIR="$2"; shift 2 ;;
--start) DO_START=1; shift ;;
--no-stop) DO_STOP=0; shift ;;
--stale) DO_STALE=1; shift ;;
-h|--help) usage ;;
*) err "未知参数: $1(见 --help)"; exit 1 ;;
esac
done
STALE_DIRS=("${BOARD_DIR}/bin" "${BOARD_DIR}/src/bin")
SSH_TARGET="${USER}@${HOST}"
SSH="ssh -o BatchMode=yes -o ConnectTimeout=5"
#-------------------------------------------------------------------
# 1. 前置检查
#-------------------------------------------------------------------
if ! ${SSH} "${SSH_TARGET}" 'true' 2>/dev/null; then
err "无法免密 SSH 到 ${SSH_TARGET}"
err "请先执行: ./scripts/deploy.sh setup-ssh"
exit 1
fi
ok "SSH 连接正常: ${SSH_TARGET}"
#-------------------------------------------------------------------
# 2. 停止服务(默认)
#-------------------------------------------------------------------
if [ "${DO_STOP}" = "1" ]; then
info "停止服务 ${SERVICES[*]} ..."
${SSH} "${SSH_TARGET}" "systemctl stop pPowerMangerHost pPowerManger moosdb 2>/dev/null; true"
ok "服务已停止"
else
warn "--no-stop:不停服务直接清理,可能产生脏数据(SQLite 仍在写入)"
fi
#-------------------------------------------------------------------
# 3. 清理 data 目录
#-------------------------------------------------------------------
BOARD_DATA="${BOARD_DIR}/data"
info "清理 ${BOARD_DATA}/ ..."
for f in "${DATA_FILES[@]}"; do
${SSH} "${SSH_TARGET}" "rm -f ${BOARD_DATA}/${f}" \
&& ok "删除 ${f}" || warn "删除 ${f} 失败(可能不存在)"
done
#-------------------------------------------------------------------
# 4. 可选: 清理历史遗留目录
#-------------------------------------------------------------------
if [ "${DO_STALE}" = "1" ]; then
for d in "${STALE_DIRS[@]}"; do
info "清理历史遗留 ${d}/ 下的 db/log ..."
${SSH} "${SSH_TARGET}" "rm -f ${d}/power_data.db ${d}/power_data.db-wal ${d}/power_data.db-shm ${d}/feedback_data.db ${d}/pPowerManger.log 2>/dev/null; true"
ok "${d} 已清理"
done
fi
#-------------------------------------------------------------------
# 5. 可选: 重启服务
#-------------------------------------------------------------------
if [ "${DO_START}" = "1" ]; then
info "启动服务 (moosdb -> pPowerManger -> pPowerMangerHost) ..."
${SSH} "${SSH_TARGET}" "systemctl start moosdb && sleep 1 && \
systemctl start pPowerManger pPowerMangerHost" \
|| { err "启动失败"; exit 1; }
ok "服务已启动"
else
echo ""
info "清理完成,服务未启动。需要重启请加 --start 或手动:"
echo " systemctl start moosdb pPowerManger pPowerMangerHost"
fi
echo ""
ok "完成。"
+125
View File
@@ -0,0 +1,125 @@
#!/bin/bash
#=======================================================================
# FILE: scripts/fetch-data.sh
# DESC: 从目标板卡 (RK3588 / Ubuntu 22.04) 下载数据库与日志到本地。
# 默认抓取板卡运行目录 /root/work/h100/data/ 下的:
# power_data.db (+ -wal/-shm) 主机功率数据库
# feedback_data.db 反馈落盘数据库
# pPowerManger.log 主机运行日志
# 可选 --journal 一并导出三个 systemd 服务的 journal 日志。
#
# 用法:
# ./scripts/fetch-data.sh # 下载 db + 日志到本地 data/board-<时间>/
# ./scripts/fetch-data.sh --journal # 额外导出 systemd journal
# ./scripts/fetch-data.sh --out-dir /tmp/xx # 指定本地保存目录
#
# 参数:
# --host <ip> 目标主机(默认 192.168.0.223)
# --user <user> 登录用户(默认 root)
# --board-dir <dir> 板卡部署根目录(默认 /root/work/h100)
# --out-dir <dir> 本地保存目录(默认 data/board-<时间>)
# --journal 额外导出 3 个服务的 systemd journal 日志
# -h, --help 显示帮助
#
# 前置: 板卡已配免密 SSH(见 scripts/deploy.sh setup-ssh)。
#=======================================================================
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "${SCRIPT_DIR}")"
HOST="192.168.0.223"
USER="root"
BOARD_DIR="/root/work/h100"
OUT_DIR=""
DO_JOURNAL=0
SERVICES=(moosdb pPowerManger pPowerMangerHost)
# 板卡 data 目录下需要下载的文件(含 SQLite WAL/SHM 以保证数据完整)
DATA_FILES=(power_data.db power_data.db-wal power_data.db-shm feedback_data.db pPowerManger.log)
info() { printf '\033[1;36m[fetch-data]\033[0m %s\n' "$*"; }
ok() { printf '\033[1;32m[fetch-data]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[fetch-data]\033[0m %s\n' "$*"; }
err() { printf '\033[1;31m[fetch-data]\033[0m %s\n' "$*"; }
usage() {
sed -n '2,26p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
exit 0
}
#-------------------------------------------------------------------
# 参数解析
#-------------------------------------------------------------------
while [ $# -gt 0 ]; do
case "$1" in
--host) [ $# -ge 2 ] || { err "--host 需要参数"; exit 1; }; HOST="$2"; shift 2 ;;
--user) [ $# -ge 2 ] || { err "--user 需要参数"; exit 1; }; USER="$2"; shift 2 ;;
--board-dir) [ $# -ge 2 ] || { err "--board-dir 需要参数"; exit 1; }; BOARD_DIR="$2"; shift 2 ;;
--out-dir) [ $# -ge 2 ] || { err "--out-dir 需要参数"; exit 1; }; OUT_DIR="$2"; shift 2 ;;
--journal) DO_JOURNAL=1; shift ;;
-h|--help) usage ;;
*) err "未知参数: $1(见 --help)"; exit 1 ;;
esac
done
SSH_TARGET="${USER}@${HOST}"
SSH="ssh -o BatchMode=yes -o ConnectTimeout=5"
SCP="scp -o BatchMode=yes -o ConnectTimeout=5"
#-------------------------------------------------------------------
# 1. 前置检查
#-------------------------------------------------------------------
if ! ${SSH} "${SSH_TARGET}" 'true' 2>/dev/null; then
err "无法免密 SSH 到 ${SSH_TARGET}"
err "请先执行: ./scripts/deploy.sh setup-ssh"
exit 1
fi
ok "SSH 连接正常: ${SSH_TARGET}"
if [ -z "${OUT_DIR}" ]; then
OUT_DIR="${PROJECT_ROOT}/data/board-$(date +%Y%m%d-%H%M%S)"
fi
mkdir -p "${OUT_DIR}" || { err "无法创建本地目录 ${OUT_DIR}"; exit 1; }
info "本地保存目录: ${OUT_DIR}"
#-------------------------------------------------------------------
# 2. 下载 data 目录下的数据库与日志
#-------------------------------------------------------------------
BOARD_DATA="${BOARD_DIR}/data"
missing=0
for f in "${DATA_FILES[@]}"; do
if ${SSH} "${SSH_TARGET}" "[ -f ${BOARD_DATA}/${f} ]" 2>/dev/null; then
info "下载 ${f} ..."
${SCP} -q "${SSH_TARGET}:${BOARD_DATA}/${f}" "${OUT_DIR}/" \
|| { err "下载 ${f} 失败"; exit 1; }
ok "${f}"
else
warn "板卡上不存在: ${BOARD_DATA}/${f}(跳过)"
missing=$((missing+1))
fi
done
[ "${missing}" -eq "${#DATA_FILES[@]}" ] && { err "板卡 data 目录下没有任何可下载文件"; exit 1; }
#-------------------------------------------------------------------
# 3. 可选: 导出 systemd journal
#-------------------------------------------------------------------
if [ "${DO_JOURNAL}" = "1" ]; then
for s in "${SERVICES[@]}"; do
info "导出 journal: ${s} ..."
${SSH} "${SSH_TARGET}" "journalctl --no-pager -u ${s} 2>/dev/null" > "${OUT_DIR}/${s}.journal.log" \
|| { warn "导出 ${s} journal 失败(可能无记录)"; }
ok "${s}.journal.log"
done
fi
#-------------------------------------------------------------------
# 4. 完成
#-------------------------------------------------------------------
echo ""
ok "下载完成。本地文件:"
ls -lah "${OUT_DIR}" | sed 's/^/ /'
echo ""
info "查看数据库可用: sqlite3 ${OUT_DIR}/power_data.db .tables"
+112 -86
View File
@@ -80,17 +80,23 @@ void LowerCommManager::setCommLogger(ICommLogger* logger)
if (m_udpComm) m_udpComm->setCommLogger(logger); if (m_udpComm) m_udpComm->setCommLogger(logger);
} }
void LowerCommManager::processPeriodicTasks() { void LowerCommManager::processPeriodicTasks() {
sendCcuCommand(m_pm->m_CcuColCmd); ccuColCmd cmd;
m_pm->m_db->insertData(m_pm->m_CcuColCmd); {
std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
cmd = m_pm->m_CcuColCmd;
}
sendCcuCommand(cmd);
m_pm->m_db->insertData(cmd);
//延时5ms //延时5ms
usleep(5000); usleep(5000);
if(m_pm->m_systemData->device_common_status.dis_hv_c1.isTimeout ) auto devStatus = m_pm->m_systemData->getDeviceCommonStatus();
if(devStatus.dis_hv_c1.isTimeout )
{ {
disHighVolBusCmd clr1{}; disHighVolBusCmd clr1{};
m_udpComm->sendDisSysCmd(clr1); m_udpComm->sendDisSysCmd(clr1);
MOOSPause(200); MOOSPause(200);
} }
if(m_pm->m_systemData->device_common_status.dis_lv_c1.isTimeout ) if(devStatus.dis_lv_c1.isTimeout )
{ {
disHighBVolBusCmd clr3{}; disHighBVolBusCmd clr3{};
m_udpComm->sendDisSysCmd(clr3); m_udpComm->sendDisSysCmd(clr3);
@@ -195,10 +201,14 @@ bool LowerCommManager::updatePoweSystemStates(){
double time; double time;
if(m_udpComm->popMsgFormQueue(time, m_CcuCurrentState)) if(m_udpComm->popMsgFormQueue(time, m_CcuCurrentState))
{ {
m_pm->m_pmCurrentState.ccustate = m_CcuCurrentState.data; ccuState local = m_CcuCurrentState.data;
m_pm->m_db->insertData(m_pm->m_pmCurrentState.ccustate); //写入数据库 {
std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
m_pm->m_pmCurrentState.ccustate = local;
}
m_pm->m_db->insertData(local); //写入数据库
msg_CcuStateFbMsg_Update_time = time; msg_CcuStateFbMsg_Update_time = time;
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.ccustate); m_pm->m_systemData->updateSystemData(local);
{ {
std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex); std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex);
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.ccu_status.lastUpdateTime = m_pm->m_lowerCommManager->msg_CcuStateFbMsg_Update_time;
@@ -219,29 +229,29 @@ bool LowerCommManager::updatePoweSystemStates(){
double time; double time;
if(m_udpComm->popMsgFormQueue(time, m_disHighVolBusCurrentState)) if(m_udpComm->popMsgFormQueue(time, m_disHighVolBusCurrentState))
{ {
// m_udpComm->popMsgFormQueue(time,m_disHighVolBusCurrentState); disHighVolBusState local = m_disHighVolBusCurrentState.data;
m_pm->m_pmCurrentState.bus1State = m_disHighVolBusCurrentState.data; {
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus1State); //写入数据库 std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
m_pm->m_pmCurrentState.bus1State = local;
disBus1Breaker pdis1{};
pdis1.fuelCellCircuitBreaker = (local.fuelCellCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.powerLithiumBatteryCircuitBreaker = (local.powerLithiumBatteryCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.propulsionMotorCircuitBreaker = (local.propulsionMotorCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.lithiumBatteryGroupInstrumentCircuitBreaker = (local.lithiumBatteryGroupInstrumentCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.dcDc5ModuleCircuitBreaker = (local.dcDc5ModuleCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.bowHighVoltageDistributionBoxCircuitBreaker = (local.bowHighVoltageDistributionBoxCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.sternFTDevice45CircuitBreaker = (local.sternFTDevice45CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.sternRudderSwitch1CircuitBreaker = (local.sternRudderSwitch1CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.sternRudderSwitch2CircuitBreaker = (local.sternRudderSwitch2CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.fbReservedCircuitBreaker = (local.fbReservedCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.tyzReservedCircuitBreaker = (local.tyzReservedCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.reservedCircuitBreaker = (local.reservedCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis1.paceholder = 0;
m_pm->m_currentDisBreakerState.bus1Breaker = pdis1;
}
m_pm->m_db->insertData(local); //写入数据库
msg_disHighVolBusFbMsg_Update_time = time; msg_disHighVolBusFbMsg_Update_time = time;
m_pm->m_systemData->updateSystemData(local);
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);
{ {
std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex); std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex);
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_c1.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighVolBusFbMsg_Update_time;
@@ -253,22 +263,23 @@ bool LowerCommManager::updatePoweSystemStates(){
double time; double time;
if(m_udpComm->popMsgFormQueue(time,m_disHighAVolBusCurrentState)) if(m_udpComm->popMsgFormQueue(time,m_disHighAVolBusCurrentState))
{ {
m_pm->m_pmCurrentState.bus2State = m_disHighAVolBusCurrentState.data; disHighAVolBusState local = m_disHighAVolBusCurrentState.data;
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus2State); //写入数据库 {
std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
m_pm->m_pmCurrentState.bus2State = local;
disBus2Breaker pdis2{};
pdis2.bowFTDevice123CircuitBreaker = (local.bowFTDevice123CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis2.actuatorCircuitBreaker = (local.actuatorCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis2.mastSteeringGearControlBoxCircuitBreaker = (local.mastSteeringGearControlBoxCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis2.xczCircuitBreaker = (local.xczCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis2.bowRudderControlBoxCircuitBreaker = (local.bowRudderControlBoxCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis2.openWaterCoverStartCylinderCircuitBreaker = (local.openWaterCoverStartCylinderCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis2.paceholder = 0;
m_pm->m_currentDisBreakerState.bus2Breaker = pdis2;
}
m_pm->m_db->insertData(local); //写入数据库
msg_disHighAVolBusFbMsg_Update_time = time; msg_disHighAVolBusFbMsg_Update_time = time;
m_pm->m_systemData->updateSystemData(local);
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);
{ {
std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex); std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex);
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_hv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighAVolBusFbMsg_Update_time;
@@ -281,22 +292,24 @@ bool LowerCommManager::updatePoweSystemStates(){
double time; double time;
if(m_udpComm->popMsgFormQueue(time,m_disHighBVolBusCurrentState)) if(m_udpComm->popMsgFormQueue(time,m_disHighBVolBusCurrentState))
{ {
m_pm->m_pmCurrentState.bus3State = m_disHighBVolBusCurrentState.data; disLowMainBusState local = m_disHighBVolBusCurrentState.data;
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus3State); //写入数据库 {
std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
m_pm->m_pmCurrentState.bus3State = local;
disBus3Breaker pdis3{};
pdis3.lithiumBatteryGroupInstrumentCircuitBreaker = (local.lithiumBatteryGroupInstrumentCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis3.bowLowVoltageDistributionBoxCircuitBreaker = (local.bowLowVoltageDistributionBoxCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis3.unit4InstrumentDC48VCircuitBreaker = (local.unit4InstrumentDC48VCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis3.dcC1DCDistributionPanelCircuitBreaker = (local.dcC1DCDistributionPanelCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis3.reservedCircuitBreaker1 = (local.reservedCircuitBreaker1 == BREAK_ON) ? 1 : 0;
pdis3.reservedCircuitBreaker2 = (local.reservedCircuitBreaker2 == BREAK_ON) ? 1 : 0;
pdis3.emergencyLithiumBatteryGroup2CircuitBreaker = (local.emergencyLithiumBatteryGroup2CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis3.paceholder = 0;
m_pm->m_currentDisBreakerState.bus3Breaker = pdis3;
}
m_pm->m_db->insertData(local); //写入数据库
msg_disHighBVolBusFbMsg_Update_time = time; msg_disHighBVolBusFbMsg_Update_time = time;
m_pm->m_systemData->updateSystemData(local);
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);
{ {
std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex); std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex);
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_c1.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighBVolBusFbMsg_Update_time;
@@ -308,23 +321,25 @@ bool LowerCommManager::updatePoweSystemStates(){
double time; double time;
if(m_udpComm->popMsgFormQueue(time,m_disLowBusState)) if(m_udpComm->popMsgFormQueue(time,m_disLowBusState))
{ {
m_pm->m_pmCurrentState.bus4State = m_disLowBusState.data; disLowBusState local = m_disLowBusState.data;
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus4State); //写入数据库 {
std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
m_pm->m_pmCurrentState.bus4State = local;
disBus4Breaker pdis4{};
pdis4.unit1CircuitBreaker = (local.unit1CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis4.unit2CircuitBreaker = (local.unit2CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis4.unit3CircuitBreaker = (local.unit3CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis4.unit5CircuitBreaker = (local.unit5CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis4.bowPZDeviceCircuitBreaker = (local.bowPZDeviceCircuitBreaker == BREAK_ON) ? 1 : 0;
pdis4.reservedCircuitBreaker1 = (local.reservedCircuitBreaker1 == BREAK_ON) ? 1 : 0;
pdis4.reservedCircuitBreaker2 = (local.reservedCircuitBreaker2 == BREAK_ON) ? 1 : 0;
pdis4.emergencyLithiumBatteryGroup1CircuitBreaker = (local.emergencyLithiumBatteryGroup1CircuitBreaker == BREAK_ON) ? 1 : 0;
pdis4.paceholder = 0;
m_pm->m_currentDisBreakerState.bus4Breaker = pdis4;
}
m_pm->m_db->insertData(local); //写入数据库
msg_disLowBusFbMsg_Update_time = time; msg_disLowBusFbMsg_Update_time = time;
m_pm->m_systemData->updateSystemData(local);
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);
{ {
std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex); std::lock_guard<std::mutex> lock(m_pm->m_systemData->m_dataMutex);
m_pm->m_systemData->device_common_status.dis_lv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disLowBusFbMsg_Update_time; m_pm->m_systemData->device_common_status.dis_lv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disLowBusFbMsg_Update_time;
@@ -476,7 +491,7 @@ void LowerCommManager::coutMsg(const msg_CcuStateFbMsg& p, std::ostream& os){
os << "甲醇浓度1 (ch3oh_concentration1): " << p.data.ch3oh_concentration1 * 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"; os << "甲醇浓度2 (ch3oh_concentration2): " << p.data.ch3oh_concentration2 * 0.01 << "% LEL\n";
for (int i = 0; i < 10; ++i) for (int i = 0; i < 2; ++i)
os << "保留字段 reserved1[" << i << "]: 0x" << std::hex << p.data.reserved1[i] << "\n"; 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_ox_concentration): " << p.data.cabin_ox_concentration * 0.1 << "%\n";
@@ -531,12 +546,18 @@ void LowerCommManager::coutMsg(const msg_CcuStateFbMsg& p, std::ostream& os){
os << "仪表紧急状态 (ins_emergency_status): 0x" << std::hex << static_cast<int>(p.data.ins_emergency_status) << "\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"; os << "动力紧急状态 (dyn_emergency_status): 0x" << static_cast<int>(p.data.dyn_emergency_status) << "\n";
for (int i = 0; i < 2; ++i) for (int i = 0; i < 1; ++i)
os << "保留字段 reserved2[" << i << "]: 0x" << std::hex << static_cast<int>(p.data.reserved2[i]) << "\n"; 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_threshold1: 0x" << std::hex << static_cast<int>(p.data.ins_soc_threshold1) << "\n";
os << "SOC门限值 ins_soc_threshold" << i+1 << ": 0x" << std::hex << static_cast<int>(p.data.ins_soc_threshold1) << "\n"; os << "SOC门限值 ins_soc_threshold2: 0x" << std::hex << static_cast<int>(p.data.ins_soc_threshold2) << "\n";
for (int i = 0; i < 4; ++i) os << "SOC门限值 ins_soc_threshold3: 0x" << std::hex << static_cast<int>(p.data.ins_soc_threshold3) << "\n";
os << "功率限制 ins_power_limit" << i+1 << ": 0x" << std::hex << static_cast<int>(p.data.ins_power_limit1) << "\n"; os << "SOC门限值 dyn_soc_threshold1: 0x" << std::hex << static_cast<int>(p.data.dyn_soc_threshold1) << "\n";
os << "SOC门限值 dyn_soc_threshold2: 0x" << std::hex << static_cast<int>(p.data.dyn_soc_threshold2) << "\n";
os << "SOC门限值 dyn_soc_threshold3: 0x" << std::hex << static_cast<int>(p.data.dyn_soc_threshold3) << "\n";
os << "功率限制 ins_power_limit1: 0x" << std::hex << static_cast<int>(p.data.ins_power_limit1) << "\n";
os << "功率限制 ins_power_limit2: 0x" << std::hex << static_cast<int>(p.data.ins_power_limit2) << "\n";
os << "功率限制 dyn_power_limit1: 0x" << std::hex << static_cast<int>(p.data.dyn_power_limit1) << "\n";
os << "功率限制 dyn_power_limit2: 0x" << std::hex << static_cast<int>(p.data.dyn_power_limit2) << "\n";
os << "设备在线状态1 (device_online_flag1): 0x" << std::hex << p.data.device_online_flag1 << "\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 << "设备在线状态2 (device_online_flag2): 0x" << p.data.device_online_flag2 << "\n";
@@ -666,11 +687,11 @@ bool LowerCommManager::operate_HV_dcDc5_Breaker(char opt)
m_udpComm->sendDisSysCmd(cmd); m_udpComm->sendDisSysCmd(cmd);
// ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1&(0x02); // ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1&(0x02);
ok = m_pm->m_systemData->m_dcdcStatus.workingStatus; ok = m_pm->m_systemData->getDcdcStatus().workingStatus;
MOOSPause(100); MOOSPause(100);
while ( !ok ) { while ( !ok ) {
if( m_pm->m_systemData->m_dcdcStatus.workingStatus ) if( m_pm->m_systemData->getDcdcStatus().workingStatus )
{ {
ok = true; ok = true;
break; break;
@@ -718,11 +739,11 @@ bool LowerCommManager::operate_HV_coolingSystem_Breaker(char opt)
m_udpComm->sendDisSysCmd(cmd); m_udpComm->sendDisSysCmd(cmd);
// ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1 & 0x60; // ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1 & 0x60;
ok = m_pm->m_systemData->m_dcdcStatus.coolingPump1Running || m_pm->m_systemData->m_dcdcStatus.coolingPump2Running; ok = m_pm->m_systemData->getDcdcStatus().coolingPump1Running || m_pm->m_systemData->getDcdcStatus().coolingPump2Running;
MOOSPause(100); MOOSPause(100);
while ( !ok ) { while ( !ok ) {
if( (m_pm->m_systemData->m_dcdcStatus.coolingPump1Running || m_pm->m_systemData->m_dcdcStatus.coolingPump2Running) ) if( (m_pm->m_systemData->getDcdcStatus().coolingPump1Running || m_pm->m_systemData->getDcdcStatus().coolingPump2Running) )
{ {
ok = true; ok = true;
break; break;
@@ -942,7 +963,12 @@ bool LowerCommManager::operateBreakerGeneric(
m_udpComm->sendDisSysCmd(cmd); m_udpComm->sendDisSysCmd(cmd);
MOOSPause(100); MOOSPause(100);
while ( !ok ) { while ( !ok ) {
if( readState() == getBreakerOption(opt) ) StateT cur;
{
std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
cur = readState();
}
if( cur == getBreakerOption(opt) )
{ {
ok = true; ok = true;
break; break;
+29 -5
View File
@@ -86,11 +86,14 @@ PowerManger::PowerManger()
PowerManger::~PowerManger() PowerManger::~PowerManger()
{ {
m_commThread.Stop(); m_commThread.Stop();
delete m_lowerCommManager; // 先停止监听线程,确保其不再调用 DB // 必须先停 HTTP 线程(stop() 内部 pthread_join 阻塞等待线程退出),
// 否则 HTTP 线程每秒仍会读取 m_systemData / m_lowerCommManager / m_upperCommManager,
// 导致 use-after-free。
delete m_httpServer;
delete m_lowerCommManager; // 停止监听线程,确保其不再调用 DB
delete m_db; delete m_db;
delete m_upperCommManager; delete m_upperCommManager;
delete m_systemData; delete m_systemData; // 最后删除,此时无任何线程引用
delete m_httpServer;
} }
//--------------------------------------------------------- //---------------------------------------------------------
@@ -374,10 +377,28 @@ void PowerManger::initControlCmd()
} }
void PowerManger::addFaultCode(unsigned int code)
{
std::lock_guard<std::mutex> lock(m_stateMutex);
faultCode.push_back(code);
}
void PowerManger::clearFaultCodes()
{
std::lock_guard<std::mutex> lock(m_stateMutex);
faultCode.clear();
}
std::vector<unsigned int> PowerManger::getFaultCodes() const
{
std::lock_guard<std::mutex> lock(m_stateMutex);
return faultCode;
}
unsigned char PowerManger::getFaultLevel() unsigned char PowerManger::getFaultLevel()
{ {
unsigned char maxLevel = 0; unsigned char maxLevel = 0;
for (auto code : faultCode) { for (auto code : getFaultCodes()) {
// 提取0xabcd中的b位 (右移8位后取低4位) // 提取0xabcd中的b位 (右移8位后取低4位)
unsigned char level = (code >> 8) & 0xF; unsigned char level = (code >> 8) & 0xF;
if (level > maxLevel) { if (level > maxLevel) {
@@ -391,7 +412,10 @@ bool PowerManger::commLoop()
{ {
while(!m_commThread.IsQuitRequested()) while(!m_commThread.IsQuitRequested())
{ {
m_CcuColCmd.heartbeat++; {
std::lock_guard<std::mutex> lock(m_stateMutex);
m_CcuColCmd.heartbeat++;
}
m_lowerCommManager->processPeriodicTasks(); m_lowerCommManager->processPeriodicTasks();
m_upperCommManager->processPeriodicTasks(); m_upperCommManager->processPeriodicTasks();
// 延时1秒 // 延时1秒
+6
View File
@@ -87,6 +87,12 @@ class PowerManger : public AppCastingMOOSApp
//===========================FEEDBACK====================================== //===========================FEEDBACK======================================
pmState m_pmCurrentState; //能源系统的当前状态(由下位机线程修改) pmState m_pmCurrentState; //能源系统的当前状态(由下位机线程修改)
disSysBreakerList m_currentDisBreakerState; //配电断路器状态 disSysBreakerList m_currentDisBreakerState; //配电断路器状态
// 跨线程共享状态保护:m_pmCurrentState / m_currentDisBreakerState / m_CcuColCmd / faultCode
// 纪律:绝不与 SystemData::m_dataMutex 同时持有(持锁期间不调用 updateSystemData/pushSystemData)
mutable std::mutex m_stateMutex;
void addFaultCode(unsigned int code);
void clearFaultCodes();
std::vector<unsigned int> getFaultCodes() const;
DriverTable m_currentDriverState; DriverTable m_currentDriverState;
DriverTable m_subDisSysState; DriverTable m_subDisSysState;
DriverTable m_subDisSysFault; DriverTable m_subDisSysFault;
+14 -5
View File
@@ -214,11 +214,20 @@ void UpperCommManager::processPeriodicTasks() {
} }
void UpperCommManager::buildSystemReport() { void UpperCommManager::buildSystemReport() {
// 跨线程共享状态(listen 线程写、comm 线程读):持锁快照,避免撕裂/竞争
pmState pmStateSnap{};
disSysBreakerList disBreakerSnap{};
{
std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
pmStateSnap = m_pm->m_pmCurrentState;
disBreakerSnap = m_pm->m_currentDisBreakerState;
}
m_pmStateMsg.state.workCondition = m_pm->workCondition; m_pmStateMsg.state.workCondition = m_pm->workCondition;
m_pmStateMsg.state.currentMod = m_pm->currentMod; m_pmStateMsg.state.currentMod = m_pm->currentMod;
m_pmStateMsg.state.powerState = m_pm->powerState; m_pmStateMsg.state.powerState = m_pm->powerState;
m_pmStateMsg.state.faultLevel = m_pm->faultLevel; m_pmStateMsg.state.faultLevel = m_pm->faultLevel;
m_pmStateMsg.state.faultCode = m_pm->faultCode; m_pmStateMsg.state.faultCode = m_pm->getFaultCodes();
// cout << "m_pmStateMsg.state.faultCode.size():" << m_pmStateMsg.state.faultCode.size() << endl; // cout << "m_pmStateMsg.state.faultCode.size():" << m_pmStateMsg.state.faultCode.size() << endl;
m_pmStateMsg.state.soc = m_pm->soc; m_pmStateMsg.state.soc = m_pm->soc;
m_pmStateMsg.state.sustainableTime = m_pm->sustainableTime; m_pmStateMsg.state.sustainableTime = m_pm->sustainableTime;
@@ -229,14 +238,14 @@ void UpperCommManager::buildSystemReport() {
m_pm->sendNotification(m_pmStateMsg.key, m_pmStateMsg.buildMsg(*(m_pm->m_systemData))); 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_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_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_disSysStateMsg.key, m_disSysStateMsg.buildMsg(*(m_pm->m_systemData), disBreakerSnap));
m_pm->sendNotification(m_currentStateMsg.key, m_currentStateMsg.buildMsg(m_pm->m_pmCurrentState)); m_pm->sendNotification(m_currentStateMsg.key, m_currentStateMsg.buildMsg(pmStateSnap));
#ifdef _DEBUG #ifdef _DEBUG
m_pmStateMsg_fb_debug = std::make_pair(m_pmStateMsg.key, m_pmStateMsg.buildMsg(*(m_pm->m_systemData))); 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_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_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_disSysStateMsg_st_debug = std::make_pair(m_disSysStateMsg.key, m_disSysStateMsg.buildMsg(*(m_pm->m_systemData), disBreakerSnap));
m_currentStateMsg_st_debug = std::make_pair(m_currentStateMsg.key, m_currentStateMsg.buildMsg(m_pm->m_pmCurrentState)); m_currentStateMsg_st_debug = std::make_pair(m_currentStateMsg.key, m_currentStateMsg.buildMsg(pmStateSnap));
#endif #endif
} }
+1 -1
View File
@@ -82,7 +82,7 @@ void Lifting::entry() {
MOOSPause(3); MOOSPause(3);
{ {
int count=0; int count=0;
while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02)) while (!(pm->m_systemData->getDynPosRelayStatus() == 0x02 && pm->m_systemData->getDynNegRelayStatus() == 0x02))
{ {
LOG_F(INFO,"动力锂电池下电中..."); LOG_F(INFO,"动力锂电池下电中...");
MOOSPause(3); MOOSPause(3);
+143 -128
View File
@@ -36,7 +36,7 @@ void PowerManagerFsm::react(CycleTriggeredEvent const &){
{ {
if(pm->m_depth < OVER_DEPTH) if(pm->m_depth < OVER_DEPTH)
{ {
if(pm->m_systemData->power_a_bus_status.xczCircuitBreaker == 1) if(pm->m_systemData->getPowerABusStatus().xczCircuitBreaker == 1)
pm->m_lowerCommManager->operate_HVA_xczCircuit_Breaker(0); pm->m_lowerCommManager->operate_HVA_xczCircuit_Breaker(0);
//舷侧阵自动下电 //舷侧阵自动下电
MOOSPause(3); MOOSPause(3);
@@ -66,10 +66,13 @@ void PowerManagerFsm::handleCuriseWork()
//依次接入执行机构动力电设备 //依次接入执行机构动力电设备
//1. 开启动力电 //1. 开启动力电
//1.1 动力锂电池上电 //1.1 动力锂电池上电
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; {
std::lock_guard<std::mutex> lock(pm->m_stateMutex);
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start;
}
// 等待动力锂电池上电完成 // 等待动力锂电池上电完成
int count=0; int count=0;
while (!(pm->m_systemData->dyn_voltage_link > 500.0)) while (!(pm->m_systemData->getDynVoltageLink() > 500.0))
{ {
LOG_F(INFO,"动力锂电池上电中..."); LOG_F(INFO,"动力锂电池上电中...");
MOOSPause(1000); MOOSPause(1000);
@@ -82,27 +85,27 @@ void PowerManagerFsm::handleCuriseWork()
count++; count++;
} }
//1.2 闭合动力电断路器 //1.2 闭合动力电断路器
if(pm->m_systemData->power_bus_status.lithiumBatteryGroupInstrumentCircuitBreaker != 1) if(pm->m_systemData->getPowerBusStatus().lithiumBatteryGroupInstrumentCircuitBreaker != 1)
{ {
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(1); pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(1);
MOOSPause(3); MOOSPause(3);
} }
if(pm->m_systemData->power_bus_status.dcDc5ModuleCircuitBreaker != 1) if(pm->m_systemData->getPowerBusStatus().dcDc5ModuleCircuitBreaker != 1)
{ {
pm->m_lowerCommManager->operate_HV_dcDc5Module_Breaker(1); pm->m_lowerCommManager->operate_HV_dcDc5Module_Breaker(1);
MOOSPause(3); MOOSPause(3);
} }
if(pm->m_systemData->m_dcdcStatus.workingStatus != 1) if(pm->m_systemData->getDcdcStatus().workingStatus != 1)
{ {
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(1); pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(1);
MOOSPause(3); MOOSPause(3);
} }
if(!(pm->m_systemData->m_dcdcStatus.coolingPump1Running || pm->m_systemData->m_dcdcStatus.coolingPump2Running)) if(!(pm->m_systemData->getDcdcStatus().coolingPump1Running || pm->m_systemData->getDcdcStatus().coolingPump2Running))
{ {
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(1); pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(1);
MOOSPause(10); MOOSPause(10);
} }
if(pm->m_systemData->power_bus_status.bowHighVoltageDistributionBoxCircuitBreaker != 1) if(pm->m_systemData->getPowerBusStatus().bowHighVoltageDistributionBoxCircuitBreaker != 1)
{ {
pm->m_lowerCommManager->operate_HV_bowHighVoltageBox_Breaker(1); pm->m_lowerCommManager->operate_HV_bowHighVoltageBox_Breaker(1);
MOOSPause(3); MOOSPause(3);
@@ -1040,7 +1043,7 @@ void PowerManagerFsm::getNoPowerDeviceStatus(DriverTable &s)
void PowerManagerFsm::getBowRudderSystemStatus(DriverTable &s) void PowerManagerFsm::getBowRudderSystemStatus(DriverTable &s)
{ {
if(pm->m_systemData->power_a_bus_status.bowRudderControlBoxCircuitBreaker == 1) if(pm->m_systemData->getPowerABusStatus().bowRudderControlBoxCircuitBreaker == 1)
{ {
//检查艏舵电缸 //检查艏舵电缸
if(pm->m_subDisSysState.bowRudderDeploy == 1) if(pm->m_subDisSysState.bowRudderDeploy == 1)
@@ -1103,7 +1106,7 @@ void PowerManagerFsm::getBowRudderSystemStatus(DriverTable &s)
} }
void PowerManagerFsm::getActuatorStatus(DriverTable &s) void PowerManagerFsm::getActuatorStatus(DriverTable &s)
{ {
if(pm->m_systemData->power_a_bus_status.actuatorCircuitBreaker == 1) if(pm->m_systemData->getPowerABusStatus().actuatorCircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.bowCover1 == 1) if(pm->m_subDisSysState.bowCover1 == 1)
{ {
@@ -1220,7 +1223,7 @@ void PowerManagerFsm::getActuatorStatus(DriverTable &s)
void PowerManagerFsm::getSternRudderStatus(DriverTable &s) void PowerManagerFsm::getSternRudderStatus(DriverTable &s)
{ {
//艉舵1 2 //艉舵1 2
if(pm->m_systemData->power_bus_status.sternRudderSwitch1CircuitBreaker == 1) if(pm->m_systemData->getPowerBusStatus().sternRudderSwitch1CircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.sternRudderServo1== 1) if(pm->m_subDisSysState.sternRudderServo1== 1)
{ {
@@ -1261,7 +1264,7 @@ void PowerManagerFsm::getSternRudderStatus(DriverTable &s)
} }
} }
//艉舵3 4 //艉舵3 4
if(pm->m_systemData->power_bus_status.sternRudderSwitch2CircuitBreaker == 1) if(pm->m_systemData->getPowerBusStatus().sternRudderSwitch2CircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.sternRudderServo3 == 1) if(pm->m_subDisSysState.sternRudderServo3 == 1)
{ {
@@ -1305,7 +1308,7 @@ void PowerManagerFsm::getSternRudderStatus(DriverTable &s)
void PowerManagerFsm::getPropulsionMotorStatus(DriverTable &s) void PowerManagerFsm::getPropulsionMotorStatus(DriverTable &s)
{ {
if(pm->m_systemData->power_bus_status.propulsionMotorCircuitBreaker == 1) if(pm->m_systemData->getPowerBusStatus().propulsionMotorCircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.thruster == 1) if(pm->m_subDisSysState.thruster == 1)
{ {
@@ -1331,7 +1334,7 @@ void PowerManagerFsm::getPropulsionMotorStatus(DriverTable &s)
void PowerManagerFsm::getBuoyancyAdjustmentStatus(DriverTable &s) void PowerManagerFsm::getBuoyancyAdjustmentStatus(DriverTable &s)
{ {
// 艉部浮调 // 艉部浮调
if(pm->m_systemData->power_bus_status.sternFTDevice45CircuitBreaker == 1) if(pm->m_systemData->getPowerBusStatus().sternFTDevice45CircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.buoyancyAdjust4 == 1) if(pm->m_subDisSysState.buoyancyAdjust4 == 1)
{ {
@@ -1373,7 +1376,7 @@ void PowerManagerFsm::getBuoyancyAdjustmentStatus(DriverTable &s)
} }
// 艏部浮调 // 艏部浮调
if(pm->m_systemData->power_a_bus_status.bowFTDevice123CircuitBreaker == 1) if(pm->m_systemData->getPowerABusStatus().bowFTDevice123CircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.buoyancyAdjust1 == 1) if(pm->m_subDisSysState.buoyancyAdjust1 == 1)
{ {
@@ -1435,7 +1438,7 @@ void PowerManagerFsm::getBuoyancyAdjustmentStatus(DriverTable &s)
void PowerManagerFsm::getSideSonarStatus(DriverTable &s) void PowerManagerFsm::getSideSonarStatus(DriverTable &s)
{ {
if(pm->m_systemData->power_a_bus_status.xczCircuitBreaker == 1) if(pm->m_systemData->getPowerABusStatus().xczCircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.sideSonar == 1) if(pm->m_subDisSysState.sideSonar == 1)
{ {
@@ -1461,7 +1464,7 @@ void PowerManagerFsm::getSideSonarStatus(DriverTable &s)
void PowerManagerFsm::getFBSystemCmdStatus(DriverTable &s) void PowerManagerFsm::getFBSystemCmdStatus(DriverTable &s)
{ {
if(pm->m_systemData->power_bus_status.fbReservedCircuitBreaker == 1) if(pm->m_systemData->getPowerBusStatus().fbReservedCircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.buoyage == 1) if(pm->m_subDisSysState.buoyage == 1)
{ {
@@ -1487,7 +1490,7 @@ void PowerManagerFsm::getFBSystemCmdStatus(DriverTable &s)
void PowerManagerFsm::getMastFoldingSystem(DriverTable &s) void PowerManagerFsm::getMastFoldingSystem(DriverTable &s)
{ {
if(pm->m_systemData->power_a_bus_status.mastSteeringGearControlBoxCircuitBreaker == 1) if(pm->m_systemData->getPowerABusStatus().mastSteeringGearControlBoxCircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.mastLiftingServo == 1) if(pm->m_subDisSysState.mastLiftingServo == 1)
{ {
@@ -1513,7 +1516,7 @@ void PowerManagerFsm::getMastFoldingSystem(DriverTable &s)
void PowerManagerFsm::getOpenWaterStatus(DriverTable &s) void PowerManagerFsm::getOpenWaterStatus(DriverTable &s)
{ {
if(pm->m_systemData->power_a_bus_status.openWaterCoverStartCylinderCircuitBreaker == 1) if(pm->m_systemData->getPowerABusStatus().openWaterCoverStartCylinderCircuitBreaker == 1)
{ {
if(pm->m_subDisSysState.bowWaterInet1 == 1) if(pm->m_subDisSysState.bowWaterInet1 == 1)
{ {
@@ -1752,12 +1755,12 @@ void PowerManagerFsm::basicNavigationFault()
if(pm->m_subDisSysFault.sternRudderServo4 == 1) if(pm->m_subDisSysFault.sternRudderServo4 == 1)
pm->m_systemData->insertFaultCode(0x1309); pm->m_systemData->insertFaultCode(0x1309);
} }
if (pm->m_systemData->disSysFaultCode.find(7) != pm->m_systemData->disSysFaultCode.end()) if (pm->m_systemData->hasDisSysFaultCode(7))
{ {
pm->m_systemData->insertFaultCode(0x1306); pm->m_systemData->insertFaultCode(0x1306);
pm->m_systemData->insertFaultCode(0x1307); pm->m_systemData->insertFaultCode(0x1307);
} }
if (pm->m_systemData->disSysFaultCode.find(8) != pm->m_systemData->disSysFaultCode.end()) if (pm->m_systemData->hasDisSysFaultCode(8))
{ {
pm->m_systemData->insertFaultCode(0x1308); pm->m_systemData->insertFaultCode(0x1308);
pm->m_systemData->insertFaultCode(0x1309); pm->m_systemData->insertFaultCode(0x1309);
@@ -1765,19 +1768,19 @@ void PowerManagerFsm::basicNavigationFault()
if(count == 0) if(count == 0)
{ {
// 清空故障码 // 清空故障码
if(pm->m_systemData->disSysFaultCode.find(7) == pm->m_systemData->disSysFaultCode.end()) if(!pm->m_systemData->hasDisSysFaultCode(7))
{ {
pm->m_systemData->eraseFaultCode(0x1306); pm->m_systemData->eraseFaultCode(0x1306);
pm->m_systemData->eraseFaultCode(0x1307); pm->m_systemData->eraseFaultCode(0x1307);
} }
if(pm->m_systemData->disSysFaultCode.find(8) == pm->m_systemData->disSysFaultCode.end()) if(!pm->m_systemData->hasDisSysFaultCode(8))
{ {
pm->m_systemData->eraseFaultCode(0x1308); pm->m_systemData->eraseFaultCode(0x1308);
pm->m_systemData->eraseFaultCode(0x1309); pm->m_systemData->eraseFaultCode(0x1309);
} }
} }
//=====处理动力电池故障====================== //=====处理动力电池故障======================
if(pm->m_systemData->dyn_emergency_status != 0 ) if(pm->m_systemData->getDynEmergencyStatus() != 0 )
{ {
pm->m_systemData->insertFaultCode(0x130B); pm->m_systemData->insertFaultCode(0x130B);
} }
@@ -1788,7 +1791,7 @@ void PowerManagerFsm::basicNavigationFault()
} }
else else
{ {
if(pm->m_systemData->disSysFaultCode.find(3) == pm->m_systemData->disSysFaultCode.end()) if(!pm->m_systemData->hasDisSysFaultCode(3))
{ {
pm->m_systemData->eraseFaultCode(0x130A); pm->m_systemData->eraseFaultCode(0x130A);
} }
@@ -1816,7 +1819,7 @@ void PowerManagerFsm::basicNavigationFault()
pm->m_systemData->eraseFaultCode(0x1412); pm->m_systemData->eraseFaultCode(0x1412);
} }
//====处理复合管控器失效 //====处理复合管控器失效
if(pm->m_systemData->device_common_status.ccu_status.isTimeout) if(pm->m_systemData->getDeviceCommonStatus().ccu_status.isTimeout)
{ {
pm->m_systemData->insertFaultCode(0x1413); pm->m_systemData->insertFaultCode(0x1413);
} }
@@ -1831,63 +1834,63 @@ void PowerManagerFsm::basicNavigationFault(FaultEvent const &e)
if((e.injectionFaultCode==1)) if((e.injectionFaultCode==1))
{ {
LOG_F(INFO, "部分深度计失效"); LOG_F(INFO, "部分深度计失效");
pm->faultCode.push_back(0x1102); pm->addFaultCode(0x1102);
pm->faultCode.push_back(0x1103); pm->addFaultCode(0x1103);
pm->faultCode.push_back(0x1104); pm->addFaultCode(0x1104);
} }
if((e.injectionFaultCode==2)) if((e.injectionFaultCode==2))
{ {
LOG_F(INFO, "DVL失效"); LOG_F(INFO, "DVL失效");
pm->faultCode.push_back(0x1301); pm->addFaultCode(0x1301);
} }
if ((e.injectionFaultCode==3)) if ((e.injectionFaultCode==3))
{ {
LOG_F(INFO, "单个艉舵失效"); LOG_F(INFO, "单个艉舵失效");
pm->faultCode.push_back(0x1207); pm->addFaultCode(0x1207);
} }
if ((e.injectionFaultCode==4)) if ((e.injectionFaultCode==4))
{ {
LOG_F(INFO, "部分艉舵失效"); LOG_F(INFO, "部分艉舵失效");
pm->faultCode.push_back(0x1308); pm->addFaultCode(0x1308);
pm->faultCode.push_back(0x1307); pm->addFaultCode(0x1307);
} }
if ((e.injectionFaultCode==5)) if ((e.injectionFaultCode==5))
{ {
LOG_F(INFO, "动力锂电池失效"); LOG_F(INFO, "动力锂电池失效");
pm->faultCode.push_back(0x130B); pm->addFaultCode(0x130B);
} }
if ((e.injectionFaultCode==6)) if ((e.injectionFaultCode==6))
{ {
LOG_F(INFO, "推进电机失效"); LOG_F(INFO, "推进电机失效");
pm->faultCode.push_back(0x130A); pm->addFaultCode(0x130A);
} }
if ((e.injectionFaultCode==7)) if ((e.injectionFaultCode==7))
{ {
LOG_F(INFO, "惯导失效"); LOG_F(INFO, "惯导失效");
pm->faultCode.push_back(0x1305); pm->addFaultCode(0x1305);
} }
if ((e.injectionFaultCode==8)) if ((e.injectionFaultCode==8))
{ {
LOG_F(INFO, "深度失效"); LOG_F(INFO, "深度失效");
pm->faultCode.push_back(0x1302); pm->addFaultCode(0x1302);
pm->faultCode.push_back(0x1303); pm->addFaultCode(0x1303);
pm->faultCode.push_back(0x1304); pm->addFaultCode(0x1304);
} }
if ((e.injectionFaultCode==9)) if ((e.injectionFaultCode==9))
{ {
LOG_F(INFO, "仪表锂电池失效"); LOG_F(INFO, "仪表锂电池失效");
pm->faultCode.push_back(0x1412); pm->addFaultCode(0x1412);
} }
if ((e.injectionFaultCode==10)) if ((e.injectionFaultCode==10))
{ {
LOG_F(INFO, "复合管控器失效"); LOG_F(INFO, "复合管控器失效");
pm->faultCode.push_back(0x1413); pm->addFaultCode(0x1413);
} }
} }
void PowerManagerFsm::extendedNavigationFault() void PowerManagerFsm::extendedNavigationFault()
{ {
//处理艏舵故障 //处理艏舵故障
if(pm->m_systemData->disSysFaultCode.find(17) != pm->m_systemData->disSysFaultCode.end()) if(pm->m_systemData->hasDisSysFaultCode(17))
{ {
pm->m_systemData->insertFaultCode(0x2311); pm->m_systemData->insertFaultCode(0x2311);
pm->m_systemData->insertFaultCode(0x2312); pm->m_systemData->insertFaultCode(0x2312);
@@ -1939,22 +1942,22 @@ void PowerManagerFsm::extendedNavigationFault(FaultEvent const &e)
if ((e.injectionFaultCode==1)) if ((e.injectionFaultCode==1))
{ {
LOG_F(INFO, "艏舵展开电缸失效"); LOG_F(INFO, "艏舵展开电缸失效");
pm->faultCode.push_back(0x2311); pm->addFaultCode(0x2311);
} }
if ((e.injectionFaultCode==2)) if ((e.injectionFaultCode==2))
{ {
LOG_F(INFO, "艏舵控制控制失效"); LOG_F(INFO, "艏舵控制控制失效");
pm->faultCode.push_back(0x2312); pm->addFaultCode(0x2312);
} }
if ((e.injectionFaultCode==3)) if ((e.injectionFaultCode==3))
{ {
LOG_F(INFO, "动力锂电池功率不满/失效"); LOG_F(INFO, "动力锂电池功率不满/失效");
pm->faultCode.push_back(0x2323); pm->addFaultCode(0x2323);
} }
if ((e.injectionFaultCode==4)) if ((e.injectionFaultCode==4))
{ {
LOG_F(INFO, "燃料电池失效"); LOG_F(INFO, "燃料电池失效");
pm->faultCode.push_back(0x2334); pm->addFaultCode(0x2334);
} }
} }
void PowerManagerFsm::obstacleAvoidanceFault() void PowerManagerFsm::obstacleAvoidanceFault()
@@ -2061,22 +2064,22 @@ void PowerManagerFsm::obstacleAvoidanceFault(FaultEvent const &e)
LOG_F(INFO, "obstacleAvoidanceFault"); LOG_F(INFO, "obstacleAvoidanceFault");
if ((e.injectionFaultCode==1)) if ((e.injectionFaultCode==1))
{ {
pm->faultCode.push_back(0x3108); pm->addFaultCode(0x3108);
pm->faultCode.push_back(0x3109); pm->addFaultCode(0x3109);
} }
if ((e.injectionFaultCode==2)) if ((e.injectionFaultCode==2))
{ {
pm->faultCode.push_back(0x3201); pm->addFaultCode(0x3201);
pm->faultCode.push_back(0x3202); pm->addFaultCode(0x3202);
pm->faultCode.push_back(0x3203); pm->addFaultCode(0x3203);
pm->faultCode.push_back(0x3204); pm->addFaultCode(0x3204);
pm->faultCode.push_back(0x3205); pm->addFaultCode(0x3205);
pm->faultCode.push_back(0x3206); pm->addFaultCode(0x3206);
pm->faultCode.push_back(0x3207); pm->addFaultCode(0x3207);
} }
if ((e.injectionFaultCode==3)) if ((e.injectionFaultCode==3))
{ {
pm->faultCode.push_back(0x3301); pm->addFaultCode(0x3301);
} }
} }
@@ -2089,8 +2092,8 @@ void PowerManagerFsm::buoyancyControlFault()
+ (pm->m_subDisSysFault.buoyancyAdjust4 == 1) + (pm->m_subDisSysFault.buoyancyAdjust4 == 1)
+ (pm->m_subDisSysFault.buoyancyAdjust5 == 1); + (pm->m_subDisSysFault.buoyancyAdjust5 == 1);
bool breaker7_fault = pm->m_systemData->disSysFaultCode.find(7) != pm->m_systemData->disSysFaultCode.end(); bool breaker7_fault = pm->m_systemData->hasDisSysFaultCode(7);
bool breaker13_fault = pm->m_systemData->disSysFaultCode.find(13) != pm->m_systemData->disSysFaultCode.end(); bool breaker13_fault = pm->m_systemData->hasDisSysFaultCode(13);
//===========艏部浮调==================== //===========艏部浮调====================
if(breaker7_fault) if(breaker7_fault)
{ {
@@ -2256,24 +2259,24 @@ void PowerManagerFsm::buoyancyControlFault(FaultEvent const &e)
if ((e.injectionFaultCode==1)) if ((e.injectionFaultCode==1))
{ {
LOG_F(INFO, "单一浮调机构失效"); LOG_F(INFO, "单一浮调机构失效");
pm->faultCode.push_back(0x4201); pm->addFaultCode(0x4201);
} }
if ((e.injectionFaultCode==2)) if ((e.injectionFaultCode==2))
{ {
LOG_F(INFO, "2-4及以上浮调装置失效"); LOG_F(INFO, "2-4及以上浮调装置失效");
pm->faultCode.push_back(0x4301); pm->addFaultCode(0x4301);
pm->faultCode.push_back(0x4302); pm->addFaultCode(0x4302);
pm->faultCode.push_back(0x4303); pm->addFaultCode(0x4303);
} }
if ((e.injectionFaultCode==3)) if ((e.injectionFaultCode==3))
{ {
LOG_F(INFO, "功率不足满足浮调要求"); LOG_F(INFO, "功率不足满足浮调要求");
pm->faultCode.push_back(0x4436); pm->addFaultCode(0x4436);
} }
if ((e.injectionFaultCode==4)) if ((e.injectionFaultCode==4))
{ {
LOG_F(INFO, "所有浮调系统失效"); LOG_F(INFO, "所有浮调系统失效");
pm->faultCode.push_back(0x4401); pm->addFaultCode(0x4401);
} }
} }
@@ -2319,7 +2322,7 @@ void PowerManagerFsm::communicationSystemFault()
else else
pm->m_systemData->eraseFaultCode(0x5301); pm->m_systemData->eraseFaultCode(0x5301);
if(pm->m_subDisSysFault.mastLiftingServo == 1 || (pm->m_systemData->disSysFaultCode.find(15) != pm->m_systemData->disSysFaultCode.end())) if(pm->m_subDisSysFault.mastLiftingServo == 1 || (pm->m_systemData->hasDisSysFaultCode(15)))
pm->m_systemData->insertFaultCode(0x5302); pm->m_systemData->insertFaultCode(0x5302);
else else
pm->m_systemData->eraseFaultCode(0x5302); pm->m_systemData->eraseFaultCode(0x5302);
@@ -2331,22 +2334,22 @@ void PowerManagerFsm::communicationSystemFault(FaultEvent const &e)
if ((e.injectionFaultCode==1)) if ((e.injectionFaultCode==1))
{ {
LOG_F(INFO, "部分水下通信失效"); LOG_F(INFO, "部分水下通信失效");
pm->faultCode.push_back(0x5203); pm->addFaultCode(0x5203);
pm->faultCode.push_back(0x5204); pm->addFaultCode(0x5204);
pm->faultCode.push_back(0x5205); pm->addFaultCode(0x5205);
} }
if ((e.injectionFaultCode==2)) if ((e.injectionFaultCode==2))
{ {
LOG_F(INFO, "水下通信失效"); LOG_F(INFO, "水下通信失效");
pm->faultCode.push_back(0x5303); pm->addFaultCode(0x5303);
pm->faultCode.push_back(0x5304); pm->addFaultCode(0x5304);
pm->faultCode.push_back(0x5305); pm->addFaultCode(0x5305);
} }
if ((e.injectionFaultCode==3)) if ((e.injectionFaultCode==3))
{ {
LOG_F(INFO, "水面通信失效"); LOG_F(INFO, "水面通信失效");
pm->faultCode.push_back(0x5301); pm->addFaultCode(0x5301);
pm->faultCode.push_back(0x5302); pm->addFaultCode(0x5302);
} }
} }
void PowerManagerFsm::payloadSystemFault() void PowerManagerFsm::payloadSystemFault()
@@ -2366,8 +2369,8 @@ void PowerManagerFsm::payloadSystemFault()
+ (pm->m_subDisSysFault.bowWaterInet7 == 1) + (pm->m_subDisSysFault.bowWaterInet7 == 1)
+ (pm->m_subDisSysFault.bowWaterInet8 == 1); + (pm->m_subDisSysFault.bowWaterInet8 == 1);
if((pm->m_systemData->disSysFaultCode.find(14) == pm->m_systemData->disSysFaultCode.end()) if((!pm->m_systemData->hasDisSysFaultCode(14))
&& (pm->m_systemData->disSysFaultCode.find(18) == pm->m_systemData->disSysFaultCode.end())) && (!pm->m_systemData->hasDisSysFaultCode(18)))
{ {
if(count > 0 && count < 14) if(count > 0 && count < 14)
{ {
@@ -2387,8 +2390,8 @@ void PowerManagerFsm::payloadSystemFault()
if(pm->m_subDisSysFault.bowWaterInet8 == 1) pm->m_systemData->insertFaultCode(0x621E); else pm->m_systemData->eraseFaultCode(0x621E); if(pm->m_subDisSysFault.bowWaterInet8 == 1) pm->m_systemData->insertFaultCode(0x621E); else pm->m_systemData->eraseFaultCode(0x621E);
} }
} }
if((pm->m_systemData->disSysFaultCode.find(14) != pm->m_systemData->disSysFaultCode.end()) if((pm->m_systemData->hasDisSysFaultCode(14))
&& (pm->m_systemData->disSysFaultCode.find(18) == pm->m_systemData->disSysFaultCode.end())) && (!pm->m_systemData->hasDisSysFaultCode(18)))
{ {
pm->m_systemData->insertFaultCode(0x633F); pm->m_systemData->insertFaultCode(0x633F);
} }
@@ -2400,8 +2403,8 @@ void PowerManagerFsm::payloadSystemFault()
{ {
pm->m_systemData->insertFaultCode(0x633F); pm->m_systemData->insertFaultCode(0x633F);
} }
if(count == 0 && ((pm->m_systemData->disSysFaultCode.find(14) == pm->m_systemData->disSysFaultCode.end()) if(count == 0 && ((!pm->m_systemData->hasDisSysFaultCode(14))
&& (pm->m_systemData->disSysFaultCode.find(18) == pm->m_systemData->disSysFaultCode.end()) && (!pm->m_systemData->hasDisSysFaultCode(18))
&& (pm->m_subDisSysFault.launchControler == 0)) && (pm->m_subDisSysFault.launchControler == 0))
) )
{ {
@@ -2413,7 +2416,7 @@ void PowerManagerFsm::payloadSystemFault()
else else
pm->m_systemData->eraseFaultCode(0x6321); pm->m_systemData->eraseFaultCode(0x6321);
if(pm->m_systemData->disSysFaultCode.find(16) == pm->m_systemData->disSysFaultCode.end()) if(!pm->m_systemData->hasDisSysFaultCode(16))
pm->m_systemData->eraseFaultCode(0x6323); pm->m_systemData->eraseFaultCode(0x6323);
else else
pm->m_systemData->insertFaultCode(0x6323); pm->m_systemData->insertFaultCode(0x6323);
@@ -2437,50 +2440,50 @@ void PowerManagerFsm::payloadSystemFault(FaultEvent const &e)
if ((e.injectionFaultCode==1)) if ((e.injectionFaultCode==1))
{ {
LOG_F(INFO, "存在启闭机构或者敞水电缸失效"); LOG_F(INFO, "存在启闭机构或者敞水电缸失效");
pm->faultCode.push_back(0x6211); pm->addFaultCode(0x6211);
pm->faultCode.push_back(0x6212); pm->addFaultCode(0x6212);
pm->faultCode.push_back(0x6213); pm->addFaultCode(0x6213);
pm->faultCode.push_back(0x6214); pm->addFaultCode(0x6214);
pm->faultCode.push_back(0x6215); pm->addFaultCode(0x6215);
pm->faultCode.push_back(0x6216); pm->addFaultCode(0x6216);
pm->faultCode.push_back(0x6217); pm->addFaultCode(0x6217);
pm->faultCode.push_back(0x6218); pm->addFaultCode(0x6218);
pm->faultCode.push_back(0x6219); pm->addFaultCode(0x6219);
pm->faultCode.push_back(0x621A); pm->addFaultCode(0x621A);
pm->faultCode.push_back(0x621B); pm->addFaultCode(0x621B);
pm->faultCode.push_back(0x621C); pm->addFaultCode(0x621C);
pm->faultCode.push_back(0x621D); pm->addFaultCode(0x621D);
pm->faultCode.push_back(0x621E); pm->addFaultCode(0x621E);
} }
if ((e.injectionFaultCode==2)) if ((e.injectionFaultCode==2))
{ {
LOG_F(INFO, "舷侧探测失效"); LOG_F(INFO, "舷侧探测失效");
pm->faultCode.push_back(0x6321); pm->addFaultCode(0x6321);
} }
if ((e.injectionFaultCode==3)) if ((e.injectionFaultCode==3))
{ {
LOG_F(INFO, "舷侧主动探测失效"); LOG_F(INFO, "舷侧主动探测失效");
pm->faultCode.push_back(0x6323); pm->addFaultCode(0x6323);
} }
if ((e.injectionFaultCode==4)) if ((e.injectionFaultCode==4))
{ {
LOG_F(INFO, "TYZ失效"); LOG_F(INFO, "TYZ失效");
pm->faultCode.push_back(0x6322); pm->addFaultCode(0x6322);
} }
if ((e.injectionFaultCode==5)) if ((e.injectionFaultCode==5))
{ {
LOG_F(INFO, "光电探测失效"); LOG_F(INFO, "光电探测失效");
pm->faultCode.push_back(0x6332); pm->addFaultCode(0x6332);
} }
if ((e.injectionFaultCode==6)) if ((e.injectionFaultCode==6))
{ {
LOG_F(INFO, "电磁探测失效"); LOG_F(INFO, "电磁探测失效");
pm->faultCode.push_back(0x6331); pm->addFaultCode(0x6331);
} }
if ((e.injectionFaultCode==7)) if ((e.injectionFaultCode==7))
{ {
LOG_F(INFO, "载荷失效或者全部载荷启闭机构均失效"); LOG_F(INFO, "载荷失效或者全部载荷启闭机构均失效");
pm->faultCode.push_back(0x633F); pm->addFaultCode(0x633F);
} }
} }
void PowerManagerFsm::emergencySystemFault() void PowerManagerFsm::emergencySystemFault()
@@ -2514,14 +2517,14 @@ void PowerManagerFsm::emergencySystemFault()
else else
pm->m_systemData->eraseFaultCode(0x7301); pm->m_systemData->eraseFaultCode(0x7301);
if(pm->m_systemData->power_bus_status.emergencyPowerLossSignal || pm->m_systemData->instrument_main_bus_status.emergencyPowerFailureSignal if(pm->m_systemData->getPowerBusStatus().emergencyPowerLossSignal || pm->m_systemData->getInstrumentMainBusStatus().emergencyPowerFailureSignal
|| (pm->m_systemData->disSysFaultCode.find(25) != pm->m_systemData->disSysFaultCode.end())) || (pm->m_systemData->hasDisSysFaultCode(25)))
pm->m_systemData->insertFaultCode(0x7306); pm->m_systemData->insertFaultCode(0x7306);
else else
pm->m_systemData->eraseFaultCode(0x7306); pm->m_systemData->eraseFaultCode(0x7306);
if(pm->m_systemData->power_a_bus_status.emergencyPowerFailureSignal || pm->m_systemData->instrument_bus_status.emergencyPowerFailureSignal if(pm->m_systemData->getPowerABusStatus().emergencyPowerFailureSignal || pm->m_systemData->getInstrumentBusStatus().emergencyPowerFailureSignal
|| (pm->m_systemData->disSysFaultCode.find(33) != pm->m_systemData->disSysFaultCode.end())) || (pm->m_systemData->hasDisSysFaultCode(33)))
pm->m_systemData->insertFaultCode(0x7307); pm->m_systemData->insertFaultCode(0x7307);
else else
pm->m_systemData->eraseFaultCode(0x7307); pm->m_systemData->eraseFaultCode(0x7307);
@@ -2534,35 +2537,35 @@ void PowerManagerFsm::emergencySystemFault(FaultEvent const &e)
{ {
//备注:抛载具有自己的电池 //备注:抛载具有自己的电池
LOG_F(INFO, "部分抛载失效"); LOG_F(INFO, "部分抛载失效");
pm->faultCode.push_back(0x7202); pm->addFaultCode(0x7202);
pm->faultCode.push_back(0x7203); pm->addFaultCode(0x7203);
} }
if ((e.injectionFaultCode==2)) if ((e.injectionFaultCode==2))
{ {
LOG_F(INFO, "一个超深检测装置失效"); LOG_F(INFO, "一个超深检测装置失效");
pm->faultCode.push_back(0x7204); pm->addFaultCode(0x7204);
pm->faultCode.push_back(0x7205); pm->addFaultCode(0x7205);
} }
if ((e.injectionFaultCode==3)) if ((e.injectionFaultCode==3))
{ {
LOG_F(INFO, "注水机构失效"); LOG_F(INFO, "注水机构失效");
pm->faultCode.push_back(0x7301); pm->addFaultCode(0x7301);
} }
if ((e.injectionFaultCode==4)) if ((e.injectionFaultCode==4))
{ {
LOG_F(INFO, "抛载失效"); LOG_F(INFO, "抛载失效");
pm->faultCode.push_back(0x7302); pm->addFaultCode(0x7302);
pm->faultCode.push_back(0x7303); pm->addFaultCode(0x7303);
} }
if ((e.injectionFaultCode==5)) if ((e.injectionFaultCode==5))
{ {
LOG_F(INFO, "艏部应急电源失效"); LOG_F(INFO, "艏部应急电源失效");
pm->faultCode.push_back(0x7306); pm->addFaultCode(0x7306);
} }
if ((e.injectionFaultCode==6)) if ((e.injectionFaultCode==6))
{ {
LOG_F(INFO, "艉部应急电源失效"); LOG_F(INFO, "艉部应急电源失效");
pm->faultCode.push_back(0x7307); pm->addFaultCode(0x7307);
} }
} }
@@ -2600,18 +2603,18 @@ void PowerManagerFsm::sensorSystemFault(FaultEvent const &e)
if ((e.injectionFaultCode==1)) if ((e.injectionFaultCode==1))
{ {
LOG_F(INFO, "部分CTD失效"); LOG_F(INFO, "部分CTD失效");
pm->faultCode.push_back(0x8202); pm->addFaultCode(0x8202);
} }
if ((e.injectionFaultCode==2)) if ((e.injectionFaultCode==2))
{ {
LOG_F(INFO, "CTD失效"); LOG_F(INFO, "CTD失效");
pm->faultCode.push_back(0x8302); pm->addFaultCode(0x8302);
pm->faultCode.push_back(0x8303); pm->addFaultCode(0x8303);
} }
if ((e.injectionFaultCode==3)) if ((e.injectionFaultCode==3))
{ {
LOG_F(INFO, "声速仪失效"); LOG_F(INFO, "声速仪失效");
pm->faultCode.push_back(0x8301); pm->addFaultCode(0x8301);
} }
} }
void PowerManagerFsm::react(FaultEvent const &e) void PowerManagerFsm::react(FaultEvent const &e)
@@ -2637,7 +2640,7 @@ void PowerManagerFsm::handelPowerCmd(){
pm->m_systemData->setSystemInfo("INFO:收到上位机控制指令:关机"); pm->m_systemData->setSystemInfo("INFO:收到上位机控制指令:关机");
// MOOSPause(3); // MOOSPause(3);
// int count=0; // int count=0;
// while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02)) // while (!(pm->m_systemData->getDynPosRelayStatus() == 0x02 && pm->m_systemData->getDynNegRelayStatus() == 0x02))
// { // {
// LOG_F(INFO,"动力锂电池下电中..."); // LOG_F(INFO,"动力锂电池下电中...");
// MOOSPause(3); // MOOSPause(3);
@@ -2729,10 +2732,13 @@ void PowerManagerFsm::handelPowerCmd(){
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0); pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0);
MOOSPause(1000); MOOSPause(1000);
//最后 关闭动力电池 //最后 关闭动力电池
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Stop; {
std::lock_guard<std::mutex> lock(pm->m_stateMutex);
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Stop;
}
{ {
int count=0; int count=0;
while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02)) while (!(pm->m_systemData->getDynPosRelayStatus() == 0x02 && pm->m_systemData->getDynNegRelayStatus() == 0x02))
{ {
LOG_F(INFO,"动力锂电池下电中..."); LOG_F(INFO,"动力锂电池下电中...");
MOOSPause(1000); MOOSPause(1000);
@@ -2751,7 +2757,10 @@ void PowerManagerFsm::handelPowerCmd(){
pm->m_systemData->setSystemInfo("INFO:次级配电系统恢复待机"); pm->m_systemData->setSystemInfo("INFO:次级配电系统恢复待机");
MOOSPause(3000); MOOSPause(3000);
//4. 执行锂电池关机指令 //4. 执行锂电池关机指令
pm->m_CcuColCmd.insBatCmd = BatteryCommand::Stop; {
std::lock_guard<std::mutex> lock(pm->m_stateMutex);
pm->m_CcuColCmd.insBatCmd = BatteryCommand::Stop;
}
break; break;
} }
case 1: case 1:
@@ -2759,10 +2768,13 @@ void PowerManagerFsm::handelPowerCmd(){
LOG_F(INFO, "收到上位机控制指令:动力电上电"); LOG_F(INFO, "收到上位机控制指令:动力电上电");
pm->m_systemData->setSystemInfo("INFO:收到上位机控制指令:动力电上电"); pm->m_systemData->setSystemInfo("INFO:收到上位机控制指令:动力电上电");
//1. 动力锂电池上电 //1. 动力锂电池上电
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; {
std::lock_guard<std::mutex> lock(pm->m_stateMutex);
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start;
}
// 等待动力锂电池上电完成 // 等待动力锂电池上电完成
int count=0; int count=0;
while (!(pm->m_systemData->dyn_voltage_link > 500.0)) while (!(pm->m_systemData->getDynVoltageLink() > 500.0))
{ {
LOG_F(INFO,"动力锂电池上电中..."); LOG_F(INFO,"动力锂电池上电中...");
MOOSPause(1000); MOOSPause(1000);
@@ -2795,7 +2807,10 @@ void PowerManagerFsm::handelPowerCmd(){
//1. 闭合动力电断路器 //1. 闭合动力电断路器
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(1); pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(1);
//2. 动力锂电池上电 //2. 动力锂电池上电
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; {
std::lock_guard<std::mutex> lock(pm->m_stateMutex);
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start;
}
break; break;
} }
case 3: case 3:
@@ -2820,7 +2835,7 @@ void PowerManagerFsm::handelPowerCmd(){
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0); pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0);
MOOSPause(3); MOOSPause(3);
int count=0; int count=0;
while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02)) while (!(pm->m_systemData->getDynPosRelayStatus() == 0x02 && pm->m_systemData->getDynNegRelayStatus() == 0x02))
{ {
LOG_F(INFO,"动力锂电池下电中..."); LOG_F(INFO,"动力锂电池下电中...");
MOOSPause(3); MOOSPause(3);
@@ -2957,7 +2972,7 @@ void PowerManagerFsm::react(TestEvent const &e)
LOG_F(INFO, "测试消息"); LOG_F(INFO, "测试消息");
if(e.type == 0){ if(e.type == 0){
LOG_F(INFO, "清空故障代码"); LOG_F(INFO, "清空故障代码");
pm->faultCode.clear(); pm->clearFaultCodes();
pm->m_leakage = 0x00; pm->m_leakage = 0x00;
pm->m_systemData->insfaultCode = 0x00; pm->m_systemData->insfaultCode = 0x00;
pm->m_systemData->powfaultCode = 0x00; pm->m_systemData->powfaultCode = 0x00;
@@ -2965,7 +2980,7 @@ void PowerManagerFsm::react(TestEvent const &e)
pm->m_systemData->fc_fault_level_3 = 0; pm->m_systemData->fc_fault_level_3 = 0;
pm->m_systemData->fc_fault_level_2 = 0; pm->m_systemData->fc_fault_level_2 = 0;
pm->m_systemData->fc_fault_level_1 = 0; pm->m_systemData->fc_fault_level_1 = 0;
pm->m_systemData->disSysFaultCode.clear(); pm->m_systemData->clearDisSysFaultCodes();
cout << "清空故障代码" << endl; cout << "清空故障代码" << endl;
}; };
// if(e.eventId == 0) return ; // if(e.eventId == 0) return ;
@@ -3070,7 +3085,7 @@ void PowerManagerFsm::react(TestEvent const &e)
{ {
LOG_F(INFO,"配电系统故障测试"); LOG_F(INFO,"配电系统故障测试");
// pm->m_systemData->distributeFaultCode.push_back(disfaultMap[e.eventId].code); // pm->m_systemData->distributeFaultCode.push_back(disfaultMap[e.eventId].code);
pm->m_systemData->disSysFaultCode.insert(disfaultMap[e.eventId].code); pm->m_systemData->insertDisSysFaultCode(disfaultMap[e.eventId].code);
} }
default: default:
LOG_F(INFO, "测试消息类型错误"); LOG_F(INFO, "测试消息类型错误");
+5 -2
View File
@@ -15,10 +15,13 @@ void ShoreBasedReady::entry() {
//依次接入执行机构动力电设备 //依次接入执行机构动力电设备
//1. 开启动力电 //1. 开启动力电
//1.1 动力锂电池上电 //1.1 动力锂电池上电
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; {
std::lock_guard<std::mutex> lock(pm->m_stateMutex);
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start;
}
// 等待动力锂电池上电完成 // 等待动力锂电池上电完成
int count=0; int count=0;
while (!(pm->m_systemData->dyn_voltage_link > 500.0)) while (!(pm->m_systemData->getDynVoltageLink() > 500.0))
{ {
LOG_F(INFO,"动力锂电池上电中..."); LOG_F(INFO,"动力锂电池上电中...");
MOOSPause(1000); MOOSPause(1000);
+30 -20
View File
@@ -35,8 +35,8 @@ void HttpServer::handleWebSocketEvent(struct mg_connection* c, int ev, void* ev_
c->id, (int)(intptr_t)c->fd, errno); c->id, (int)(intptr_t)c->fd, errno);
// 打印socket错误信息 // 打印socket错误信息
char buf[256]; char buf[256];
strerror_r(errno, buf, sizeof(buf)); const char *err = strerror_r(errno, buf, sizeof(buf));
LOG_F(ERROR, "Socket error: %s", buf); LOG_F(ERROR, "Socket error: %s", err ? err : buf);
} else { } else {
LOG_F(ERROR, "WebSocket connection closed abnormally: id=%lu fd=%d", LOG_F(ERROR, "WebSocket connection closed abnormally: id=%lu fd=%d",
c->id, (int)(intptr_t)c->fd); c->id, (int)(intptr_t)c->fd);
@@ -133,16 +133,19 @@ void HttpServer::handleWebSocketEvent(struct mg_connection* c, int ev, void* ev_
fuelCellMode, fuelCellCommand, fuelCellPower, fuelCellMode, fuelCellCommand, fuelCellPower,
instrumentBattery, instrumentBatteryCharge, powerBattery, powerBatteryPower, hostStatus); instrumentBattery, instrumentBatteryCharge, powerBattery, powerBatteryPower, hostStatus);
m_powerManger->m_CcuColCmd.fcmode = fuelCellMode; {
m_powerManger->m_CcuColCmd.fcuCmd = fuelCellCommand; std::lock_guard<std::mutex> lock(m_powerManger->m_stateMutex);
m_powerManger->m_CcuColCmd.fcuPowerEfficiency = fuelCellPower; m_powerManger->m_CcuColCmd.fcmode = fuelCellMode;
m_powerManger->m_CcuColCmd.insBatCmd = instrumentBattery; m_powerManger->m_CcuColCmd.fcuCmd = fuelCellCommand;
m_powerManger->m_CcuColCmd.fcuPowerEfficiency = fuelCellPower;
m_powerManger->m_CcuColCmd.insBatCmd = instrumentBattery;
m_powerManger->m_CcuColCmd.powerBatCmd = powerBattery;
m_powerManger->m_CcuColCmd.powerBatEfficiency = powerBatteryPower;
m_powerManger->m_CcuColCmd.masterState = hostStatus;
m_powerManger->m_CcuColCmd.insChargeEnable = instrumentBatteryCharge;
}
cout << "powerBatteryPower:" << (int)instrumentBattery << endl; cout << "powerBatteryPower:" << (int)instrumentBattery << endl;
m_powerManger->m_CcuColCmd.powerBatCmd = powerBattery; cout << "m_powerManger->m_CcuColCmd.masterState:" << (int)hostStatus << endl;
m_powerManger->m_CcuColCmd.powerBatEfficiency = powerBatteryPower;
m_powerManger->m_CcuColCmd.masterState = hostStatus;
m_powerManger->m_CcuColCmd.insChargeEnable = instrumentBatteryCharge;
cout << "m_powerManger->m_CcuColCmd.masterState:" << (int)m_powerManger->m_CcuColCmd.masterState << endl;
mg_http_reply(c, 200, "Content-Type: application/json\r\n", mg_http_reply(c, 200, "Content-Type: application/json\r\n",
"{\"success\": true, \"message\": \"电池配置提交成功\"}"); "{\"success\": true, \"message\": \"电池配置提交成功\"}");
@@ -353,6 +356,13 @@ void HttpServer::pushSystemData() {
return; return;
} }
// 先持 m_stateMutex 快照 m_CcuColCmd(绝不与下方 m_dataMutex 同时持有,避免锁序死锁)
ccuColCmd ccuCmd;
if (m_powerManger) {
std::lock_guard<std::mutex> stateLock(m_powerManger->m_stateMutex);
ccuCmd = m_powerManger->m_CcuColCmd;
}
std::lock_guard<std::mutex> dataLock(m_systemData->m_dataMutex); std::lock_guard<std::mutex> dataLock(m_systemData->m_dataMutex);
// 序列化系统数据为JSON // 序列化系统数据为JSON
@@ -772,15 +782,15 @@ void HttpServer::pushSystemData() {
j["debug"]["m_liBatStateMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_liBatStateMsg_st_debug.second); j["debug"]["m_liBatStateMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_liBatStateMsg_st_debug.second);
#endif #endif
j["ccuColCmd"]["fcmode"] = Json::Value(m_powerManger->m_CcuColCmd.fcmode); j["ccuColCmd"]["fcmode"] = Json::Value(ccuCmd.fcmode);
j["ccuColCmd"]["fcuCmd"] = Json::Value(m_powerManger->m_CcuColCmd.fcuCmd); j["ccuColCmd"]["fcuCmd"] = Json::Value(ccuCmd.fcuCmd);
j["ccuColCmd"]["fcuPowerEfficiency"] = Json::Value(m_powerManger->m_CcuColCmd.fcuPowerEfficiency); j["ccuColCmd"]["fcuPowerEfficiency"] = Json::Value(ccuCmd.fcuPowerEfficiency);
j["ccuColCmd"]["insChargeEnable"] = Json::Value(m_powerManger->m_CcuColCmd.insChargeEnable); j["ccuColCmd"]["insChargeEnable"] = Json::Value(ccuCmd.insChargeEnable);
j["ccuColCmd"]["insBatCmd"] = Json::Value(m_powerManger->m_CcuColCmd.insBatCmd); j["ccuColCmd"]["insBatCmd"] = Json::Value(ccuCmd.insBatCmd);
j["ccuColCmd"]["powerBatCmd"] = Json::Value(m_powerManger->m_CcuColCmd.powerBatCmd); j["ccuColCmd"]["powerBatCmd"] = Json::Value(ccuCmd.powerBatCmd);
j["ccuColCmd"]["powerBatEfficiency"] = Json::Value(m_powerManger->m_CcuColCmd.powerBatEfficiency); j["ccuColCmd"]["powerBatEfficiency"] = Json::Value(ccuCmd.powerBatEfficiency);
j["ccuColCmd"]["heartbeat"] = Json::Value(m_powerManger->m_CcuColCmd.heartbeat); j["ccuColCmd"]["heartbeat"] = Json::Value(ccuCmd.heartbeat);
j["ccuColCmd"]["masterState"] = Json::Value(m_powerManger->m_CcuColCmd.masterState); j["ccuColCmd"]["masterState"] = Json::Value(ccuCmd.masterState);
// 时间戳 // 时间戳
j["timestamp"] = Json::Value((Json::UInt64)(std::chrono::duration_cast<std::chrono::milliseconds>( j["timestamp"] = Json::Value((Json::UInt64)(std::chrono::duration_cast<std::chrono::milliseconds>(
+64 -4
View File
@@ -37,6 +37,7 @@ public:
* @return uint8_t 故障等级,00H-无故障, 10H-一级, 20H-二级, 30H-三级, 40H-四级 * @return uint8_t 故障等级,00H-无故障, 10H-一级, 20H-二级, 30H-三级, 40H-四级
*/ */
uint8_t getFaultCodeLevel() const { uint8_t getFaultCodeLevel() const {
std::lock_guard<std::mutex> lock(sysFaultCodesMutex);
uint8_t maxLevel = 0; uint8_t maxLevel = 0;
// 遍历 sysFaultCodes 集合中的每个故障码 // 遍历 sysFaultCodes 集合中的每个故障码
for (auto code : sysFaultCodes) { for (auto code : sysFaultCodes) {
@@ -536,6 +537,7 @@ public:
bool leakStatus[8] = {false}; bool leakStatus[8] = {false};
unsigned char generateLeakageCode() { unsigned char generateLeakageCode() {
std::lock_guard<std::mutex> lock(m_dataMutex);
unsigned char code = 0; unsigned char code = 0;
if(leakStatus[LEAKAGE_BOW_EMERGENCY]) code |= 0x01; if(leakStatus[LEAKAGE_BOW_EMERGENCY]) code |= 0x01;
if(leakStatus[LEAKAGE_BOW_HIGH_VOLTAGE]) code |= 0x02; if(leakStatus[LEAKAGE_BOW_HIGH_VOLTAGE]) code |= 0x02;
@@ -615,6 +617,65 @@ public:
}; };
~SystemData(){}; ~SystemData(){};
//============== 跨线程读访问器(锁内拷贝,避免与更新线程竞争)==============
float getDynVoltageLink() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return dyn_voltage_link;
}
uint8_t getDynPosRelayStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return dyn_pos_relay_status;
}
uint8_t getDynNegRelayStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return dyn_neg_relay_status;
}
uint8_t getDynEmergencyStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return dyn_emergency_status;
}
DcdcStatus getDcdcStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return m_dcdcStatus;
}
decltype(power_bus_status) getPowerBusStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return power_bus_status;
}
decltype(power_a_bus_status) getPowerABusStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return power_a_bus_status;
}
decltype(instrument_main_bus_status) getInstrumentMainBusStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return instrument_main_bus_status;
}
decltype(instrument_bus_status) getInstrumentBusStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return instrument_bus_status;
}
DeviceCommonStatus getDeviceCommonStatus() const {
std::lock_guard<std::mutex> lock(m_dataMutex);
return device_common_status;
}
// 配电故障码集合(std::set 非原子,必须加锁访问)
bool hasDisSysFaultCode(unsigned int code) const {
std::lock_guard<std::mutex> lock(faultCodeMutex);
return disSysFaultCode.find(code) != disSysFaultCode.end();
}
void insertDisSysFaultCode(unsigned int code) {
std::lock_guard<std::mutex> lock(faultCodeMutex);
disSysFaultCode.insert(code);
}
void clearDisSysFaultCodes() {
std::lock_guard<std::mutex> lock(faultCodeMutex);
disSysFaultCode.clear();
}
std::set<unsigned int> getDisSysFaultCodes() const {
std::lock_guard<std::mutex> lock(faultCodeMutex);
return disSysFaultCode;
}
void updateCommonStatus(double time_out=30){ void updateCommonStatus(double time_out=30){
std::lock_guard<std::mutex> lock(m_dataMutex); std::lock_guard<std::mutex> lock(m_dataMutex);
//更新时间 //更新时间
@@ -754,10 +815,9 @@ public:
ins_emergency_status = data.ins_emergency_status; ins_emergency_status = data.ins_emergency_status;
dyn_emergency_status = data.dyn_emergency_status; dyn_emergency_status = data.dyn_emergency_status;
//保留字段 //保留字段:ccuState 中 reserved2 仅声明 1 字节(协议预留 2 字节),只拷贝已有元素,避免越界读
for(int i=0; i<2; i++) { reserved2[0] = data.reserved2[0];
reserved2[i] = data.reserved2[i]; reserved2[1] = 0;
}
//SOC门限值 //SOC门限值
ins_soc_threshold1 = data.ins_soc_threshold1; ins_soc_threshold1 = data.ins_soc_threshold1;
+16 -34
View File
@@ -470,17 +470,13 @@ bool udpComm::sendDisSysCmd(const disHighVolBusCmd cmd)
msgBuf = reinterpret_cast<unsigned char *>(msg); msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBCmd),sizeof(cChecksum)); cc = calculateChecksum(msgBuf,sizeof(msg_disHVBCmd),sizeof(cChecksum));
msg->checkCode = cc; msg->checkCode = cc;
try bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBCmd));
{ if (!sendResult) {
sendMsg(msgBuf,sizeof(msg_disHVBCmd)); LOG_F(ERROR, "sendDisSysCmd(disHighVolBusCmd) send failed");
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
} }
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUS_CMD_ID, "disHighVolBusCmd", msgBuf, sizeof(msg_disHVBCmd), true); if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUS_CMD_ID, "disHighVolBusCmd", msgBuf, sizeof(msg_disHVBCmd), true);
delete msg; delete msg;
return true; return sendResult;
} }
bool udpComm::sendDisSysCmd(const disHighAVolBusCmd cmd) bool udpComm::sendDisSysCmd(const disHighAVolBusCmd cmd)
@@ -498,17 +494,13 @@ bool udpComm::sendDisSysCmd(const disHighAVolBusCmd cmd)
msgBuf = reinterpret_cast<unsigned char *>(msg); msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBACmd),sizeof(cChecksum)); cc = calculateChecksum(msgBuf,sizeof(msg_disHVBACmd),sizeof(cChecksum));
msg->checkCode = cc; msg->checkCode = cc;
try bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBACmd));
{ if (!sendResult) {
sendMsg(msgBuf,sizeof(msg_disHVBACmd)); LOG_F(ERROR, "sendDisSysCmd(disHighAVolBusCmd) send failed");
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
} }
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUSA_CMD_ID, "disHighAVolBusCmd", msgBuf, sizeof(msg_disHVBACmd), true); if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUSA_CMD_ID, "disHighAVolBusCmd", msgBuf, sizeof(msg_disHVBACmd), true);
delete msg; delete msg;
return true; return sendResult;
} }
bool udpComm::sendDisSysCmd(const disHighBVolBusCmd cmd) bool udpComm::sendDisSysCmd(const disHighBVolBusCmd cmd)
@@ -526,18 +518,13 @@ bool udpComm::sendDisSysCmd(const disHighBVolBusCmd cmd)
msgBuf = reinterpret_cast<unsigned char *>(msg); msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBBCmd),sizeof(cChecksum)); cc = calculateChecksum(msgBuf,sizeof(msg_disHVBBCmd),sizeof(cChecksum));
msg->checkCode = cc; msg->checkCode = cc;
try bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBBCmd));
{ if (!sendResult) {
// cout << "=========" <<(int)sizeof(msg_disHVBBCmd) << endl; LOG_F(ERROR, "sendDisSysCmd(disHighBVolBusCmd) send failed");
sendMsg(msgBuf,sizeof(msg_disHVBBCmd));
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
} }
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUSB_CMD_ID, "disLowMainBusCmd", msgBuf, sizeof(msg_disHVBBCmd), true); if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUSB_CMD_ID, "disLowMainBusCmd", msgBuf, sizeof(msg_disHVBBCmd), true);
delete msg; delete msg;
return true; return sendResult;
} }
bool udpComm::sendDisSysCmd(const disLowBusCmd cmd) bool udpComm::sendDisSysCmd(const disLowBusCmd cmd)
@@ -556,18 +543,13 @@ bool udpComm::sendDisSysCmd(const disLowBusCmd cmd)
cc = calculateChecksum(msgBuf,sizeof(msg_disLVBCmd),sizeof(cChecksum)); cc = calculateChecksum(msgBuf,sizeof(msg_disLVBCmd),sizeof(cChecksum));
// msg->checkCode = static_cast<cChecksum>(cc & 0xFF); // msg->checkCode = static_cast<cChecksum>(cc & 0xFF);
msg->checkCode = cc; msg->checkCode = cc;
cout << "cc======disLowBusCmd=============================" << (int) msg->checkCode << endl; bool sendResult = sendMsg(msgBuf, sizeof(msg_disLVBCmd));
try if (!sendResult) {
{ LOG_F(ERROR, "sendDisSysCmd(disLowBusCmd) send failed");
sendMsg(msgBuf,sizeof(msg_disLVBCmd));
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
} }
if (m_commLogger) m_commLogger->onFrame(1, DIS_LVBUS_CMD_ID, "disLowBusCmd", msgBuf, sizeof(msg_disLVBCmd), true); if (m_commLogger) m_commLogger->onFrame(1, DIS_LVBUS_CMD_ID, "disLowBusCmd", msgBuf, sizeof(msg_disLVBCmd), true);
delete msg; delete msg;
return true; return sendResult;
} }
bool udpComm::sendCcuColCmd(const ccuColCmd cmd) bool udpComm::sendCcuColCmd(const ccuColCmd cmd)
@@ -137,6 +137,7 @@ public:
// std::string buildMsg(SystemData data,disSysBreakerList currentDisBreakerState) // std::string buildMsg(SystemData data,disSysBreakerList currentDisBreakerState)
std::string buildMsg(const SystemData& data,disSysBreakerList currentDisBreakerState) std::string buildMsg(const SystemData& data,disSysBreakerList currentDisBreakerState)
{ {
std::lock_guard<std::mutex> lock(data.m_dataMutex);
//构建配电系统状态报告 //构建配电系统状态报告
Json::Value dis; Json::Value dis;
// disBus1Breaker dis1 = currentDisBreakerState.bus1Breaker; // disBus1Breaker dis1 = currentDisBreakerState.bus1Breaker;
+1
View File
@@ -27,6 +27,7 @@ public:
// std::string buildMsg(SystemData data) // std::string buildMsg(SystemData data)
std::string buildMsg(const SystemData& data) std::string buildMsg(const SystemData& data)
{ {
std::lock_guard<std::mutex> lock(data.m_dataMutex);
//TODO:根据最新协议修改 //TODO:根据最新协议修改
Json::Value fcs; Json::Value fcs;
// suffix = getTypeName(typeid(ccustate.fcuState).name()); // suffix = getTypeName(typeid(ccustate.fcuState).name());
@@ -18,6 +18,7 @@ public:
// std::string buildMsg(SystemData data) // std::string buildMsg(SystemData data)
std::string buildMsg(const SystemData& data) std::string buildMsg(const SystemData& data)
{ {
std::lock_guard<std::mutex> lock(data.m_dataMutex);
//TODO:根据最新协议修改 //TODO:根据最新协议修改
Json::Value lbs; Json::Value lbs;
//构建锂电池状态报告 //构建锂电池状态报告
+17
View File
@@ -108,3 +108,20 @@ target_link_libraries(udpFeeder
pthread pthread
dl dl
) )
################################################fullFeeder(集成测试用)#######
# 全类型 UDP 仿真器:CCU 状态 + 4 路配电反馈(自包含,仅依赖协议结构体头文件)
add_executable(fullFeeder
integration/full_feeder.cpp
)
target_include_directories(fullFeeder PRIVATE
${PM_SRC_DIR}
${PM_SRC_DIR}/udpcomm
)
set_target_properties(fullFeeder PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
)
target_link_libraries(fullFeeder
pthread
)
+292
View File
@@ -0,0 +1,292 @@
//=======================================================================
// full_feeder.cpp: 集成测试用 — 仿真真实 CCU + 配电系统,向 pPowerManger
// 发送全部 5 类状态反馈 UDP 消息(CCU 状态 + 4 路配电反馈)。
// 直接使用真实 C++ 结构体构造消息(字节级与协议一致,无打包漂移)。
// 用法: fullFeeder [host] [port] [rounds] [interval_ms]
// rounds=0 表示持续发送直到被 kill。
//=======================================================================
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <thread>
#include <chrono>
#include "udpcomm/ccuUdpMsg.h"
static int g_fd = -1;
static sockaddr_in g_addr{};
static bool sendBuf(const void* buf, size_t len) {
ssize_t n = sendto(g_fd, buf, len, 0,
reinterpret_cast<sockaddr*>(&g_addr), sizeof(g_addr));
return n == (ssize_t)len;
}
// CCU 消息校验和:4 字节全宽(sum 覆盖 sizeof-4 字节)
static unsigned int ccuChecksum(const unsigned char* d, int size) {
unsigned int s = 0;
for (int i = 0; i < size - (int)sizeof(Checksum); ++i) s += d[i];
return s;
}
// 配电消息校验和:1 字节(sum 覆盖 sizeof-1 字节,&0xFF)
static unsigned char disChecksum(const unsigned char* d, int size) {
unsigned int s = 0;
for (int i = 0; i < size - (int)sizeof(cChecksum); ++i) s += d[i];
return (unsigned char)(s & 0xFF);
}
static void fillCcuState(msg_CcuStateFbMsg& m, unsigned int beat) {
memset(&m, 0, sizeof(m));
m.header.start1 = CCU_UDPMSG_START1;
m.header.start2 = CCU_UDPMSG_START2;
m.header.id = CCU_STATE_FB_ID;
m.header.length = sizeof(ccuState);
m.data.fc_mode = 0x02; // 自动
m.data.fc_status = 0x04; // 运行
m.data.fc_fault_level = 0x00; // 无故障
m.data.output_power_limit = 30000;
m.data.total_generation_time = 1234;
m.data.total_generation_power = 8000;
m.data.hydrogen_capacity = 70;
m.data.liquid_oxygen_capacity = 65;
m.data.palladium_temp = 60;
m.data.main_pipe_pressure = 200;
m.data.aux_pipe_pressure = 180;
m.data.cabin_pressure1 = 101;
m.data.cabin_pressure2 = 101;
m.data.cabin_temp1 = 25;
m.data.cabin_temp2 = 26;
m.data.cabin_humidity1 = 50;
m.data.cabin_humidity2 = 52;
m.data.flame_detector1 = 0x00;
m.data.flame_detector2 = 0x00;
m.data.h2_concentration1 = 5;
m.data.o2_concentration1 = 2000;
m.data.ch3oh_concentration1 = 3;
m.data.emergency_battery1_voltage = 240;
m.data.emergency_battery1_current = 10;
m.data.emergency_battery1_max_temp = 30;
m.data.emergency_battery2_voltage = 240;
m.data.emergency_battery2_current = 10;
m.data.emergency_battery2_max_temp = 31;
m.data.cabin_ox_concentration = 2000;
m.data.cabin_temperature = 25;
m.data.cabin_humidity = 50;
m.data.cabin_pressure = 101;
m.data.power_cabin_ox_concentration = 2000;
m.data.power_cabin_temperature = 28;
m.data.power_cabin_humidity = 48;
m.data.power_cabin_pressure = 101;
m.data.ins_relay_status1 = 0x11;
m.data.ins_relay_status2 = 0x12;
m.data.dyn_relay_status1 = 0x11;
m.data.dyn_relay_status2 = 0x12;
m.data.ins_max_discharge_power = 200;
m.data.dyn_max_discharge_power = 400;
m.data.ins_soc = 85;
m.data.dyn_soc = 80;
m.data.ins_total_energy = 100;
m.data.dyn_total_energy = 500;
m.data.ins_power_input = 10;
m.data.dyn_power_input = 30;
m.data.ins_charge_status = 0x20; // 放电
m.data.dyn_charge_status = 0x20;
m.data.ins_voltage_link = 2400; // 240.0V
m.data.ins_voltage_pack = 2350;
m.data.ins_current = 400; // 20A
m.data.ins_resistance_pos = 999;
m.data.ins_resistance_neg = 999;
m.data.dyn_voltage_link = 5200; // 520.0V
m.data.dyn_voltage_pack = 5150;
m.data.dyn_current = 600; // 30A
m.data.dyn_resistance_pos = 999;
m.data.dyn_resistance_neg = 999;
m.data.ins_emergency_status = 0x00;
m.data.dyn_emergency_status = 0x00;
m.data.ins_soc_threshold1 = 90;
m.data.ins_soc_threshold2 = 80;
m.data.ins_soc_threshold3 = 70;
m.data.dyn_soc_threshold1 = 90;
m.data.dyn_soc_threshold2 = 80;
m.data.dyn_soc_threshold3 = 70;
m.data.device_online_flag1 = 0x000000FF;
m.data.device_online_flag2 = 0x0000001F;
m.data.dyn_charge_level = 0x01;
m.data.dyn_water_leak_status = 0x00;
m.data.ins_water_leak_dcdc_status = 0x00;
m.data.heartbeat = beat;
m.checkCode = ccuChecksum(reinterpret_cast<unsigned char*>(&m), sizeof(m));
}
static void fillDisHighVolBus(msg_disHighVolBusFbMsg& m) {
memset(&m, 0, sizeof(m));
m.header.start1 = DIS_MSG_HEAD1;
m.header.start2 = DIS_MSG_HEAD2;
m.header.id = DIS_HVBUS_FB_ID;
m.header.length = sizeof(disHighVolBusState);
m.data.fuelCellCircuitBreaker = BREAK_ON;
m.data.powerLithiumBatteryCircuitBreaker = BREAK_ON;
m.data.propulsionMotorCircuitBreaker = BREAK_OFF;
m.data.lithiumBatteryGroupInstrumentCircuitBreaker = BREAK_ON;
m.data.dcDc5ModuleCircuitBreaker = BREAK_ON;
m.data.bowHighVoltageDistributionBoxCircuitBreaker = BREAK_ON;
m.data.sternFTDevice45CircuitBreaker = BREAK_OFF;
m.data.sternRudderSwitch1CircuitBreaker = BREAK_OFF;
m.data.sternRudderSwitch2CircuitBreaker = BREAK_OFF;
m.data.fbReservedCircuitBreaker = BREAK_OFF;
m.data.tyzReservedCircuitBreaker = BREAK_OFF;
m.data.reservedCircuitBreaker = BREAK_OFF;
m.data.dcDcFaultWord1 = 0x00;
m.data.dcDcFaultWord2 = 0x62; // 工作状态启动 + 冷却泵运行
m.data.powerBusInsulationStatus = BREAK_ON; // 正常
m.data.aBusInsulationStatus = BREAK_ON;
m.data.meterPowerLossSignal = BREAK_ON;
m.data.emergencyPowerLossSignal = BREAK_ON;
m.data.dcDcTemperature = 60;
m.data.powerBusVoltage = 5000; // 500.0V
m.data.dcDc5ModuleCurrent = 200;
m.data.powerBusCurrent = 400;
m.data.busbarAVoltage = 5000;
m.data.propulsionMotorControlBoxCurrent = 10;
m.data.busbarACurrent = 300;
m.data.lithiumBatteryGroupMeterCurrent = 50;
m.data.bowHighVoltageDistributionBoxCurrent = 100;
m.data.sternFTDevice45Current = 0;
m.data.tyzReservedSwitchCurrent = 0;
m.data.sternRudderSwitch1Current = 0;
m.data.sternRudderSwitch2Current = 0;
m.data.coolWaterPressure = 150;
m.checkCode = disChecksum(reinterpret_cast<unsigned char*>(&m), sizeof(m));
}
static void fillDisHighAVolBus(msg_disHighAVolBusFbMsg& m) {
memset(&m, 0, sizeof(m));
m.header.start1 = DIS_MSG_HEAD1;
m.header.start2 = DIS_MSG_HEAD2;
m.header.id = DIS_HVBUSA_FB_ID;
m.header.length = sizeof(disHighAVolBusState);
m.data.bowFTDevice123CircuitBreaker = BREAK_ON;
m.data.actuatorCircuitBreaker = BREAK_OFF;
m.data.mastSteeringGearControlBoxCircuitBreaker = BREAK_OFF;
m.data.xczCircuitBreaker = BREAK_ON;
m.data.bowRudderControlBoxCircuitBreaker = BREAK_OFF;
m.data.openWaterCoverStartCylinderCircuitBreaker = BREAK_OFF;
m.data.instrumentPowerFailureSignal = BREAK_ON;
m.data.emergencyPowerFailureSignal = BREAK_ON;
m.data.waterIngressionAlarm = BREAK_ON; // 正常
m.data.busbarBVoltage = 5000;
m.data.busbarBCurrent = 300;
m.data.bowFTDevice123Current = 80;
m.data.actuatorCurrent = 0;
m.data.mastSteeringGearControlBoxCurrent = 0;
m.data.xczCurrent = 40;
m.data.bowRudderControlBoxCurrent = 0;
m.data.openWaterCoverStartCylinderCurrent = 0;
m.checkCode = disChecksum(reinterpret_cast<unsigned char*>(&m), sizeof(m));
}
static void fillDisLowMainBus(msg_disLowMainBusFbMsg& m) {
memset(&m, 0, sizeof(m));
m.header.start1 = DIS_MSG_HEAD1;
m.header.start2 = DIS_MSG_HEAD2;
m.header.id = DIS_HVBUSB_FB_ID;
m.header.length = sizeof(disLowMainBusState);
m.data.lithiumBatteryGroupInstrumentCircuitBreaker = BREAK_ON;
m.data.bowLowVoltageDistributionBoxCircuitBreaker = BREAK_ON;
m.data.unit4InstrumentDC48VCircuitBreaker = BREAK_ON;
m.data.dcC1DCDistributionPanelCircuitBreaker = BREAK_ON;
m.data.reservedCircuitBreaker1 = BREAK_OFF;
m.data.reservedCircuitBreaker2 = BREAK_OFF;
m.data.emergencyLithiumBatteryGroup2CircuitBreaker = BREAK_ON;
m.data.instrumentPowerFailureSignal = BREAK_ON;
m.data.emergencyPowerFailureSignal = BREAK_ON;
m.data.instrumentBusbarInsulationLow = BREAK_ON; // 正常
m.data.instrumentBusbarVoltage = 480; // 48.0V
m.data.bowLowVoltageDistributionBoxCurrent = 50;
m.data.dcC1InstrumentDC48VCurrent = 30;
m.data.emergencyLithiumBatteryGroup2Current = 10;
m.data.lithiumBatteryGroupInstrumentCurrent = 20;
m.data.unit4InstrumentDC48VCurrent = 15;
m.data.emergency2BusbarVoltage = 480;
m.data.compositeEnergyManagementSystemEmergencyDC48VCurrent = 5;
m.data.fuelCellSecuritySystemEmergencyDC48VCurrent = 5;
m.data.plcControlPowerCurrent = 8;
m.checkCode = disChecksum(reinterpret_cast<unsigned char*>(&m), sizeof(m));
}
static void fillDisLowBus(msg_disLowBusFbMsg& m) {
memset(&m, 0, sizeof(m));
m.header.start1 = DIS_MSG_HEAD1;
m.header.start2 = DIS_MSG_HEAD2;
m.header.id = DIS_LVBUS_FB_ID;
m.header.length = sizeof(disLowBusState);
m.data.unit1CircuitBreaker = BREAK_ON;
m.data.unit2CircuitBreaker = BREAK_ON;
m.data.unit3CircuitBreaker = BREAK_ON;
m.data.unit5CircuitBreaker = BREAK_OFF;
m.data.bowPZDeviceCircuitBreaker = BREAK_ON;
m.data.reservedCircuitBreaker1 = BREAK_OFF;
m.data.reservedCircuitBreaker2 = BREAK_OFF;
m.data.emergencyLithiumBatteryGroup1CircuitBreaker = BREAK_ON;
m.data.powerFailureSignal = BREAK_ON;
m.data.emergencyPowerFailureSignal = BREAK_ON;
m.data.waterIngressionAlarm = BREAK_ON; // 正常
m.data.instrumentBusbarVoltage = 240; // 24.0V
m.data.instrumentBusbarCurrent = 60;
m.data.unit1Current = 15;
m.data.unit2Current = 15;
m.data.unit3Current = 15;
m.data.unit5Current = 0;
m.data.bowPZDeviceCurrent = 10;
m.data.emergencyLithiumBatteryGroup1Current = 8;
m.data.emergency1BusbarVoltage = 240;
m.checkCode = disChecksum(reinterpret_cast<unsigned char*>(&m), sizeof(m));
}
int main(int argc, char* argv[]) {
const char* host = (argc > 1) ? argv[1] : "127.0.0.1";
int port = (argc > 2) ? atoi(argv[2]) : 5001;
int rounds = (argc > 3) ? atoi(argv[3]) : 0; // 0 = 持续
int intervalMs = (argc > 4) ? atoi(argv[4]) : 200;
g_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (g_fd < 0) { perror("socket"); return 1; }
g_addr.sin_family = AF_INET;
g_addr.sin_port = htons(static_cast<unsigned short>(port));
if (inet_pton(AF_INET, host, &g_addr.sin_addr) != 1) {
perror("inet_pton"); close(g_fd); return 1;
}
unsigned int beat = 1;
int sent = 0;
while (rounds == 0 || sent < rounds) {
msg_CcuStateFbMsg ccu;
msg_disHighVolBusFbMsg hv;
msg_disHighAVolBusFbMsg hva;
msg_disLowMainBusFbMsg lvmain;
msg_disLowBusFbMsg lv;
fillCcuState(ccu, beat);
fillDisHighVolBus(hv);
fillDisHighAVolBus(hva);
fillDisLowMainBus(lvmain);
fillDisLowBus(lv);
if (!sendBuf(&ccu, sizeof(ccu)) ||
!sendBuf(&hv, sizeof(hv)) ||
!sendBuf(&hva, sizeof(hva)) ||
!sendBuf(&lvmain, sizeof(lvmain)) ||
!sendBuf(&lv, sizeof(lv))) {
perror("sendto"); break;
}
++beat;
++sent;
std::this_thread::sleep_for(std::chrono::milliseconds(intervalMs));
}
close(g_fd);
printf("sent %d round(s) of 5 message types to %s:%d\n", sent, host, port);
return 0;
}
+13
View File
@@ -170,3 +170,16 @@ TEST(UdpCommTest, GetDate)
EXPECT_LE(minute, 59u); EXPECT_LE(minute, 59u);
EXPECT_LE(second, 59u); EXPECT_LE(second, 59u);
} }
TEST(UdpCommTest, SendDisSysCmdFailsWithoutSocket)
{
udpComm u; // 默认构造 udpScoket=nullptr,sendMsg 应返回 false
disHighVolBusCmd c1{};
disHighAVolBusCmd c2{};
disHighBVolBusCmd c3{};
disLowBusCmd c4{};
EXPECT_FALSE(u.sendDisSysCmd(c1));
EXPECT_FALSE(u.sendDisSysCmd(c2));
EXPECT_FALSE(u.sendDisSysCmd(c3));
EXPECT_FALSE(u.sendDisSysCmd(c4));
}
+1392
View File
File diff suppressed because it is too large Load Diff