Files
gcs-nf/App/ToolsUI/Payload/dev/flare_device.h
T
2026-06-15 08:18:27 +08:00

454 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef FLARE_DEVICE_H
#define FLARE_DEVICE_H
#include <QObject>
#include <QByteArray>
#include <QString>
#include <QVector>
#include <QList>
#include <QtGlobal>
#include <stdexcept>
namespace payload_protocol {
// 干扰弹设备指令类型
enum class FlareCommandType : quint8 {
SAFETY_RELEASE = 0x01, // 投放保险指令
MISSION_TRIGGER = 0x02, // 任务触发指令
MANUAL_TRIGGER = 0x03, // 手动触发指令
SELF_TEST = 0x04, // 设备自检指令
STATUS_QUERY = 0x25 // 状态查询指令
};
// 干扰弹下行报文类型
enum class FlareDownlinkType : quint8 {
STATUS_AUTO = 0xE5 // 状态信息自动下传
};
// 工作状态枚举
enum class FlareWorkStatus : quint8 {
STANDBY = 0x00, // 待机
MISSION_1 = 0x01, // 正在执行任务1
MISSION_2 = 0x02, // 正在执行任务2
MISSION_3 = 0x03, // 正在执行任务3
MISSION_4 = 0x04, // 正在执行任务4
MISSION_5 = 0x05, // 正在执行任务5
MISSION_6 = 0x06, // 正在执行任务6
MISSION_7 = 0x07, // 正在执行任务7
MISSION_8 = 0x08, // 正在执行任务8
MISSION_9 = 0x09, // 正在执行任务9
MISSION_10 = 0x0A, // 正在执行任务10
MISSION_11 = 0x0B, // 正在执行任务11
MISSION_12 = 0x0C, // 正在执行任务12
MISSION_13 = 0x0D, // 正在执行任务13
MISSION_14 = 0x0E, // 正在执行任务14
MISSION_15 = 0x0F, // 正在执行任务15
SELF_TESTING = 0x40, // 正在执行设备自检
MANUAL_TRIGGERING = 0xFF // 正在执行手动触发
};
// 保险状态
enum class SafetyStatus : quint8 {
OFF = 0x00, // 关
ON = 0x01 // 开
};
// 电源电压状态
enum class PowerVoltageStatus : quint8 {
NORMAL = 0x00, // 电压正常
ABNORMAL = 0x01 // 电压异常
};
// 火工开关状态
enum class IgniterStatus : quint8 {
OFF = 0x00, // 火工关
ABNORMAL = 0x01, // 火工异常
ON = 0x03 // 火工开
};
// 自检状态
enum class SelfTestStatus : quint8 {
NOT_TESTED = 0x00, // 上电未自检
NORMAL = 0x01, // 自检正常
ABNORMAL = 0x02 // 自检异常
};
// 干扰弹帧头
constexpr quint8 FLARE_UPLINK_HEADER1 = 0xE8;
constexpr quint8 FLARE_UPLINK_HEADER2 = 0xD7;
constexpr quint8 FLARE_DOWNLINK_HEADER1 = 0xE6;
constexpr quint8 FLARE_DOWNLINK_HEADER2 = 0xD5;
// 干扰弹帧长度
constexpr qint32 FLARE_UPLINK_FRAME_LENGTH = 12; // 上行帧长度
constexpr qint32 FLARE_DOWNLINK_FRAME_LENGTH = 20; // 下行帧长度
// 最大通道数量
constexpr qint32 MAX_FLARE_CHANNELS = 24;
constexpr qint32 MAX_DEVICE_ID = 15;
// 投放保险指令参数
constexpr quint8 SAFETY_ON = 0xAA; // 投放保险开
constexpr quint8 SAFETY_OFF = 0x55; // 投放保险关
// 干扰弹上行指令基础结构
struct FlareUplinkData {
// 字节0-1: 帧头(在序列化时添加)
// 字节2: 指令类型
FlareCommandType command_type;
// 字节3-4: 权限/设备号(16位)
struct {
quint8 reserved_bit : 1; // bit15: 保留位,为0
quint16 device_permissions : 15; // bit14~0: 对应设备ID为15~1的控制权限
} device_permissions;
// 字节5-9: 数据(具体内容取决于指令类型)
QByteArray command_data;
// 字节10: 和校验(在序列化时计算)
// 字节11: 异或校验(在序列化时计算)
FlareUplinkData();
// 序列化为字节流
QByteArray serialize() const;
// 从字节流反序列化
bool deserialize(const QByteArray& data);
// 验证双校验
bool validateChecksum(const QByteArray& data) const;
// 设置设备权限(支持多设备控制)
void setDevicePermissions(quint16 permissions);
// 检查是否具有特定设备权限
bool hasDevicePermission(quint8 device_id) const;
// 添加设备权限
void addDevicePermission(quint8 device_id);
// 移除设备权限
void removeDevicePermission(quint8 device_id);
// 获取设备权限掩码
quint16 getDevicePermissions() const;
};
// 投放保险指令数据结构
struct SafetyReleaseCommand : public FlareUplinkData {
quint8 safety_status; // 投放保险状态:0xAA开,0x55关
SafetyReleaseCommand();
// 设置投放保险状态
void setSafetyStatus(bool on);
// 检查是否为开启命令
bool isSafetyOn() const;
// 检查是否为关闭命令
bool isSafetyOff() const;
// 序列化
QByteArray serialize() const;
// 反序列化
bool deserialize(const QByteArray& data);
};
// 手动触发指令数据结构
struct ManualTriggerCommand : public FlareUplinkData {
quint16 release_interval; // 投放间隔时间,单位ms,范围0-60000
quint32 channel_selection; // 通道选择,24位掩码
ManualTriggerCommand();
// 设置投放间隔时间
void setReleaseInterval(quint16 interval_ms);
// 设置通道选择
void setChannelSelection(quint32 channel_mask);
// 选择特定通道
void selectChannel(quint8 channel);
// 取消选择通道
void deselectChannel(quint8 channel);
// 检查通道是否被选择
bool isChannelSelected(quint8 channel) const;
// 获取选择的通道数量
quint8 getSelectedChannelCount() const;
// 序列化
QByteArray serialize() const;
// 反序列化
bool deserialize(const QByteArray& data);
};
// 设备自检指令数据结构
struct SelfTestCommand : public FlareUplinkData {
SelfTestCommand();
// 序列化
QByteArray serialize() const;
// 反序列化
bool deserialize(const QByteArray& data);
};
// 干扰弹下行状态数据结构
struct FlareDownlinkData {
// 字节0-1: 帧头(在序列化时添加)
// 字节2: 报文类型
FlareDownlinkType message_type;
// 字节3: 当前设备ID
quint8 current_device_id;
// 字节4: 设备硬件通道数量
quint8 hardware_channel_count;
// 字节5: 工作状态
FlareWorkStatus work_status;
// 字节6: 电源电压、火工、保险状态
struct {
quint8 reserved_bits : 3; // bit7~5: 保留
SafetyStatus safety_status : 1; // bit4: 投放保险状态
PowerVoltageStatus power_status : 2; // bit3~2: 电源电压状态
IgniterStatus igniter_status : 2; // bit1~0: 火工开关状态
} status_byte;
// 字节7-8: 任务状态(16位,bit0~14对应任务1~15
quint16 mission_status;
// 字节9: 自检状态
SelfTestStatus self_test_status;
// 字节10-12: 弹状态(24位,bit0~23对应弹1~24
quint32 flare_status;
// 字节13-15: 通道有弹状态(24位,bit0~23对应通道1~24
quint32 channel_loaded_status;
// 字节16-17: 响应帧序号(16位)
quint16 response_frame_number;
// 字节18: 和校验(在序列化时计算)
// 字节19: 异或校验(在序列化时计算)
FlareDownlinkData();
// 序列化为字节流
QByteArray serialize() const;
// 从字节流反序列化
bool deserialize(const QByteArray& data);
// 验证双校验
bool validateChecksum(const QByteArray& data) const;
// 检查任务是否已执行
bool isMissionExecuted(quint8 mission_id) const;
// 设置任务执行状态
void setMissionExecuted(quint8 mission_id, bool executed);
// 检查弹是否正常
bool isFlareNormal(quint8 flare_id) const;
// 设置弹状态
void setFlareStatus(quint8 flare_id, bool normal);
// 检查通道是否有弹
bool isChannelLoaded(quint8 channel_id) const;
// 设置通道有弹状态
void setChannelLoaded(quint8 channel_id, bool loaded);
// 获取工作状态描述
QString getWorkStatusDescription() const;
// 获取状态摘要
QString getStatusSummary() const;
};
// 干扰弹设备类 - 支持信号槽机制
class FlareDevice : public QObject {
Q_OBJECT
public:
explicit FlareDevice(QObject* parent = nullptr);
explicit FlareDevice(quint8 device_id, QObject* parent = nullptr);
// 获取设备ID
quint8 getDeviceId() const { return device_id_; }
// 设置设备ID
void setDeviceId(quint8 id) { device_id_ = id; }
// 创建投放保险指令
QByteArray createSafetyReleaseCommand(quint16 device_permissions, bool safety_on) const;
// 创建手动触发指令
QByteArray createManualTriggerCommand(quint16 device_permissions,
quint16 release_interval,
quint32 channel_selection) const;
// 创建设备自检指令
QByteArray createSelfTestCommand(quint16 device_permissions) const;
// 创建任务触发指令(靶机不使用,但协议中有定义)
QByteArray createMissionTriggerCommand(quint16 device_permissions, quint8 mission_id) const;
// 创建状态查询指令
QByteArray createStatusQueryCommand(quint16 device_permissions) const;
// 解析下行状态数据 - 槽函数
Q_SLOT bool parseStatusData(const QByteArray& data);
// 手动解析状态数据(兼容原有接口)
bool parseStatusData(const QByteArray& data, FlareDownlinkData& downlink_data) const;
// 发送投放保险指令 - 槽函数
Q_SLOT void sendSafetyReleaseCommand(quint16 device_permissions, bool safety_on);
// 发送手动触发指令 - 槽函数
Q_SLOT void sendManualTriggerCommand(quint16 device_permissions,
quint16 release_interval,
quint32 channel_selection);
// 发送设备自检指令 - 槽函数
Q_SLOT void sendSelfTestCommand(quint16 device_permissions);
// 发送原始指令数据 - 槽函数
Q_SLOT void sendRawCommand(const QByteArray& command_data);
// 验证上行帧头
static bool validateUplinkFrameHeader(const QByteArray& data);
// 验证下行帧头
static bool validateDownlinkFrameHeader(const QByteArray& data);
// 计算和校验
static quint8 calculateAdditiveChecksum(const QByteArray& data, qint32 length = 0);
// 计算异或校验
static quint8 calculateXorChecksum(const QByteArray& data, qint32 length = 0);
// 创建设备权限掩码(支持多设备)
static quint16 createDevicePermissions(quint8 device_id);
// 创建多设备权限掩码
static quint16 createMultiDevicePermissions(const QList<quint8>& device_ids);
// 从权限掩码中提取设备ID列表
static QList<quint8> extractDeviceIdsFromPermissions(quint16 permissions);
// 创建通道选择掩码
static quint32 createChannelSelectionMask(const QList<quint8>& channels);
// 从通道掩码中提取通道列表
static QList<quint8> extractChannelsFromMask(quint32 channel_mask);
// 检查通道ID是否有效(1-24)
static bool isValidChannel(quint8 channel_id);
// 检查设备ID是否有效(1-15)
static bool isValidDeviceId(quint8 device_id);
signals:
// 状态更新信号
void statusUpdated(const payload_protocol::FlareDownlinkData& status);
// 保险状态变化信号
void safetyStatusChanged(bool safety_on);
// 弹状态变化信号
void flareStatusChanged(quint8 flare_id, bool normal);
// 通道有弹状态变化信号
void channelLoadedStatusChanged(quint8 channel_id, bool loaded);
// 任务执行状态变化信号
void missionStatusChanged(quint8 mission_id, bool executed);
// 设备连接状态变化信号
void connectionStatusChanged(bool connected);
// 指令发送信号
void commandSent(const QByteArray& command_data);
// 错误信号
void errorOccurred(const QString& error_message);
public slots:
// 设置投放保险状态
Q_SLOT void setSafety(bool on);
// 选择特定通道
Q_SLOT void selectChannel(quint8 channel);
// 取消选择通道
Q_SLOT void deselectChannel(quint8 channel);
// 触发手动投放
Q_SLOT void triggerManualRelease(quint16 release_interval, const QList<quint8>& channels);
// 执行设备自检
Q_SLOT void performSelfTest();
// 请求状态更新
Q_SLOT void requestStatusUpdate();
// 重置设备
Q_SLOT void resetDevice();
private slots:
// 处理内部状态更新
void handleStatusUpdate(const payload_protocol::FlareDownlinkData& status);
private:
quint8 device_id_; // 当前设备ID1-15
// 最后接收到的状态
FlareDownlinkData last_status_;
// 当前保险状态
bool current_safety_status_ = false;
// 当前选择的通道
quint32 selected_channels_ = 0;
// 设置设备权限到指令数据中
void setDevicePermissionsInCommand(QByteArray& command, quint16 permissions) const;
// 创建基础指令帧
QByteArray createBaseCommandFrame(FlareCommandType command_type,
quint16 device_permissions,
const QByteArray& command_data) const;
};
} // namespace payload_protocol
Q_DECLARE_METATYPE(payload_protocol::FlareCommandType)
Q_DECLARE_METATYPE(payload_protocol::FlareDownlinkType)
Q_DECLARE_METATYPE(payload_protocol::FlareWorkStatus)
Q_DECLARE_METATYPE(payload_protocol::SafetyStatus)
Q_DECLARE_METATYPE(payload_protocol::PowerVoltageStatus)
Q_DECLARE_METATYPE(payload_protocol::IgniterStatus)
Q_DECLARE_METATYPE(payload_protocol::SelfTestStatus)
Q_DECLARE_METATYPE(payload_protocol::FlareDownlinkData)
Q_DECLARE_METATYPE(payload_protocol::FlareUplinkData)
Q_DECLARE_METATYPE(payload_protocol::SafetyReleaseCommand)
Q_DECLARE_METATYPE(payload_protocol::ManualTriggerCommand)
Q_DECLARE_METATYPE(payload_protocol::SelfTestCommand)
#endif // FLARE_DEVICE_H