build-test-deploy / ci (push) Successful in 1h13m13s
FC协议(0827 docx): - 控制指令域:字节12,13/16,17由纵倾/横倾姿态数据2改为预留(编码恒0、解码忽略) - 状态反馈域:字节147,148由预留12改为剩余发电量(MWh),贯通JSON/网页显示 - PM→CCU链路:姿态字段4xuchar改为2xshort(数据1),结构体大小与线上布局不变 - 同步更新:CCU转发映射、SnapshotBuilder、pCCU网页、fuelcell网页、SQLite列描述、单测/模拟器 - 修正集成测试遗留断言(20B→24B、心跳d[19]→d[23])并增强预留字节校验 CCU地址可配置: - pPowerManger 支持 moos 配置项 ccuhost/ccuport(默认127.0.0.1:7000) - build-board.sh 增加 --ccu-host/--ccu-port 参数 文档:FC协议文档更新为0827版,清理过期协议docx
318 lines
17 KiB
C++
318 lines
17 KiB
C++
#ifndef PCCU_PM_PROTOCOL_H
|
||
#define PCCU_PM_PROTOCOL_H
|
||
|
||
#include <cstdint>
|
||
#include <vector>
|
||
#include "Message.h"
|
||
|
||
namespace ccu {
|
||
|
||
//============================================================================
|
||
// PM 协议(复合管控器 <-> 控制主机 pPowerManger)
|
||
// 依据:docs/控制主机与复合管控器通信协议 - 0824.xlsx
|
||
//
|
||
// 帧格式统一:0x40 0x40 + 域标识符(2B) + 域字节数(2B) + 数据域 + uint32 校验和
|
||
// 校验和为从域起始符到校验和之前所有数据的字节和。
|
||
//
|
||
// 四条消息(均带 uint32 校验和):
|
||
// 0x0001 操控指令域 (控制主机->复合管控器)payload 35B,总长 45B
|
||
// 0x0002 参数设定指令域 (控制主机->复合管控器)payload 18B,总长 28B
|
||
// 0x0003 参数设定反馈域 (复合管控器->控制主机)payload 2B,总长 12B
|
||
// 0x0004 状态报文域 (复合管控器->控制主机)payload 238B,总长 248B
|
||
//============================================================================
|
||
|
||
//--------------------------------------------------------------------------
|
||
// 0x0001 操控指令域
|
||
// payload 35 字节,对应文档字节 7~41
|
||
//--------------------------------------------------------------------------
|
||
struct PmControlValue {
|
||
// 系统时间
|
||
uint16_t year = 0;
|
||
uint8_t month = 0;
|
||
uint8_t day = 0;
|
||
uint8_t hour = 0;
|
||
uint8_t minute = 0;
|
||
uint8_t second = 0;
|
||
uint8_t millisecond10 = 0; // 10毫秒
|
||
// 指令
|
||
uint8_t mode = 0; // 模式设定 00~03
|
||
uint8_t cmd = 0; // 操控指令 00~0B
|
||
uint8_t outputPower = 0; // 输出功率指令 0~250,0.1kW
|
||
int16_t pitch = 0; // 纵倾姿态数据1 int16,分辨率0.1°(字节18,19)
|
||
int16_t roll = 0; // 横倾姿态数据1 int16,分辨率0.1°(字节20,21)
|
||
uint8_t emergencyAllow = 0; // 应急允许
|
||
uint16_t depth = 0; // 潜深深度 m
|
||
uint8_t supplyCmd = 0; // 补给/排放指令
|
||
uint8_t reservedCmd5 = 0; // 预留指令5
|
||
uint8_t reservedCmd6 = 0; // 预留指令6
|
||
uint8_t insBatCmd = 0; // 仪表锂电池启停指令 00/10/20
|
||
uint8_t dynBatCmd = 0; // 动力锂电池启停指令 00/10/20
|
||
uint16_t dynBatPower = 0; // 动力锂电池功率配置值 kW
|
||
uint8_t heartbeat = 0; // 通信心跳,每次+1
|
||
uint8_t hostState = 0; // 主机状态 运行AAH/关机FFH/故障其他
|
||
uint32_t reserved1 = 0; // 预留
|
||
uint32_t reserved2 = 0; // 预留
|
||
};
|
||
|
||
//--------------------------------------------------------------------------
|
||
// 0x0002 参数设定指令域
|
||
// payload 18 字节,对应文档字节 7~24
|
||
//--------------------------------------------------------------------------
|
||
struct PmParamSetValue {
|
||
uint8_t insSocHold1 = 0; // 仪表电池充电一级功率SOC门限
|
||
uint8_t insSocHold2 = 0; // 仪表电池充电二级功率SOC门限
|
||
uint8_t insSocHold3 = 0; // 仪表电池充电三级功率SOC门限
|
||
uint8_t insOutputPower = 0; // 仪表锂电池输出功率 %
|
||
uint8_t insReserved = 0; // 预留
|
||
uint8_t dynSocHold1 = 0; // 动力电池充电一级功率SOC门限
|
||
uint8_t dynSocHold2 = 0; // 动力电池充电二级功率SOC门限
|
||
uint8_t dynSocHold3 = 0; // 动力电池充电三级功率SOC门限
|
||
uint8_t dynOutputPower = 0; // 动力电池输出功率 %
|
||
uint8_t dynReserved = 0; // 预留
|
||
uint32_t reserved1 = 0; // 预留
|
||
uint32_t reserved2 = 0; // 预留
|
||
};
|
||
|
||
//--------------------------------------------------------------------------
|
||
// 0x0003 参数设定反馈域
|
||
// payload 2 字节,对应文档字节 7~8
|
||
//--------------------------------------------------------------------------
|
||
struct PmParamSetFbValue {
|
||
uint8_t flag = 0; // 设定标志:00H无效 / 10H成功 / 20H失败
|
||
uint8_t failCode = 0; // 设定失败原因
|
||
};
|
||
|
||
//--------------------------------------------------------------------------
|
||
// 0x0004 状态报文域
|
||
// payload 238 字节,对应文档字节 7~244
|
||
//--------------------------------------------------------------------------
|
||
struct PmStatusValue {
|
||
uint8_t fc_mode = 0; // 燃料电池系统运行模式
|
||
uint8_t fc_status = 0; // 燃料电池系统运行状态
|
||
uint16_t fault_level_1 = 0; // 一级故障码
|
||
uint16_t fault_level_2 = 0; // 二级故障码
|
||
uint16_t fault_level_3 = 0; // 三级故障码
|
||
uint16_t fault_level_4 = 0; // 四级故障码
|
||
uint16_t total_generation_time = 0; // 累积发电时间 0.1h
|
||
uint8_t fc_fault_level = 0; // 系统故障等级 00~04
|
||
uint16_t output_power_limit = 0; // 系统输出功率限定功率 W
|
||
uint16_t generation_power = 0; // 系统发电功率 0.01kW
|
||
uint8_t hydrogen_capacity = 0; // 储氢剩余容量 %
|
||
uint8_t liquid_oxygen_capacity = 0; // 液氧剩余容量 %
|
||
|
||
uint8_t fc1_min_cell_voltage = 0; // I#FC最低单片电压 10mV
|
||
uint8_t fc1_min_cell_pos = 0; // I#FC最低单片电压位置
|
||
uint8_t fc1_avg_cell_voltage = 0; // I#FC平均单片电压
|
||
uint8_t fc2_min_cell_voltage = 0; // 2#FC最低单片电压
|
||
uint8_t fc2_min_cell_pos = 0; // 2#FC最低单片电压位置
|
||
uint8_t fc2_avg_cell_voltage = 0; // 2#FC平均单片电压
|
||
|
||
uint16_t palladium_temp = 0; // 甲醇制氢装置钯膜最高温度 0.1℃
|
||
uint16_t buffer_tank_pressure = 0; // 缓冲罐压力 0.1kPa
|
||
uint16_t flue_total_emission = 0; // 烟气累计排放量 0.1kg
|
||
uint16_t flue_pressure = 0; // 烟气压力 0.001MPa
|
||
uint16_t reactor_pressure = 0; // 反应器压力 0.001MPa
|
||
uint16_t electric_valve_open = 0; // 电动阀开度 0.1%
|
||
uint16_t main_pipe_pressure = 0; // 主水路盘管侧压力 0.01kPa
|
||
uint16_t aux_pipe_pressure = 0; // 辅水路盘管侧压力 0.01kPa
|
||
|
||
uint16_t dcdc1_in_voltage = 0; // DC/DC通道1输入电压 0.1V
|
||
uint16_t dcdc1_in_current = 0; // DC/DC通道1输入电流 0.1A
|
||
uint16_t dcdc2_in_voltage = 0; // DC/DC通道2输入电压 0.1V
|
||
uint16_t dcdc2_in_current = 0; // DC/DC通道2输入电流 0.1A
|
||
uint16_t dcdc_out_voltage = 0; // DC/DC输出电压 0.1V
|
||
uint16_t dcdc_out_current = 0; // DC/DC输出电流 0.1A
|
||
uint8_t dcdc_ctrl_voltage = 0; // DC/DC控制电源电压 0.25V
|
||
uint8_t dcdc_aux_voltage = 0; // DC/DC辅电输出电压 0.125V
|
||
|
||
uint16_t methanol_total_use = 0; // 甲醇累计使用量 0.1kg
|
||
uint16_t methanol_feed = 0; // 甲醇溶液进料量 1mL/min
|
||
uint16_t oxygen_side_water_level = 0; // 氧侧生成水箱液位 0.01mm
|
||
uint16_t hydrogen_side_water_level = 0; // 氢侧生成水箱液位
|
||
uint16_t ballast_water_level = 0; // 配重水箱液位
|
||
|
||
uint16_t exhaust_inlet_pressure = 0; // 尾气装置进气压力 0.01MPa
|
||
uint16_t exhaust_outlet_pressure = 0; // 尾气装置排气压力 0.01MPa
|
||
uint16_t exhaust_run_freq = 0; // 尾气装置运行频率 0.01Hz
|
||
uint16_t exhaust_inlet_temp = 0; // 尾气装置进气温度 0.01℃
|
||
uint16_t exhaust_outlet_temp = 0; // 尾气装置排气温度 0.01℃
|
||
uint16_t exhaust_water_in_pressure = 0; // 尾气装置进水压力 0.01kPa
|
||
uint16_t exhaust_water_out_pressure = 0; // 尾气装置排水压力 0.01kPa
|
||
|
||
uint16_t tank_lo2_pressure = 0; // 一体化罐装置液氧罐压力 0.01MPa
|
||
uint16_t tank_co2_pressure = 0; // 一体化罐装置二氧化碳压力 0.01MPa
|
||
uint16_t tank_lo2_level = 0; // 一体化罐装置液氧罐液位 0.01mm
|
||
|
||
uint16_t alloy_h2_flow = 0; // 合金供氢流量 0.01L/min
|
||
uint16_t fc_h2_flow = 0; // FC供氢流量 0.01L/min
|
||
uint16_t fc_o2_flow = 0; // FC供氧流量 0.01L/min
|
||
|
||
uint16_t emergency_float_depth = 0; // 应急上浮深度 1m
|
||
uint16_t emergency_float_time = 0; // 应急上浮时间 1min
|
||
|
||
uint16_t cabin_pressure1 = 0; // 舱室压力1 0.01kPa
|
||
uint16_t cabin_pressure2 = 0; // 舱室压力2
|
||
uint16_t cabin_temp1 = 0; // 舱室温度1 0.01℃
|
||
uint16_t cabin_temp2 = 0; // 舱室温度2
|
||
uint16_t cabin_humidity1 = 0; // 舱室湿度1 0.01%RH
|
||
uint16_t cabin_humidity2 = 0; // 舱室湿度2
|
||
uint16_t h2_concentration1 = 0; // 舱室H2浓度1 0.01%LEL
|
||
uint16_t h2_concentration2 = 0; // 舱室H2浓度2
|
||
uint16_t h2_concentration3 = 0; // 舱室H2浓度3
|
||
uint16_t o2_concentration1 = 0; // 舱室O2浓度1 0.01%Vol
|
||
uint16_t o2_concentration2 = 0; // 舱室O2浓度2
|
||
uint16_t ch3oh_concentration1 = 0; // 舱室甲醇浓度1 0.01%LEL
|
||
uint16_t ch3oh_concentration2 = 0; // 舱室甲醇浓度2
|
||
|
||
uint8_t flame_detector1 = 0; // 火焰探测器1状态
|
||
uint8_t flame_detector2 = 0; // 火焰探测器2状态
|
||
uint16_t pmReserved1 = 0; // 预留
|
||
uint16_t pmReserved2 = 0; // 预留
|
||
|
||
uint16_t emergency_battery1_voltage = 0; // 应急电池1总电压
|
||
uint16_t emergency_battery1_current = 0; // 应急电池1总电流
|
||
uint16_t emergency_battery1_max_temp = 0; // 应急电池1最高温度
|
||
uint16_t emergency_battery1_fault_word = 0;// 应急电池1故障字
|
||
uint16_t emergency_battery2_voltage = 0; // 应急电池2总电压
|
||
uint16_t emergency_battery2_current = 0; // 应急电池2总电流
|
||
uint16_t emergency_battery2_max_temp = 0; // 应急电池2最高温度
|
||
uint16_t emergency_battery2_fault_word = 0;// 应急电池2故障字
|
||
|
||
uint16_t ins_cabin_ox_concentration = 0; // 仪表舱内氧气浓度 %
|
||
uint16_t ins_cabin_temperature = 0; // 仪表舱内温度 ℃
|
||
uint16_t ins_cabin_humidity = 0; // 仪表舱内湿度 %RH
|
||
uint16_t ins_cabin_pressure = 0; // 仪表舱内大气压 kPa
|
||
uint16_t dyn_cabin_ox_concentration = 0; // 动力舱内氧气浓度 %
|
||
uint16_t dyn_cabin_temperature = 0; // 动力舱内温度 ℃
|
||
uint16_t dyn_cabin_humidity = 0; // 动力舱内湿度 %RH
|
||
uint16_t dyn_cabin_pressure = 0; // 动力舱内大气压 kPa
|
||
uint8_t pmReserved3 = 0; // 预留
|
||
|
||
uint8_t dyn_alarm_flag[6] = {0}; // 动力锂电池报警标识字1~6
|
||
uint8_t ins_alarm_flag[6] = {0}; // 仪表锂电池报警标识字1~6
|
||
|
||
uint8_t ins_relay_status1 = 0; // 仪表电池正极+充电继电器状态
|
||
uint8_t ins_relay_status2 = 0; // 仪表电池预充+负极继电器状态
|
||
uint8_t dyn_relay_status1 = 0; // 动力电池正极+充电继电器状态
|
||
uint8_t dyn_relay_status2 = 0; // 动力电池预充+负极继电器状态
|
||
|
||
uint16_t ins_max_discharge_power = 0; // 仪表电池允许最高放电功率 0.05kW
|
||
uint16_t dyn_max_discharge_power = 0; // 动力电池允许最高放电功率 0.05kW
|
||
uint8_t ins_soc = 0; // 仪表锂电池SOC %
|
||
uint8_t dyn_soc = 0; // 动力锂电池SOC %
|
||
uint16_t ins_total_energy = 0; // 仪表锂电池总能量 0.1kWh
|
||
uint16_t dyn_total_energy = 0; // 动力锂电池总电量 0.1kWh
|
||
uint16_t ins_power_input = 0; // 仪表电池当前接入功率 kW
|
||
uint16_t dyn_power_input = 0; // 动力电池当前接入功率 kW
|
||
|
||
uint8_t ins_charge_status = 0; // 仪表电池充电状态
|
||
uint8_t dyn_charge_status = 0; // 动力电池充电状态
|
||
|
||
uint16_t ins_voltage_link = 0; // 仪表电池电压LINK端 0.01V
|
||
uint16_t ins_voltage_pack = 0; // 仪表电池电压PACK端 0.01V
|
||
uint16_t ins_current = 0; // 仪表电池放电电流 0.05A
|
||
uint16_t ins_resistance_pos = 0; // 仪表电池正端绝缘电阻 kΩ
|
||
uint16_t ins_resistance_neg = 0; // 仪表电池负端绝缘电阻 kΩ
|
||
uint16_t dyn_voltage_link = 0; // 动力电池电压LINK端 0.01V
|
||
uint16_t dyn_voltage_pack = 0; // 动力电池电压PACK端 0.01V
|
||
uint16_t dyn_current = 0; // 动力电池放电电流 0.05A
|
||
uint16_t dyn_resistance_pos = 0; // 动力电池正端绝缘电阻 kΩ
|
||
uint16_t dyn_resistance_neg = 0; // 动力电池负端绝缘电阻 kΩ
|
||
|
||
uint8_t ins_emergency_status = 0; // 仪表电池紧急状态
|
||
uint8_t dyn_emergency_status = 0; // 动力电池紧急状态
|
||
|
||
uint8_t ins_soc_threshold1 = 0; // 仪表电池充电一级功率SOC门限当前值
|
||
uint8_t ins_soc_threshold2 = 0; // 仪表电池充电二级
|
||
uint8_t ins_soc_threshold3 = 0; // 仪表电池充电三级
|
||
uint8_t ins_power_limit1 = 0; // 仪表通路FC输出功率一级限制当前值
|
||
uint8_t ins_power_limit2 = 0; // 仪表通路FC输出功率二级限制当前值
|
||
uint8_t dyn_soc_threshold1 = 0; // 动力电池充电一级功率SOC门限当前值
|
||
uint8_t dyn_soc_threshold2 = 0; // 动力电池充电二级
|
||
uint8_t dyn_soc_threshold3 = 0; // 动力电池充电三级
|
||
uint8_t dyn_power_limit1 = 0; // 动力通路FC输出功率一级限制当前值
|
||
uint8_t dyn_power_limit2 = 0; // 动力通路FC输出功率二级限制当前值
|
||
|
||
uint32_t device_online_flag1 = 0; // 设备在线状态标志字1
|
||
uint32_t device_online_flag2 = 0; // 设备在线状态标志字2
|
||
uint32_t pmReserved4 = 0; // 预留
|
||
|
||
uint8_t heartbeat = 0; // 通信心跳,每次+1
|
||
uint8_t emergency_cmd = 0; // 应急指令
|
||
};
|
||
|
||
//--------------------------------------------------------------------------
|
||
// 消息类
|
||
//--------------------------------------------------------------------------
|
||
|
||
class PmControlMessage : public Message {
|
||
public:
|
||
uint16_t id() const override { return 0x0001; }
|
||
const char* name() const override { return "pm_control"; }
|
||
const ChecksumPolicy& checksum() const override { return m_checksum; }
|
||
size_t payloadLength() const override { return 35; }
|
||
std::vector<uint8_t> encode(const void* obj) const override;
|
||
bool decode(const std::vector<uint8_t>& frame, void* obj) const override;
|
||
std::vector<uint8_t> encode(const PmControlValue& v) const { return encode(&v); }
|
||
bool decode(const std::vector<uint8_t>& frame, PmControlValue& v) const {
|
||
return decode(frame, static_cast<void*>(&v));
|
||
}
|
||
private:
|
||
ChecksumPolicy m_checksum{ChecksumType::Sum32};
|
||
};
|
||
|
||
class PmParamSetMessage : public Message {
|
||
public:
|
||
uint16_t id() const override { return 0x0002; }
|
||
const char* name() const override { return "pm_param_set"; }
|
||
const ChecksumPolicy& checksum() const override { return m_checksum; }
|
||
size_t payloadLength() const override { return 18; }
|
||
std::vector<uint8_t> encode(const void* obj) const override;
|
||
bool decode(const std::vector<uint8_t>& frame, void* obj) const override;
|
||
std::vector<uint8_t> encode(const PmParamSetValue& v) const { return encode(&v); }
|
||
bool decode(const std::vector<uint8_t>& frame, PmParamSetValue& v) const {
|
||
return decode(frame, static_cast<void*>(&v));
|
||
}
|
||
private:
|
||
ChecksumPolicy m_checksum{ChecksumType::Sum32};
|
||
};
|
||
|
||
class PmParamSetFbMessage : public Message {
|
||
public:
|
||
uint16_t id() const override { return 0x0003; }
|
||
const char* name() const override { return "pm_param_set_fb"; }
|
||
const ChecksumPolicy& checksum() const override { return m_checksum; }
|
||
size_t payloadLength() const override { return 2; }
|
||
std::vector<uint8_t> encode(const void* obj) const override;
|
||
bool decode(const std::vector<uint8_t>& frame, void* obj) const override;
|
||
std::vector<uint8_t> encode(const PmParamSetFbValue& v) const { return encode(&v); }
|
||
bool decode(const std::vector<uint8_t>& frame, PmParamSetFbValue& v) const {
|
||
return decode(frame, static_cast<void*>(&v));
|
||
}
|
||
private:
|
||
ChecksumPolicy m_checksum{ChecksumType::Sum32};
|
||
};
|
||
|
||
class PmStatusMessage : public Message {
|
||
public:
|
||
uint16_t id() const override { return 0x0004; }
|
||
const char* name() const override { return "pm_status"; }
|
||
const ChecksumPolicy& checksum() const override { return m_checksum; }
|
||
size_t payloadLength() const override { return 238; }
|
||
std::vector<uint8_t> encode(const void* obj) const override;
|
||
bool decode(const std::vector<uint8_t>& frame, void* obj) const override;
|
||
std::vector<uint8_t> encode(const PmStatusValue& v) const { return encode(&v); }
|
||
bool decode(const std::vector<uint8_t>& frame, PmStatusValue& v) const {
|
||
return decode(frame, static_cast<void*>(&v));
|
||
}
|
||
private:
|
||
ChecksumPolicy m_checksum{ChecksumType::Sum32};
|
||
};
|
||
|
||
// 注册 PM 消息到给定注册表
|
||
void registerPmMessages(class MessageRegistry& reg);
|
||
|
||
} // namespace ccu
|
||
|
||
#endif // PCCU_PM_PROTOCOL_H
|