修复:跨线程数据竞争 + 协议字段越界 + 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:
@@ -260,6 +260,12 @@ reports/
|
||||
# CI test binaries (built into bin/)
|
||||
bin/PowerMangerTests
|
||||
bin/udpFeeder
|
||||
bin/fullFeeder
|
||||
|
||||
# SQLite runtime artifacts
|
||||
*.db-shm
|
||||
*.db-wal
|
||||
*.db-journal
|
||||
|
||||
# Cross-compiled aarch64 artifacts (scripts/cross-build-local.sh)
|
||||
bin/arm64/
|
||||
|
||||
Executable
+138
@@ -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 "完成。"
|
||||
Executable
+125
@@ -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"
|
||||
@@ -80,17 +80,23 @@ void LowerCommManager::setCommLogger(ICommLogger* logger)
|
||||
if (m_udpComm) m_udpComm->setCommLogger(logger);
|
||||
}
|
||||
void LowerCommManager::processPeriodicTasks() {
|
||||
sendCcuCommand(m_pm->m_CcuColCmd);
|
||||
m_pm->m_db->insertData(m_pm->m_CcuColCmd);
|
||||
ccuColCmd cmd;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_pm->m_stateMutex);
|
||||
cmd = m_pm->m_CcuColCmd;
|
||||
}
|
||||
sendCcuCommand(cmd);
|
||||
m_pm->m_db->insertData(cmd);
|
||||
//延时5ms
|
||||
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{};
|
||||
m_udpComm->sendDisSysCmd(clr1);
|
||||
MOOSPause(200);
|
||||
}
|
||||
if(m_pm->m_systemData->device_common_status.dis_lv_c1.isTimeout )
|
||||
if(devStatus.dis_lv_c1.isTimeout )
|
||||
{
|
||||
disHighBVolBusCmd clr3{};
|
||||
m_udpComm->sendDisSysCmd(clr3);
|
||||
@@ -195,10 +201,14 @@ bool LowerCommManager::updatePoweSystemStates(){
|
||||
double time;
|
||||
if(m_udpComm->popMsgFormQueue(time, m_CcuCurrentState))
|
||||
{
|
||||
m_pm->m_pmCurrentState.ccustate = m_CcuCurrentState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.ccustate); //写入数据库
|
||||
ccuState local = m_CcuCurrentState.data;
|
||||
{
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
if(m_udpComm->popMsgFormQueue(time, m_disHighVolBusCurrentState))
|
||||
{
|
||||
// m_udpComm->popMsgFormQueue(time,m_disHighVolBusCurrentState);
|
||||
m_pm->m_pmCurrentState.bus1State = m_disHighVolBusCurrentState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus1State); //写入数据库
|
||||
disHighVolBusState local = m_disHighVolBusCurrentState.data;
|
||||
{
|
||||
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;
|
||||
|
||||
disBus1Breaker* pdis1=new disBus1Breaker;
|
||||
(m_pm->m_pmCurrentState.bus1State.fuelCellCircuitBreaker == BREAK_ON) ? pdis1 -> fuelCellCircuitBreaker = 1 : pdis1 -> fuelCellCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.powerLithiumBatteryCircuitBreaker == BREAK_ON) ? pdis1 -> powerLithiumBatteryCircuitBreaker = 1 : pdis1 -> powerLithiumBatteryCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.propulsionMotorCircuitBreaker == BREAK_ON) ? pdis1 -> propulsionMotorCircuitBreaker = 1 : pdis1 -> propulsionMotorCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.lithiumBatteryGroupInstrumentCircuitBreaker == BREAK_ON) ? pdis1 -> lithiumBatteryGroupInstrumentCircuitBreaker = 1 : pdis1 -> lithiumBatteryGroupInstrumentCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.dcDc5ModuleCircuitBreaker == BREAK_ON) ? pdis1 -> dcDc5ModuleCircuitBreaker = 1 : pdis1 -> dcDc5ModuleCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.bowHighVoltageDistributionBoxCircuitBreaker == BREAK_ON) ? pdis1 -> bowHighVoltageDistributionBoxCircuitBreaker = 1 : pdis1 -> bowHighVoltageDistributionBoxCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.sternFTDevice45CircuitBreaker == BREAK_ON) ? pdis1 -> sternFTDevice45CircuitBreaker = 1 : pdis1 -> sternFTDevice45CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.sternRudderSwitch1CircuitBreaker == BREAK_ON) ? pdis1 -> sternRudderSwitch1CircuitBreaker = 1 : pdis1 -> sternRudderSwitch1CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.sternRudderSwitch2CircuitBreaker == BREAK_ON) ? pdis1 -> sternRudderSwitch2CircuitBreaker = 1 : pdis1 -> sternRudderSwitch2CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.fbReservedCircuitBreaker == BREAK_ON) ? pdis1 -> fbReservedCircuitBreaker = 1 : pdis1 -> fbReservedCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.tyzReservedCircuitBreaker == BREAK_ON) ? pdis1 -> tyzReservedCircuitBreaker = 1 : pdis1 -> tyzReservedCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus1State.reservedCircuitBreaker == BREAK_ON) ? pdis1 -> reservedCircuitBreaker = 1 : pdis1 -> reservedCircuitBreaker = 0;
|
||||
pdis1 -> paceholder = 0;
|
||||
m_pm->m_currentDisBreakerState.bus1Breaker = *pdis1;
|
||||
delete pdis1;
|
||||
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus1State);
|
||||
m_pm->m_systemData->updateSystemData(local);
|
||||
{
|
||||
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;
|
||||
@@ -253,22 +263,23 @@ bool LowerCommManager::updatePoweSystemStates(){
|
||||
double time;
|
||||
if(m_udpComm->popMsgFormQueue(time,m_disHighAVolBusCurrentState))
|
||||
{
|
||||
m_pm->m_pmCurrentState.bus2State = m_disHighAVolBusCurrentState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus2State); //写入数据库
|
||||
disHighAVolBusState local = m_disHighAVolBusCurrentState.data;
|
||||
{
|
||||
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;
|
||||
|
||||
disBus2Breaker* pdis2=new disBus2Breaker;
|
||||
(m_pm->m_pmCurrentState.bus2State.bowFTDevice123CircuitBreaker == BREAK_ON)? pdis2 -> bowFTDevice123CircuitBreaker = 1 : pdis2 -> bowFTDevice123CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.actuatorCircuitBreaker == BREAK_ON)? pdis2 -> actuatorCircuitBreaker = 1 : pdis2 -> actuatorCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.mastSteeringGearControlBoxCircuitBreaker == BREAK_ON)? pdis2 -> mastSteeringGearControlBoxCircuitBreaker = 1 : pdis2 -> mastSteeringGearControlBoxCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.xczCircuitBreaker == BREAK_ON)? pdis2 -> xczCircuitBreaker = 1 : pdis2 -> xczCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.bowRudderControlBoxCircuitBreaker == BREAK_ON)? pdis2 -> bowRudderControlBoxCircuitBreaker = 1 : pdis2 -> bowRudderControlBoxCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus2State.openWaterCoverStartCylinderCircuitBreaker == BREAK_ON)? pdis2 -> openWaterCoverStartCylinderCircuitBreaker = 1 : pdis2 -> openWaterCoverStartCylinderCircuitBreaker = 0;
|
||||
pdis2 -> paceholder = 0;
|
||||
m_pm->m_currentDisBreakerState.bus2Breaker = *pdis2;
|
||||
delete pdis2;
|
||||
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus2State);
|
||||
m_pm->m_systemData->updateSystemData(local);
|
||||
{
|
||||
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;
|
||||
@@ -281,22 +292,24 @@ bool LowerCommManager::updatePoweSystemStates(){
|
||||
double time;
|
||||
if(m_udpComm->popMsgFormQueue(time,m_disHighBVolBusCurrentState))
|
||||
{
|
||||
m_pm->m_pmCurrentState.bus3State = m_disHighBVolBusCurrentState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus3State); //写入数据库
|
||||
disLowMainBusState local = m_disHighBVolBusCurrentState.data;
|
||||
{
|
||||
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;
|
||||
|
||||
disBus3Breaker* pdis3=new disBus3Breaker;
|
||||
(m_pm->m_pmCurrentState.bus3State.lithiumBatteryGroupInstrumentCircuitBreaker == BREAK_ON)? pdis3 -> lithiumBatteryGroupInstrumentCircuitBreaker = 1 : pdis3 -> lithiumBatteryGroupInstrumentCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.bowLowVoltageDistributionBoxCircuitBreaker == BREAK_ON)? pdis3 -> bowLowVoltageDistributionBoxCircuitBreaker = 1 : pdis3 -> bowLowVoltageDistributionBoxCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.unit4InstrumentDC48VCircuitBreaker == BREAK_ON)? pdis3 -> unit4InstrumentDC48VCircuitBreaker = 1 : pdis3 -> unit4InstrumentDC48VCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.dcC1DCDistributionPanelCircuitBreaker == BREAK_ON)? pdis3 -> dcC1DCDistributionPanelCircuitBreaker = 1 : pdis3 -> dcC1DCDistributionPanelCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.reservedCircuitBreaker1 == BREAK_ON)? pdis3 -> reservedCircuitBreaker1 = 1 : pdis3 -> reservedCircuitBreaker1 = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.reservedCircuitBreaker2 == BREAK_ON)? pdis3 -> reservedCircuitBreaker2 = 1 : pdis3 -> reservedCircuitBreaker2 = 0;
|
||||
(m_pm->m_pmCurrentState.bus3State.emergencyLithiumBatteryGroup2CircuitBreaker == BREAK_ON)? pdis3 -> emergencyLithiumBatteryGroup2CircuitBreaker = 1 : pdis3 -> emergencyLithiumBatteryGroup2CircuitBreaker = 0;
|
||||
pdis3->paceholder = 0;
|
||||
m_pm->m_currentDisBreakerState.bus3Breaker = *pdis3;
|
||||
delete pdis3;
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus3State);
|
||||
m_pm->m_systemData->updateSystemData(local);
|
||||
{
|
||||
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;
|
||||
@@ -308,23 +321,25 @@ bool LowerCommManager::updatePoweSystemStates(){
|
||||
double time;
|
||||
if(m_udpComm->popMsgFormQueue(time,m_disLowBusState))
|
||||
{
|
||||
m_pm->m_pmCurrentState.bus4State = m_disLowBusState.data;
|
||||
m_pm->m_db->insertData(m_pm->m_pmCurrentState.bus4State); //写入数据库
|
||||
disLowBusState local = m_disLowBusState.data;
|
||||
{
|
||||
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;
|
||||
|
||||
disBus4Breaker* pdis4=new disBus4Breaker;
|
||||
(m_pm->m_pmCurrentState.bus4State.unit1CircuitBreaker == BREAK_ON)? pdis4 -> unit1CircuitBreaker = 1 : pdis4 -> unit1CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.unit2CircuitBreaker == BREAK_ON)? pdis4 -> unit2CircuitBreaker = 1 : pdis4 -> unit2CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.unit3CircuitBreaker == BREAK_ON)? pdis4 -> unit3CircuitBreaker = 1 : pdis4 -> unit3CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.unit5CircuitBreaker == BREAK_ON)? pdis4 -> unit5CircuitBreaker = 1 : pdis4 -> unit5CircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.bowPZDeviceCircuitBreaker == BREAK_ON)? pdis4 -> bowPZDeviceCircuitBreaker = 1 : pdis4 -> bowPZDeviceCircuitBreaker = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.reservedCircuitBreaker1 == BREAK_ON)? pdis4 -> reservedCircuitBreaker1 = 1 : pdis4 -> reservedCircuitBreaker1 = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.reservedCircuitBreaker2 == BREAK_ON)? pdis4 -> reservedCircuitBreaker2 = 1 : pdis4 -> reservedCircuitBreaker2 = 0;
|
||||
(m_pm->m_pmCurrentState.bus4State.emergencyLithiumBatteryGroup1CircuitBreaker == BREAK_ON)? pdis4 -> emergencyLithiumBatteryGroup1CircuitBreaker = 1 : pdis4 -> emergencyLithiumBatteryGroup1CircuitBreaker = 0;
|
||||
pdis4 -> paceholder = 0;
|
||||
m_pm->m_currentDisBreakerState.bus4Breaker = *pdis4;
|
||||
delete pdis4;
|
||||
m_pm->m_systemData->updateSystemData(m_pm->m_pmCurrentState.bus4State);
|
||||
m_pm->m_systemData->updateSystemData(local);
|
||||
{
|
||||
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;
|
||||
@@ -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 << "甲醇浓度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 << "仪表舱 氧气浓度 (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 << "动力紧急状态 (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";
|
||||
for (int i = 0; i < 6; ++i)
|
||||
os << "SOC门限值 ins_soc_threshold" << i+1 << ": 0x" << std::hex << static_cast<int>(p.data.ins_soc_threshold1) << "\n";
|
||||
for (int i = 0; i < 4; ++i)
|
||||
os << "功率限制 ins_power_limit" << i+1 << ": 0x" << std::hex << static_cast<int>(p.data.ins_power_limit1) << "\n";
|
||||
os << "SOC门限值 ins_soc_threshold1: 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";
|
||||
os << "SOC门限值 ins_soc_threshold3: 0x" << std::hex << static_cast<int>(p.data.ins_soc_threshold3) << "\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 << "设备在线状态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);
|
||||
|
||||
// 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);
|
||||
while ( !ok ) {
|
||||
if( m_pm->m_systemData->m_dcdcStatus.workingStatus )
|
||||
if( m_pm->m_systemData->getDcdcStatus().workingStatus )
|
||||
{
|
||||
ok = true;
|
||||
break;
|
||||
@@ -718,11 +739,11 @@ bool LowerCommManager::operate_HV_coolingSystem_Breaker(char opt)
|
||||
m_udpComm->sendDisSysCmd(cmd);
|
||||
|
||||
// ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1 & 0x60;
|
||||
ok = m_pm->m_systemData->m_dcdcStatus.coolingPump1Running || m_pm->m_systemData->m_dcdcStatus.coolingPump2Running;
|
||||
ok = m_pm->m_systemData->getDcdcStatus().coolingPump1Running || m_pm->m_systemData->getDcdcStatus().coolingPump2Running;
|
||||
|
||||
MOOSPause(100);
|
||||
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;
|
||||
break;
|
||||
@@ -942,7 +963,12 @@ bool LowerCommManager::operateBreakerGeneric(
|
||||
m_udpComm->sendDisSysCmd(cmd);
|
||||
MOOSPause(100);
|
||||
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;
|
||||
break;
|
||||
|
||||
@@ -86,11 +86,14 @@ PowerManger::PowerManger()
|
||||
PowerManger::~PowerManger()
|
||||
{
|
||||
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_upperCommManager;
|
||||
delete m_systemData;
|
||||
delete m_httpServer;
|
||||
delete m_systemData; // 最后删除,此时无任何线程引用
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
@@ -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 maxLevel = 0;
|
||||
for (auto code : faultCode) {
|
||||
for (auto code : getFaultCodes()) {
|
||||
// 提取0xabcd中的b位 (右移8位后取低4位)
|
||||
unsigned char level = (code >> 8) & 0xF;
|
||||
if (level > maxLevel) {
|
||||
@@ -391,7 +412,10 @@ bool PowerManger::commLoop()
|
||||
{
|
||||
while(!m_commThread.IsQuitRequested())
|
||||
{
|
||||
m_CcuColCmd.heartbeat++;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_stateMutex);
|
||||
m_CcuColCmd.heartbeat++;
|
||||
}
|
||||
m_lowerCommManager->processPeriodicTasks();
|
||||
m_upperCommManager->processPeriodicTasks();
|
||||
// 延时1秒
|
||||
|
||||
@@ -87,6 +87,12 @@ class PowerManger : public AppCastingMOOSApp
|
||||
//===========================FEEDBACK======================================
|
||||
pmState m_pmCurrentState; //能源系统的当前状态(由下位机线程修改)
|
||||
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_subDisSysState;
|
||||
DriverTable m_subDisSysFault;
|
||||
|
||||
@@ -214,11 +214,20 @@ void UpperCommManager::processPeriodicTasks() {
|
||||
}
|
||||
|
||||
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.currentMod = m_pm->currentMod;
|
||||
m_pmStateMsg.state.powerState = m_pm->powerState;
|
||||
m_pmStateMsg.state.faultLevel = m_pm->faultLevel;
|
||||
m_pmStateMsg.state.faultCode = m_pm->faultCode;
|
||||
m_pmStateMsg.state.faultCode = m_pm->getFaultCodes();
|
||||
// cout << "m_pmStateMsg.state.faultCode.size():" << m_pmStateMsg.state.faultCode.size() << endl;
|
||||
m_pmStateMsg.state.soc = m_pm->soc;
|
||||
m_pmStateMsg.state.sustainableTime = m_pm->sustainableTime;
|
||||
@@ -229,14 +238,14 @@ void UpperCommManager::buildSystemReport() {
|
||||
m_pm->sendNotification(m_pmStateMsg.key, m_pmStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_pm->sendNotification(m_fcsStateMsg.key, m_fcsStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_pm->sendNotification(m_liBatStateMsg.key, m_liBatStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_pm->sendNotification(m_disSysStateMsg.key, m_disSysStateMsg.buildMsg(*(m_pm->m_systemData),m_pm->m_currentDisBreakerState));
|
||||
m_pm->sendNotification(m_currentStateMsg.key, m_currentStateMsg.buildMsg(m_pm->m_pmCurrentState));
|
||||
m_pm->sendNotification(m_disSysStateMsg.key, m_disSysStateMsg.buildMsg(*(m_pm->m_systemData), disBreakerSnap));
|
||||
m_pm->sendNotification(m_currentStateMsg.key, m_currentStateMsg.buildMsg(pmStateSnap));
|
||||
|
||||
#ifdef _DEBUG
|
||||
m_pmStateMsg_fb_debug = std::make_pair(m_pmStateMsg.key, m_pmStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_fcsStateMsg_st_debug = std::make_pair(m_fcsStateMsg.key, m_fcsStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_liBatStateMsg_st_debug = std::make_pair(m_liBatStateMsg.key, m_liBatStateMsg.buildMsg(*(m_pm->m_systemData)));
|
||||
m_disSysStateMsg_st_debug = std::make_pair(m_disSysStateMsg.key, m_disSysStateMsg.buildMsg(*(m_pm->m_systemData),m_pm->m_currentDisBreakerState));
|
||||
m_currentStateMsg_st_debug = std::make_pair(m_currentStateMsg.key, m_currentStateMsg.buildMsg(m_pm->m_pmCurrentState));
|
||||
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(pmStateSnap));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ void Lifting::entry() {
|
||||
MOOSPause(3);
|
||||
{
|
||||
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,"动力锂电池下电中...");
|
||||
MOOSPause(3);
|
||||
|
||||
@@ -36,7 +36,7 @@ void PowerManagerFsm::react(CycleTriggeredEvent const &){
|
||||
{
|
||||
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);
|
||||
//舷侧阵自动下电
|
||||
MOOSPause(3);
|
||||
@@ -66,10 +66,13 @@ void PowerManagerFsm::handleCuriseWork()
|
||||
//依次接入执行机构动力电设备
|
||||
//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;
|
||||
while (!(pm->m_systemData->dyn_voltage_link > 500.0))
|
||||
while (!(pm->m_systemData->getDynVoltageLink() > 500.0))
|
||||
{
|
||||
LOG_F(INFO,"动力锂电池上电中...");
|
||||
MOOSPause(1000);
|
||||
@@ -82,27 +85,27 @@ void PowerManagerFsm::handleCuriseWork()
|
||||
count++;
|
||||
}
|
||||
//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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
MOOSPause(3);
|
||||
@@ -1040,7 +1043,7 @@ void PowerManagerFsm::getNoPowerDeviceStatus(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)
|
||||
@@ -1103,7 +1106,7 @@ void PowerManagerFsm::getBowRudderSystemStatus(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)
|
||||
{
|
||||
@@ -1220,7 +1223,7 @@ void PowerManagerFsm::getActuatorStatus(DriverTable &s)
|
||||
void PowerManagerFsm::getSternRudderStatus(DriverTable &s)
|
||||
{
|
||||
//艉舵1 2
|
||||
if(pm->m_systemData->power_bus_status.sternRudderSwitch1CircuitBreaker == 1)
|
||||
if(pm->m_systemData->getPowerBusStatus().sternRudderSwitch1CircuitBreaker == 1)
|
||||
{
|
||||
if(pm->m_subDisSysState.sternRudderServo1== 1)
|
||||
{
|
||||
@@ -1261,7 +1264,7 @@ void PowerManagerFsm::getSternRudderStatus(DriverTable &s)
|
||||
}
|
||||
}
|
||||
//艉舵3 4
|
||||
if(pm->m_systemData->power_bus_status.sternRudderSwitch2CircuitBreaker == 1)
|
||||
if(pm->m_systemData->getPowerBusStatus().sternRudderSwitch2CircuitBreaker == 1)
|
||||
{
|
||||
if(pm->m_subDisSysState.sternRudderServo3 == 1)
|
||||
{
|
||||
@@ -1305,7 +1308,7 @@ void PowerManagerFsm::getSternRudderStatus(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)
|
||||
{
|
||||
@@ -1331,7 +1334,7 @@ void PowerManagerFsm::getPropulsionMotorStatus(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)
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
@@ -1435,7 +1438,7 @@ void PowerManagerFsm::getBuoyancyAdjustmentStatus(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)
|
||||
{
|
||||
@@ -1461,7 +1464,7 @@ void PowerManagerFsm::getSideSonarStatus(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)
|
||||
{
|
||||
@@ -1487,7 +1490,7 @@ void PowerManagerFsm::getFBSystemCmdStatus(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)
|
||||
{
|
||||
@@ -1513,7 +1516,7 @@ void PowerManagerFsm::getMastFoldingSystem(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)
|
||||
{
|
||||
@@ -1752,12 +1755,12 @@ void PowerManagerFsm::basicNavigationFault()
|
||||
if(pm->m_subDisSysFault.sternRudderServo4 == 1)
|
||||
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(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(0x1309);
|
||||
@@ -1765,19 +1768,19 @@ void PowerManagerFsm::basicNavigationFault()
|
||||
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(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(0x1309);
|
||||
}
|
||||
}
|
||||
//=====处理动力电池故障======================
|
||||
if(pm->m_systemData->dyn_emergency_status != 0 )
|
||||
if(pm->m_systemData->getDynEmergencyStatus() != 0 )
|
||||
{
|
||||
pm->m_systemData->insertFaultCode(0x130B);
|
||||
}
|
||||
@@ -1788,7 +1791,7 @@ void PowerManagerFsm::basicNavigationFault()
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pm->m_systemData->disSysFaultCode.find(3) == pm->m_systemData->disSysFaultCode.end())
|
||||
if(!pm->m_systemData->hasDisSysFaultCode(3))
|
||||
{
|
||||
pm->m_systemData->eraseFaultCode(0x130A);
|
||||
}
|
||||
@@ -1816,7 +1819,7 @@ void PowerManagerFsm::basicNavigationFault()
|
||||
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);
|
||||
}
|
||||
@@ -1831,63 +1834,63 @@ void PowerManagerFsm::basicNavigationFault(FaultEvent const &e)
|
||||
if((e.injectionFaultCode==1))
|
||||
{
|
||||
LOG_F(INFO, "部分深度计失效");
|
||||
pm->faultCode.push_back(0x1102);
|
||||
pm->faultCode.push_back(0x1103);
|
||||
pm->faultCode.push_back(0x1104);
|
||||
pm->addFaultCode(0x1102);
|
||||
pm->addFaultCode(0x1103);
|
||||
pm->addFaultCode(0x1104);
|
||||
}
|
||||
if((e.injectionFaultCode==2))
|
||||
{
|
||||
LOG_F(INFO, "DVL失效");
|
||||
pm->faultCode.push_back(0x1301);
|
||||
pm->addFaultCode(0x1301);
|
||||
}
|
||||
if ((e.injectionFaultCode==3))
|
||||
{
|
||||
LOG_F(INFO, "单个艉舵失效");
|
||||
pm->faultCode.push_back(0x1207);
|
||||
pm->addFaultCode(0x1207);
|
||||
}
|
||||
if ((e.injectionFaultCode==4))
|
||||
{
|
||||
LOG_F(INFO, "部分艉舵失效");
|
||||
pm->faultCode.push_back(0x1308);
|
||||
pm->faultCode.push_back(0x1307);
|
||||
pm->addFaultCode(0x1308);
|
||||
pm->addFaultCode(0x1307);
|
||||
}
|
||||
if ((e.injectionFaultCode==5))
|
||||
{
|
||||
LOG_F(INFO, "动力锂电池失效");
|
||||
pm->faultCode.push_back(0x130B);
|
||||
pm->addFaultCode(0x130B);
|
||||
}
|
||||
if ((e.injectionFaultCode==6))
|
||||
{
|
||||
LOG_F(INFO, "推进电机失效");
|
||||
pm->faultCode.push_back(0x130A);
|
||||
pm->addFaultCode(0x130A);
|
||||
}
|
||||
if ((e.injectionFaultCode==7))
|
||||
{
|
||||
LOG_F(INFO, "惯导失效");
|
||||
pm->faultCode.push_back(0x1305);
|
||||
pm->addFaultCode(0x1305);
|
||||
}
|
||||
if ((e.injectionFaultCode==8))
|
||||
{
|
||||
LOG_F(INFO, "深度失效");
|
||||
pm->faultCode.push_back(0x1302);
|
||||
pm->faultCode.push_back(0x1303);
|
||||
pm->faultCode.push_back(0x1304);
|
||||
pm->addFaultCode(0x1302);
|
||||
pm->addFaultCode(0x1303);
|
||||
pm->addFaultCode(0x1304);
|
||||
}
|
||||
if ((e.injectionFaultCode==9))
|
||||
{
|
||||
LOG_F(INFO, "仪表锂电池失效");
|
||||
pm->faultCode.push_back(0x1412);
|
||||
pm->addFaultCode(0x1412);
|
||||
}
|
||||
if ((e.injectionFaultCode==10))
|
||||
{
|
||||
LOG_F(INFO, "复合管控器失效");
|
||||
pm->faultCode.push_back(0x1413);
|
||||
pm->addFaultCode(0x1413);
|
||||
}
|
||||
}
|
||||
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(0x2312);
|
||||
@@ -1939,22 +1942,22 @@ void PowerManagerFsm::extendedNavigationFault(FaultEvent const &e)
|
||||
if ((e.injectionFaultCode==1))
|
||||
{
|
||||
LOG_F(INFO, "艏舵展开电缸失效");
|
||||
pm->faultCode.push_back(0x2311);
|
||||
pm->addFaultCode(0x2311);
|
||||
}
|
||||
if ((e.injectionFaultCode==2))
|
||||
{
|
||||
LOG_F(INFO, "艏舵控制控制失效");
|
||||
pm->faultCode.push_back(0x2312);
|
||||
pm->addFaultCode(0x2312);
|
||||
}
|
||||
if ((e.injectionFaultCode==3))
|
||||
{
|
||||
LOG_F(INFO, "动力锂电池功率不满/失效");
|
||||
pm->faultCode.push_back(0x2323);
|
||||
pm->addFaultCode(0x2323);
|
||||
}
|
||||
if ((e.injectionFaultCode==4))
|
||||
{
|
||||
LOG_F(INFO, "燃料电池失效");
|
||||
pm->faultCode.push_back(0x2334);
|
||||
pm->addFaultCode(0x2334);
|
||||
}
|
||||
}
|
||||
void PowerManagerFsm::obstacleAvoidanceFault()
|
||||
@@ -2061,22 +2064,22 @@ void PowerManagerFsm::obstacleAvoidanceFault(FaultEvent const &e)
|
||||
LOG_F(INFO, "obstacleAvoidanceFault");
|
||||
if ((e.injectionFaultCode==1))
|
||||
{
|
||||
pm->faultCode.push_back(0x3108);
|
||||
pm->faultCode.push_back(0x3109);
|
||||
pm->addFaultCode(0x3108);
|
||||
pm->addFaultCode(0x3109);
|
||||
}
|
||||
if ((e.injectionFaultCode==2))
|
||||
{
|
||||
pm->faultCode.push_back(0x3201);
|
||||
pm->faultCode.push_back(0x3202);
|
||||
pm->faultCode.push_back(0x3203);
|
||||
pm->faultCode.push_back(0x3204);
|
||||
pm->faultCode.push_back(0x3205);
|
||||
pm->faultCode.push_back(0x3206);
|
||||
pm->faultCode.push_back(0x3207);
|
||||
pm->addFaultCode(0x3201);
|
||||
pm->addFaultCode(0x3202);
|
||||
pm->addFaultCode(0x3203);
|
||||
pm->addFaultCode(0x3204);
|
||||
pm->addFaultCode(0x3205);
|
||||
pm->addFaultCode(0x3206);
|
||||
pm->addFaultCode(0x3207);
|
||||
}
|
||||
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.buoyancyAdjust5 == 1);
|
||||
|
||||
bool breaker7_fault = pm->m_systemData->disSysFaultCode.find(7) != pm->m_systemData->disSysFaultCode.end();
|
||||
bool breaker13_fault = pm->m_systemData->disSysFaultCode.find(13) != pm->m_systemData->disSysFaultCode.end();
|
||||
bool breaker7_fault = pm->m_systemData->hasDisSysFaultCode(7);
|
||||
bool breaker13_fault = pm->m_systemData->hasDisSysFaultCode(13);
|
||||
//===========艏部浮调====================
|
||||
if(breaker7_fault)
|
||||
{
|
||||
@@ -2256,24 +2259,24 @@ void PowerManagerFsm::buoyancyControlFault(FaultEvent const &e)
|
||||
if ((e.injectionFaultCode==1))
|
||||
{
|
||||
LOG_F(INFO, "单一浮调机构失效");
|
||||
pm->faultCode.push_back(0x4201);
|
||||
pm->addFaultCode(0x4201);
|
||||
}
|
||||
if ((e.injectionFaultCode==2))
|
||||
{
|
||||
LOG_F(INFO, "2-4及以上浮调装置失效");
|
||||
pm->faultCode.push_back(0x4301);
|
||||
pm->faultCode.push_back(0x4302);
|
||||
pm->faultCode.push_back(0x4303);
|
||||
pm->addFaultCode(0x4301);
|
||||
pm->addFaultCode(0x4302);
|
||||
pm->addFaultCode(0x4303);
|
||||
}
|
||||
if ((e.injectionFaultCode==3))
|
||||
{
|
||||
LOG_F(INFO, "功率不足满足浮调要求");
|
||||
pm->faultCode.push_back(0x4436);
|
||||
pm->addFaultCode(0x4436);
|
||||
}
|
||||
if ((e.injectionFaultCode==4))
|
||||
{
|
||||
LOG_F(INFO, "所有浮调系统失效");
|
||||
pm->faultCode.push_back(0x4401);
|
||||
pm->addFaultCode(0x4401);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2319,7 +2322,7 @@ void PowerManagerFsm::communicationSystemFault()
|
||||
else
|
||||
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);
|
||||
else
|
||||
pm->m_systemData->eraseFaultCode(0x5302);
|
||||
@@ -2331,22 +2334,22 @@ void PowerManagerFsm::communicationSystemFault(FaultEvent const &e)
|
||||
if ((e.injectionFaultCode==1))
|
||||
{
|
||||
LOG_F(INFO, "部分水下通信失效");
|
||||
pm->faultCode.push_back(0x5203);
|
||||
pm->faultCode.push_back(0x5204);
|
||||
pm->faultCode.push_back(0x5205);
|
||||
pm->addFaultCode(0x5203);
|
||||
pm->addFaultCode(0x5204);
|
||||
pm->addFaultCode(0x5205);
|
||||
}
|
||||
if ((e.injectionFaultCode==2))
|
||||
{
|
||||
LOG_F(INFO, "水下通信失效");
|
||||
pm->faultCode.push_back(0x5303);
|
||||
pm->faultCode.push_back(0x5304);
|
||||
pm->faultCode.push_back(0x5305);
|
||||
pm->addFaultCode(0x5303);
|
||||
pm->addFaultCode(0x5304);
|
||||
pm->addFaultCode(0x5305);
|
||||
}
|
||||
if ((e.injectionFaultCode==3))
|
||||
{
|
||||
LOG_F(INFO, "水面通信失效");
|
||||
pm->faultCode.push_back(0x5301);
|
||||
pm->faultCode.push_back(0x5302);
|
||||
pm->addFaultCode(0x5301);
|
||||
pm->addFaultCode(0x5302);
|
||||
}
|
||||
}
|
||||
void PowerManagerFsm::payloadSystemFault()
|
||||
@@ -2366,8 +2369,8 @@ void PowerManagerFsm::payloadSystemFault()
|
||||
+ (pm->m_subDisSysFault.bowWaterInet7 == 1)
|
||||
+ (pm->m_subDisSysFault.bowWaterInet8 == 1);
|
||||
|
||||
if((pm->m_systemData->disSysFaultCode.find(14) == pm->m_systemData->disSysFaultCode.end())
|
||||
&& (pm->m_systemData->disSysFaultCode.find(18) == pm->m_systemData->disSysFaultCode.end()))
|
||||
if((!pm->m_systemData->hasDisSysFaultCode(14))
|
||||
&& (!pm->m_systemData->hasDisSysFaultCode(18)))
|
||||
{
|
||||
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_systemData->disSysFaultCode.find(14) != pm->m_systemData->disSysFaultCode.end())
|
||||
&& (pm->m_systemData->disSysFaultCode.find(18) == pm->m_systemData->disSysFaultCode.end()))
|
||||
if((pm->m_systemData->hasDisSysFaultCode(14))
|
||||
&& (!pm->m_systemData->hasDisSysFaultCode(18)))
|
||||
{
|
||||
pm->m_systemData->insertFaultCode(0x633F);
|
||||
}
|
||||
@@ -2400,8 +2403,8 @@ void PowerManagerFsm::payloadSystemFault()
|
||||
{
|
||||
pm->m_systemData->insertFaultCode(0x633F);
|
||||
}
|
||||
if(count == 0 && ((pm->m_systemData->disSysFaultCode.find(14) == pm->m_systemData->disSysFaultCode.end())
|
||||
&& (pm->m_systemData->disSysFaultCode.find(18) == pm->m_systemData->disSysFaultCode.end())
|
||||
if(count == 0 && ((!pm->m_systemData->hasDisSysFaultCode(14))
|
||||
&& (!pm->m_systemData->hasDisSysFaultCode(18))
|
||||
&& (pm->m_subDisSysFault.launchControler == 0))
|
||||
)
|
||||
{
|
||||
@@ -2413,7 +2416,7 @@ void PowerManagerFsm::payloadSystemFault()
|
||||
else
|
||||
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);
|
||||
else
|
||||
pm->m_systemData->insertFaultCode(0x6323);
|
||||
@@ -2437,50 +2440,50 @@ void PowerManagerFsm::payloadSystemFault(FaultEvent const &e)
|
||||
if ((e.injectionFaultCode==1))
|
||||
{
|
||||
LOG_F(INFO, "存在启闭机构或者敞水电缸失效");
|
||||
pm->faultCode.push_back(0x6211);
|
||||
pm->faultCode.push_back(0x6212);
|
||||
pm->faultCode.push_back(0x6213);
|
||||
pm->faultCode.push_back(0x6214);
|
||||
pm->faultCode.push_back(0x6215);
|
||||
pm->faultCode.push_back(0x6216);
|
||||
pm->faultCode.push_back(0x6217);
|
||||
pm->faultCode.push_back(0x6218);
|
||||
pm->faultCode.push_back(0x6219);
|
||||
pm->faultCode.push_back(0x621A);
|
||||
pm->faultCode.push_back(0x621B);
|
||||
pm->faultCode.push_back(0x621C);
|
||||
pm->faultCode.push_back(0x621D);
|
||||
pm->faultCode.push_back(0x621E);
|
||||
pm->addFaultCode(0x6211);
|
||||
pm->addFaultCode(0x6212);
|
||||
pm->addFaultCode(0x6213);
|
||||
pm->addFaultCode(0x6214);
|
||||
pm->addFaultCode(0x6215);
|
||||
pm->addFaultCode(0x6216);
|
||||
pm->addFaultCode(0x6217);
|
||||
pm->addFaultCode(0x6218);
|
||||
pm->addFaultCode(0x6219);
|
||||
pm->addFaultCode(0x621A);
|
||||
pm->addFaultCode(0x621B);
|
||||
pm->addFaultCode(0x621C);
|
||||
pm->addFaultCode(0x621D);
|
||||
pm->addFaultCode(0x621E);
|
||||
}
|
||||
if ((e.injectionFaultCode==2))
|
||||
{
|
||||
LOG_F(INFO, "舷侧探测失效");
|
||||
pm->faultCode.push_back(0x6321);
|
||||
pm->addFaultCode(0x6321);
|
||||
}
|
||||
if ((e.injectionFaultCode==3))
|
||||
{
|
||||
LOG_F(INFO, "舷侧主动探测失效");
|
||||
pm->faultCode.push_back(0x6323);
|
||||
pm->addFaultCode(0x6323);
|
||||
}
|
||||
if ((e.injectionFaultCode==4))
|
||||
{
|
||||
LOG_F(INFO, "TYZ失效");
|
||||
pm->faultCode.push_back(0x6322);
|
||||
pm->addFaultCode(0x6322);
|
||||
}
|
||||
if ((e.injectionFaultCode==5))
|
||||
{
|
||||
LOG_F(INFO, "光电探测失效");
|
||||
pm->faultCode.push_back(0x6332);
|
||||
pm->addFaultCode(0x6332);
|
||||
}
|
||||
if ((e.injectionFaultCode==6))
|
||||
{
|
||||
LOG_F(INFO, "电磁探测失效");
|
||||
pm->faultCode.push_back(0x6331);
|
||||
pm->addFaultCode(0x6331);
|
||||
}
|
||||
if ((e.injectionFaultCode==7))
|
||||
{
|
||||
LOG_F(INFO, "载荷失效或者全部载荷启闭机构均失效");
|
||||
pm->faultCode.push_back(0x633F);
|
||||
pm->addFaultCode(0x633F);
|
||||
}
|
||||
}
|
||||
void PowerManagerFsm::emergencySystemFault()
|
||||
@@ -2514,14 +2517,14 @@ void PowerManagerFsm::emergencySystemFault()
|
||||
else
|
||||
pm->m_systemData->eraseFaultCode(0x7301);
|
||||
|
||||
if(pm->m_systemData->power_bus_status.emergencyPowerLossSignal || pm->m_systemData->instrument_main_bus_status.emergencyPowerFailureSignal
|
||||
|| (pm->m_systemData->disSysFaultCode.find(25) != pm->m_systemData->disSysFaultCode.end()))
|
||||
if(pm->m_systemData->getPowerBusStatus().emergencyPowerLossSignal || pm->m_systemData->getInstrumentMainBusStatus().emergencyPowerFailureSignal
|
||||
|| (pm->m_systemData->hasDisSysFaultCode(25)))
|
||||
pm->m_systemData->insertFaultCode(0x7306);
|
||||
else
|
||||
pm->m_systemData->eraseFaultCode(0x7306);
|
||||
|
||||
if(pm->m_systemData->power_a_bus_status.emergencyPowerFailureSignal || pm->m_systemData->instrument_bus_status.emergencyPowerFailureSignal
|
||||
|| (pm->m_systemData->disSysFaultCode.find(33) != pm->m_systemData->disSysFaultCode.end()))
|
||||
if(pm->m_systemData->getPowerABusStatus().emergencyPowerFailureSignal || pm->m_systemData->getInstrumentBusStatus().emergencyPowerFailureSignal
|
||||
|| (pm->m_systemData->hasDisSysFaultCode(33)))
|
||||
pm->m_systemData->insertFaultCode(0x7307);
|
||||
else
|
||||
pm->m_systemData->eraseFaultCode(0x7307);
|
||||
@@ -2534,35 +2537,35 @@ void PowerManagerFsm::emergencySystemFault(FaultEvent const &e)
|
||||
{
|
||||
//备注:抛载具有自己的电池
|
||||
LOG_F(INFO, "部分抛载失效");
|
||||
pm->faultCode.push_back(0x7202);
|
||||
pm->faultCode.push_back(0x7203);
|
||||
pm->addFaultCode(0x7202);
|
||||
pm->addFaultCode(0x7203);
|
||||
}
|
||||
if ((e.injectionFaultCode==2))
|
||||
{
|
||||
LOG_F(INFO, "一个超深检测装置失效");
|
||||
pm->faultCode.push_back(0x7204);
|
||||
pm->faultCode.push_back(0x7205);
|
||||
pm->addFaultCode(0x7204);
|
||||
pm->addFaultCode(0x7205);
|
||||
}
|
||||
if ((e.injectionFaultCode==3))
|
||||
{
|
||||
LOG_F(INFO, "注水机构失效");
|
||||
pm->faultCode.push_back(0x7301);
|
||||
pm->addFaultCode(0x7301);
|
||||
}
|
||||
if ((e.injectionFaultCode==4))
|
||||
{
|
||||
LOG_F(INFO, "抛载失效");
|
||||
pm->faultCode.push_back(0x7302);
|
||||
pm->faultCode.push_back(0x7303);
|
||||
pm->addFaultCode(0x7302);
|
||||
pm->addFaultCode(0x7303);
|
||||
}
|
||||
if ((e.injectionFaultCode==5))
|
||||
{
|
||||
LOG_F(INFO, "艏部应急电源失效");
|
||||
pm->faultCode.push_back(0x7306);
|
||||
pm->addFaultCode(0x7306);
|
||||
}
|
||||
if ((e.injectionFaultCode==6))
|
||||
{
|
||||
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))
|
||||
{
|
||||
LOG_F(INFO, "部分CTD失效");
|
||||
pm->faultCode.push_back(0x8202);
|
||||
pm->addFaultCode(0x8202);
|
||||
}
|
||||
if ((e.injectionFaultCode==2))
|
||||
{
|
||||
LOG_F(INFO, "CTD失效");
|
||||
pm->faultCode.push_back(0x8302);
|
||||
pm->faultCode.push_back(0x8303);
|
||||
pm->addFaultCode(0x8302);
|
||||
pm->addFaultCode(0x8303);
|
||||
}
|
||||
if ((e.injectionFaultCode==3))
|
||||
{
|
||||
LOG_F(INFO, "声速仪失效");
|
||||
pm->faultCode.push_back(0x8301);
|
||||
pm->addFaultCode(0x8301);
|
||||
}
|
||||
}
|
||||
void PowerManagerFsm::react(FaultEvent const &e)
|
||||
@@ -2637,7 +2640,7 @@ void PowerManagerFsm::handelPowerCmd(){
|
||||
pm->m_systemData->setSystemInfo("INFO:收到上位机控制指令:关机");
|
||||
// MOOSPause(3);
|
||||
// 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,"动力锂电池下电中...");
|
||||
// MOOSPause(3);
|
||||
@@ -2729,10 +2732,13 @@ void PowerManagerFsm::handelPowerCmd(){
|
||||
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0);
|
||||
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;
|
||||
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,"动力锂电池下电中...");
|
||||
MOOSPause(1000);
|
||||
@@ -2751,7 +2757,10 @@ void PowerManagerFsm::handelPowerCmd(){
|
||||
pm->m_systemData->setSystemInfo("INFO:次级配电系统恢复待机");
|
||||
MOOSPause(3000);
|
||||
//4. 执行锂电池关机指令
|
||||
pm->m_CcuColCmd.insBatCmd = BatteryCommand::Stop;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(pm->m_stateMutex);
|
||||
pm->m_CcuColCmd.insBatCmd = BatteryCommand::Stop;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
@@ -2759,10 +2768,13 @@ void PowerManagerFsm::handelPowerCmd(){
|
||||
LOG_F(INFO, "收到上位机控制指令:动力电上电");
|
||||
pm->m_systemData->setSystemInfo("INFO:收到上位机控制指令:动力电上电");
|
||||
//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;
|
||||
while (!(pm->m_systemData->dyn_voltage_link > 500.0))
|
||||
while (!(pm->m_systemData->getDynVoltageLink() > 500.0))
|
||||
{
|
||||
LOG_F(INFO,"动力锂电池上电中...");
|
||||
MOOSPause(1000);
|
||||
@@ -2795,7 +2807,10 @@ void PowerManagerFsm::handelPowerCmd(){
|
||||
//1. 闭合动力电断路器
|
||||
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(1);
|
||||
//2. 动力锂电池上电
|
||||
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(pm->m_stateMutex);
|
||||
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
@@ -2820,7 +2835,7 @@ void PowerManagerFsm::handelPowerCmd(){
|
||||
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0);
|
||||
MOOSPause(3);
|
||||
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,"动力锂电池下电中...");
|
||||
MOOSPause(3);
|
||||
@@ -2957,7 +2972,7 @@ void PowerManagerFsm::react(TestEvent const &e)
|
||||
LOG_F(INFO, "测试消息");
|
||||
if(e.type == 0){
|
||||
LOG_F(INFO, "清空故障代码");
|
||||
pm->faultCode.clear();
|
||||
pm->clearFaultCodes();
|
||||
pm->m_leakage = 0x00;
|
||||
pm->m_systemData->insfaultCode = 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_2 = 0;
|
||||
pm->m_systemData->fc_fault_level_1 = 0;
|
||||
pm->m_systemData->disSysFaultCode.clear();
|
||||
pm->m_systemData->clearDisSysFaultCodes();
|
||||
cout << "清空故障代码" << endl;
|
||||
};
|
||||
// if(e.eventId == 0) return ;
|
||||
@@ -3070,7 +3085,7 @@ void PowerManagerFsm::react(TestEvent const &e)
|
||||
{
|
||||
LOG_F(INFO,"配电系统故障测试");
|
||||
// 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:
|
||||
LOG_F(INFO, "测试消息类型错误");
|
||||
|
||||
@@ -15,10 +15,13 @@ void ShoreBasedReady::entry() {
|
||||
//依次接入执行机构动力电设备
|
||||
//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;
|
||||
while (!(pm->m_systemData->dyn_voltage_link > 500.0))
|
||||
while (!(pm->m_systemData->getDynVoltageLink() > 500.0))
|
||||
{
|
||||
LOG_F(INFO,"动力锂电池上电中...");
|
||||
MOOSPause(1000);
|
||||
|
||||
@@ -35,8 +35,8 @@ void HttpServer::handleWebSocketEvent(struct mg_connection* c, int ev, void* ev_
|
||||
c->id, (int)(intptr_t)c->fd, errno);
|
||||
// 打印socket错误信息
|
||||
char buf[256];
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
LOG_F(ERROR, "Socket error: %s", buf);
|
||||
const char *err = strerror_r(errno, buf, sizeof(buf));
|
||||
LOG_F(ERROR, "Socket error: %s", err ? err : buf);
|
||||
} else {
|
||||
LOG_F(ERROR, "WebSocket connection closed abnormally: id=%lu fd=%d",
|
||||
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,
|
||||
instrumentBattery, instrumentBatteryCharge, powerBattery, powerBatteryPower, hostStatus);
|
||||
|
||||
m_powerManger->m_CcuColCmd.fcmode = fuelCellMode;
|
||||
m_powerManger->m_CcuColCmd.fcuCmd = fuelCellCommand;
|
||||
m_powerManger->m_CcuColCmd.fcuPowerEfficiency = fuelCellPower;
|
||||
m_powerManger->m_CcuColCmd.insBatCmd = instrumentBattery;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_powerManger->m_stateMutex);
|
||||
m_powerManger->m_CcuColCmd.fcmode = fuelCellMode;
|
||||
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;
|
||||
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 << "m_powerManger->m_CcuColCmd.masterState:" << (int)m_powerManger->m_CcuColCmd.masterState << endl;
|
||||
cout << "m_powerManger->m_CcuColCmd.masterState:" << (int)hostStatus << endl;
|
||||
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
|
||||
"{\"success\": true, \"message\": \"电池配置提交成功\"}");
|
||||
@@ -353,6 +356,13 @@ void HttpServer::pushSystemData() {
|
||||
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);
|
||||
|
||||
// 序列化系统数据为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);
|
||||
#endif
|
||||
|
||||
j["ccuColCmd"]["fcmode"] = Json::Value(m_powerManger->m_CcuColCmd.fcmode);
|
||||
j["ccuColCmd"]["fcuCmd"] = Json::Value(m_powerManger->m_CcuColCmd.fcuCmd);
|
||||
j["ccuColCmd"]["fcuPowerEfficiency"] = Json::Value(m_powerManger->m_CcuColCmd.fcuPowerEfficiency);
|
||||
j["ccuColCmd"]["insChargeEnable"] = Json::Value(m_powerManger->m_CcuColCmd.insChargeEnable);
|
||||
j["ccuColCmd"]["insBatCmd"] = Json::Value(m_powerManger->m_CcuColCmd.insBatCmd);
|
||||
j["ccuColCmd"]["powerBatCmd"] = Json::Value(m_powerManger->m_CcuColCmd.powerBatCmd);
|
||||
j["ccuColCmd"]["powerBatEfficiency"] = Json::Value(m_powerManger->m_CcuColCmd.powerBatEfficiency);
|
||||
j["ccuColCmd"]["heartbeat"] = Json::Value(m_powerManger->m_CcuColCmd.heartbeat);
|
||||
j["ccuColCmd"]["masterState"] = Json::Value(m_powerManger->m_CcuColCmd.masterState);
|
||||
j["ccuColCmd"]["fcmode"] = Json::Value(ccuCmd.fcmode);
|
||||
j["ccuColCmd"]["fcuCmd"] = Json::Value(ccuCmd.fcuCmd);
|
||||
j["ccuColCmd"]["fcuPowerEfficiency"] = Json::Value(ccuCmd.fcuPowerEfficiency);
|
||||
j["ccuColCmd"]["insChargeEnable"] = Json::Value(ccuCmd.insChargeEnable);
|
||||
j["ccuColCmd"]["insBatCmd"] = Json::Value(ccuCmd.insBatCmd);
|
||||
j["ccuColCmd"]["powerBatCmd"] = Json::Value(ccuCmd.powerBatCmd);
|
||||
j["ccuColCmd"]["powerBatEfficiency"] = Json::Value(ccuCmd.powerBatEfficiency);
|
||||
j["ccuColCmd"]["heartbeat"] = Json::Value(ccuCmd.heartbeat);
|
||||
j["ccuColCmd"]["masterState"] = Json::Value(ccuCmd.masterState);
|
||||
|
||||
// 时间戳
|
||||
j["timestamp"] = Json::Value((Json::UInt64)(std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
* @return uint8_t 故障等级,00H-无故障, 10H-一级, 20H-二级, 30H-三级, 40H-四级
|
||||
*/
|
||||
uint8_t getFaultCodeLevel() const {
|
||||
std::lock_guard<std::mutex> lock(sysFaultCodesMutex);
|
||||
uint8_t maxLevel = 0;
|
||||
// 遍历 sysFaultCodes 集合中的每个故障码
|
||||
for (auto code : sysFaultCodes) {
|
||||
@@ -536,6 +537,7 @@ public:
|
||||
bool leakStatus[8] = {false};
|
||||
|
||||
unsigned char generateLeakageCode() {
|
||||
std::lock_guard<std::mutex> lock(m_dataMutex);
|
||||
unsigned char code = 0;
|
||||
if(leakStatus[LEAKAGE_BOW_EMERGENCY]) code |= 0x01;
|
||||
if(leakStatus[LEAKAGE_BOW_HIGH_VOLTAGE]) code |= 0x02;
|
||||
@@ -615,6 +617,65 @@ public:
|
||||
};
|
||||
~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){
|
||||
std::lock_guard<std::mutex> lock(m_dataMutex);
|
||||
//更新时间
|
||||
@@ -754,10 +815,9 @@ public:
|
||||
ins_emergency_status = data.ins_emergency_status;
|
||||
dyn_emergency_status = data.dyn_emergency_status;
|
||||
|
||||
//保留字段
|
||||
for(int i=0; i<2; i++) {
|
||||
reserved2[i] = data.reserved2[i];
|
||||
}
|
||||
//保留字段:ccuState 中 reserved2 仅声明 1 字节(协议预留 2 字节),只拷贝已有元素,避免越界读
|
||||
reserved2[0] = data.reserved2[0];
|
||||
reserved2[1] = 0;
|
||||
|
||||
//SOC门限值
|
||||
ins_soc_threshold1 = data.ins_soc_threshold1;
|
||||
|
||||
@@ -470,17 +470,13 @@ bool udpComm::sendDisSysCmd(const disHighVolBusCmd cmd)
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBCmd),sizeof(cChecksum));
|
||||
msg->checkCode = cc;
|
||||
try
|
||||
{
|
||||
sendMsg(msgBuf,sizeof(msg_disHVBCmd));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBCmd));
|
||||
if (!sendResult) {
|
||||
LOG_F(ERROR, "sendDisSysCmd(disHighVolBusCmd) send failed");
|
||||
}
|
||||
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUS_CMD_ID, "disHighVolBusCmd", msgBuf, sizeof(msg_disHVBCmd), true);
|
||||
delete msg;
|
||||
return true;
|
||||
return sendResult;
|
||||
}
|
||||
|
||||
bool udpComm::sendDisSysCmd(const disHighAVolBusCmd cmd)
|
||||
@@ -498,17 +494,13 @@ bool udpComm::sendDisSysCmd(const disHighAVolBusCmd cmd)
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBACmd),sizeof(cChecksum));
|
||||
msg->checkCode = cc;
|
||||
try
|
||||
{
|
||||
sendMsg(msgBuf,sizeof(msg_disHVBACmd));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBACmd));
|
||||
if (!sendResult) {
|
||||
LOG_F(ERROR, "sendDisSysCmd(disHighAVolBusCmd) send failed");
|
||||
}
|
||||
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUSA_CMD_ID, "disHighAVolBusCmd", msgBuf, sizeof(msg_disHVBACmd), true);
|
||||
delete msg;
|
||||
return true;
|
||||
return sendResult;
|
||||
}
|
||||
|
||||
bool udpComm::sendDisSysCmd(const disHighBVolBusCmd cmd)
|
||||
@@ -526,18 +518,13 @@ bool udpComm::sendDisSysCmd(const disHighBVolBusCmd cmd)
|
||||
msgBuf = reinterpret_cast<unsigned char *>(msg);
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBBCmd),sizeof(cChecksum));
|
||||
msg->checkCode = cc;
|
||||
try
|
||||
{
|
||||
// cout << "=========" <<(int)sizeof(msg_disHVBBCmd) << endl;
|
||||
sendMsg(msgBuf,sizeof(msg_disHVBBCmd));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBBCmd));
|
||||
if (!sendResult) {
|
||||
LOG_F(ERROR, "sendDisSysCmd(disHighBVolBusCmd) send failed");
|
||||
}
|
||||
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUSB_CMD_ID, "disLowMainBusCmd", msgBuf, sizeof(msg_disHVBBCmd), true);
|
||||
delete msg;
|
||||
return true;
|
||||
return sendResult;
|
||||
}
|
||||
|
||||
bool udpComm::sendDisSysCmd(const disLowBusCmd cmd)
|
||||
@@ -556,18 +543,13 @@ bool udpComm::sendDisSysCmd(const disLowBusCmd cmd)
|
||||
cc = calculateChecksum(msgBuf,sizeof(msg_disLVBCmd),sizeof(cChecksum));
|
||||
// msg->checkCode = static_cast<cChecksum>(cc & 0xFF);
|
||||
msg->checkCode = cc;
|
||||
cout << "cc======disLowBusCmd=============================" << (int) msg->checkCode << endl;
|
||||
try
|
||||
{
|
||||
sendMsg(msgBuf,sizeof(msg_disLVBCmd));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
bool sendResult = sendMsg(msgBuf, sizeof(msg_disLVBCmd));
|
||||
if (!sendResult) {
|
||||
LOG_F(ERROR, "sendDisSysCmd(disLowBusCmd) send failed");
|
||||
}
|
||||
if (m_commLogger) m_commLogger->onFrame(1, DIS_LVBUS_CMD_ID, "disLowBusCmd", msgBuf, sizeof(msg_disLVBCmd), true);
|
||||
delete msg;
|
||||
return true;
|
||||
return sendResult;
|
||||
}
|
||||
|
||||
bool udpComm::sendCcuColCmd(const ccuColCmd cmd)
|
||||
|
||||
@@ -137,6 +137,7 @@ public:
|
||||
// std::string buildMsg(SystemData data,disSysBreakerList currentDisBreakerState)
|
||||
std::string buildMsg(const SystemData& data,disSysBreakerList currentDisBreakerState)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(data.m_dataMutex);
|
||||
//构建配电系统状态报告
|
||||
Json::Value dis;
|
||||
// disBus1Breaker dis1 = currentDisBreakerState.bus1Breaker;
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
// std::string buildMsg(SystemData data)
|
||||
std::string buildMsg(const SystemData& data)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(data.m_dataMutex);
|
||||
//TODO:根据最新协议修改
|
||||
Json::Value fcs;
|
||||
// suffix = getTypeName(typeid(ccustate.fcuState).name());
|
||||
|
||||
@@ -18,6 +18,7 @@ public:
|
||||
// std::string buildMsg(SystemData data)
|
||||
std::string buildMsg(const SystemData& data)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(data.m_dataMutex);
|
||||
//TODO:根据最新协议修改
|
||||
Json::Value lbs;
|
||||
//构建锂电池状态报告
|
||||
|
||||
@@ -108,3 +108,20 @@ target_link_libraries(udpFeeder
|
||||
pthread
|
||||
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
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -170,3 +170,16 @@ TEST(UdpCommTest, GetDate)
|
||||
EXPECT_LE(minute, 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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user