267 lines
8.2 KiB
C++
267 lines
8.2 KiB
C++
#ifndef UV_WARNING_DEVICE_H
|
||
#define UV_WARNING_DEVICE_H
|
||
|
||
#include <QObject>
|
||
#include <QByteArray>
|
||
#include <QString>
|
||
#include <QVector>
|
||
#include <QtGlobal>
|
||
#include <stdexcept>
|
||
|
||
namespace payload_protocol {
|
||
|
||
// 紫外告警设备识别码
|
||
constexpr quint8 UV_WARNING_DEVICE_ID = 0x02;
|
||
|
||
// 紫外告警帧头
|
||
constexpr quint8 UV_HEADER1 = 0xDD;
|
||
constexpr quint8 UV_HEADER2 = 0x77;
|
||
|
||
// 紫外告警帧长度
|
||
constexpr qint32 UV_UPLINK_FRAME_LENGTH = 13; // 上行帧长度
|
||
constexpr qint32 UV_DOWNLINK_FRAME_LENGTH = 30; // 下行帧长度
|
||
|
||
// 目标位置枚举
|
||
enum class TargetPosition : quint8 {
|
||
NO_TARGET = 0b00, // 无目标
|
||
LEFT_FIELD = 0b01, // 左侧视场
|
||
RIGHT_FIELD = 0b10, // 右侧视场
|
||
CENTER_FIELD = 0b00 // 中间视场(bit2~bit1为00时)
|
||
};
|
||
|
||
// 曝光模式
|
||
enum class ExposureMode : quint8 {
|
||
AUTO = 0,
|
||
MANUAL = 1
|
||
};
|
||
|
||
// 对比度模式
|
||
enum class ContrastMode : quint8 {
|
||
AUTO = 0,
|
||
MANUAL = 1
|
||
};
|
||
|
||
// Gamma模式
|
||
enum class GammaMode : quint8 {
|
||
OFF = 0,
|
||
ON = 1
|
||
};
|
||
|
||
// 动态范围压缩模式
|
||
enum class DynamicRangeMode : quint8 {
|
||
OFF = 0,
|
||
ON = 1
|
||
};
|
||
|
||
// 紫外告警下行数据结构(设备 -> 飞控)
|
||
struct UvDownlinkData {
|
||
// 字节0-1: 帧头(在序列化时添加)
|
||
|
||
// 字节2: 设备识别码
|
||
quint8 device_id = UV_WARNING_DEVICE_ID;
|
||
|
||
// 字节3: 告警标志字节
|
||
struct {
|
||
quint8 has_target : 1; // bit0: 1有目标,0无目标
|
||
quint8 target_position : 2; // bit2~bit1: 目标位置
|
||
quint8 reserved : 5; // bit7~bit3: 保留
|
||
} warning_flags;
|
||
|
||
// 字节4-6: 积分时间(3字节)
|
||
quint32 integration_time; // 24位
|
||
|
||
// 字节7-8: 图像平均亮度(2字节)
|
||
quint16 average_brightness;
|
||
|
||
// 字节9: 设备状态1
|
||
struct {
|
||
quint8 exposure_mode : 1; // bit0: 1自动曝光,0手动曝光
|
||
quint8 contrast_mode : 1; // bit1: 1自动对比度,0手动对比度
|
||
quint8 gamma_mode : 1; // bit2: 1GAMMA开启,0GAMMA关闭
|
||
quint8 dynamic_range_mode : 1; // bit3: 1动态范围压缩开启,0关闭
|
||
quint8 tracker_serial_status : 1; // bit4: 1跟踪器串口正常,0异常
|
||
quint8 camera_serial_status : 1; // bit5: 1相机串口正常,0异常
|
||
quint8 flight_controller_status : 1; // bit6: 1飞控串口正常,0异常
|
||
quint8 image_output_status : 1; // bit7: 1图像输出正常,0异常
|
||
} device_status1;
|
||
|
||
// 字节10: 设备状态2 - 当前检测目标强度阈值
|
||
quint8 intensity_threshold;
|
||
|
||
// 字节11: 设备状态3 - 当前检测范围阈值
|
||
quint8 range_threshold;
|
||
|
||
// 字节12-28: 保留(17字节)
|
||
QByteArray reserved_bytes;
|
||
|
||
// 字节29: 校验和(在序列化时计算)
|
||
|
||
UvDownlinkData();
|
||
|
||
// 序列化为字节流
|
||
QByteArray serialize() const;
|
||
|
||
// 从字节流反序列化
|
||
bool deserialize(const QByteArray& data);
|
||
|
||
// 验证校验和
|
||
bool validateChecksum(const QByteArray& data) const;
|
||
|
||
// 检查是否触发告警(用于飞控判断)
|
||
bool shouldTriggerAlarm(quint8 set_intensity_threshold, quint8 set_range_threshold) const;
|
||
|
||
// 获取目标位置
|
||
TargetPosition getTargetPosition() const;
|
||
|
||
// 设置目标位置
|
||
void setTargetPosition(TargetPosition position, bool has_target);
|
||
};
|
||
|
||
// 紫外告警上行数据结构(飞控 -> 设备)
|
||
struct UvUplinkData {
|
||
// 字节0-1: 帧头(在序列化时添加)
|
||
|
||
// 字节2: 设备识别码
|
||
quint8 device_id = UV_WARNING_DEVICE_ID;
|
||
|
||
// 字节3: 告警设备命令字节
|
||
struct {
|
||
quint8 exposure_mode : 1; // bit0: 0自动曝光,1手动曝光
|
||
quint8 contrast_mode : 1; // bit1: 0自动对比度,1手动对比度
|
||
quint8 gamma_mode : 1; // bit2: 1GAMMA开启,0GAMMA关闭
|
||
quint8 dynamic_range_mode : 1; // bit3: 1动态范围压缩开启,0关闭
|
||
quint8 exposure_increase : 1; // bit4: 1曝光时间加100微秒
|
||
quint8 exposure_decrease : 1; // bit5: 1曝光时间减100微秒
|
||
quint8 set_intensity_threshold : 1; // bit6: 1设置强度阈值
|
||
quint8 set_range_threshold : 1; // bit7: 1设置范围阈值
|
||
} command_byte;
|
||
|
||
// 字节4: 强度档位参数(配合command_byte.bit6)
|
||
quint8 intensity_level;
|
||
|
||
// 字节5: 范围档位参数(配合command_byte.bit7)
|
||
quint8 range_level;
|
||
|
||
// 字节6-11: 保留(6字节)
|
||
QByteArray reserved_bytes;
|
||
|
||
// 字节12: 校验和(在序列化时计算)
|
||
|
||
UvUplinkData();
|
||
|
||
// 序列化为字节流
|
||
QByteArray serialize() const;
|
||
|
||
// 从字节流反序列化
|
||
bool deserialize(const QByteArray& data);
|
||
|
||
// 验证校验和
|
||
bool validateChecksum(const QByteArray& data) const;
|
||
|
||
// 设置曝光调整命令
|
||
void setExposureAdjustment(bool increase);
|
||
|
||
// 设置阈值命令
|
||
void setThresholds(quint8 intensity, quint8 range, bool set_intensity, bool set_range);
|
||
|
||
// 检查命令是否有效
|
||
bool isCommandValid() const;
|
||
};
|
||
|
||
// 紫外告警设备类 - 支持信号槽机制
|
||
class UvWarningDevice : public QObject {
|
||
Q_OBJECT
|
||
|
||
public:
|
||
explicit UvWarningDevice(QObject* parent = nullptr);
|
||
explicit UvWarningDevice(quint8 device_number, QObject* parent = nullptr);
|
||
|
||
// 获取设备编号
|
||
quint8 getDeviceNumber() const { return device_number_; }
|
||
|
||
// 设置设备编号
|
||
void setDeviceNumber(quint8 number) { device_number_ = number; }
|
||
|
||
// 创建控制指令(上行数据)
|
||
QByteArray createControlCommand(const UvUplinkData& uplink_data) const;
|
||
|
||
// 解析状态数据(下行数据) - 槽函数
|
||
Q_SLOT bool parseStatusData(const QByteArray& data);
|
||
|
||
// 手动解析状态数据(兼容原有接口)
|
||
bool parseStatusData(const QByteArray& data, UvDownlinkData& downlink_data) const;
|
||
|
||
// 发送控制指令 - 槽函数
|
||
Q_SLOT void sendControlCommand(const UvUplinkData& uplink_data);
|
||
|
||
// 发送原始指令数据 - 槽函数
|
||
Q_SLOT void sendRawCommand(const QByteArray& command_data);
|
||
|
||
// 验证帧头
|
||
static bool validateFrameHeader(const QByteArray& data);
|
||
|
||
// 验证设备识别码
|
||
static bool validateDeviceId(const QByteArray& data);
|
||
|
||
// 创建全控指令(设备编号为0x00)
|
||
static QByteArray createBroadcastCommand(const UvUplinkData& uplink_data);
|
||
|
||
// 计算校验和(用于紫外告警协议)
|
||
static quint8 calculateChecksum(const QByteArray& data, qint32 length = 0);
|
||
|
||
signals:
|
||
// 状态更新信号
|
||
void statusUpdated(const payload_protocol::UvDownlinkData& status);
|
||
|
||
// 告警触发信号
|
||
void alarmTriggered(const payload_protocol::UvDownlinkData& status,
|
||
quint8 set_intensity_threshold,
|
||
quint8 set_range_threshold);
|
||
|
||
// 目标检测信号
|
||
void targetDetected(payload_protocol::TargetPosition position);
|
||
|
||
// 设备连接状态变化信号
|
||
void connectionStatusChanged(bool connected);
|
||
|
||
// 指令发送信号
|
||
void commandSent(const QByteArray& command_data);
|
||
|
||
// 错误信号
|
||
void errorOccurred(const QString& error_message);
|
||
|
||
public slots:
|
||
// 设置告警阈值
|
||
Q_SLOT void setAlarmThresholds(quint8 intensity_threshold, quint8 range_threshold);
|
||
|
||
// 重置设备
|
||
Q_SLOT void resetDevice();
|
||
|
||
// 请求状态更新
|
||
Q_SLOT void requestStatusUpdate();
|
||
|
||
private slots:
|
||
// 处理内部状态更新
|
||
void handleStatusUpdate(const payload_protocol::UvDownlinkData& status);
|
||
|
||
private:
|
||
quint8 device_number_; // 设备编号:0x00=全控,0x01=1号设备,0x02=2号设备...
|
||
|
||
// 告警阈值
|
||
quint8 intensity_threshold_ = 50;
|
||
quint8 range_threshold_ = 30;
|
||
|
||
// 最后接收到的状态
|
||
UvDownlinkData last_status_;
|
||
|
||
// 在控制数据中插入设备编号
|
||
void insertDeviceNumber(QByteArray& data) const;
|
||
};
|
||
|
||
} // namespace payload_protocol
|
||
|
||
Q_DECLARE_METATYPE(payload_protocol::TargetPosition)
|
||
Q_DECLARE_METATYPE(payload_protocol::UvDownlinkData)
|
||
Q_DECLARE_METATYPE(payload_protocol::UvUplinkData)
|
||
|
||
#endif // UV_WARNING_DEVICE_H
|