From c51eb7073a8a496a8bcd644bc1cce051e92a1564 Mon Sep 17 00:00:00 2001 From: zhaojingkui <1553836110@qq.com> Date: Sun, 6 Apr 2025 20:16:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8tinyfsm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/{ => msg}/subDisSysCmd.json | 0 data/protocol-specs/udp/ccu_set_param_fb.json | 52 ++ data/protocol-specs/udp/ccu_state_fb.json | 637 ++++++++++++++++++ .../udp/dis_high_a_vol_bus_fb.json | 142 ++++ .../udp/dis_high_b_vol_bus_fb.json | 154 +++++ .../udp/dis_high_vol_bus_fb.json | 184 +++++ data/uPower_sysState_cmd.json | 5 - src/pPowerManger/CMakeLists.txt | 8 +- src/pPowerManger/PowerManagerFsm.cpp | 29 + src/pPowerManger/PowerManagerFsm.hpp | 153 +++++ src/pPowerManger/PowerManger.cpp | 246 +------ src/pPowerManger/PowerManger.h | 161 +++-- src/pPowerManger/fsm.h | 20 +- src/pPowerManger/tinyfsm.hpp | 251 +++++++ test/model/ccu.slx | Bin 82346 -> 0 bytes test/model/controlFlow.slx | Bin 55125 -> 0 bytes test/model/untitled.slx | Bin 77597 -> 0 bytes test/model/untitled.slx.original | Bin 61108 -> 0 bytes 18 files changed, 1720 insertions(+), 322 deletions(-) rename data/{ => msg}/subDisSysCmd.json (100%) create mode 100644 data/protocol-specs/udp/ccu_set_param_fb.json create mode 100644 data/protocol-specs/udp/ccu_state_fb.json create mode 100644 data/protocol-specs/udp/dis_high_a_vol_bus_fb.json create mode 100644 data/protocol-specs/udp/dis_high_b_vol_bus_fb.json create mode 100644 data/protocol-specs/udp/dis_high_vol_bus_fb.json delete mode 100644 data/uPower_sysState_cmd.json create mode 100644 src/pPowerManger/PowerManagerFsm.cpp create mode 100644 src/pPowerManger/PowerManagerFsm.hpp create mode 100644 src/pPowerManger/tinyfsm.hpp delete mode 100644 test/model/ccu.slx delete mode 100644 test/model/controlFlow.slx delete mode 100644 test/model/untitled.slx delete mode 100644 test/model/untitled.slx.original diff --git a/data/subDisSysCmd.json b/data/msg/subDisSysCmd.json similarity index 100% rename from data/subDisSysCmd.json rename to data/msg/subDisSysCmd.json diff --git a/data/protocol-specs/udp/ccu_set_param_fb.json b/data/protocol-specs/udp/ccu_set_param_fb.json new file mode 100644 index 0000000..3f1c4a2 --- /dev/null +++ b/data/protocol-specs/udp/ccu_set_param_fb.json @@ -0,0 +1,52 @@ +{ + "protocol_name": "CCU参数设置反馈", + "message_id": "0x0040", + "length": 10, + "checksum": { + "start_offset": 0, + "end_offset": 6, + "algorithm": "sum" + }, + "fields": [ + { + "name": "start1", + "offset": 0, + "type": "uint8", + "value": "0x20", + "description": "起始字节1" + }, + { + "name": "start2", + "offset": 1, + "type": "uint8", + "value": "0x20", + "description": "起始字节2" + }, + { + "name": "id", + "offset": 2, + "type": "uint16", + "value": "0x0040", + "description": "消息ID" + }, + { + "name": "length", + "offset": 4, + "type": "uint16", + "value": 10, + "description": "消息长度" + }, + { + "name": "flag", + "offset": 6, + "type": "uint8", + "description": "设置标志位" + }, + { + "name": "failvreCode", + "offset": 7, + "type": "uint8", + "description": "故障代码" + } + ] +} \ No newline at end of file diff --git a/data/protocol-specs/udp/ccu_state_fb.json b/data/protocol-specs/udp/ccu_state_fb.json new file mode 100644 index 0000000..d7a838a --- /dev/null +++ b/data/protocol-specs/udp/ccu_state_fb.json @@ -0,0 +1,637 @@ +{ + "message_name": "CCUStateFbMsg", + "protocol_id": "0x0041", + "endianness": "little", + "fields": [ + { + "name": "start1", + "offset": 0, + "length": 1, + "type": "uint8", + "value": "0x20", + "description": "起始字节1" + }, + { + "name": "start2", + "offset": 1, + "length": 1, + "type": "uint8", + "value": "0x20", + "description": "起始字节2" + }, + { + "name": "id", + "offset": 2, + "length": 2, + "type": "uint16", + "value": "0x0041", + "description": "消息ID" + }, + { + "name": "length", + "offset": 4, + "length": 2, + "type": "uint16", + "dynamic": true, + "description": "数据长度(自动计算)" + }, + { + "name": "currentWorkCondition", + "offset": 6, + "length": 1, + "type": "uint8", + "enum": {"0x00":"待机","0x01":"运行","0x02":"故障"}, + "description": "当前工作状态" + }, + { + "name": "fcuState", + "offset": 7, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "燃料电池状态" + }, + { + "name": "fcuFaultLeve", + "offset": 8, + "length": 1, + "type": "uint8", + "description": "故障等级" + }, + { + "name": "powerLimit", + "offset": 9, + "length": 4, + "type": "float32", + "unit": "kW", + "description": "功率限制值" + }, + { + "name": "totalPowerGeneration", + "offset": 13, + "length": 4, + "type": "float32", + "unit": "kWh", + "description": "总发电量" + }, + { + "name": "ch4o", + "offset": 17, + "length": 4, + "type": "float32", + "unit": "ppm", + "description": "甲醇浓度" + }, + { + "name": "o2", + "offset": 21, + "length": 4, + "type": "float32", + "unit": "%", + "description": "氧气浓度" + }, + { + "name": "fcuVoltage", + "offset": 25, + "length": 4, + "type": "float32", + "unit": "V", + "description": "燃料电池电压" + }, + { + "name": "fcuCurrent", + "offset": 29, + "length": 4, + "type": "float32", + "unit": "A", + "description": "燃料电池电流" + }, + { + "name": "o2Level", + "offset": 33, + "length": 4, + "type": "float32", + "unit": "%", + "description": "氧气含量" + }, + { + "name": "placeholder1", + "offset": 37, + "length": 4, + "type": "float32", + "description": "预留字段1" + }, + { + "name": "exchangerTemperature", + "offset": 41, + "length": 4, + "type": "float32", + "unit": "°C", + "description": "换热器温度" + }, + { + "name": "fcuOutPower", + "offset": 45, + "length": 4, + "type": "float32", + "unit": "kW", + "description": "燃料电池输出功率" + }, + { + "name": "fcuOutIns", + "offset": 49, + "length": 4, + "type": "float32", + "unit": "kΩ", + "description": "绝缘电阻" + }, + { + "name": "fcuVoltageIns", + "offset": 53, + "length": 4, + "type": "float32", + "unit": "V", + "description": "绝缘监测电压" + }, + { + "name": "fcuVoltagePower", + "offset": 57, + "length": 4, + "type": "float32", + "unit": "V", + "description": "功率电压" + }, + { + "name": "fcuCurrentIns", + "offset": 61, + "length": 4, + "type": "float32", + "unit": "A", + "description": "绝缘监测电流" + }, + { + "name": "fcuCurrentPower", + "offset": 65, + "length": 4, + "type": "float32", + "unit": "A", + "description": "功率电流" + }, + { + "name": "h2Concentration1", + "offset": 69, + "length": 4, + "type": "float32", + "unit": "ppm", + "description": "氢气浓度1" + }, + { + "name": "h2Concentration2", + "offset": 73, + "length": 4, + "type": "float32", + "unit": "ppm", + "description": "氢气浓度2" + }, + { + "name": "o2Concentration1", + "offset": 77, + "length": 4, + "type": "float32", + "unit": "%", + "description": "氧气浓度1" + }, + { + "name": "o2Concentration2", + "offset": 81, + "length": 4, + "type": "float32", + "unit": "%", + "description": "氧气浓度2" + }, + { + "name": "ch4oConcentration1", + "offset": 85, + "length": 4, + "type": "float32", + "unit": "ppm", + "description": "甲醇浓度1" + }, + { + "name": "ch4oConcentration2", + "offset": 89, + "length": 4, + "type": "float32", + "unit": "ppm", + "description": "甲醇浓度2" + }, + { + "name": "backpressure1", + "offset": 93, + "length": 4, + "type": "float32", + "unit": "kPa", + "description": "背压1" + }, + { + "name": "backpressure2", + "offset": 97, + "length": 4, + "type": "float32", + "unit": "kPa", + "description": "背压2" + }, + { + "name": "flameDetection", + "offset": 101, + "length": 1, + "type": "uint8", + "description": "火焰检测状态" + }, + { + "name": "fcuGZ_1L", + "offset": 102, + "length": 1, + "type": "uint8", + "description": "故障字1低字节" + }, + { + "name": "fcuGZ_1H", + "offset": 103, + "length": 1, + "type": "uint8", + "description": "故障字1高字节" + }, + { + "name": "fcuGZ_2L", + "offset": 104, + "length": 1, + "type": "uint8", + "description": "故障字2低字节" + }, + { + "name": "fcuGZ_2H", + "offset": 105, + "length": 1, + "type": "uint8", + "description": "故障字2高字节" + }, + { + "name": "fcuGZ_3L", + "offset": 106, + "length": 1, + "type": "uint8", + "description": "故障字3低字节" + }, + { + "name": "fcuGZ_3H", + "offset": 107, + "length": 1, + "type": "uint8", + "description": "故障字3高字节" + }, + { + "name": "insPosRelayState", + "offset": 108, + "length": 1, + "type": "uint8", + "description": "绝缘正极继电器状态" + }, + { + "name": "insNegRelayState", + "offset": 109, + "length": 1, + "type": "uint8", + "description": "绝缘负极继电器状态" + }, + { + "name": "powerPosRelayState", + "offset": 110, + "length": 1, + "type": "uint8", + "description": "功率正极继电器状态" + }, + { + "name": "powerNegRelayState", + "offset": 111, + "length": 1, + "type": "uint8", + "description": "功率负极继电器状态" + }, + { + "name": "insBatLimit", + "offset": 112, + "length": 2, + "type": "uint16", + "unit": "A", + "description": "绝缘电池电流限制" + }, + { + "name": "powerBatLimit", + "offset": 114, + "length": 2, + "type": "uint16", + "unit": "A", + "description": "功率电池电流限制" + }, + { + "name": "insBatSoc", + "offset": 116, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "绝缘电池SOC" + }, + { + "name": "powerBatSoc", + "offset": 117, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "功率电池SOC" + }, + { + "name": "insBatTotalElectricity", + "offset": 118, + "length": 2, + "type": "uint16", + "unit": "kWh", + "description": "绝缘电池总电量" + }, + { + "name": "powerBatTotalElectricity", + "offset": 120, + "length": 2, + "type": "uint16", + "unit": "kWh", + "description": "功率电池总电量" + }, + { + "name": "insBatCurrentElectricity", + "offset": 122, + "length": 2, + "type": "uint16", + "unit": "A", + "description": "绝缘电池当前电流" + }, + { + "name": "powerBatCurrentElectricity", + "offset": 124, + "length": 2, + "type": "uint16", + "unit": "A", + "description": "功率电池当前电流" + }, + { + "name": "insChargeState", + "offset": 126, + "length": 1, + "type": "uint8", + "description": "绝缘电池充电状态" + }, + { + "name": "powerChargeState", + "offset": 127, + "length": 1, + "type": "uint8", + "description": "功率电池充电状态" + }, + { + "name": "insLinkVoltage", + "offset": 128, + "length": 2, + "type": "uint16", + "unit": "V", + "description": "绝缘链路电压" + }, + { + "name": "insPackVoltage", + "offset": 130, + "length": 2, + "type": "uint16", + "unit": "V", + "description": "绝缘电池组电压" + }, + { + "name": "insCurrent", + "offset": 132, + "length": 2, + "type": "uint16", + "unit": "A", + "description": "绝缘电流" + }, + { + "name": "insPosInsulationResistance", + "offset": 134, + "length": 2, + "type": "uint16", + "unit": "kΩ", + "description": "正极绝缘电阻" + }, + { + "name": "insNegInsulationResistance", + "offset": 136, + "length": 2, + "type": "uint16", + "unit": "kΩ", + "description": "负极绝缘电阻" + }, + { + "name": "powerLinkVoltage", + "offset": 138, + "length": 2, + "type": "uint16", + "unit": "V", + "description": "功率链路电压" + }, + { + "name": "powerPackVoltage", + "offset": 140, + "length": 2, + "type": "uint16", + "unit": "V", + "description": "功率电池组电压" + }, + { + "name": "powerCurrent", + "offset": 142, + "length": 2, + "type": "uint16", + "unit": "A", + "description": "功率电流" + }, + { + "name": "powerPosInsulationResistance", + "offset": 144, + "length": 2, + "type": "uint16", + "unit": "kΩ", + "description": "功率正极绝缘电阻" + }, + { + "name": "powerNegInsulationResistance", + "offset": 146, + "length": 2, + "type": "uint16", + "unit": "kΩ", + "description": "功率负极绝缘电阻" + }, + { + "name": "insEmergencyStatusWord", + "offset": 148, + "length": 1, + "type": "uint8", + "description": "绝缘紧急状态字" + }, + { + "name": "powerEmergencyStatusWord", + "offset": 149, + "length": 1, + "type": "uint8", + "description": "功率紧急状态字" + }, + { + "name": "insAlarmIdentificationWord", + "offset": 150, + "length": 1, + "type": "uint8", + "description": "绝缘报警标识字" + }, + { + "name": "powerAlarmIdentificationWord", + "offset": 151, + "length": 1, + "type": "uint8", + "description": "功率报警标识字" + }, + { + "name": "insCurrentSocHold1", + "offset": 152, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "绝缘电流SOC保持1" + }, + { + "name": "insCurrentSocHold2", + "offset": 153, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "绝缘电流SOC保持2" + }, + { + "name": "insCurrentSocHold3", + "offset": 154, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "绝缘电流SOC保持3" + }, + { + "name": "fcuCurrentToInsLimit1", + "offset": 155, + "length": 1, + "type": "uint8", + "unit": "A", + "description": "FCU到绝缘限制1" + }, + { + "name": "fcuCurrentToinsLimit2", + "offset": 156, + "length": 1, + "type": "uint8", + "unit": "A", + "description": "FCU到绝缘限制2" + }, + { + "name": "powerCurrentSocHold1", + "offset": 157, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "功率电流SOC保持1" + }, + { + "name": "powerCurrentSocHold2", + "offset": 158, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "功率电流SOC保持2" + }, + { + "name": "powerCurrentSocHold3", + "offset": 159, + "length": 1, + "type": "uint8", + "unit": "%", + "description": "功率电流SOC保持3" + }, + { + "name": "powerCurrentToInsLimit1", + "offset": 160, + "length": 1, + "type": "uint8", + "unit": "A", + "description": "功率到绝缘限制1" + }, + { + "name": "powerCurrentToinsLimit2", + "offset": 161, + "length": 1, + "type": "uint8", + "unit": "A", + "description": "功率到绝缘限制2" + }, + { + "name": "placeholder2", + "offset": 162, + "length": 4, + "type": "float32", + "description": "预留字段2" + }, + { + "name": "placeholder3", + "offset": 166, + "length": 4, + "type": "float32", + "description": "预留字段3" + }, + { + "name": "placeholder4", + "offset": 170, + "length": 4, + "type": "float32", + "description": "预留字段4" + }, + { + "name": "placeholder5", + "offset": 174, + "length": 4, + "type": "float32", + "description": "预留字段5" + }, + { + "name": "checkCode", + "offset": 178, + "length": 4, + "type": "uint32", + "description": "校验码(从start1到placeholder5的字节累加和)" + } + ], + "metadata": { + "total_length": 182, + "data_section_start": 6, + "data_section_end": 178, + "checksum_range": "0-178", + "float_precision": "IEEE-754单精度", + "reserved_fields": [ + "placeholder1", + "placeholder2", + "placeholder3", + "placeholder4", + "placeholder5" + ] + } +} \ No newline at end of file diff --git a/data/protocol-specs/udp/dis_high_a_vol_bus_fb.json b/data/protocol-specs/udp/dis_high_a_vol_bus_fb.json new file mode 100644 index 0000000..8495ad6 --- /dev/null +++ b/data/protocol-specs/udp/dis_high_a_vol_bus_fb.json @@ -0,0 +1,142 @@ +{ + "protocol_name": "高压A母线状态反馈", + "message_id": "0x0006", + "length": 10, + "checksum": { + "start_offset": 0, + "end_offset": 30, + "algorithm": "sum_low_byte" + }, + "fields": [ + { + "name": "start1", + "offset": 0, + "type": "uint8", + "value": "0x20", + "description": "起始字节1" + }, + { + "name": "start2", + "offset": 1, + "type": "uint8", + "value": "0x20", + "description": "起始字节2" + }, + { + "name": "id", + "offset": 2, + "type": "uint16", + "value": "0x0006", + "description": "消息ID" + }, + { + "name": "length", + "offset": 4, + "type": "uint16", + "value": 10, + "description": "消息长度" + }, + { + "name": "bowFTDevice123CircuitBreaker", + "offset": 6, + "type": "uint8", + "description": "艏部FT设备123断路器" + }, + { + "name": "actuatorCircuitBreaker", + "offset": 7, + "type": "uint8", + "description": "执行机构断路器" + }, + { + "name": "mastSteeringGearControlBoxCircuitBreaker", + "offset": 8, + "type": "uint8", + "description": "桅杆舵机控制箱断路器" + }, + { + "name": "xczCircuitBreaker", + "offset": 9, + "type": "uint8", + "description": "XCZ断路器" + }, + { + "name": "bowRudderControlBoxCircuitBreaker", + "offset": 10, + "type": "uint8", + "description": "艏舵控制箱断路器" + }, + { + "name": "openWaterCoverStartCylinderCircuitBreaker", + "offset": 11, + "type": "uint8", + "description": "开盖启动气缸断路器" + }, + { + "name": "instrumentPowerFailureSignal", + "offset": 12, + "type": "uint8", + "description": "仪表电源失效信号" + }, + { + "name": "emergencyPowerFailureSignal", + "offset": 13, + "type": "uint8", + "description": "应急电源失效信号" + }, + { + "name": "waterIngressionAlarm", + "offset": 14, + "type": "uint8", + "description": "进水报警" + }, + { + "name": "busbarBVoltage", + "offset": 15, + "type": "uint16", + "description": "B排电压(V)" + }, + { + "name": "busbarBCurrent", + "offset": 17, + "type": "uint16", + "description": "B排电流(A)" + }, + { + "name": "bowFTDevice123Current", + "offset": 19, + "type": "uint16", + "description": "艏部FT设备123电流(A)" + }, + { + "name": "actuatorCurrent", + "offset": 21, + "type": "uint16", + "description": "执行机构电流(A)" + }, + { + "name": "mastSteeringGearControlBoxCurrent", + "offset": 23, + "type": "uint16", + "description": "桅杆舵机控制箱电流(A)" + }, + { + "name": "xczCurrent", + "offset": 25, + "type": "uint16", + "description": "XCZ电流(A)" + }, + { + "name": "bowRudderControlBoxCurrent", + "offset": 27, + "type": "uint16", + "description": "艏舵控制箱电流(A)" + }, + { + "name": "openWaterCoverStartCylinderCurrent", + "offset": 29, + "type": "uint16", + "description": "开盖启动气缸电流(A)" + } + ] +} \ No newline at end of file diff --git a/data/protocol-specs/udp/dis_high_b_vol_bus_fb.json b/data/protocol-specs/udp/dis_high_b_vol_bus_fb.json new file mode 100644 index 0000000..d627ae1 --- /dev/null +++ b/data/protocol-specs/udp/dis_high_b_vol_bus_fb.json @@ -0,0 +1,154 @@ +{ + "protocol_name": "高压B母线状态反馈", + "message_id": "0x0007", + "length": 36, + "checksum": { + "start_offset": 0, + "end_offset": 34, + "algorithm": "sum_low_byte" + }, + "fields": [ + { + "name": "start1", + "offset": 0, + "type": "uint8", + "value": "0x20", + "description": "起始字节1" + }, + { + "name": "start2", + "offset": 1, + "type": "uint8", + "value": "0x20", + "description": "起始字节2" + }, + { + "name": "id", + "offset": 2, + "type": "uint16", + "value": "0x0007", + "description": "消息ID" + }, + { + "name": "length", + "offset": 4, + "type": "uint16", + "value": 36, + "description": "消息长度(包含校验码)" + }, + { + "name": "lithiumBatteryGroupInstrumentCircuitBreaker", + "offset": 6, + "type": "uint8", + "description": "锂电池组仪表断路器" + }, + { + "name": "bowLowVoltageDistributionBoxCircuitBreaker", + "offset": 7, + "type": "uint8", + "description": "艏部低压配电箱断路器" + }, + { + "name": "unit4InstrumentDC48VCircuitBreaker", + "offset": 8, + "type": "uint8", + "description": "单元4仪表DC48V断路器" + }, + { + "name": "dcC1DCDistributionPanelCircuitBreaker", + "offset": 9, + "type": "uint8", + "description": "DC C1直流配电板断路器" + }, + { + "name": "reservedCircuitBreaker1", + "offset": 10, + "type": "uint8", + "description": "备用断路器1" + }, + { + "name": "reservedCircuitBreaker2", + "offset": 11, + "type": "uint8", + "description": "备用断路器2" + }, + { + "name": "emergencyLithiumBatteryGroup2CircuitBreaker", + "offset": 12, + "type": "uint8", + "description": "应急锂电池组2断路器" + }, + { + "name": "instrumentPowerFailureSignal", + "offset": 13, + "type": "uint8", + "description": "仪表电源故障信号" + }, + { + "name": "emergencyPowerFailureSignal", + "offset": 14, + "type": "uint8", + "description": "应急电源故障信号" + }, + { + "name": "instrumentBusbarVoltage", + "offset": 15, + "type": "uint16", + "description": "仪表母线电压(V)" + }, + { + "name": "bowLowVoltageDistributionBoxCurrent", + "offset": 17, + "type": "uint16", + "description": "艏部低压配电箱电流(A)" + }, + { + "name": "dcC1InstrumentDC48VCurrent", + "offset": 19, + "type": "uint16", + "description": "DC C1仪表DC48V电流(A)" + }, + { + "name": "reservedCurrent1", + "offset": 21, + "type": "uint16", + "description": "备用电流1(A)" + }, + { + "name": "emergencyLithiumBatteryGroup2Current", + "offset": 23, + "type": "uint16", + "description": "应急锂电池组2电流(A)" + }, + { + "name": "lithiumBatteryGroupInstrumentCurrent", + "offset": 25, + "type": "uint16", + "description": "锂电池组仪表电流(A)" + }, + { + "name": "unit4InstrumentDC48VCurrent", + "offset": 27, + "type": "uint16", + "description": "单元4仪表DC48V电流(A)" + }, + { + "name": "reservedCurrent2", + "offset": 29, + "type": "uint16", + "description": "备用电流2(A)" + }, + { + "name": "emergency2BusbarVoltage", + "offset": 31, + "type": "uint16", + "description": "应急2母线电压(V)" + }, + { + "name": "compositeEnergyManagementSystemEmergencyDC48VCurrent", + "offset": 33, + "type": "uint16", + "description": "综合能源管理系统应急DC48V电流(A)" + } + ] +} diff --git a/data/protocol-specs/udp/dis_high_vol_bus_fb.json b/data/protocol-specs/udp/dis_high_vol_bus_fb.json new file mode 100644 index 0000000..2ea80a3 --- /dev/null +++ b/data/protocol-specs/udp/dis_high_vol_bus_fb.json @@ -0,0 +1,184 @@ +{ + "protocol_name": "高压母线状态反馈", + "message_id": "0x0005", + "length": 38, + "checksum": { + "start_offset": 0, + "end_offset": 37, + "algorithm": "sum_low_byte" + }, + "fields": [ + { + "name": "start1", + "offset": 0, + "type": "uint8", + "value": "0x20", + "description": "起始字节1" + }, + { + "name": "start2", + "offset": 1, + "type": "uint8", + "value": "0x20", + "description": "起始字节2" + }, + { + "name": "id", + "offset": 2, + "type": "uint16", + "value": "0x0005", + "description": "消息ID" + }, + { + "name": "length", + "offset": 4, + "type": "uint16", + "value": 38, + "description": "消息长度" + }, + { + "name": "DCB1", + "offset": 6, + "type": "uint8", + "description": "直流断路器1状态" + }, + { + "name": "DCB2", + "offset": 7, + "type": "uint8", + "description": "直流断路器2状态" + }, + { + "name": "ZK1", + "offset": 8, + "type": "uint8", + "description": "真空接触器1状态" + }, + { + "name": "ZK2", + "offset": 9, + "type": "uint8", + "description": "真空接触器2状态" + }, + { + "name": "ZK3", + "offset": 10, + "type": "uint8", + "description": "真空接触器3状态" + }, + { + "name": "ZK4", + "offset": 11, + "type": "uint8", + "description": "真空接触器4状态" + }, + { + "name": "ZK5", + "offset": 12, + "type": "uint8", + "description": "真空接触器5状态" + }, + { + "name": "ZK6", + "offset": 13, + "type": "uint8", + "description": "真空接触器6状态" + }, + { + "name": "ZK7", + "offset": 14, + "type": "uint8", + "description": "真空接触器7状态" + }, + { + "name": "ZK8", + "offset": 15, + "type": "uint8", + "description": "真空接触器8状态" + }, + { + "name": "ZK9", + "offset": 16, + "type": "uint8", + "description": "真空接触器9状态" + }, + { + "name": "ZK10", + "offset": 17, + "type": "uint8", + "description": "真空接触器10状态" + }, + { + "name": "busInsulationLow", + "offset": 18, + "type": "uint8", + "description": "母线绝缘低报警" + }, + { + "name": "busAInsulationHigh", + "offset": 19, + "type": "uint8", + "description": "A母线绝缘高报警" + }, + { + "name": "lostPower", + "offset": 20, + "type": "uint8", + "description": "失电信号" + }, + { + "name": "lostEmerPower", + "offset": 21, + "type": "uint8", + "description": "应急失电信号" + }, + { + "name": "powerBusVoltage", + "offset": 22, + "type": "uint16", + "description": "动力母线电压(V)" + }, + { + "name": "dcDc5ModuleCurrent", + "offset": 24, + "type": "uint16", + "description": "DC/DC5模块电流(A)" + }, + { + "name": "powerBusCurrent", + "offset": 26, + "type": "uint16", + "description": "动力母线电流(A)" + }, + { + "name": "busbarAVoltage", + "offset": 28, + "type": "uint16", + "description": "A排电压(V)" + }, + { + "name": "propulsionMotorControlBoxCurrent", + "offset": 30, + "type": "uint16", + "description": "推进电机控制箱电流(A)" + }, + { + "name": "busbarACurrent", + "offset": 32, + "type": "uint16", + "description": "A排电流(A)" + }, + { + "name": "lithiumBatteryGroupMeterCurrent", + "offset": 34, + "type": "uint16", + "description": "锂电池组表计电流(A)" + }, + { + "name": "bowHighVoltageDistributionBoxCurrent", + "offset": 36, + "type": "uint16", + "description": "艏部高压配电箱电流(A)" + } + ] +} \ No newline at end of file diff --git a/data/uPower_sysState_cmd.json b/data/uPower_sysState_cmd.json deleted file mode 100644 index 4309ae7..0000000 --- a/data/uPower_sysState_cmd.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "powerCMD":0, - "modCMD":0, - "workCMD":0 -} \ No newline at end of file diff --git a/src/pPowerManger/CMakeLists.txt b/src/pPowerManger/CMakeLists.txt index 31fee1c..506c265 100644 --- a/src/pPowerManger/CMakeLists.txt +++ b/src/pPowerManger/CMakeLists.txt @@ -22,10 +22,10 @@ SET(SRC PowerManger.cpp PowerManger_Info.cpp udpComm.cpp - fsm.cpp main.cpp SQLiteDB.cpp driver.cpp + PowerManagerFsm.cpp ) ADD_EXECUTABLE(pPowerManger ${SRC}) @@ -51,7 +51,7 @@ SET(SQLITEDB_SRC ) SET(FSMLIB_SRC - fsm.cpp) + PowerManagerFsm.cpp) SET(DRIVER_SRC driver.cpp) @@ -60,9 +60,9 @@ SET(POWERMANGE_SRC PowerManger.cpp PowerManger_Info.cpp udpComm.cpp - fsm.cpp SQLiteDB.cpp - driver.cpp) + driver.cpp + PowerManagerFsm.cpp) ADD_LIBRARY(SQLiteDB STATIC ${SQLITEDB_SRC}) ADD_LIBRARY(UDPComm STATIC ${UDPCOMM_SRC}) diff --git a/src/pPowerManger/PowerManagerFsm.cpp b/src/pPowerManger/PowerManagerFsm.cpp new file mode 100644 index 0000000..e351e5f --- /dev/null +++ b/src/pPowerManger/PowerManagerFsm.cpp @@ -0,0 +1,29 @@ +#include "PowerManagerFsm.hpp" +#include "PowerManger.h" + +// 初始化静态成员 +PowerManger* PowerManagerFsm::pm = nullptr; + +// 状态实例化 +InitState initState; +StandbyState standbyState; +FaultState faultState; + +// 状态机初始化 +void PowerManagerFsm::init(PowerManger* powerManager) { + pm = powerManager; + start(); +} + +// 状态转换接口实现 +void PowerManagerFsm::triggerInitEvent() { + dispatch(InitEvent()); +} + +void PowerManagerFsm::triggerStandbyEvent() { + dispatch(StandbyEvent()); +} + +void PowerManagerFsm::triggerFaultEvent(unsigned int faultCode) { + dispatch(FaultEvent(faultCode)); +} \ No newline at end of file diff --git a/src/pPowerManger/PowerManagerFsm.hpp b/src/pPowerManger/PowerManagerFsm.hpp new file mode 100644 index 0000000..06968a1 --- /dev/null +++ b/src/pPowerManger/PowerManagerFsm.hpp @@ -0,0 +1,153 @@ +#ifndef POWER_MANAGER_FSM_HPP +#define POWER_MANAGER_FSM_HPP + +#include "PowerManger.h" +#include "tinyfsm.hpp" + +// 前向声明 +class PowerManger; + +// 定义事件类型 +struct InitEvent : tinyfsm::Event { }; +struct StandbyEvent : tinyfsm::Event { }; +struct FaultEvent : tinyfsm::Event { + unsigned int faultCode; + FaultEvent(unsigned int code) : faultCode(code) {} +}; + +// 定义状态机基类 +class PowerManagerFsm : public tinyfsm::Fsm { +protected: + static PowerManger* pm; + +public: + // 初始化状态机 + static void init(PowerManger* powerManager) { + pm = powerManager; + } + + // 响应事件默认实现 + virtual void react(tinyfsm::Event const &) { } + + // 状态转换接口 + void triggerInitEvent() { dispatch(InitEvent()); } + void triggerStandbyEvent() { dispatch(StandbyEvent()); } + void triggerFaultEvent(unsigned int faultCode) { dispatch(FaultEvent(faultCode)); } +}; + +// 初始化静态成员 +PowerManger* PowerManagerFsm::pm = nullptr; + +// 定义状态类 +class InitState : public PowerManagerFsm { +public: + void entry() { + PowerManagerFsm::pm->m_pmEvent = "初始化状态"; + PowerManagerFsm::pm->printState("InitState", "进入初始化状态"); + } + + void react(InitEvent const &) { + // 1. 检查通信是否正常 + double StartTime = PowerManagerFsm::pm->GetAppStartTime(); + while (PowerManagerFsm::pm->connectState < 5) { + MOOSPause(1000); + PowerManagerFsm::pm->updateTime(); + double dft = abs(PowerManagerFsm::pm->m_current_time - StartTime); + if(dft > 10) { + transit(); + PowerManagerFsm::pm->m_faultNum = 1; + return; + } + string desp = "等待复合管控消息 : " + to_string(10-dft); + PowerManagerFsm::pm->printState("InitState", desp); + } + + // 2. 检查复合管控器是否上报故障 + if(PowerManagerFsm::pm->checkError() < 0) { + transit(); + PowerManagerFsm::pm->m_faultNum = 2; + return; + } + + // 3. 初始化系统为待机状态 + PowerManagerFsm::pm->initControlCmd(); + + // 4. 判断关键断路器是否闭合 + while (true) { + if(PowerManagerFsm::pm->m_currentDisBreakerState.bus3Breaker.unit4InstrumentDC48VCircuitBreaker == 1 || + PowerManagerFsm::pm->m_currentDisBreakerState.bus4Breaker.unit5CircuitBreaker == 1 || + PowerManagerFsm::pm->m_currentDisBreakerState.bus4Breaker.unit2CircuitBreaker == 1 || + PowerManagerFsm::pm->m_currentDisBreakerState.bus4Breaker.unit3CircuitBreaker == 1 || + PowerManagerFsm::pm->m_currentDisBreakerState.bus4Breaker.unit1CircuitBreaker == 1) { + transit(); + return; + } + PowerManagerFsm::pm->m_pmEvent = "等待关键断路器闭合"; + MOOSPause(1000); + PowerManagerFsm::pm->printState("InitState", PowerManagerFsm::pm->m_pmEvent); + } + } +}; + +class StandbyState : public PowerManagerFsm { +public: + void entry() { + PowerManagerFsm::pm->m_stateData.note = "待机状态"; + PowerManagerFsm::pm->printState("StandbyState", "进入待机状态"); + } + + void react(StandbyEvent const &) { + while (true) { + // 1. 检查当前是否存在故障 + if(PowerManagerFsm::pm->checkError() < 0) { + transit(); + return; + } + + // 2. 处理上位机控制指令 + handlePowerCommands(); + MOOSPause(1000); + } + } + +private: + void handlePowerCommands() { + switch (PowerManagerFsm::pm->m_msCmd.powerCMD) { + case 0: PowerManagerFsm::pm->m_pmEvent = "收到上位机控制指令:关机"; break; + case 1: handlePowerOn(); break; + // 其他处理函数省略... + } + } + + void handlePowerOn() { + PowerManagerFsm::pm->m_pmEvent = "动力电上电"; + PowerManagerFsm::pm->m_CcuColCmd.powerBatCmd = 0x10; + if(PowerManagerFsm::pm->m_pmCurrentState.ccustate.fcuState == 0x04) + PowerManagerFsm::pm->m_CcuColCmd.fcuCmd = 0x02; + } +}; + +class FaultState : public PowerManagerFsm { +public: + void entry() { + PowerManagerFsm::pm->printState("FaultState", "进入故障状态"); + } + + void react(FaultEvent const & e) { + switch (e.faultCode) { + case 1: + PowerManagerFsm::pm->m_pmEvent = "复合管控连接超时"; + PowerManagerFsm::pm->printState("FaultState", "通信故障"); + break; + case 2: + PowerManagerFsm::pm->m_pmEvent = "能源系统故障"; + PowerManagerFsm::pm->printState("FaultState", "能源故障"); + break; + } + } +}; + +// 设置初始状态 +FSM_INITIAL_STATE(PowerManagerFsm, InitState); + +#endif // POWER_MANAGER_FSM_HPP \ No newline at end of file diff --git a/src/pPowerManger/PowerManger.cpp b/src/pPowerManger/PowerManger.cpp index b5c5736..dd617f6 100644 --- a/src/pPowerManger/PowerManger.cpp +++ b/src/pPowerManger/PowerManger.cpp @@ -71,17 +71,9 @@ PowerManger::PowerManger() m_db->createDriversTables(VAR_TO_STR(m_subDisSysCmd)); m_db->createDriversTables(VAR_TO_STR(m_MSDriverCmd)); - //注册状态机 - m_fsm.RegisterState("Init", 1, m_Inite_s1); - m_fsm.RegisterState("Stady", 2, m_Standby_s2); - m_fsm.RegisterState("Fault", 99, m_Fault_s99); - - m_fsm.RegisterHandleFunction(&m_Inite_s1, handleInite_s1); - m_fsm.RegisterHandleFunction(&m_Standby_s2, handleStandby_s2); - m_fsm.RegisterHandleFunction(&m_Fault_s99, handleFault_s99); - // 初始化状态机 - m_pmState = m_Inite_s1; + m_fsm.init(this); + PowerManagerFsm::start(); } //--------------------------------------------------------- @@ -344,7 +336,14 @@ bool PowerManger::FsmLoop() //状态机循环 while (!m_FsmThread.IsQuitRequested()) { - m_fsm.run(m_pmState,this); + // 检查故障并触发事件 + if(int error = checkError()) { + triggerFaultEvent(error); + } else { + // 自动状态转换由状态机内部处理 + MOOSPause(1000); + } + //延时1s usleep(1000000); } @@ -599,7 +598,22 @@ int PowerManger::checkError() } -void PowerManger::printState(FSM_State st, string desp){ +void PowerManger::triggerInitEvent() +{ + PowerManagerFsm::dispatch(InitEvent()); +} + +void PowerManger::triggerStandbyEvent() +{ + PowerManagerFsm::dispatch(StandbyEvent()); +} + +void PowerManger::triggerFaultEvent(unsigned int faultCode) +{ + PowerManagerFsm::dispatch(FaultEvent(faultCode)); +} + +void PowerManger::printState(const std::string& stateName, const std::string& desp){ cout << MOOS::ConsoleColours::Yellow() << "STATE " << st.id << " [" << st.name << "] " << MOOS::ConsoleColours::reset(); cout << MOOS::ConsoleColours::Blue() << " -> " << MOOS::ConsoleColours::reset(); // 检查desp是否有“故障” @@ -610,214 +624,6 @@ void PowerManger::printState(FSM_State st, string desp){ cout << MOOS::ConsoleColours::Green() << desp << MOOS::ConsoleColours::reset() << endl; } -int PowerManger::handleInite_s1(FSM_State &fsm, void* pData) -{ - PowerManger* pm = (PowerManger*)pData; - bool ok = true; - //1. 检查通信是否正常 如果超时则进入故障状态 - double StartTime = pm->GetAppStartTime(); - while (pm->connectState < 5) - { - MOOSPause(1000); - pm->updateTime(); - double dft = abs(pm->m_current_time - StartTime); - if(dft > 10) - { - pm->m_pmState = pm->m_Fault_s99; - pm->m_faultNum = 1; //通信故障 - ok = false; - break; - } - string desp = "等待复合管控消息 : " + to_string(10-dft); - pm->printState(fsm,desp); - } - //2. 检查复合管控器是否上报故障 如果故障则进入故障状态 - if(pm->checkError() < 0) - { - ok = false; - pm->m_faultNum = 2; //能源故障 - } - //3. 初始化系统为待机状态 - pm->initControlCmd(); - //4.判断关键断路器是否闭合 - ok = false; - while (!ok) - { - if(pm->m_currentDisBreakerState.bus3Breaker.unit4InstrumentDC48VCircuitBreaker == 1 || - pm->m_currentDisBreakerState.bus4Breaker.unit5CircuitBreaker == 1 || - pm->m_currentDisBreakerState.bus4Breaker.unit2CircuitBreaker == 1 || - pm->m_currentDisBreakerState.bus4Breaker.unit3CircuitBreaker == 1 || - pm->m_currentDisBreakerState.bus4Breaker.unit1CircuitBreaker == 1) - { - ok = true; - } - pm->m_pmEvent = "等待关键断路器闭合"; - MOOSPause(1000); - pm->printState(fsm,pm->m_pmEvent); - } - //5. 进入下一状态 - if(ok) - { - pm->m_pmState = pm->m_Standby_s2; - } - if(!ok) - { - pm->m_pmState = pm->m_Fault_s99; - } - return 0; -} - -int PowerManger::handleStandby_s2(FSM_State &fsm, void* pData) -{ - PowerManger* pm = (PowerManger*)pData; - pm->m_stateData.note = "待机状态"; - while (true) - { - string desp = "待机状态"; - pm->printState(fsm,desp); - //1. 检查当前是否存在故障 - if(pm->checkError() < 0) - { - pm->m_pmState = pm->m_Fault_s99; - break; - } - //2. 检查上位机上电控制指令 - switch (pm->m_msCmd.powerCMD) - { - case 0: - pm->m_pmEvent = "收到上位机控制指令:关机"; - // pm->shutdown(); - break; - case 1: - pm->m_pmEvent = "动力电上电"; - // pm->powerOn(); - //1.先上动力锂电池 - pm->m_CcuColCmd.powerBatCmd = 0x10; - //2.检查燃料电池是否就绪,如果就绪则启动 - if(pm->m_pmCurrentState.ccustate.fcuState = 0x04) - pm->m_CcuColCmd.fcuCmd = 0x02; - break; - case 2: - pm->m_pmEvent = "锂动力电启动"; - pm->m_CcuColCmd.powerBatCmd = 0x10; - break; - case 3: - pm->m_pmEvent = "燃料电池启动"; - pm->m_CcuColCmd.fcuCmd = 0x02; - break; - case 4: - pm->m_pmEvent = "锂动力电关闭"; - pm->m_CcuColCmd.powerBatCmd = 0x20; - case 5: - pm->m_pmEvent = "燃料电池停机"; - pm->m_CcuColCmd.fcuCmd = 0x03; - break; - case 6: - pm->m_pmEvent = "燃料电池预热指令"; - pm->m_CcuColCmd.fcuCmd = 0x07; - break; - case 7: - pm->m_pmEvent = "燃料电池自检指令"; - pm->m_CcuColCmd.fcuCmd = 0x01; - break; - case 8: - pm->m_pmEvent = "燃料电池紧急停机"; - pm->m_CcuColCmd.fcuCmd = 0x05; - break; - case 9: - pm->m_pmEvent = "燃料电池复位指令"; - pm->m_CcuColCmd.fcuCmd = 0x04; - break; - case 10: - pm->m_pmEvent = "燃料电池补给指令"; - pm->m_CcuColCmd.fcuCmd = 0x06; - break; - case 11: - pm->m_pmEvent = "燃料电池停机维护"; - pm->m_CcuColCmd.fcuCmd = 0x08; - break; - default: - break; - } - //2. 检查上位机模式切换指令 - switch (pm->m_msCmd.modCMD) - { - case 0: - //无效 - break; - case 1: - pm->m_pmEvent = "待机工况"; - break; - case 2: - pm->m_pmEvent = "岸基备航"; - break; - case 3: - pm->m_pmEvent = "水中备航"; - break; - case 4: - pm->m_pmEvent = "遥控工况"; - break; - case 5: - pm->m_pmEvent = "巡航模式"; - break; - case 6: - pm->m_pmEvent = "高速模式"; - break; - case 7: - pm->m_pmEvent = "上浮下潜"; - break; - case 8: - pm->m_pmEvent = "浮调模式"; - break; - case 9: - pm->m_pmEvent = "水下侦查"; - break; - case 10: - pm->m_pmEvent = "水面侦查"; - break; - case 11: - pm->m_pmEvent = "DJ模式"; - break; - default: - break; - } - //3. 检查上位机工作模式切换控制指令 - switch (pm->m_msCmd.workCMD) - { - case 0: - pm->m_pmEvent = "正常模式(默认)"; - break; - case 1: - pm->m_pmEvent = "试验模式"; - pm->currentMod = 1; - break; - case 2: - pm->m_pmEvent = "调试模式"; - pm->currentMod = 2; - break; - } - MOOSPause(1000); - } - -} - -int PowerManger::handleFault_s99(FSM_State &fsm, void* pData) -{ - // cout << fsm.name << endl; - PowerManger* pm = (PowerManger*)pData; - switch (pm->m_faultNum) - { - case 1: - pm->printState(fsm,"通信故障"); - pm->m_pmEvent = "复合管控连接超时"; - break; - - default: - break; - } - pm->printState(fsm,"故障"); - return 0; -} //==============================系统操作函数==================== diff --git a/src/pPowerManger/PowerManger.h b/src/pPowerManger/PowerManger.h index b56b07b..44293ca 100644 --- a/src/pPowerManger/PowerManger.h +++ b/src/pPowerManger/PowerManger.h @@ -30,7 +30,7 @@ #include "json/json.h" #include "udpComm.h" #include "pmSysvariable.h" -#include "fsm.h" +#include "PowerManagerFsm.hpp" #include "SQLiteDB.h" #include "driver.h" @@ -96,92 +96,81 @@ class PowerManger : public AppCastingMOOSApp double msg_disHighAVolBusFbMsg_Update_time; double msg_disHighBVolBusFbMsg_Update_time; double msg_disLowBusFbMsg_Update_time; - - protected: - //===========================交互状态变量================================== - Driver m_driver; //设备驱动 - pmState m_pmCurrentState; //能源系统的当前状态 - disSysBreakerList m_currentDisBreakerState; //配电断路器状态 - disSysBreakerList m_targetDisBreakerState; - DriverTable m_currentDriverState; - DriverTable m_MSDriverCmd; - DriverTable m_subDisSysCmd; - DriverTable m_subDisSysState; -//=========================================================================== - //系统运行状态 - unsigned char workCondition; - unsigned char currentMod; - unsigned char powerState; - unsigned char falutLevel; - vector faultCode; - unsigned int soc; - unsigned int sustainableTime; - - // 配电和CCU的反馈状态 - msg_CcuStateFbMsg m_CcuCurrentState; - msg_disHighVolBusFbMsg m_disHighVolBusCurrentState; - msg_disHighAVolBusFbMsg m_disHighAVolBusCurrentState; - msg_disHighBVolBusFbMsg m_disHighBVolBusCurrentState; - msg_disLowBusFbMsg m_disLowBusState; - - //下位机操作函数 - ccuColCmd m_CcuColCmd; - void disSysOption(); - void ccuOption(); - - char getBreakerOption(char cmd); - void initControlCmd(); - - //上位机操作函数 - MSControlCmd m_msCmd; - bool buildPowerSysReport(); - bool getMsCmdFromJson(MSControlCmd &cmd,const string &strJson); - - private: - udpComm m_udpComm; - XPCUdpSocket *m_pCcuUdpComm; - CMOOSThread m_ListenThread; - CMOOSThread m_FsmThread; - long m_lPort; - unsigned int m_nReceiveBufferSizeKB; - unsigned int m_nSendBufferSizeKB; - double m_current_time; - unsigned int m_faultNum; - unsigned int m_ticker; - - public: - //===========================状态机实现============================================== - void printState(FSM_State st, string desp); + protected: + //===========================交互状态变量================================== + Driver m_driver; //设备驱动 + pmState m_pmCurrentState; //能源系统的当前状态 + disSysBreakerList m_currentDisBreakerState; //配电断路器状态 + disSysBreakerList m_targetDisBreakerState; + DriverTable m_currentDriverState; + DriverTable m_MSDriverCmd; + DriverTable m_subDisSysCmd; + DriverTable m_subDisSysState; + //=========================================================================== + //系统运行状态 + unsigned char workCondition; + unsigned char currentMod; + unsigned char powerState; + unsigned char falutLevel; + vector faultCode; + unsigned int soc; + unsigned int sustainableTime; + + // 配电和CCU的反馈状态 + msg_CcuStateFbMsg m_CcuCurrentState; + msg_disHighVolBusFbMsg m_disHighVolBusCurrentState; + msg_disHighAVolBusFbMsg m_disHighAVolBusCurrentState; + msg_disHighBVolBusFbMsg m_disHighBVolBusCurrentState; + msg_disLowBusFbMsg m_disLowBusState; + + //下位机操作函数 + ccuColCmd m_CcuColCmd; + void disSysOption(); + void ccuOption(); + + char getBreakerOption(char cmd); + void initControlCmd(); + + //上位机操作函数 + MSControlCmd m_msCmd; + bool buildPowerSysReport(); + bool getMsCmdFromJson(MSControlCmd &cmd,const string &strJson); + + private: + udpComm m_udpComm; + XPCUdpSocket *m_pCcuUdpComm; + CMOOSThread m_ListenThread; + CMOOSThread m_FsmThread; + long m_lPort; + unsigned int m_nReceiveBufferSizeKB; + unsigned int m_nSendBufferSizeKB; + double m_current_time; + unsigned int m_faultNum; + unsigned int m_ticker; + + // 状态机实例 + PowerManagerFsm m_fsm; + + public: + //===========================状态机接口======================================= + void printState(const std::string& stateName, const std::string& desp); bool FSM_RUN_IS_OK = true; - - StateData m_stateData; - FSM_State m_pmState; //当前状态 - string m_pmEvent; - FSM m_fsm; - - //初始化状态 - FSM_State m_Inite_s1; - static int handleInite_s1(FSM_State &fsm, void* pData); - - //待机状态 - FSM_State m_Standby_s2; - static int handleStandby_s2(FSM_State &fsm, void* pData); - - //岸基备航 - // FSM_State m_ShoreReady_s3; - - //水中备航 - - //自动工况 - - //故障处理 - FSM_State m_Fault_s99; - static int handleFault_s99(FSM_State &fsm, void* pData); - //====================================================================================== - int checkError(); - bool shutdown(); - bool powerOn(); - bool powerOff(); + + // 初始化状态机 + void initFsm() { + m_fsm.init(this); + } + + // 状态机事件触发接口 + void triggerInitEvent() { m_fsm.triggerInitEvent(); } + void triggerStandbyEvent() { m_fsm.triggerStandbyEvent(); } + void triggerFaultEvent(unsigned int faultCode) { m_fsm.triggerFaultEvent(faultCode); } + //================================================================================== + int checkError(); + bool shutdown(); + bool powerOn(); + bool powerOff(); + }; diff --git a/src/pPowerManger/fsm.h b/src/pPowerManger/fsm.h index 491b19a..9078755 100644 --- a/src/pPowerManger/fsm.h +++ b/src/pPowerManger/fsm.h @@ -27,14 +27,20 @@ public: int run(FSM_State &fsm,void* data); int run(FSM_State *fsm,void* data, std::string event); - //TODO: 事件注册机制实现 - int RegisterEvent(FSM_State* fsm, std::string event, FSM_State *state); - int unRegisterEvent(FSM_State* fsm, std::string event); - - int RegisterState(std::string name, unsigned int id,FSM_State &state); - FSM_State getState(std::string name); - unsigned int getStateId(std::string name); + // 事件处理机制 + int RegisterEvent(FSM_State* fsm, const std::string& event, FSM_State *state); + int unRegisterEvent(FSM_State* fsm, const std::string& event); + + // 状态管理 + int RegisterState(const std::string& name, unsigned int id, FSM_State &state); + FSM_State getState(const std::string& name) const; + unsigned int getStateId(const std::string& name) const; + + // 处理函数管理 int RegisterHandleFunction(FSM_State* fsm, FSM_Handle handle); int unRegisterHandleFunction(FSM_State* fsm); + + // 事件触发 + int triggerEvent(FSM_State* currentState, const std::string& event, void* data); }; #endif \ No newline at end of file diff --git a/src/pPowerManger/tinyfsm.hpp b/src/pPowerManger/tinyfsm.hpp new file mode 100644 index 0000000..5a11f8a --- /dev/null +++ b/src/pPowerManger/tinyfsm.hpp @@ -0,0 +1,251 @@ +/* + * TinyFSM - Tiny Finite State Machine Processor + * + * Copyright (c) 2012-2022 Axel Burri + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* --------------------------------------------------------------------- + * Version: 0.3.3 + * + * API documentation: see "../doc/50-API.md" + * + * The official TinyFSM website is located at: + * https://digint.ch/tinyfsm/ + * + * Author: + * Axel Burri + * --------------------------------------------------------------------- + */ + +#ifndef TINYFSM_HPP_INCLUDED +#define TINYFSM_HPP_INCLUDED + +#ifndef TINYFSM_NOSTDLIB +#include +#endif + +// #include +// #define DBG(str) do { std::cerr << str << std::endl; } while( false ) +// DBG("*** dbg_example *** " << __PRETTY_FUNCTION__); + +namespace tinyfsm +{ + + // -------------------------------------------------------------------------- + + struct Event { }; + + // -------------------------------------------------------------------------- + +#ifdef TINYFSM_NOSTDLIB + // remove dependency on standard library (silent fail!). + // useful in conjunction with -nostdlib option, e.g. if your compiler + // does not provide a standard library. + // NOTE: this silently disables all static_assert() calls below! + template + struct is_same_fsm { static constexpr bool value = true; }; +#else + // check if both fsm and state class share same fsmtype + template + struct is_same_fsm : std::is_same< typename F::fsmtype, typename S::fsmtype > { }; +#endif + + template + struct _state_instance + { + using value_type = S; + using type = _state_instance; + static S value; + }; + + template + typename _state_instance::value_type _state_instance::value; + + // -------------------------------------------------------------------------- + + template + class Fsm + { + public: + + using fsmtype = Fsm; + using state_ptr_t = F *; + + static state_ptr_t current_state_ptr; + + // public, leaving ability to access state instance (e.g. on reset) + template + static constexpr S & state(void) { + static_assert(is_same_fsm::value, "accessing state of different state machine"); + return _state_instance::value; + } + + template + static constexpr bool is_in_state(void) { + static_assert(is_same_fsm::value, "accessing state of different state machine"); + return current_state_ptr == &_state_instance::value; + } + + /// state machine functions + public: + + // explicitely specialized in FSM_INITIAL_STATE macro + static void set_initial_state(); + + static void reset() { }; + + static void enter() { + current_state_ptr->entry(); + } + + static void start() { + set_initial_state(); + enter(); + } + + template + static void dispatch(E const & event) { + current_state_ptr->react(event); + } + + + /// state transition functions + protected: + + template + void transit(void) { + static_assert(is_same_fsm::value, "transit to different state machine"); + current_state_ptr->exit(); + current_state_ptr = &_state_instance::value; + current_state_ptr->entry(); + } + + template + void transit(ActionFunction action_function) { + static_assert(is_same_fsm::value, "transit to different state machine"); + current_state_ptr->exit(); + // NOTE: do not send events in action_function definisions. + action_function(); + current_state_ptr = &_state_instance::value; + current_state_ptr->entry(); + } + + template + void transit(ActionFunction action_function, ConditionFunction condition_function) { + if(condition_function()) { + transit(action_function); + } + } + }; + + template + typename Fsm::state_ptr_t Fsm::current_state_ptr; + + // -------------------------------------------------------------------------- + + template + struct FsmList; + + template<> struct FsmList<> { + static void set_initial_state() { } + static void reset() { } + static void enter() { } + template + static void dispatch(E const &) { } + }; + + template + struct FsmList + { + using fsmtype = Fsm; + + static void set_initial_state() { + fsmtype::set_initial_state(); + FsmList::set_initial_state(); + } + + static void reset() { + F::reset(); + FsmList::reset(); + } + + static void enter() { + fsmtype::enter(); + FsmList::enter(); + } + + static void start() { + set_initial_state(); + enter(); + } + + template + static void dispatch(E const & event) { + fsmtype::template dispatch(event); + FsmList::template dispatch(event); + } + }; + + // -------------------------------------------------------------------------- + + template struct StateList; + template<> struct StateList<> { + static void reset() { } + }; + template + struct StateList + { + static void reset() { + _state_instance::value = S(); + StateList::reset(); + } + }; + + // -------------------------------------------------------------------------- + + template + struct MooreMachine : tinyfsm::Fsm + { + virtual void entry(void) { }; /* entry actions in some states */ + void exit(void) { }; /* no exit actions */ + }; + + template + struct MealyMachine : tinyfsm::Fsm + { + // input actions are modeled in react(): + // - conditional dependent of event type or payload + // - transit<>(ActionFunction) + void entry(void) { }; /* no entry actions */ + void exit(void) { }; /* no exit actions */ + }; + +} /* namespace tinyfsm */ + + +#define FSM_INITIAL_STATE(_FSM, _STATE) \ +namespace tinyfsm { \ + template<> void Fsm< _FSM >::set_initial_state(void) { \ + current_state_ptr = &_state_instance< _STATE >::value; \ + } \ +} + +#endif /* TINYFSM_HPP_INCLUDED */ diff --git a/test/model/ccu.slx b/test/model/ccu.slx deleted file mode 100644 index dc0770de94b4b5fc9860634482fa6dd2b2cf5810..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82346 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 diff --git a/test/model/untitled.slx b/test/model/untitled.slx deleted file mode 100644 index 6657b567a75679d6062fa0995f1c7a07e290c3a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77597 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%0ABNLPpMf}EBg3sr>V%1#9JCQ;KanJqCn7|t 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 Ol<4E#@7~44Nc=zBVBC=a diff --git a/test/model/untitled.slx.original b/test/model/untitled.slx.original deleted file mode 100644 index 4a8ec29d29ac6b33dbd749d0cc32717330d6a9b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61108 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