ard-work/src/main/java/com/ard/tianyu/controller/UavController.java
@@ -4,6 +4,9 @@ import com.ard.tianyu.model.dto.BoxHistoryDTO; import com.ard.tianyu.model.dto.BoxPhotosDTO; import com.ard.tianyu.model.dto.BoxSettingsDTO; import com.ard.tianyu.model.dto.signal.SignalInfo; import com.ard.tianyu.model.dto.state.UavState; import com.ard.tianyu.model.dto.telemetry.TelemetryData; import com.ard.tianyu.model.receiver.BoxHistoryReceiver; import com.ard.tianyu.model.receiver.BoxPhotosReceiver; import com.ard.tianyu.model.receiver.BoxInfoReceiver; @@ -63,22 +66,46 @@ List<BoxPhotosReceiver> boxPhotos = tyService.getBoxPhotos(boxPhotosDTO); return AjaxResult.success(boxPhotos); } @ApiOperation("修改云盒设置") @PostMapping("/updateBoxSettings") public AjaxResult updateBoxSettings(@RequestBody BoxSettingsDTO boxSettingsDTO) { Boolean state = tyService.updateBoxSettings(boxSettingsDTO); return AjaxResult.success(state); } @ApiOperation("无人机控制订阅") @GetMapping("/uavControlSubscribe") public AjaxResult uavControlSubscribe(String boxSn) { tyService.uavControlSubscribe(boxSn); return AjaxResult.success(); } @ApiOperation("云台转动(基于角度)") @GetMapping("/controlAngle") public AjaxResult controlAngle(String boxSn) { tyService.controlAngle(boxSn); public AjaxResult controlAngle(String boxSn,Integer actionId,Integer rotationAngle) { tyService.controlAngle(boxSn,actionId,rotationAngle); return AjaxResult.success(); } @ApiOperation("获取无人机状态") @GetMapping("/getUavState") public AjaxResult getUavState(String boxSn) { UavState uavState = tyService.getUavState(boxSn); return AjaxResult.success(uavState); } @ApiOperation("获取无人机遥测数据") @GetMapping("/getUavTelemetryData") public AjaxResult getUavTelemetryData(String boxSn) { TelemetryData telemetryData = tyService.getUavTelemetryData(boxSn); return AjaxResult.success(telemetryData); } @ApiOperation("获取无人机信道质量数据") @GetMapping("/getSignalInfo") public AjaxResult getSignalInfo(String boxSn) { SignalInfo signalInfo = tyService.getSignalInfo(boxSn); return AjaxResult.success(signalInfo); } } ard-work/src/main/java/com/ard/tianyu/model/cache/UavSignalInfoCache.java
New file @@ -0,0 +1,32 @@ package com.ard.tianyu.model.cache; import com.ard.tianyu.model.dto.signal.SignalInfo; import java.util.concurrent.ConcurrentHashMap; /** * 无人机遥测数据缓存 * * @author 刘苏义 * @date 2024/10/24 8:55 */ public class UavSignalInfoCache { // 使用 ConcurrentHashMap 来缓存无人机信道质量数据,key 是 boxSn(无人机序列号) private static final ConcurrentHashMap<String, SignalInfo> uavSignalInfoCache = new ConcurrentHashMap<>(); // 存储无人机信道质量数据到缓存 public static void putUavSignalInfoCache(SignalInfo signalInfo) { uavSignalInfoCache.put(signalInfo.getBoxSn(), signalInfo); } // 从缓存中获取信道质量数据 public static SignalInfo getUavSignalInfo(String boxSn) { return uavSignalInfoCache.get(boxSn); } // 删除缓存中的信道质量数据 public static void removeUavSignalInfo(String boxSn) { uavSignalInfoCache.remove(boxSn); } } ard-work/src/main/java/com/ard/tianyu/model/cache/UavStateCache.java
New file @@ -0,0 +1,31 @@ package com.ard.tianyu.model.cache; import com.ard.tianyu.model.dto.state.UavState; import java.util.concurrent.ConcurrentHashMap; /** * 无人机状态缓存 * * @author 刘苏义 * @date 2024/10/24 8:55 */ public class UavStateCache { // 使用 ConcurrentHashMap 来缓存无人机状态数据,key 是 boxSn(无人机序列号) private static final ConcurrentHashMap<String, UavState> uavStateCache = new ConcurrentHashMap<>(); // 存储无人机状态数据到缓存 public static void putUavState(UavState uavState) { uavStateCache.put(uavState.getBoxSn(), uavState); } // 从缓存中获取无人机状态数据 public static UavState getUavState(String boxSn) { return uavStateCache.get(boxSn); } // 删除缓存中的无人机状态数据 public static void removeUavState(String boxSn) { uavStateCache.remove(boxSn); } } ard-work/src/main/java/com/ard/tianyu/model/cache/UavTelemetryDataCache.java
New file @@ -0,0 +1,33 @@ package com.ard.tianyu.model.cache; import com.ard.tianyu.model.dto.state.UavState; import com.ard.tianyu.model.dto.telemetry.TelemetryData; import java.util.concurrent.ConcurrentHashMap; /** * 无人机遥测数据缓存 * * @author 刘苏义 * @date 2024/10/24 8:55 */ public class UavTelemetryDataCache { // 使用 ConcurrentHashMap 来缓存无人机遥测数据,key 是 boxSn(无人机序列号) private static final ConcurrentHashMap<String, TelemetryData> uavTelemetryDataCache = new ConcurrentHashMap<>(); // 存储无人机遥测数据到缓存 public static void putUavTelemetryData(TelemetryData telemetryData) { uavTelemetryDataCache.put(telemetryData.getBoxSn(), telemetryData); } // 从缓存中获取无人机遥测数据 public static TelemetryData getUavTelemetryData(String boxSn) { return uavTelemetryDataCache.get(boxSn); } // 删除缓存中的无人机遥测数据 public static void removeUavTelemetryData(String boxSn) { uavTelemetryDataCache.remove(boxSn); } } ard-work/src/main/java/com/ard/tianyu/model/dto/converter/UavSignalInfoConverter.java
New file @@ -0,0 +1,19 @@ package com.ard.tianyu.model.dto.converter; import com.ard.tianyu.model.dto.signal.SignalInfo; import com.ard.tianyu.netty.protobuf.TelemetryDataPB; import org.springframework.beans.BeanUtils; /** * SignalInfoConverter * * @author liusuyi * @date 2024年10月24日10:38 **/ public class UavSignalInfoConverter { public static SignalInfo convertProtoToEntity(TelemetryDataPB.SignalInfo proto) { SignalInfo signalInfo = new SignalInfo(); BeanUtils.copyProperties(proto, signalInfo); return signalInfo; } } ard-work/src/main/java/com/ard/tianyu/model/dto/converter/UavStateConverter.java
New file @@ -0,0 +1,139 @@ package com.ard.tianyu.model.dto.converter; import com.ard.tianyu.model.dto.state.*; import com.ard.tianyu.netty.protobuf.TelemetryDataPB; import org.springframework.beans.BeanUtils; import java.util.List; import java.util.stream.Collectors; public class UavStateConverter { // 将 Protobuf UavState 转换为 Java 实体类 UavState public static UavState convertProtoToEntity(TelemetryDataPB.UavState protobufUavState) { UavState uavState = new UavState(); // 复制简单字段 uavState.setBoxSn(protobufUavState.getBoxSn()); // 处理嵌套的 FlightControllerState if (protobufUavState.hasFlightControllerState()) { uavState.setFlightControllerState(convertFlightControllerState(protobufUavState.getFlightControllerState())); } // 处理嵌套的 BatteryState if (protobufUavState.hasBatteryState()) { uavState.setBatteryState(convertBatteryState(protobufUavState.getBatteryState())); } // 处理嵌套的 PtzState if (protobufUavState.hasPtzState()) { uavState.setPtzState(convertPtzState(protobufUavState.getPtzState())); } // 处理嵌套的 CameraState if (protobufUavState.hasCameraState()) { uavState.setCameraState(convertCameraState(protobufUavState.getCameraState())); } // 处理嵌套的 MissionState if (protobufUavState.hasMissionState()) { uavState.setMissionState(convertMissionState(protobufUavState.getMissionState())); } // 处理 AvoidanceData if (protobufUavState.hasAvoidanceData()) { uavState.setAvoidanceData(convertAvoidanceData(protobufUavState.getAvoidanceData())); } // 处理 List<HmsAlarmData> List<HmsAlarmData> hmsAlarmDataList = protobufUavState.getHmsAlarmDataList().stream() .map(UavStateConverter::convertHmsAlarmData) .collect(Collectors.toList()); uavState.setHmsAlarmData(hmsAlarmDataList); return uavState; } // 其他转换方法如下: // 处理 BatteryState 逻辑 public static BatteryState convertBatteryState(TelemetryDataPB.BatteryState protobufBatteryState) { BatteryState batteryState = new BatteryState(); // 复制简单字段 batteryState.setBatteryNum(protobufBatteryState.getBatteryNum()); batteryState.setBatteryPower(protobufBatteryState.getBatteryPower()); batteryState.setBatteryVoltage(protobufBatteryState.getBatteryVoltage()); // 处理嵌套的 BatteryStateInfo if (protobufBatteryState.hasFirstBatteryInfo()) { batteryState.setFirstBatteryInfo(convertBatteryStateInfo(protobufBatteryState.getFirstBatteryInfo())); } if (protobufBatteryState.hasSecondBatteryInfo()) { batteryState.setSecondBatteryInfo(convertBatteryStateInfo(protobufBatteryState.getSecondBatteryInfo())); } return batteryState; } // 处理 BatteryStateInfo 逻辑 public static BatteryStateInfo convertBatteryStateInfo(TelemetryDataPB.BatteryStateInfo protobufBatteryStateInfo) { BatteryStateInfo batteryStateInfo = new BatteryStateInfo(); BeanUtils.copyProperties(protobufBatteryStateInfo, batteryStateInfo); return batteryStateInfo; } // 处理 FlightControllerState 逻辑 public static FlightControllerState convertFlightControllerState(TelemetryDataPB.FlightControllerState proto) { FlightControllerState flightControllerState = new FlightControllerState(); // 处理 PointData(起飞点和返航点) if (proto.hasStartPoint()) { flightControllerState.setStartPoint(convertPointData(proto.getStartPoint())); } if (proto.hasHomePoint()) { flightControllerState.setHomePoint(convertPointData(proto.getHomePoint())); } BeanUtils.copyProperties(proto, flightControllerState); return flightControllerState; } // 处理 PointData 逻辑 public static PointData convertPointData(TelemetryDataPB.PointData protoPoint) { PointData pointData = new PointData(); pointData.setLat(protoPoint.getLat()); pointData.setLng(protoPoint.getLng()); return pointData; } public static PtzState convertPtzState(TelemetryDataPB.PtzState proto) { PtzState ptzState = new PtzState(); BeanUtils.copyProperties(proto, ptzState); return ptzState; } public static CameraState convertCameraState(TelemetryDataPB.CameraState proto) { CameraState cameraState = new CameraState(); BeanUtils.copyProperties(proto, cameraState); return cameraState; } public static MissionState convertMissionState(TelemetryDataPB.MissionState proto) { MissionState missionState = new MissionState(); BeanUtils.copyProperties(proto, missionState); return missionState; } public static AvoidanceData convertAvoidanceData(TelemetryDataPB.AvoidanceData proto) { AvoidanceData avoidanceData = new AvoidanceData(); BeanUtils.copyProperties(proto, avoidanceData); return avoidanceData; } public static HmsAlarmData convertHmsAlarmData(TelemetryDataPB.HmsAlarmData proto) { HmsAlarmData hmsAlarmData = new HmsAlarmData(); BeanUtils.copyProperties(proto, hmsAlarmData); return hmsAlarmData; } } ard-work/src/main/java/com/ard/tianyu/model/dto/converter/UavTelemetryDataConverter.java
New file @@ -0,0 +1,20 @@ package com.ard.tianyu.model.dto.converter; import com.ard.tianyu.model.dto.state.UavState; import com.ard.tianyu.model.dto.telemetry.TelemetryData; import com.ard.tianyu.netty.protobuf.TelemetryDataPB; import org.springframework.beans.BeanUtils; /** * UavTelemetryDataConverter * * @author liusuyi * @date 2024年10月24日10:38 **/ public class UavTelemetryDataConverter { public static TelemetryData convertProtoToEntity(TelemetryDataPB.TelemetryData proto) { TelemetryData telemetryData = new TelemetryData(); BeanUtils.copyProperties(proto, telemetryData); return telemetryData; } } ard-work/src/main/java/com/ard/tianyu/model/dto/init/UavInitInfo.java
New file @@ -0,0 +1,16 @@ package com.ard.tianyu.model.dto.init; import lombok.Builder; import lombok.Data; @Data @Builder public class UavInitInfo { private String uavModel; // 无人机型号 private String uavSn; // 无人机SN private String uavVersion; // 无人机固件版本号 private String ptModel; // 挂载相机型号 private String ptVersion; // 挂载相机固件版本号 private int ptPosition; // 挂载相机psdk日位置 private String moduleVersion; // 模组固件版本号 } ard-work/src/main/java/com/ard/tianyu/model/dto/signal/SignalInfo.java
New file @@ -0,0 +1,74 @@ package com.ard.tianyu.model.dto.signal; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class SignalInfo { private String mode; // 入网模式: NR5G-SA, NR5G-NSA,LTE private String mcc; // NR5G-SA, NR5G-NSA, LTE private String mnc; // NR5G-SA, NR5G-NSA, LTE private String cellid; // NR5G-SA, LTE private String pcid; // NR5G-SA, NR5G-NSA, LTE private String tac; // NR5G-SA, LTE private String arfcn; // NR5G-SA, NR5G-NSA private String band; // NR5G-SA, NR5G-NSA @JsonProperty("nr_dl_bandwidth") private String nrDlBandwidth; // NR5G-SA private String rsrp; // NR5G-SA, NR5G-NSA, LTE private String rsrq; // NR5G-SA, NR5G-NSA, LTE private String sinr; // NR5G-SA, NR5G-NSA, LTE @JsonProperty("tx_power") private String txPower; // NR5G-SA, LTE private String srxlev; // NR5G-SA, LTE private String cqi; // LTE private String earfcn; // LTE @JsonProperty("freq_band_ind") private String freqBandInd; // LTE @JsonProperty("ul_bandwidth") private String ulBandwidth; // LTE @JsonProperty("dl_bandwidth") private String dlBandwidth; // LTE @JsonProperty("is_tdd") private String isTdd; // LTE private String rssi; // LTE @JsonProperty("duplex_mode") private String duplexMode; // NR5G-SA private double lng; // 经度 private double lat; // 纬度 private float height; // 高度(单位:米) private int timestamp; // 时间戳(单位:秒) private int boxstate; // 1=线缆故障,2=OSDK未激活,3=正常,4=云盒固件更新 private String isp; // 运营商 private int tempMax; // 模组芯片温度(单位:摄氏度) @JsonProperty("prx_rsrp") private String prxRsrp; // prx路径的rsrp值 @JsonProperty("drx_rsrp") private String drxRsrp; // drx路径的rsrp值 @JsonProperty("rx2_rsrp") private String rx2Rsrp; // rx2路径的rsrp值 @JsonProperty("rx3_rsrp") private String rx3Rsrp; // rx3路径的rsrp值 @JsonProperty("box_sn") private String boxSn; // 云盒编号 @JsonProperty("sim_use_seat") private int simUseSeat; // 当前使用的SIM卡在卡槽中的位置:1或2 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/AvoidanceData.java
New file @@ -0,0 +1,23 @@ package com.ard.tianyu.model.dto.state; import lombok.Data; // 避障数据类 @Data public class AvoidanceData { private int downHealth; // 下方健康状态 private float down; // 距下障碍物的距离(单位:米),downHealth 为 1 时值有效 private int frontHealth; // 前方健康状态 private float front; // 距前障碍物的距离(单位:米),frontHealth 为 1 时值有效 private int rightHealth; // 右方健康状态 private float right; // 距右障碍物的距离(单位:米),rightHealth 为 1 时值有效 private int backHealth; // 后方健康状态 private float back; // 距后障碍物的距离(单位:米),backHealth 为 1 时值有效 private int leftHealth; // 左方健康状态 private float left; // 距左障碍物的距离(单位:米),leftHealth 为 1 时值有效 private int upHealth; // 上方健康状态 private float up; // 距上障碍物的距离(单位:米),upHealth 为 1 时值有效 private int avoidanceEnableStatusDown; // 下视觉避障开关状态:0-关闭,1-打开 private int avoidanceEnableStatusUp; // 上视觉避障开关状态:0-关闭,1-打开 private int avoidanceEnableStatusHorizontal; // 水平视觉避障开关状态:0-关闭,1-打开 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/BatteryState.java
New file @@ -0,0 +1,19 @@ package com.ard.tianyu.model.dto.state; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class BatteryState { private int batteryNum; // 电池数量 private String batteryPower; // 电池电量,多个电池用下划线分割 private String batteryVoltage; // 电池电压,多个电池用下划线分割(单位: V) private BatteryStateInfo firstBatteryInfo; // 第一块电池状态信息 private BatteryStateInfo secondBatteryInfo; // 第二块电池状态信息 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/BatteryStateInfo.java
New file @@ -0,0 +1,30 @@ package com.ard.tianyu.model.dto.state; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * BatteryStateDto * * @author liusuyi * @date 2024年10月24日9:45 **/ @Data @AllArgsConstructor @NoArgsConstructor public class BatteryStateInfo { private int isBatteryEmbed; // 电池插入飞机状态:0=插入,1=未插入 private int batteryCapacityPercent; // 电池电量百分比 private int currentVoltage; // 电池电压 (单位: mV) private int currentElectric; // 当前电池电流 (单位: mA) private int fullCapacity; // 满电池容量 (单位: mAh) private int remainedCapacity; // 剩余电池容量 (单位: mAh) private float batteryTemperature; // 电池温度 (单位: 摄氏度) private int cellCount; // 电池组数 private int batSOHState; // 电池循环健康状态:0=正常,1=警报,2=注意安全 private int sop; // 相对功率百分比 (Relative power percentage) private int heatState; // 电池加热状态:0=未加热,1=加热中,2=保持恒温 private int socState; // 电池 SOC 荷电状态:0=正常,1=高,2=下降,3=上升,4=无效 private int selfCheckError; // 电池自检错误标志:0=正常,其他值表示错误 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/CameraState.java
New file @@ -0,0 +1,21 @@ package com.ard.tianyu.model.dto.state; import lombok.Data; // 相机状态类 @Data public class CameraState { private int mode; // 相机模式:1=拍照模式,2=录像模式,0=未知 private int isRecording; // 是否录制中:1=录制中,0=未录制 private int recordDuration; // 录制时长(单位:秒) private int source; // 相机视源:0=可见,1=变焦,2=红外 private int camera; // 相机:0=FPV,1=相机(1),2=相机(2) private float zoomFactor; // 相机当前变焦倍数 private int width; // 水平像素(例如:1920) private int height; // 垂直像素(例如:1080) private int frameRate; // 帧率(例如:30) private int bitstream; // 码率(单位:0.001)(例如:6兆设置值为6000) private int pointThermometrying; // 单点测温状态:0=非单点测温中,1=单点测温中 private int areaThermometrying; // 区域测温状态:0=非区域测温中,1=区域测温中 private int laserRanging; // 激光测距状态:0=非激光测距中,1=激光测距中 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/FlightControllerState.java
New file @@ -0,0 +1,23 @@ package com.ard.tianyu.model.dto.state; import lombok.Data; @Data public class FlightControllerState { private int satelliteCount; // 卫星计数 private int gpsSignalLevel; // GPS信号级别 (0-5) private int flightMode; // 飞行模式 private int flightStatus; // 飞行状态 private PointData startPoint; // 起飞点(包含经纬度) private PointData homePoint; // 返航点(包含经纬度) private int homeHeight; // 返航高度(单位:米) private int safeLine; // 飞行模式安全线 private int deviceStatus; // 控制权状态 private int uwbNodeCount; // UWB星数 private String rcMode; // 遥控器档位模式 private int isEmergencyBraking; // 是否紧急制动中 private int outFlyAreaFlag; // 是否在电子围栏外 private int inNoFlyAreaFlag; // 是否在禁飞区内 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/HmsAlarmData.java
New file @@ -0,0 +1,11 @@ package com.ard.tianyu.model.dto.state; import lombok.Data; // Hms报警信息类 @Data public class HmsAlarmData { private int alarmId; // 报警信息ID private int reportLevel; // 等级 [1/2-警告 3/4/5-错误] private String alarmMssInfo; // 报警信息描述(支持中文和英文版本,默认中文,如需切换请联系技术支持) } ard-work/src/main/java/com/ard/tianyu/model/dto/state/MissionState.java
New file @@ -0,0 +1,22 @@ package com.ard.tianyu.model.dto.state; import lombok.Data; // 任务状态类 @Data public class MissionState { private int isPause; // 航线是否暂停中:0=未暂停,1=暂停中 private int targetWaypointIndex; // 目标航点下标 private int isWaypointFinished; // 是否航点完成:1完成、0未完成(此值废弃) private int pushVideo; // 云盒是否发送视频数据:0=不发送,1=发送 private int lock4g; // 是否锁定4G:0=不锁定,1=锁定 private int boxModel; // 是否开通图片自动回传功能:0=未开通,1=已开通 private int mapPlay; // 自动拍照间隔:0未开始,3~255间隔时间 private int loseAction; // 网络失联后动作:0=返回HOME点,1=继续航线 private int isPointControl; // 是否打点飞行控制中:0=否,1=是 private int isUwbLanding; // 是否UWB精准降落中:0=不是,1=是 private int isPushVideoing; // 视频是否推流中:0=不是,1=是 private int isDLanding; // 是否二维码精准降落中:0=不是,1=是 private int perceptionFlag; // 二维码精准降落模式:0=载荷降落,1=下视降落 private int isPositionControl; // 是否指定距离飞行控制中:0=否,1=是 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/PointData.java
New file @@ -0,0 +1,10 @@ package com.ard.tianyu.model.dto.state; import lombok.Data; // 假设 PointData 类定义如下 @Data public class PointData { private double lat; // 纬度 private double lng; // 经度 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/PtzState.java
New file @@ -0,0 +1,12 @@ package com.ard.tianyu.model.dto.state; import lombok.Data; // 云台状态类 @Data public class PtzState { private float pitch; // 俯仰角,范围:-120° ~ 30° private float roll; // 横滚角,范围:-90° ~ 60° private float yaw; // 偏航角,范围:-180° ~ 180° private int gimbalMode; // 云台模式:1=自由模式,2=跟随模式,3=FPV模式 } ard-work/src/main/java/com/ard/tianyu/model/dto/state/UavState.java
New file @@ -0,0 +1,24 @@ package com.ard.tianyu.model.dto.state; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class UavState { private FlightControllerState flightControllerState; // 飞控状态 private BatteryState batteryState; // 电池状态 private PtzState ptzState; // 云台状态 private CameraState cameraState; // 相机状态 private MissionState missionState; // 任务状态 private String boxSn; // 云盒编号 private AvoidanceData avoidanceData; // 避障数据 private List<HmsAlarmData> hmsAlarmData; // HMS报警信息 (飞机告警信息) } ard-work/src/main/java/com/ard/tianyu/model/dto/telemetry/TelemetryData.java
New file @@ -0,0 +1,46 @@ package com.ard.tianyu.model.dto.telemetry; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class TelemetryData { private double lng; // 经度 private double lat; // 纬度 private float altitude; // 海拔高度 (椭球高) (单位: 米) private float ultrasonic; // 相对高度 (单位: 米) private float pitch; // 俯仰角 private float roll; // 横滚角 private float yaw; // 偏航角 private float airspeed; // 空速 (单位: 米/秒) private float velocity; // 地速 (单位: 米/秒) private long timestamp; // 时间戳 private float ptpitch; // 载荷俯仰角 private float ptroll; // 载荷横滚角 private float ptyaw; // 载荷航向角 private float zoomfactor; // 载荷当前倍数 private String boxSn; // 云盒编号 private String batteryPower; // 电池电量 (多个电池以下划线分割) private int satelliteCount; // 卫星计数 private long taskId; // 任务编号 private double rtkLng; // RTK 经度 private double rtkLat; // RTK 纬度 private float rtkHFSL; // RTK 海拔高度 (平均海平面高度) (单位: 米) private int rtkPositionInfo; // RTK 状态 private int airFlyTimes; // 当前架次飞行时长 (单位: 秒) private float airFlyDistance; // 当前架次飞行实际距离 (单位: 米) private String uavSn; // 无人机编号 private String uavModel; // 无人机型号 private float homeRange; // 距降落点水平直线距离 (单位: 米) private int flightMode; // 飞行模式 private float targetDistance; // 距目标点实际距离 (单位: 米) private int predictFlyTime; // 预计剩余飞行时间 private float ultrasonicMax; // 本架次最大相对高度值 private float ultrasonicMin; // 本架次最小相对高度值 } ard-work/src/main/java/com/ard/tianyu/netty/command/ControlAngleCommand.java
@@ -32,16 +32,16 @@ public short getDataLength() { // 计算数据长度: 云盒编号 + 指令编号 + 加密标志 + 动作编号 + 转动角度 return (short) (2 + 15 + 1 + 1 + 1); // 帧头 + 数据内容 return (short) (1 + 15 + 1 + 1 + 1); // 帧头 + 数据内容 } public void encode(ByteBuf out) { out.writeShort(getDataHeader()); // 写入帧头 out.writeShort(getDataLength()); // 写入数据长度 out.writeBytes(boxSn); // 写入云盒编号 out.writeByte(getCmdCode()); // 写入指令编号 out.writeBytes(boxSn); // 写入云盒编号 out.writeByte(encryptFlag); // 写入加密标志 out.writeByte(actionId); // 写入动作编号 out.writeByte(rotationAngle); // 写入转动角度 out.writeByte(encryptFlag); // 写入加密标志 out.writeByte(actionId); // 写入动作编号 out.writeByte(rotationAngle); // 写入转动角度 } } ard-work/src/main/java/com/ard/tianyu/netty/command/DroneReadyNotificationCommand.java
New file @@ -0,0 +1,31 @@ package com.ard.tianyu.netty.command; import com.ard.tianyu.netty.protobuf.TelemetryDataPB; import io.netty.buffer.ByteBuf; import lombok.Data; /** * 无人机就绪通知命令 * * @author 刘苏义 * @date 2024/10/24 17:18 */ @Data public class DroneReadyNotificationCommand extends BaseCommand { private byte actionCode; private TelemetryDataPB.UavInitInfo uavInitInfo; public DroneReadyNotificationCommand(TelemetryDataPB.UavInitInfo uavInitInfo, byte actionCode) { setDataHeader((short) 0x6A77); // 设置帧头 // setDataLength((short) (1 + uavState.toByteArray().length)); // 数据长度 setCmdCode((byte) 0xD1); // 设置命令编号 this.uavInitInfo = uavInitInfo; this.actionCode = actionCode; } @Override public void encode(ByteBuf out) { } } ard-work/src/main/java/com/ard/tianyu/netty/command/SignalInfoCommand.java
New file @@ -0,0 +1,25 @@ package com.ard.tianyu.netty.command; import com.ard.tianyu.netty.protobuf.TelemetryDataPB; import io.netty.buffer.ByteBuf; import lombok.Data; @Data public class SignalInfoCommand extends BaseCommand { private int delayTime; private TelemetryDataPB.SignalInfo signalInfo; // 构造函数 public SignalInfoCommand(TelemetryDataPB.SignalInfo signalInfo) { setDataHeader((short) 0x6A77); // 设置帧头 // setDataLength((short) (1 + uavState.toByteArray().length)); // 数据长度 setCmdCode((byte) 0x0C); // 设置命令编号 this.signalInfo = signalInfo; } // 实现 encode 方法,如果需要 @Override public void encode(ByteBuf out) { // 根据需要实现编码 } } ard-work/src/main/java/com/ard/tianyu/netty/command/UavInitInfoCommand.java
New file @@ -0,0 +1,37 @@ package com.ard.tianyu.netty.command; import io.netty.buffer.ByteBuf; import lombok.Data; /** * 无人机初始化回复命令 * * @author 刘苏义 * @date 2024/10/22 16:36 */ @Data public class UavInitInfoCommand extends BaseCommand{ private final byte encryptFlag; // 加密标志 private final byte actionId; // 动作编号 private final byte result; // 执行结果 public UavInitInfoCommand(byte encryptFlag, byte actionId, byte result) { setDataHeader((short)0x7479); setDataLength((short) 3); setCmdCode((byte)0xD1); this.encryptFlag = encryptFlag; this.actionId = actionId; this.result = result; } public void encode(ByteBuf out) { out.writeShort(getDataHeader()); // 写入帧头 out.writeShort(getDataLength()); // 写入数据长度 out.writeByte(getCmdCode()); // 写入指令编号 out.writeByte(encryptFlag); // 写入加密标志 out.writeByte(actionId); // 写入动作编号 out.writeByte(result); // 写入执行结果 } } ard-work/src/main/java/com/ard/tianyu/netty/command/UavStateCommand.java
@@ -9,6 +9,9 @@ // 构造函数 public UavStateCommand(TelemetryDataPB.UavState uavState) { setDataHeader((short) 0x6A77); // 设置帧头 // setDataLength((short) (1 + uavState.toByteArray().length)); // 数据长度 setCmdCode((byte) 0xA8); // 设置命令编号 this.uavState = uavState; } ard-work/src/main/java/com/ard/tianyu/netty/command/UavTelemetryDataCommand.java
File was renamed from ard-work/src/main/java/com/ard/tianyu/netty/command/UavDataCommand.java @@ -9,10 +9,13 @@ * @author liusuyi * @date 2024年10月23日9:33 **/ public class UavDataCommand extends BaseCommand{ public class UavTelemetryDataCommand extends BaseCommand{ private TelemetryDataPB.TelemetryData telemetryData; // 构造函数 public UavDataCommand(TelemetryDataPB.TelemetryData telemetryData) { public UavTelemetryDataCommand(TelemetryDataPB.TelemetryData telemetryData) { setDataHeader((short) 0x6A77); // 设置帧头 // setDataLength((short) (1 + uavState.toByteArray().length)); // 数据长度 setCmdCode((byte) 0xA9); // 设置命令编号 this.telemetryData = telemetryData; } ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java
@@ -54,17 +54,52 @@ in.readBytes(uavStatus); // 读取 ProtoBuf 数据 TelemetryDataPB.UavState uavState = TelemetryDataPB.UavState.parseFrom(uavStatus); baseCommand = new UavStateCommand(uavState); log.warn("无人机状态数据: {}", uavState.getBoxSn()); log.debug("无人机状态数据: {}", uavState.getBoxSn()); break; case (byte) 0xA9: byte[] uavData = new byte[dataLength - 1]; in.readBytes(uavData); TelemetryDataPB.TelemetryData telemetryData = TelemetryDataPB.TelemetryData.parseFrom(uavData); baseCommand = new UavDataCommand(telemetryData); log.warn("无人机遥测数据: {}", telemetryData.getBoxSn()); baseCommand = new UavTelemetryDataCommand(telemetryData); log.debug("遥测数据: {}", telemetryData.getBoxSn()); break; case (byte) 0x0C: int delayTime = in.readInt(); uavData = new byte[15]; in.readBytes(uavData); // String boxSn12 = new String(uavData); uavData = new byte[dataLength - 20]; in.readBytes(uavData); TelemetryDataPB.SignalInfo signalInfo = TelemetryDataPB.SignalInfo.parseFrom(uavData); baseCommand = new SignalInfoCommand(signalInfo); log.debug("信道质量数据: {}", delayTime); break; case (byte) 0xD1: byte encryptionFlag = in.readByte(); byte actionCode = in.readByte(); switch (actionCode) { case 0x42: byte[] uavData1 = new byte[dataLength - 18]; in.readBytes(uavData1); byte[] uavData2 = new byte[15]; in.readBytes(uavData2); TelemetryDataPB.UavInitInfo uavInitInfo = TelemetryDataPB.UavInitInfo.parseFrom(uavData1); baseCommand = new DroneReadyNotificationCommand(uavInitInfo, actionCode); log.info("无人机初始化数据: {}", uavInitInfo.getUavModel()); break; default: log.warn("无法识别的命令码动作编号:{}", String.format("0x%02X", actionCode & 0xFF)); break; } break; default: log.warn("无法识别的命令码: {}", String.format("0x%02X", cmdCode & 0xFF));//String.format("0x%02X", cmdCode & 0xFF) encryptionFlag = in.readByte(); actionCode = in.readByte(); log.warn("无法识别的命令码: {},加密标志:{},动作编号:{}", String.format("0x%02X", cmdCode & 0xFF), String.format("0x%02X", encryptionFlag & 0xFF), String.format("0x%02X", actionCode & 0xFF));//String.format("0x%02X", cmdCode & 0xFF) } if (baseCommand != null) { out.add(baseCommand); ard-work/src/main/java/com/ard/tianyu/netty/protobuf/TelemetryDataBuf-new.proto
@@ -1,280 +1,291 @@ syntax = "proto3"; option java_package = "com.ard.tianyu.netty.protobuf"; option java_outer_classname ="TelemetryDataPB"; option java_outer_classname = "TelemetryDataPB"; //下行遥测 message TelemetryData{ double lng=1;//经度 double lat=2;//纬度 float altitude=3;//海拔高度(椭球高)(单位:米)[与遥控器显示值不同源,可能不一致。会受周围气压湿度等环境影响,数据差异及误差比较大] float ultrasonic=4;//相对高度(单位:米)[飞行器距地面10米以下,此值为真实距地距离,大于10米时为距起飞点的相对高度] float pitch=5;//俯仰角 float roll=6;//横滚角 float yaw=7;//偏航角 float airspeed=8;//空速(单位:米/秒) float velocity=9;//地速(单位:米/秒) uint64 timestamp=10;//时间戳 float ptpitch=11;//载荷俯仰角 float ptroll=12;//载荷横滚角 float ptyaw=13;//载荷航向角 float zoomfactor=14;//载荷当前倍数 string boxSn=15;//云盒子编号 string batteryPower=16;//电池电量,多个电池以下划线分割,如:80_60 uint32 satelliteCount=17;//卫星计数 uint64 taskId=18;//任务编号 double rtkLng=19;//rtk经度 double rtkLat=20;//rtk纬度 float rtkHFSL=21;//rtk海拔高度(平均海平面高度)(单位:米) uint32 rtkPositionInfo=22;//rtk状态(值为50时[rtk数据fix固定解],rtk的经纬度及海拔高度值可用) uint32 airFlyTimes=23;//当前架次飞行时长(单位:秒) [起飞->落地 视为一个架次] float airFlyDistance=24;//当前架次飞行实际距离(单位:米) string uavSn=25;//无人机编号 string uavModel=26;//无人机型号 float homeRange=27;//距降落点水平直线距离(单位:米) uint32 flightMode=28;//飞行模式:1=手动控制模式,2=姿态模式,6=MODE_P_GPS,9=热点任务中,11=自动起飞中,12=降落中,14=航线中,15=返航中,17=虚拟摇杆控制中,33=强制降落中,41=解锁电机准备起飞中 float targetDistance=29;//距目标点实际距离(单位:米) [适用于打点飞行和航线飞行] uint32 predictFlyTime=30;//预计剩余飞行时间[适用于打点飞行和航线飞行] float ultrasonicMax=31;//本架次最大相对高度值 float ultrasonicMin=32;//本架次最小相对高度值 double lng = 1;//经度 double lat = 2;//纬度 float altitude = 3;//海拔高度(椭球高)(单位:米)[与遥控器显示值不同源,可能不一致。会受周围气压湿度等环境影响,数据差异及误差比较大] float ultrasonic = 4;//相对高度(单位:米)[飞行器距地面10米以下,此值为真实距地距离,大于10米时为距起飞点的相对高度] float pitch = 5;//俯仰角 float roll = 6;//横滚角 float yaw = 7;//偏航角 float airspeed = 8;//空速(单位:米/秒) float velocity = 9;//地速(单位:米/秒) uint64 timestamp = 10;//时间戳 float ptpitch = 11;//载荷俯仰角 float ptroll = 12;//载荷横滚角 float ptyaw = 13;//载荷航向角 float zoomfactor = 14;//载荷当前倍数 string boxSn = 15;//云盒子编号 string batteryPower = 16;//电池电量,多个电池以下划线分割,如:80_60 uint32 satelliteCount = 17;//卫星计数 uint64 taskId = 18;//任务编号 double rtkLng = 19;//rtk经度 double rtkLat = 20;//rtk纬度 float rtkHFSL = 21;//rtk海拔高度(平均海平面高度)(单位:米) uint32 rtkPositionInfo = 22;//rtk状态(值为50时[rtk数据fix固定解],rtk的经纬度及海拔高度值可用) uint32 airFlyTimes = 23;//当前架次飞行时长(单位:秒) [起飞->落地 视为一个架次] float airFlyDistance = 24;//当前架次飞行实际距离(单位:米) string uavSn = 25;//无人机编号 string uavModel = 26;//无人机型号 float homeRange = 27;//距降落点水平直线距离(单位:米) uint32 flightMode = 28;//飞行模式:1=手动控制模式,2=姿态模式,6=MODE_P_GPS,9=热点任务中,11=自动起飞中,12=降落中,14=航线中,15=返航中,17=虚拟摇杆控制中,33=强制降落中,41=解锁电机准备起飞中 float targetDistance = 29;//距目标点实际距离(单位:米) [适用于打点飞行和航线飞行] uint32 predictFlyTime = 30;//预计剩余飞行时间[适用于打点飞行和航线飞行] float ultrasonicMax = 31;//本架次最大相对高度值 float ultrasonicMin = 32;//本架次最小相对高度值 } //飞行历史 message TelemetryList{ repeated TelemetryData telemetryList = 1; repeated TelemetryData telemetryList = 1; } //信道质量 //信道质量 message SignalInfo{ string mode=1; //入网模式:NR5G-SA,NR5G-NSA,LTE string mcc=2; //NR5G-SA,NR5G-NSA,LTE string mnc=3; //NR5G-SA,NR5G-NSA,LTE string cellid=4; //NR5G-SA,LTE string pcid=5; //NR5G-SA,NR5G-NSA,LTE string tac=6; //NR5G-SA,LTE string arfcn=7; //NR5G-SA,NR5G-NSA string band=8; //NR5G-SA,NR5G-NSA string nr_dl_bandwidth=9; //NR5G-SA string rsrp=10; //NR5G-SA,NR5G-NSA,LTE string rsrq=11; //NR5G-SA,NR5G-NSA,LTE string sinr=12; //NR5G-SA,NR5G-NSA,LTE string tx_power=13; //NR5G-SA,LTE string srxlev=14; //NR5G-SA,LTE string cqi=15; //LTE string earfcn=16; //LTE string freq_band_ind=17; //LTE string ul_bandwidth=18; //LTE string dl_bandwidth=19; //LTE string is_tdd=20; //LTE string rssi=21; //LTE string duplex_mode=22; //NR5G-SA double lng=23;//经度 double lat=24;//纬度 float height=25;//高度(单位:米) uint32 timestamp=26;//时间戳(单位:秒) uint32 boxstate=27;//1=线缆故障,2=OSDK未激活,3=正常,4=云盒固件更新 string isp=28;//运营商 uint32 tempMax=29;//模组芯片温度(单位:摄氏度) string prx_rsrp=30;//prx路径的rsrp值 string drx_rsrp=31;//drx路径的rsrp值 string rx2_rsrp=32;//rx2路径的rsrp值 string rx3_rsrp=33;//rx3路径的rsrp值 string box_sn=34;//云盒编号 string mode = 1; //入网模式:NR5G-SA,NR5G-NSA,LTE string mcc = 2; //NR5G-SA,NR5G-NSA,LTE string mnc = 3; //NR5G-SA,NR5G-NSA,LTE string cellid = 4; //NR5G-SA,LTE string pcid = 5; //NR5G-SA,NR5G-NSA,LTE string tac = 6; //NR5G-SA,LTE string arfcn = 7; //NR5G-SA,NR5G-NSA string band = 8; //NR5G-SA,NR5G-NSA string nr_dl_bandwidth = 9; //NR5G-SA string rsrp = 10; //NR5G-SA,NR5G-NSA,LTE string rsrq = 11; //NR5G-SA,NR5G-NSA,LTE string sinr = 12; //NR5G-SA,NR5G-NSA,LTE string tx_power = 13; //NR5G-SA,LTE string srxlev = 14; //NR5G-SA,LTE string cqi = 15; //LTE string earfcn = 16; //LTE string freq_band_ind = 17; //LTE string ul_bandwidth = 18; //LTE string dl_bandwidth = 19; //LTE string is_tdd = 20; //LTE string rssi = 21; //LTE string duplex_mode = 22; //NR5G-SA double lng = 23;//经度 double lat = 24;//纬度 float height = 25;//高度(单位:米) uint32 timestamp = 26;//时间戳(单位:秒) uint32 boxstate = 27;//1=线缆故障,2=OSDK未激活,3=正常,4=云盒固件更新 string isp = 28;//运营商 uint32 tempMax = 29;//模组芯片温度(单位:摄氏度) string prx_rsrp = 30;//prx路径的rsrp值 string drx_rsrp = 31;//drx路径的rsrp值 string rx2_rsrp = 32;//rx2路径的rsrp值 string rx3_rsrp = 33;//rx3路径的rsrp值 string box_sn = 34;//云盒编号 } message SignalList{ repeated SignalInfo signalInfo = 1; repeated SignalInfo signalInfo = 1; } //无人机状态对象 message UavState{ FlightControllerState flightControllerState=1;//飞控状态 BatteryState batteryState=2;//电池状态 PtzState ptzState=3;//云台状态 CameraState cameraState=4;//相机状态 MissionState missionState=5;//任务状态 string boxSn=6;//云盒编号 AvoidanceData avoidanceData=7;//避障数据 repeated HmsAlarmData hmsAlarmData=8;//Hms报警信息[飞机告警信息] FlightControllerState flightControllerState = 1;//飞控状态 BatteryState batteryState = 2;//电池状态 PtzState ptzState = 3;//云台状态 CameraState cameraState = 4;//相机状态 MissionState missionState = 5;//任务状态 string boxSn = 6;//云盒编号 AvoidanceData avoidanceData = 7;//避障数据 repeated HmsAlarmData hmsAlarmData = 8;//Hms报警信息[飞机告警信息] } message FlightControllerState{ uint32 satelliteCount=1;//卫星计数 uint32 gpsSignalLevel=2;//GPS信号级别,0~5[4,5等级可以执行航线] uint32 flightMode=3;//飞行模式:1=手动控制模式,2=姿态模式,6=MODE_P_GPS,9=热点任务中,11=自动起飞中,12=降落中,14=航线中,15=返航中,17=虚拟摇杆控制中,33=强制降落中,41=解锁电机准备起飞中 uint32 flightStatus=4;//飞行状态:0=电机未启动(地面),1=电机启动未起飞(地面),2=起飞在空中(空中) PointData startPoint=5;//起飞点(只包含lat和lng信息) PointData homePoint=6;//返航点(只包含lat和lng信息) int32 homeHeight=7;//返航高度(单位:米) uint32 safeLine=8;//打点飞行模式:0=节能模式【飞机直线飞到目标点,需飞机在空中并且有控制权】,1=安全模式【飞机飞行至目标点高度再平飞到目标点,飞机可以在地面】 默认为节能模式 uint32 deviceStatus=9;//控制权状态:0=遥控器,1=msdk,4=云盒[此控制权只针对虚拟摇杆控制权,起飞、降落、强制降落、航线操作、返航不需要此控制权,但是遥控器断连情况下,如果云盒没有控制权,飞机会执行遥控器的失联策略] uint32 uwbNodeCount=10;//UWB星数(只有等于4时,才可以开启uwb精准降落模式) string rcMode=11;//遥控器档位模式(说明:1.遥控器与飞机正常连接:(M300:T-P-S/M30:F-S-N/M3:C-N-S),2.遥控器与飞机未连接:W,3.只有在M300-P挡、M30-N挡、M3-N挡下云盒才能正常控制无人机) uint32 isEmergencyBrakeing=12;//是否紧急制动中,0=否,1=是 【飞行器在地面限制起飞,飞行器在空中限制飞行.如果想操作飞行,请先解除紧急制动】 uint32 outFlyAreaFlag=13;//飞行器是否在所有自定义电子围栏外,0=电子围栏内 1=电子围栏外 uint32 inNoFlyAreaFlag=14;//飞行器是否在自定义禁飞区内,0=禁飞区外 1=禁飞区内 uint32 satelliteCount = 1;//卫星计数 uint32 gpsSignalLevel = 2;//GPS信号级别,0~5[4,5等级可以执行航线] uint32 flightMode = 3;//飞行模式:1=手动控制模式,2=姿态模式,6=MODE_P_GPS,9=热点任务中,11=自动起飞中,12=降落中,14=航线中,15=返航中,17=虚拟摇杆控制中,33=强制降落中,41=解锁电机准备起飞中 uint32 flightStatus = 4;//飞行状态:0=电机未启动(地面),1=电机启动未起飞(地面),2=起飞在空中(空中) PointData startPoint = 5;//起飞点(只包含lat和lng信息) PointData homePoint = 6;//返航点(只包含lat和lng信息) int32 homeHeight = 7;//返航高度(单位:米) uint32 safeLine = 8;//打点飞行模式:0=节能模式【飞机直线飞到目标点,需飞机在空中并且有控制权】,1=安全模式【飞机飞行至目标点高度再平飞到目标点,飞机可以在地面】 默认为节能模式 uint32 deviceStatus = 9;//控制权状态:0=遥控器,1=msdk,4=云盒[此控制权只针对虚拟摇杆控制权,起飞、降落、强制降落、航线操作、返航不需要此控制权,但是遥控器断连情况下,如果云盒没有控制权,飞机会执行遥控器的失联策略] uint32 uwbNodeCount = 10;//UWB星数(只有等于4时,才可以开启uwb精准降落模式) string rcMode = 11;//遥控器档位模式(说明:1.遥控器与飞机正常连接:(M300:T-P-S/M30:F-S-N/M3:C-N-S),2.遥控器与飞机未连接:W,3.只有在M300-P挡、M30-N挡、M3-N挡下云盒才能正常控制无人机) uint32 isEmergencyBrakeing = 12;//是否紧急制动中,0=否,1=是 【飞行器在地面限制起飞,飞行器在空中限制飞行.如果想操作飞行,请先解除紧急制动】 uint32 outFlyAreaFlag = 13;//飞行器是否在所有自定义电子围栏外,0=电子围栏内 1=电子围栏外 uint32 inNoFlyAreaFlag = 14;//飞行器是否在自定义禁飞区内,0=禁飞区外 1=禁飞区内 } //电池状态 message BatteryState{ uint32 batteryNum=1;//电池数量 string batteryPower=2;//电池电量,多个电池以下划线分割,如:80_60 string batteryVoltage=3;//电池电压,多个电池以下划线分割,如:40_30(单位:V)[注意:如果2块电池电压差大于0.7V,飞机限制起飞] BatteryStateInfo firstBatteryInfo=4;//第一块电池状态信息(安装在飞机左边电池槽) BatteryStateInfo secondBatteryInfo=5;//第二块电池状态信息(安装在飞机右边电池槽) uint32 batteryNum = 1;//电池数量 string batteryPower = 2;//电池电量,多个电池以下划线分割,如:80_60 string batteryVoltage = 3;//电池电压,多个电池以下划线分割,如:40_30(单位:V)[注意:如果2块电池电压差大于0.7V,飞机限制起飞] BatteryStateInfo firstBatteryInfo = 4;//第一块电池状态信息(安装在飞机左边电池槽) BatteryStateInfo secondBatteryInfo = 5;//第二块电池状态信息(安装在飞机右边电池槽) } //电池状态信息 message BatteryStateInfo{ uint32 isBatteryEmbed=1;//电池插入飞机状态(注意:如果未插入所有电池信息不可用):0=插入,1=未插入 uint32 batteryCapacityPercent=2;//电池电量百分比 int32 currentVoltage=3;//电池电压(单位:mV) int32 currentElectric=4;//当前电池电流(单位:mA) uint32 fullCapacity=5;//满电池容量(单位:mAh) uint32 remainedCapacity=6;//剩余电池容量(单位:mAh) float batteryTemperature=7;//电池温度(单位:摄氏度) uint32 cellCount=8;//电池组数(电池硬件型号有关) uint32 batSOHState=9;//电池循环健康状态:0=正常,1=警报,2=注意安全 uint32 sop=10;//相对功率百分比(Relative power percentage) uint32 heatState=11;//电池加热状态:0=未加热,1=加热中,2=保持恒温 uint32 socState=12;//电池SOC荷电状态: 0=SOC正常,1=SOC_ABNORMAL_HIGH,2=SOC_JUMP_DOWN,3=SOC_JUMP_UP,4=SOC_INVALID uint32 selfCheckError=13;//电池自检错误标志(注意:如果此值非0,就是电池损坏需要维修):0=正常,1=电池自检NTC异常,2=电池自检MOS异常,3=电池自检采样电阻异常,4=电池电芯损坏,5=电池未校准,6=电量计参数异常 uint32 isBatteryEmbed = 1;//电池插入飞机状态(注意:如果未插入所有电池信息不可用):0=插入,1=未插入 uint32 batteryCapacityPercent = 2;//电池电量百分比 int32 currentVoltage = 3;//电池电压(单位:mV) int32 currentElectric = 4;//当前电池电流(单位:mA) uint32 fullCapacity = 5;//满电池容量(单位:mAh) uint32 remainedCapacity = 6;//剩余电池容量(单位:mAh) float batteryTemperature = 7;//电池温度(单位:摄氏度) uint32 cellCount = 8;//电池组数(电池硬件型号有关) uint32 batSOHState = 9;//电池循环健康状态:0=正常,1=警报,2=注意安全 uint32 sop = 10;//相对功率百分比(Relative power percentage) uint32 heatState = 11;//电池加热状态:0=未加热,1=加热中,2=保持恒温 uint32 socState = 12;//电池SOC荷电状态: 0=SOC正常,1=SOC_ABNORMAL_HIGH,2=SOC_JUMP_DOWN,3=SOC_JUMP_UP,4=SOC_INVALID uint32 selfCheckError = 13;//电池自检错误标志(注意:如果此值非0,就是电池损坏需要维修):0=正常,1=电池自检NTC异常,2=电池自检MOS异常,3=电池自检采样电阻异常,4=电池电芯损坏,5=电池未校准,6=电量计参数异常 } //云台状态 message PtzState{ float pitch=1;//俯仰角 范围:-120° ~ 30° float roll=2;//横滚角 范围:-90° ~ 60° float yaw=3;//偏航角 范围:-180° ~ 180° uint32 gimbalMode=4;//云台模式 1=自由模式,2=跟随模式,3=FPV模式 float pitch = 1;//俯仰角 范围:-120° ~ 30° float roll = 2;//横滚角 范围:-90° ~ 60° float yaw = 3;//偏航角 范围:-180° ~ 180° uint32 gimbalMode = 4;//云台模式 1=自由模式,2=跟随模式,3=FPV模式 } //相机状态 message CameraState{ uint32 mode=1;//相机模式:1=拍照模式,2=录像模式,0=未知 uint32 isRecording=2;//是否录制中:1=录制中,0=未录制 uint32 recordDuration=3;//录制时长(单位:秒) uint32 source=4;//相机视源:0=可见,1=变焦,2=红外 uint32 camera=5;//相机: 0=FPV,1=相机(1),2=相机(2) float zoomfactor=6;//相机当前变焦倍数 uint32 width=7;//水平像素(例如:1920) uint32 height=8;//垂直像素(例如:1080) uint32 frameRate=9;//帧率(例如:30) uint32 bitstream=10;//码率(单位:0.001)(例如:6兆设置值为6000) uint32 pointThermometrying=11;//单点测温状态:0=非单点测温中,1=单点测温中 uint32 areaThermometrying=12;//区域测温状态:0=非区域测温中,1=区域测温中 uint32 laserRanging=13;//激光测距状态:0=非激光测距中,1=激光测距中 uint32 mode = 1;//相机模式:1=拍照模式,2=录像模式,0=未知 uint32 isRecording = 2;//是否录制中:1=录制中,0=未录制 uint32 recordDuration = 3;//录制时长(单位:秒) uint32 source = 4;//相机视源:0=可见,1=变焦,2=红外 uint32 camera = 5;//相机: 0=FPV,1=相机(1),2=相机(2) float zoomfactor = 6;//相机当前变焦倍数 uint32 width = 7;//水平像素(例如:1920) uint32 height = 8;//垂直像素(例如:1080) uint32 frameRate = 9;//帧率(例如:30) uint32 bitstream = 10;//码率(单位:0.001)(例如:6兆设置值为6000) uint32 pointThermometrying = 11;//单点测温状态:0=非单点测温中,1=单点测温中 uint32 areaThermometrying = 12;//区域测温状态:0=非区域测温中,1=区域测温中 uint32 laserRanging = 13;//激光测距状态:0=非激光测距中,1=激光测距中 } //任务状态 message MissionState{ uint32 isPause=1;//航线是否暂停中:0=未暂停,1=暂停中 uint32 targetWaypointIndex=2;//目标航点下标(说明:开始成功到第一个航点之间此值为0,到达第一个航点此值为1,到达第二个航点此值为2,以此类推,航线结束后此值不清空直到下一次开始航线) uint32 isWaypointFinished=3;//是否航点完成:1完成、0未完成(此值废弃) uint32 pushVideo=4;//云盒是否发送视频数据:0=不发送,1=发送 uint32 lock4g=5;//是否锁定4G:0=不锁定,1=锁定 uint32 boxModel=6;//是否开通图片自动回传功能:0=未开通,1=已开通 uint32 mapPlay=7;//自动拍照间隔:0未开始,3~255间隔时间 uint32 loseAction=8;//网络失联后动作:0=返回HOME点,1=继续航线 uint32 isPointControl=9;//是否打点飞行控制中:0=否,1=是 uint32 isUwbLanding=10;//是否UWB精准降落中:0=不是,1=是 uint32 isPushVideoing=11;//视频是否推流中:0=不是,1=是 uint32 isDLanding=12;//是否二维码精准降落中:0=不是,1=是 uint32 perceptionFlag=13;//二维码精准降落模式:0=载荷降落,1=下视降落 uint32 isPositionControl=14;//是否指定距离飞行控制中:0=否,1=是 uint32 isPause = 1;//航线是否暂停中:0=未暂停,1=暂停中 uint32 targetWaypointIndex = 2;//目标航点下标(说明:开始成功到第一个航点之间此值为0,到达第一个航点此值为1,到达第二个航点此值为2,以此类推,航线结束后此值不清空直到下一次开始航线) uint32 isWaypointFinished = 3;//是否航点完成:1完成、0未完成(此值废弃) uint32 pushVideo = 4;//云盒是否发送视频数据:0=不发送,1=发送 uint32 lock4g = 5;//是否锁定4G:0=不锁定,1=锁定 uint32 boxModel = 6;//是否开通图片自动回传功能:0=未开通,1=已开通 uint32 mapPlay = 7;//自动拍照间隔:0未开始,3~255间隔时间 uint32 loseAction = 8;//网络失联后动作:0=返回HOME点,1=继续航线 uint32 isPointControl = 9;//是否打点飞行控制中:0=否,1=是 uint32 isUwbLanding = 10;//是否UWB精准降落中:0=不是,1=是 uint32 isPushVideoing = 11;//视频是否推流中:0=不是,1=是 uint32 isDLanding = 12;//是否二维码精准降落中:0=不是,1=是 uint32 perceptionFlag = 13;//二维码精准降落模式:0=载荷降落,1=下视降落 uint32 isPositionControl = 14;//是否指定距离飞行控制中:0=否,1=是 } //避障数据 message AvoidanceData{ uint32 downHealth=1; float down=2;//距下障碍物的距离(单位:米),downHealth为1时值有效 uint32 frontHealth=3; float front=4;//距前障碍物的距离(单位:米),frontHealth为1时值有效 uint32 rightHealth=5; float right=6;//距右障碍物的距离(单位:米),rightHealth为1时值有效 uint32 backHealth=7; float back=8;//距后障碍物的距离(单位:米),backHealth为1时值有效 uint32 leftHealth=9; float left=10;//距左障碍物的距离(单位:米),leftHealth为1时值有效 uint32 upHealth=11; float up=12;//距上障碍物的距离(单位:米),upHealth为1时值有效 uint32 avoidanceEnableStatusDown=13;//下视觉避障开关状态:0-关闭 1-打开 uint32 avoidanceEnableStatusUp=14;//上视觉避障开关状态:0-关闭 1-打开 uint32 avoidanceEnableStatusHorizontal=15;//水平视觉避障开关状态:0-关闭 1-打开 uint32 downHealth = 1; float down = 2;//距下障碍物的距离(单位:米),downHealth为1时值有效 uint32 frontHealth = 3; float front = 4;//距前障碍物的距离(单位:米),frontHealth为1时值有效 uint32 rightHealth = 5; float right = 6;//距右障碍物的距离(单位:米),rightHealth为1时值有效 uint32 backHealth = 7; float back = 8;//距后障碍物的距离(单位:米),backHealth为1时值有效 uint32 leftHealth = 9; float left = 10;//距左障碍物的距离(单位:米),leftHealth为1时值有效 uint32 upHealth = 11; float up = 12;//距上障碍物的距离(单位:米),upHealth为1时值有效 uint32 avoidanceEnableStatusDown = 13;//下视觉避障开关状态:0-关闭 1-打开 uint32 avoidanceEnableStatusUp = 14;//上视觉避障开关状态:0-关闭 1-打开 uint32 avoidanceEnableStatusHorizontal = 15;//水平视觉避障开关状态:0-关闭 1-打开 } //Hms报警信息 message HmsAlarmData{ uint32 alarmId=1;//报警信息ID uint32 reportLevel=2;//等级[1/2-警告 3/4/5-错误] string alarmMssInfo=3;//报警信息描述(说明:支持中文和英文版本,默认中文,如需切换请联系技术支持) uint32 alarmId = 1;//报警信息ID uint32 reportLevel = 2;//等级[1/2-警告 3/4/5-错误] string alarmMssInfo = 3;//报警信息描述(说明:支持中文和英文版本,默认中文,如需切换请联系技术支持) } //航线 message PlanLineData{ uint32 finishedAction=1;//结束航线后动作:1=返航,2=原地悬停,3=原地降落,4=原地绕飞[目前只osdk4.1版本支持,中心点为最后一个航点,飞机绕此点画圆飞行],5=返回至第一个航点并悬停[如果飞机到最后一个点时RC和飞机失联,飞机会在最后一个点悬停] float maxSpeed=2;//最大飞行速度(单位:米/秒,范围0~15),默认15 float autoSpeed=3;//自动飞行速度(单位:米/秒,范围0~15),默认8 repeated PointData points=4;//坐标点数组 uint32 loseAction=5;//网络失联后动作:0=返回HOME点,1=继续航线,默认0 uint32 homeHeight=6;//返航高度:(单位:米,范围20~1500),说明:此值为相对起飞点高度,如果太高会有失去网络覆盖风险。不同飞行器返航逻辑不一样,若飞行器距HOME点距离过近,可能不会升高再返航。具体逻辑请咨询大疆DJI uint32 isSaveEnergyMode=7;//是否开启节能模式:0=不是,1=是(说明:节能模式下,飞机沿最短直线距离由起飞点到航线第一个航点,非升高到第一个航点高度再飞往第一个航点) HangarPoint takePoint=8;//起飞点机库信息 HangarPoint landPoint=9;//降落点机库信息 repeated PointData interests=10;//兴趣点数组(对象只包含经纬高) NormalModel normalModel=11;//普通建模 SurroundModel surroundModel=12;//环绕建模 PointData takeOffPoint=13;//起飞点(对象只包含经纬高) uint32 finishedAction = 1;//结束航线后动作:1=返航,2=原地悬停,3=原地降落,4=原地绕飞[目前只osdk4.1版本支持,中心点为最后一个航点,飞机绕此点画圆飞行],5=返回至第一个航点并悬停[如果飞机到最后一个点时RC和飞机失联,飞机会在最后一个点悬停] float maxSpeed = 2;//最大飞行速度(单位:米/秒,范围0~15),默认15 float autoSpeed = 3;//自动飞行速度(单位:米/秒,范围0~15),默认8 repeated PointData points = 4;//坐标点数组 uint32 loseAction = 5;//网络失联后动作:0=返回HOME点,1=继续航线,默认0 uint32 homeHeight = 6;//返航高度:(单位:米,范围20~1500),说明:此值为相对起飞点高度,如果太高会有失去网络覆盖风险。不同飞行器返航逻辑不一样,若飞行器距HOME点距离过近,可能不会升高再返航。具体逻辑请咨询大疆DJI uint32 isSaveEnergyMode = 7;//是否开启节能模式:0=不是,1=是(说明:节能模式下,飞机沿最短直线距离由起飞点到航线第一个航点,非升高到第一个航点高度再飞往第一个航点) HangarPoint takePoint = 8;//起飞点机库信息 HangarPoint landPoint = 9;//降落点机库信息 repeated PointData interests = 10;//兴趣点数组(对象只包含经纬高) NormalModel normalModel = 11;//普通建模 SurroundModel surroundModel = 12;//环绕建模 PointData takeOffPoint = 13;//起飞点(对象只包含经纬高) } //航线点 message PointData{ double lng=1;//经度 double lat=2;//纬度 float height=3;//高度(单位:米,范围0~遥控器限高),说明:此值为相对起飞点高度,如果太高会有失去网络覆盖风险 float speed=4;//速度(单位:米/秒,范围0~15),默认8 repeated PointAction actions=5;//动作数组 uint32 flightPathMode=6;//航线飞行模式:1=直线飞行,2=协调转弯,3=曲线飞行(停),4=曲线飞行(不停) float dampingDistance=7;//转弯半径(仅协调转弯模式下有效),取值范围1~655.35单位:米,两点间距离要小于此值,此值要根据实际情况计算,切勿随便设此值[可能导致航线开始失败],具体计算方法可以咨询售后支持或者大疆DJI uint32 safeGohomeFlag=8;//是否为安全返航点 0=不是,1=是 (暂时未启用) uint32 headingMode=9;//偏航模式 0=自动,1=锁定,2=遥控器控制,3=云台依照航点方向旋转,4=朝向兴趣点,5=飞机和云台的偏航同时旋转 float heading=10;//航点偏航 -180~180 int32 interestIndex=11;//兴趣点下标,默认-1 uint32 groupIndex=12;//组下标 double lng = 1;//经度 double lat = 2;//纬度 float height = 3;//高度(单位:米,范围0~遥控器限高),说明:此值为相对起飞点高度,如果太高会有失去网络覆盖风险 float speed = 4;//速度(单位:米/秒,范围0~15),默认8 repeated PointAction actions = 5;//动作数组 uint32 flightPathMode = 6;//航线飞行模式:1=直线飞行,2=协调转弯,3=曲线飞行(停),4=曲线飞行(不停) float dampingDistance = 7;//转弯半径(仅协调转弯模式下有效),取值范围1~655.35单位:米,两点间距离要小于此值,此值要根据实际情况计算,切勿随便设此值[可能导致航线开始失败],具体计算方法可以咨询售后支持或者大疆DJI uint32 safeGohomeFlag = 8;//是否为安全返航点 0=不是,1=是 (暂时未启用) uint32 headingMode = 9;//偏航模式 0=自动,1=锁定,2=遥控器控制,3=云台依照航点方向旋转,4=朝向兴趣点,5=飞机和云台的偏航同时旋转 float heading = 10;//航点偏航 -180~180 int32 interestIndex = 11;//兴趣点下标,默认-1 uint32 groupIndex = 12;//组下标 } //航线点动作 message PointAction{ uint32 type=1;//类型:1.变焦 2.拍照 3.录像 4.停录 5.控制飞机机头偏航 6.控制云台俯仰 7.控制云台偏航 8.控制云台横滚 9.悬停 10.等距间隔拍照 11.等时间隔拍照 12.结束间隔拍照 13.单条喊话 14.开始循环喊话 15.结束循环喊话 16.对焦 float param=2;//参数:[1.变焦]->变焦倍数(范围:2~200) 、 [5.控制飞机机头偏航(范围:-180~180)、6.控制云台俯仰(范围:-120~30)、7.控制云台偏航(范围:-180~180)、8.控制云台横滚(范围:-90~60)]->角度(按正北坐标系绝对值控制) 、[9.悬停]->时间(单位:秒,范围:1~25,如果想停留大于25秒时长,可以加多组悬停动作) [10.等距间隔拍照]->距离(单位:米,范围:1~100) [11.等时间隔拍照]->时间(单位:秒,范围:1~30) [13/14->喊话器俯仰角度,如果此值为0默认改成-90](范围:0~-90) int32 waitTime=3;//动作触发后等待时长(单位:秒) [此值如果不需要可以不传,如需悬停可添加类型9悬停动作] [13/14->喊话器声音,如果此值不传默认50](范围:0~100) string speakInfo=4;//喊话内容[type=13和type=14时生效] uint32 type = 1;//类型:1.变焦 2.拍照 3.录像 4.停录 5.控制飞机机头偏航 6.控制云台俯仰 7.控制云台偏航 8.控制云台横滚 9.悬停 10.等距间隔拍照 11.等时间隔拍照 12.结束间隔拍照 13.单条喊话 14.开始循环喊话 15.结束循环喊话 16.对焦 float param = 2;//参数:[1.变焦]->变焦倍数(范围:2~200) 、 [5.控制飞机机头偏航(范围:-180~180)、6.控制云台俯仰(范围:-120~30)、7.控制云台偏航(范围:-180~180)、8.控制云台横滚(范围:-90~60)]->角度(按正北坐标系绝对值控制) 、[9.悬停]->时间(单位:秒,范围:1~25,如果想停留大于25秒时长,可以加多组悬停动作) [10.等距间隔拍照]->距离(单位:米,范围:1~100) [11.等时间隔拍照]->时间(单位:秒,范围:1~30) [13/14->喊话器俯仰角度,如果此值为0默认改成-90](范围:0~-90) int32 waitTime = 3;//动作触发后等待时长(单位:秒) [此值如果不需要可以不传,如需悬停可添加类型9悬停动作] [13/14->喊话器声音,如果此值不传默认50](范围:0~100) string speakInfo = 4;//喊话内容[type=13和type=14时生效] } //机库信息 message HangarPoint{ string hangarId=1;//机库ID double hangarLng=2;//机库经度 double hangarLat=3;//机库纬度 double alternateLng=4;//备降点经度 double alternateLat=5;//备降点纬度 string hangarId = 1;//机库ID double hangarLng = 2;//机库经度 double hangarLat = 3;//机库纬度 double alternateLng = 4;//备降点经度 double alternateLat = 5;//备降点纬度 } //普通建模 message NormalModel{ repeated PointData area=1;//作业区域 uint32 serviceId=2;//建模平台编号:1=瞰景,2=大势,默认1 uint32 cameraId=3;//相机编号 uint32 isModeling=4;//是否实时建模:0=不,1=是 uint32 mode=5;//作业模式:1=倾斜,2=正摄 uint32 hOverlap=6;//横向重叠率 uint32 vOverlap=7;//纵向重叠率 uint32 mirror=8;//方向正反 repeated PointData area = 1;//作业区域 uint32 serviceId = 2;//建模平台编号:1=瞰景,2=大势,默认1 uint32 cameraId = 3;//相机编号 uint32 isModeling = 4;//是否实时建模:0=不,1=是 uint32 mode = 5;//作业模式:1=倾斜,2=正摄 uint32 hOverlap = 6;//横向重叠率 uint32 vOverlap = 7;//纵向重叠率 uint32 mirror = 8;//方向正反 } //环绕建模 message SurroundModel{ repeated PointData area=1;//作业区域 uint32 serviceId=2;//建模平台编号:1=瞰景 uint32 cameraId=3;//相机编号 uint32 isModeling=4;//是否实时建模:0=不,1=是 } repeated PointData area = 1;//作业区域 uint32 serviceId = 2;//建模平台编号:1=瞰景 uint32 cameraId = 3;//相机编号 uint32 isModeling = 4;//是否实时建模:0=不,1=是 } //无人机初始化详情 message UavInitInfo{ string uavModel = 1; //无人机型号 string uavSn=2; //无人机SN string uavVersion = 3; //无人机固件版本号 string ptModel = 4; //挂载相机型号 string ptVersion = 5; //挂载相机固件版本号 uint32 ptPosition = 6; //挂载相机psdk日位置 string moduleVersion = 7; //模组固件版本号 } ard-work/src/main/java/com/ard/tianyu/netty/protobuf/TelemetryDataPB.java
Diff too large ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
@@ -3,6 +3,9 @@ import com.ard.tianyu.model.dto.BoxHistoryDTO; import com.ard.tianyu.model.dto.BoxPhotosDTO; import com.ard.tianyu.model.dto.BoxSettingsDTO; import com.ard.tianyu.model.dto.signal.SignalInfo; import com.ard.tianyu.model.dto.state.UavState; import com.ard.tianyu.model.dto.telemetry.TelemetryData; import com.ard.tianyu.model.receiver.*; import com.ard.tianyu.netty.command.BaseCommand; import com.dtflys.forest.annotation.Var; @@ -67,9 +70,23 @@ /** * 云台转动(基于角度) */ void controlAngle(String boxSn); void controlAngle(String boxSn,Integer actionId,Integer rotationAngle) ; /** * 获取无人机状态 */ UavState getUavState(String boxSn); /** * 获取无人机遥测 */ TelemetryData getUavTelemetryData(String boxSn); /** * 获取信道质量遥测 */ SignalInfo getSignalInfo(String boxSn); /** * 解析天宇服务端发来的消息 */ void processMessage(String key, BaseCommand tyMessage); ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
@@ -2,9 +2,18 @@ import com.ard.tianyu.config.TyConfiguration; import com.ard.tianyu.http.TyClient; import com.ard.tianyu.model.cache.UavSignalInfoCache; import com.ard.tianyu.model.cache.UavStateCache; import com.ard.tianyu.model.cache.UavTelemetryDataCache; import com.ard.tianyu.model.dto.BoxHistoryDTO; import com.ard.tianyu.model.dto.BoxPhotosDTO; import com.ard.tianyu.model.dto.BoxSettingsDTO; import com.ard.tianyu.model.dto.converter.UavSignalInfoConverter; import com.ard.tianyu.model.dto.converter.UavStateConverter; import com.ard.tianyu.model.dto.converter.UavTelemetryDataConverter; import com.ard.tianyu.model.dto.signal.SignalInfo; import com.ard.tianyu.model.dto.state.UavState; import com.ard.tianyu.model.dto.telemetry.TelemetryData; import com.ard.tianyu.model.receiver.*; import com.ard.tianyu.netty.command.*; import com.ard.tianyu.netty.TyNettyTcpClient; @@ -154,9 +163,33 @@ * 云台控制基于角度 */ @Override public void controlAngle(String boxSn) { ControlAngleCommand controlAngleCommand = new ControlAngleCommand(boxSn.getBytes(), (byte) 0x00, (byte) 0x00, (byte) 0x05); public void controlAngle(String boxSn, Integer actionId, Integer rotationAngle) { ControlAngleCommand controlAngleCommand = new ControlAngleCommand(boxSn.getBytes(), (byte) 0x00, actionId.byteValue(), rotationAngle.byteValue()); this.sendMessage(tyConfiguration.getIpPort(), controlAngleCommand); } /** * 获取无人机状态 */ @Override public UavState getUavState(String boxSn) { return UavStateCache.getUavState(boxSn); } /** * 获取无人机遥测数据 */ @Override public TelemetryData getUavTelemetryData(String boxSn) { return UavTelemetryDataCache.getUavTelemetryData(boxSn); } /** * 获取无人机遥测数据 */ @Override public SignalInfo getSignalInfo(String boxSn) { return UavSignalInfoCache.getUavSignalInfo(boxSn); } @Override @@ -176,7 +209,7 @@ case 0x02: // 处理注册消息 HeartbeatReplyCommand heartbeatReplyCommand = (HeartbeatReplyCommand) tyCommand; log.info("收到心跳消息-->处理心跳消息{}", heartbeatReplyCommand.getTimestamp()); log.debug("收到心跳消息-->处理心跳消息{}", heartbeatReplyCommand.getTimestamp()); break; case 0x03: // 处理订阅消息 @@ -190,14 +223,37 @@ break; case (byte) 0xA8: // 处理无人机状态消息 log.info("收到无人机状态消息-->无人机状态消息"); log.debug("收到无人机状态消息-->无人机状态消息"); UavStateCommand uavStateCommand = (UavStateCommand) tyCommand; UavState uavState = UavStateConverter.convertProtoToEntity(uavStateCommand.getUavState()); UavStateCache.putUavState(uavState); break; case (byte) 0xA9: // 处理无人机遥测消息 log.info("收到无人机遥测消息-->无人机遥测消息"); log.debug("收到无人机遥测消息-->无人机遥测消息"); UavTelemetryDataCommand uavTelemetryDataCommand = (UavTelemetryDataCommand) tyCommand; TelemetryData telemetryData = UavTelemetryDataConverter.convertProtoToEntity(uavTelemetryDataCommand.getTelemetryData()); UavTelemetryDataCache.putUavTelemetryData(telemetryData); break; case (byte) 0x0C: // 处理无人机信道质量数据 log.debug("收到无人机信道质量数据消息-->无人机信道质量数据消息"); SignalInfoCommand signalInfoCommand = (SignalInfoCommand) tyCommand; SignalInfo signalInfo = UavSignalInfoConverter.convertProtoToEntity(signalInfoCommand.getSignalInfo()); UavSignalInfoCache.putUavSignalInfoCache(signalInfo); break; case (byte) 0xD1: // 处理无人机 DroneReadyNotificationCommand droneReadyNotificationCommand = (DroneReadyNotificationCommand) tyCommand; if (droneReadyNotificationCommand.getActionCode() == (byte) 0x42) { UavInitInfoCommand uavInitCommand = new UavInitInfoCommand((byte) 0x00, (byte) 0x42, (byte) 0x01); this.sendMessage(tyConfiguration.getIpPort(), uavInitCommand); log.info("收到无人机初始化详情-回复防止再次发送"); } break; default: // 处理其他消息 log.debug("收到其他消息-->其他消息"); } }