From 05ba868736725db54db1944ed5cf7a95d14efc37 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Wed, 30 Oct 2024 17:07:51 +0800
Subject: [PATCH] 增加:手动飞行控制
---
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCmd.java | 33 +
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/PointControlReachedReplyCmd.java | 33 +
ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java | 57 ++
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyControlCmd.java | 45 ++
ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java | 109 ++++
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeDTO.java | 1
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/ReturnHomeCancelReplyCmd.java | 33 +
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandCancelDTO.java | 20
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandReplyCmd.java | 33 +
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandForcedReplyCmd.java | 33 +
ard-work/src/main/java/com/ard/tianyu/controller/UavManualFlyController.java | 73 +++
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandForcedDTO.java | 20
ard-work/src/main/java/com/ard/tianyu/websocket/handler/TyMessageHandler.java | 39 +
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyPointControlCancelDTO.java | 20
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/EmeragencyBrakeDTO.java | 23 +
ard-work/src/main/java/com/ard/tianyu/model/dto/BoxSettingsDTO.java | 14
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCancelReplyCmd.java | 33 +
ard-work/src/main/java/com/ard/tianyu/controller/UavGimbalController.java | 3
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyPointControlDTO.java | 46 ++
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandDTO.java | 20
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/EmergencyBrakeReplyCmd.java | 34 +
ard-work/src/main/java/com/ard/tianyu/websocket/interceptor/TyHandshakeInterceptor.java | 35 +
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyPointControlCmd.java | 46 ++
ard-framework/src/main/java/com/ard/framework/config/SecurityConfig.java | 2
ard-work/src/main/java/com/ard/tianyu/http/TyClient.java | 2
ard-work/src/main/java/com/ard/tianyu/service/ITyService.java | 45 +
ard-work/pom.xml | 5
/dev/null | 30 -
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/EmergencyBrakeCmd.java | 35 +
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCancelCmd.java | 33 +
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeCancelDTO.java | 21
ard-work/src/main/java/com/ard/tianyu/websocket/utils/WebSocketUtil.java | 141 ++++++
ard-work/src/main/java/com/ard/tianyu/websocket/config/WebSocketConfig.java | 27 +
ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyControlDTO.java | 40 +
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyPointControlCancelCmd.java | 32 +
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/ReturnHomeCancelCmd.java | 33 +
ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandForcedCmd.java | 33 +
37 files changed, 1,229 insertions(+), 53 deletions(-)
diff --git a/ard-framework/src/main/java/com/ard/framework/config/SecurityConfig.java b/ard-framework/src/main/java/com/ard/framework/config/SecurityConfig.java
index 86a2920..61b71ea 100644
--- a/ard-framework/src/main/java/com/ard/framework/config/SecurityConfig.java
+++ b/ard-framework/src/main/java/com/ard/framework/config/SecurityConfig.java
@@ -111,7 +111,7 @@
.authorizeHttpRequests((requests) -> {
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
- requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
+ requests.antMatchers("/login", "/register", "/captchaImage", "/ws/**").permitAll()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
diff --git a/ard-work/pom.xml b/ard-work/pom.xml
index 9dd55b0..2214e30 100644
--- a/ard-work/pom.xml
+++ b/ard-work/pom.xml
@@ -55,6 +55,11 @@
<artifactId>protobuf-java</artifactId>
<version>3.20.1</version>
</dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-websocket</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/ard-work/src/main/java/com/ard/tianyu/controller/UavGimbalController.java b/ard-work/src/main/java/com/ard/tianyu/controller/UavGimbalController.java
index 22ff46d..93fc471 100644
--- a/ard-work/src/main/java/com/ard/tianyu/controller/UavGimbalController.java
+++ b/ard-work/src/main/java/com/ard/tianyu/controller/UavGimbalController.java
@@ -41,8 +41,7 @@
private ITyService tyService;
-
- @ApiOperation(value = "云台转动(基于角度)", notes = "actionCode值:0-回中,1-上,2-右上,3-右,4-右下,5-下,6-左下,7-左,8-左上,254-停止")
+ @ApiOperation(value = "云台转动(基于角度)", notes = "actionCode值:0-回中,1-上,2-右上,3-右,4-右下,5-下,6-左下,7-左,8-左上,254-停止 \r\n rotationAngle值:取值范围:0~255【云台实际转动角度= 转动角度/100+2.5 单位:度】")
@ApiOperationSupport(order = 1)
@PostMapping("/angleControl")
public AjaxResult angleControl(@RequestBody AngleControlDTO angleControlDto) {
diff --git a/ard-work/src/main/java/com/ard/tianyu/controller/UavManualFlyController.java b/ard-work/src/main/java/com/ard/tianyu/controller/UavManualFlyController.java
index d90cab3..c77853f 100644
--- a/ard-work/src/main/java/com/ard/tianyu/controller/UavManualFlyController.java
+++ b/ard-work/src/main/java/com/ard/tianyu/controller/UavManualFlyController.java
@@ -1,9 +1,7 @@
package com.ard.tianyu.controller;
import com.ard.common.core.domain.AjaxResult;
-import com.ard.tianyu.model.dto.manual.ReturnHomeDTO;
-import com.ard.tianyu.model.dto.manual.SwitchUavControlDTO;
-import com.ard.tianyu.model.dto.manual.TakeOffDTO;
+import com.ard.tianyu.model.dto.manual.*;
import com.ard.tianyu.service.ITyService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
@@ -33,6 +31,7 @@
tyService.switchUavControl(switchUavControlDTO);
return AjaxResult.success();
}
+
@ApiOperation(value = "起飞", notes = "起飞高度height取值范围:1.2~100,误差:+-0.4米")
@ApiOperationSupport(order = 2)
@PostMapping("/takeOff")
@@ -48,4 +47,72 @@
tyService.returnHome(returnHomeDTO);
return AjaxResult.success();
}
+
+ @ApiOperation("取消返航")
+ @ApiOperationSupport(order = 4)
+ @PostMapping("/returnHomeCancel")
+ public AjaxResult returnHomeCancel(@RequestBody ReturnHomeCancelDTO returnHomeCancelDTO) {
+ tyService.returnHomeCancel(returnHomeCancelDTO);
+ return AjaxResult.success();
+ }
+
+ @ApiOperation("降落")
+ @ApiOperationSupport(order = 5)
+ @PostMapping("/land")
+ public AjaxResult land(@RequestBody LandDTO landDTO) {
+ tyService.land(landDTO);
+ return AjaxResult.success();
+ }
+
+ @ApiOperation("取消降落")
+ @ApiOperationSupport(order = 6)
+ @PostMapping("/landCancel")
+ public AjaxResult landCancel(@RequestBody LandCancelDTO landCancelDTO) {
+ tyService.landCancel(landCancelDTO);
+ return AjaxResult.success();
+ }
+
+ @ApiOperation("强制降落")
+ @ApiOperationSupport(order = 7)
+ @PostMapping("/landForced")
+ public AjaxResult landForced(@RequestBody LandForcedDTO landForcedDTO) {
+ tyService.landForced(landForcedDTO);
+ return AjaxResult.success();
+ }
+
+ @ApiOperation(value = "方向控制", notes = "前后速度frSpeed:【前0至30 后0至-30】单位m/s " +
+ "左右速度lrSpeed:【右0至30 左0至-30】单位m/s " +
+ "上下速度udSpeed:【上0至5 后0至-5 】单位m/s 偏航角yaw:-150~150 deg/s")
+ @ApiOperationSupport(order = 8)
+ @PostMapping("/flyControl")
+ public AjaxResult flyControl(@RequestBody FlyControlDTO flyControlDTO) {
+ tyService.flyControl(flyControlDTO);
+ return AjaxResult.success();
+ }
+
+ @ApiOperation(value = "开始指点飞行", notes = "速度speed:0~20 单位m/s " +
+ "飞行模式flyMode:0-节能模式【飞机直线飞到目标点,需飞机在空中】," +
+ "1-安全模式【飞机飞行至目标点高度再平飞到目标点,飞机可以在地面或空中】 默认为节能模式")
+ @ApiOperationSupport(order = 9)
+ @PostMapping("/flyPointControl")
+ public AjaxResult flyPointControl(@RequestBody FlyPointControlDTO flyPointControlDTO) {
+ tyService.flyPointControl(flyPointControlDTO);
+ return AjaxResult.success();
+ }
+
+ @ApiOperation("停止指点飞行")
+ @ApiOperationSupport(order = 10)
+ @PostMapping("/flyPointControlCancel")
+ public AjaxResult flyPointControlCancel(@RequestBody FlyPointControlCancelDTO flyPointControlCancelDTO) {
+ tyService.flyPointControlCancel(flyPointControlCancelDTO);
+ return AjaxResult.success();
+ }
+
+ @ApiOperation(value = "紧急制动", notes = "动作参数actionParam: 0-解除紧急制动 1-紧急制动")
+ @ApiOperationSupport(order = 11)
+ @PostMapping("/emeragencyBrake")
+ public AjaxResult emeragencyBrake(@RequestBody EmeragencyBrakeDTO emeragencyBrakeDTO) {
+ tyService.emeragencyBrake(emeragencyBrakeDTO);
+ return AjaxResult.success();
+ }
}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java b/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
index 303fa79..b67b86f 100644
--- a/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
+++ b/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
@@ -54,5 +54,5 @@
* 修改云盒设置
*/
@Post(TyConst.POST_BOX_UPDATE)
- TyHttpCommonReceiver updateBoxSettings(@JSONBody BoxSettingsDTO boxSettingsDTO, @Header Map<String, String> headers);
+ TyHttpCommonReceiver<?> updateBoxSettings(@JSONBody BoxSettingsDTO boxSettingsDTO, @Header Map<String, String> headers);
}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/BoxSettingsDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/BoxSettingsDTO.java
index 5e607d5..bd6be4e 100644
--- a/ard-work/src/main/java/com/ard/tianyu/model/dto/BoxSettingsDTO.java
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/BoxSettingsDTO.java
@@ -34,41 +34,41 @@
* 照片实时回传开关,0-关闭,1-开启
*/
@JsonProperty("openImgRtp")
- private String openImgRtp;
+ private Integer openImgRtp;
/**
* 视频包排序开关,0-关闭,1-开启(排序会增加视频延时)
*/
@JsonProperty("openVideoSort")
- private String openVideoSort;
+ private Integer openVideoSort;
/**
* 云端视频存储开关,0-关闭,1-开启
*/
@JsonProperty("openVideoStorage")
- private String openVideoStorage;
+ private Integer openVideoStorage;
/**
* 视频自动推流开关,0-关闭,1-开启
*/
@JsonProperty("videoAutoPush")
- private String videoAutoPush;
+ private Integer videoAutoPush;
/**
* 云盒固件自动升级开关,0-关闭,1-开启
*/
@JsonProperty("autoUpdate")
- private String autoUpdate;
+ private Integer autoUpdate;
/**
* 云盒与平台失联xx秒后自动返航
*/
@JsonProperty("lostTime")
- private String lostTime;
+ private Integer lostTime;
/**
* 低电量自动返航开关:0-关闭,1-智能计算,xx-指定的返航电量
*/
@JsonProperty("minHomeBattery")
- private String minHomeBattery;
+ private Integer minHomeBattery;
}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/EmeragencyBrakeDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/EmeragencyBrakeDTO.java
new file mode 100644
index 0000000..bb2af4c
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/EmeragencyBrakeDTO.java
@@ -0,0 +1,23 @@
+package com.ard.tianyu.model.dto.manual;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 紧急制动实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class EmeragencyBrakeDTO {
+ private String boxSn;
+
+ //0x00-解除紧急制动 0x01-紧急制动
+ private byte actionParam;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyControlDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyControlDTO.java
new file mode 100644
index 0000000..6f616af
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyControlDTO.java
@@ -0,0 +1,40 @@
+package com.ard.tianyu.model.dto.manual;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 方向控制实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class FlyControlDTO {
+
+ private String boxSn;
+
+ /**
+ * 前后速度
+ */
+ private Float frSpeed;
+ /**
+ * 左右速度
+ */
+ private Float lrSpeed;
+ /**
+ * 上下速度
+ */
+ private Float udSpeed;
+
+ /**
+ * 偏航角
+ */
+ private Float yaw;
+
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyPointControlCancelDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyPointControlCancelDTO.java
new file mode 100644
index 0000000..1d2af00
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyPointControlCancelDTO.java
@@ -0,0 +1,20 @@
+package com.ard.tianyu.model.dto.manual;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 停止指点飞行实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class FlyPointControlCancelDTO {
+ private String boxSn;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyPointControlDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyPointControlDTO.java
new file mode 100644
index 0000000..40ac18d
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/FlyPointControlDTO.java
@@ -0,0 +1,46 @@
+package com.ard.tianyu.model.dto.manual;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 指点飞行控制实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class FlyPointControlDTO {
+
+ private String boxSn;
+
+ /**
+ * 经度
+ */
+ private Double longitude;
+ /**
+ * 纬度
+ */
+ private Double latitude;
+ /**
+ * 高度
+ */
+ private Float altitude;
+
+ /**
+ * 速度
+ */
+ private Float speed;
+
+ /**
+ * 飞行模式
+ */
+ @Builder.Default
+ private byte flyMode = 0;
+
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandCancelDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandCancelDTO.java
new file mode 100644
index 0000000..bb50469
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandCancelDTO.java
@@ -0,0 +1,20 @@
+package com.ard.tianyu.model.dto.manual;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 取消降落实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class LandCancelDTO {
+ private String boxSn;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandDTO.java
new file mode 100644
index 0000000..a81d15e
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandDTO.java
@@ -0,0 +1,20 @@
+package com.ard.tianyu.model.dto.manual;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 降落实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class LandDTO {
+ private String boxSn;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandForcedDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandForcedDTO.java
new file mode 100644
index 0000000..6a5a519
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/LandForcedDTO.java
@@ -0,0 +1,20 @@
+package com.ard.tianyu.model.dto.manual;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 取消降落实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class LandForcedDTO {
+ private String boxSn;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeCancelDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeCancelDTO.java
new file mode 100644
index 0000000..af885c3
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeCancelDTO.java
@@ -0,0 +1,21 @@
+package com.ard.tianyu.model.dto.manual;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * 取消返航实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ReturnHomeCancelDTO {
+ private String boxSn;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeDTO.java
index fa22f5a..2fd48fb 100644
--- a/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeDTO.java
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/manual/ReturnHomeDTO.java
@@ -19,7 +19,6 @@
@Builder
@AllArgsConstructor
@NoArgsConstructor
-@Validated
public class ReturnHomeDTO {
private String boxSn;
}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/PointFlyCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/PointFlyCmd.java
deleted file mode 100644
index 46be995..0000000
--- a/ard-work/src/main/java/com/ard/tianyu/netty/command/PointFlyCmd.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ard.tianyu.netty.command;// PointFlyCommand.java
-import io.netty.buffer.ByteBuf;
-
-public class PointFlyCmd extends BaseCmd {
- private double longitude;
- private double latitude;
- private float height;
- private float speed;
-
- public PointFlyCmd(double longitude, double latitude, float height, float speed) {
- this.longitude = longitude;
- this.latitude = latitude;
- this.height = height;
- this.speed = speed;
- setDataHeader((short) 0x7479);
- setCmdCode((byte) 0xD1);
- setDataLength((short) 17); // 数据长度计算
- }
-
- @Override
- public void encode(ByteBuf out) {
- out.writeShort(getDataHeader()); // 写入数据头
- out.writeShort(getDataLength()); // 写入数据长度
- out.writeByte(getCmdCode()); // 写入命令码
- out.writeDouble(longitude); // 写入经度
- out.writeDouble(latitude); // 写入纬度
- out.writeFloat(height); // 写入高度
- out.writeFloat(speed); // 写入速度
- }
-}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/EmergencyBrakeCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/EmergencyBrakeCmd.java
new file mode 100644
index 0000000..761ee74
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/EmergencyBrakeCmd.java
@@ -0,0 +1,35 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.EmeragencyBrakeDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 紧急制动指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+public class EmergencyBrakeCmd extends BaseCmd {
+
+ private final byte actionParam; //动作参数
+
+ public EmergencyBrakeCmd(EmeragencyBrakeDTO emeragencyBrakeDTO) {
+ setDataHeader((short) 0x7479);
+ setDataLength((short) 19);
+ setBoxSn(emeragencyBrakeDTO.getBoxSn().getBytes());
+ setCmdCode((byte) 0xD1);
+ this.actionParam = emeragencyBrakeDTO.getActionParam();
+ }
+
+
+ public void encode(ByteBuf out) {
+ out.writeShort(getDataHeader()); // 写入数据头
+ out.writeShort(getDataLength()); // 写入数据长度
+ out.writeBytes(getBoxSn()); // 写入盒子SN
+ out.writeByte(getCmdCode()); // 写入命令码
+ out.writeByte(0x00); // 写入加密标志
+ out.writeByte(0x32); // 写入动作编号
+ out.writeByte(this.actionParam); // 写入动作参数
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/EmergencyBrakeReplyCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/EmergencyBrakeReplyCmd.java
new file mode 100644
index 0000000..3ed5bf3
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/EmergencyBrakeReplyCmd.java
@@ -0,0 +1,34 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.EmeragencyBrakeDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+
+/**
+ * 紧急制动回复指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+@Data
+public class EmergencyBrakeReplyCmd extends BaseCmd {
+
+ private final byte encryptFlag = 0x00; // 加密标志
+ private final byte actionCode = 0x32; // 动作编号
+ private final byte result; // 执行结果
+ private final Integer errorCode; // 错误码
+
+ public EmergencyBrakeReplyCmd(String boxSn, Byte result, Integer errorCode) {
+ setDataHeader((short) 0x6A77);
+ setDataLength((short) 23);
+ setBoxSn(boxSn.getBytes());
+ setCmdCode((byte) 0xD1);
+ this.result = result;
+ this.errorCode = errorCode;
+ }
+
+ public void encode(ByteBuf out) {
+
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyControlCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyControlCmd.java
new file mode 100644
index 0000000..e0f4811
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyControlCmd.java
@@ -0,0 +1,45 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.FlyControlDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 方向控制指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+public class FlyControlCmd extends BaseCmd {
+ private final float frSpeed; // 前后速度
+ private final float lrSpeed; // 左右速度
+ private final float udSpeed; // 上下速度
+ private final float yaw; // 偏航角
+ private final short execTime = 200; // 执行时间
+
+ public FlyControlCmd(FlyControlDTO flyControlDTO) {
+ setDataHeader((short) 0x7479);
+ setDataLength((short) 36);
+ setBoxSn(flyControlDTO.getBoxSn().getBytes());
+ setCmdCode((byte) 0xD1);
+ this.frSpeed = flyControlDTO.getFrSpeed();
+ this.lrSpeed = flyControlDTO.getLrSpeed();
+ this.udSpeed = flyControlDTO.getUdSpeed();
+ this.yaw = flyControlDTO.getYaw();
+ }
+
+
+ public void encode(ByteBuf out) {
+ out.writeShort(getDataHeader()); // 写入数据头
+ out.writeShort(getDataLength()); // 写入数据长度
+ out.writeBytes(getBoxSn()); // 写入盒子SN
+ out.writeByte(getCmdCode()); // 写入命令码
+ out.writeByte(0x00); // 写入加密标志
+ out.writeByte(0x28); // 写入动作编号
+ out.writeFloat(frSpeed); // 写入前后速度
+ out.writeFloat(lrSpeed); // 写入左右速度
+ out.writeFloat(udSpeed); // 写入上下速度
+ out.writeFloat(yaw); // 写入偏航角
+ out.writeShort(execTime); // 写入执行时间
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyPointControlCancelCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyPointControlCancelCmd.java
new file mode 100644
index 0000000..3c345f7
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyPointControlCancelCmd.java
@@ -0,0 +1,32 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.FlyPointControlCancelDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 停止指点飞行指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+public class FlyPointControlCancelCmd extends BaseCmd {
+
+
+ public FlyPointControlCancelCmd(FlyPointControlCancelDTO flyPointControlCancelDTO) {
+ setDataHeader((short) 0x7479);
+ setDataLength((short) 18);
+ setBoxSn(flyPointControlCancelDTO.getBoxSn().getBytes());
+ setCmdCode((byte) 0xD1);
+ }
+
+
+ public void encode(ByteBuf out) {
+ out.writeShort(getDataHeader()); // 写入数据头
+ out.writeShort(getDataLength()); // 写入数据长度
+ out.writeBytes(getBoxSn()); // 写入盒子SN
+ out.writeByte(getCmdCode()); // 写入命令码
+ out.writeByte(0x00); // 写入加密标志
+ out.writeByte(0x3A); // 写入动作编号
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyPointControlCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyPointControlCmd.java
new file mode 100644
index 0000000..5838ea7
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/FlyPointControlCmd.java
@@ -0,0 +1,46 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.FlyPointControlDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 指点飞行控制指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+public class FlyPointControlCmd extends BaseCmd {
+ private final double longitude; // 经度
+ private final double latitude; // 纬度
+ private final float altitude; // 高度
+ private final float speed; // 速度
+ private final byte flyMode; // 飞行模式
+
+ public FlyPointControlCmd(FlyPointControlDTO flyPointControlDTO) {
+ setDataHeader((short) 0x7479);
+ setDataLength((short) 36);
+ setBoxSn(flyPointControlDTO.getBoxSn().getBytes());
+ setCmdCode((byte) 0xD1);
+ this.longitude = flyPointControlDTO.getLongitude();
+ this.latitude = flyPointControlDTO.getLatitude();
+ this.altitude = flyPointControlDTO.getAltitude();
+ this.speed = flyPointControlDTO.getSpeed();
+ this.flyMode = flyPointControlDTO.getFlyMode();
+ }
+
+
+ public void encode(ByteBuf out) {
+ out.writeShort(getDataHeader()); // 写入数据头
+ out.writeShort(getDataLength()); // 写入数据长度
+ out.writeBytes(getBoxSn()); // 写入盒子SN
+ out.writeByte(getCmdCode()); // 写入命令码
+ out.writeByte(0x00); // 写入加密标志
+ out.writeByte(0x39); // 写入动作编号
+ out.writeDouble(longitude); // 写入经度
+ out.writeDouble(latitude); // 写入纬度
+ out.writeFloat(altitude); // 写入高度
+ out.writeFloat(speed); // 写入速度
+ out.writeByte(flyMode); // 写入飞行模式
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCancelCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCancelCmd.java
new file mode 100644
index 0000000..b791898
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCancelCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.LandCancelDTO;
+import com.ard.tianyu.model.dto.manual.LandDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 取消降落指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+public class LandCancelCmd extends BaseCmd {
+
+
+ public LandCancelCmd(LandCancelDTO landCancleDTO) {
+ setDataHeader((short) 0x7479);
+ setDataLength((short) 18);
+ setBoxSn(landCancleDTO.getBoxSn().getBytes());
+ setCmdCode((byte) 0xD1);
+ }
+
+
+ public void encode(ByteBuf out) {
+ out.writeShort(getDataHeader()); // 写入数据头
+ out.writeShort(getDataLength()); // 写入数据长度
+ out.writeBytes(getBoxSn()); // 写入盒子SN
+ out.writeByte(getCmdCode()); // 写入命令码
+ out.writeByte(0x00); // 写入加密标志
+ out.writeByte(0x15); // 写入动作编号
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCancelReplyCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCancelReplyCmd.java
new file mode 100644
index 0000000..3de41ce
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCancelReplyCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+
+/**
+ * 取消降落回复指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+@Data
+public class LandCancelReplyCmd extends BaseCmd {
+
+ private final byte encryptFlag = 0x00; // 加密标志
+ private final byte actionCode = 0x15; // 动作编号
+ private final byte result; // 执行结果
+ private final Integer errorCode; // 错误码
+
+ public LandCancelReplyCmd(String boxSn, Byte result, Integer errorCode) {
+ setDataHeader((short) 0x6A77);
+ setDataLength((short) 23);
+ setBoxSn(boxSn.getBytes());
+ setCmdCode((byte) 0xD1);
+ this.result = result;
+ this.errorCode = errorCode;
+ }
+
+ public void encode(ByteBuf out) {
+
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCmd.java
new file mode 100644
index 0000000..384ce0a
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.LandDTO;
+import com.ard.tianyu.model.dto.manual.ReturnHomeCancelDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 降落指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+public class LandCmd extends BaseCmd {
+
+
+ public LandCmd(LandDTO landDTO) {
+ setDataHeader((short) 0x7479);
+ setDataLength((short) 18);
+ setBoxSn(landDTO.getBoxSn().getBytes());
+ setCmdCode((byte) 0xD1);
+ }
+
+
+ public void encode(ByteBuf out) {
+ out.writeShort(getDataHeader()); // 写入数据头
+ out.writeShort(getDataLength()); // 写入数据长度
+ out.writeBytes(getBoxSn()); // 写入盒子SN
+ out.writeByte(getCmdCode()); // 写入命令码
+ out.writeByte(0x00); // 写入加密标志
+ out.writeByte(0x14); // 写入动作编号
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandForcedCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandForcedCmd.java
new file mode 100644
index 0000000..758380c
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandForcedCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.LandCancelDTO;
+import com.ard.tianyu.model.dto.manual.LandForcedDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 强制降落指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+public class LandForcedCmd extends BaseCmd {
+
+
+ public LandForcedCmd(LandForcedDTO landForcedDTO) {
+ setDataHeader((short) 0x7479);
+ setDataLength((short) 18);
+ setBoxSn(landForcedDTO.getBoxSn().getBytes());
+ setCmdCode((byte) 0xD1);
+ }
+
+
+ public void encode(ByteBuf out) {
+ out.writeShort(getDataHeader()); // 写入数据头
+ out.writeShort(getDataLength()); // 写入数据长度
+ out.writeBytes(getBoxSn()); // 写入盒子SN
+ out.writeByte(getCmdCode()); // 写入命令码
+ out.writeByte(0x00); // 写入加密标志
+ out.writeByte(0x29); // 写入动作编号
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandForcedReplyCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandForcedReplyCmd.java
new file mode 100644
index 0000000..ee7cb16
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandForcedReplyCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+
+/**
+ * 强制降落回复指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+@Data
+public class LandForcedReplyCmd extends BaseCmd {
+
+ private final byte encryptFlag = 0x00; // 加密标志
+ private final byte actionCode = 0x29; // 动作编号
+ private final byte result; // 执行结果
+ private final Integer errorCode; // 错误码
+
+ public LandForcedReplyCmd(String boxSn, Byte result, Integer errorCode) {
+ setDataHeader((short) 0x6A77);
+ setDataLength((short) 23);
+ setBoxSn(boxSn.getBytes());
+ setCmdCode((byte) 0xD1);
+ this.result = result;
+ this.errorCode = errorCode;
+ }
+
+ public void encode(ByteBuf out) {
+
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandReplyCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandReplyCmd.java
new file mode 100644
index 0000000..311d554
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/LandReplyCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+
+/**
+ * 降落回复指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+@Data
+public class LandReplyCmd extends BaseCmd {
+
+ private final byte encryptFlag = 0x00; // 加密标志
+ private final byte actionCode = 0x14; // 动作编号
+ private final byte result; // 执行结果
+ private final Integer errorCode; // 错误码
+
+ public LandReplyCmd(String boxSn, Byte result, Integer errorCode) {
+ setDataHeader((short) 0x6A77);
+ setDataLength((short) 23);
+ setBoxSn(boxSn.getBytes());
+ setCmdCode((byte) 0xD1);
+ this.result = result;
+ this.errorCode = errorCode;
+ }
+
+ public void encode(ByteBuf out) {
+
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/PointControlReachedReplyCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/PointControlReachedReplyCmd.java
new file mode 100644
index 0000000..001ff9b
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/PointControlReachedReplyCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+
+/**
+ * 到达指点飞行位置回复指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+@Data
+public class PointControlReachedReplyCmd extends BaseCmd {
+
+ private final byte encryptFlag = 0x00; // 加密标志
+ private final byte actionCode = 0x39; // 动作编号
+ private final byte result; // 执行结果
+ private final Integer errorCode; // 错误码
+
+ public PointControlReachedReplyCmd(String boxSn, Byte result, Integer errorCode) {
+ setDataHeader((short) 0x6A77);
+ setDataLength((short) 19);
+ setBoxSn(boxSn.getBytes());
+ setCmdCode((byte) 0xD1);
+ this.result = result;
+ this.errorCode = errorCode;
+ }
+
+ public void encode(ByteBuf out) {
+
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/ReturnHomeCancelCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/ReturnHomeCancelCmd.java
new file mode 100644
index 0000000..be109fc
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/ReturnHomeCancelCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.model.dto.manual.ReturnHomeCancelDTO;
+import com.ard.tianyu.model.dto.manual.ReturnHomeDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 取消返航指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+public class ReturnHomeCancelCmd extends BaseCmd {
+
+
+ public ReturnHomeCancelCmd(ReturnHomeCancelDTO returnHomeCancelDTO) {
+ setDataHeader((short) 0x7479);
+ setDataLength((short) 18);
+ setBoxSn(returnHomeCancelDTO.getBoxSn().getBytes());
+ setCmdCode((byte) 0xD1);
+ }
+
+
+ public void encode(ByteBuf out) {
+ out.writeShort(getDataHeader()); // 写入数据头
+ out.writeShort(getDataLength()); // 写入数据长度
+ out.writeBytes(getBoxSn()); // 写入盒子SN
+ out.writeByte(getCmdCode()); // 写入命令码
+ out.writeByte(0x00); // 写入加密标志
+ out.writeByte(0x13); // 写入动作编号
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/ReturnHomeCancelReplyCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/ReturnHomeCancelReplyCmd.java
new file mode 100644
index 0000000..52e356a
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/manual/ReturnHomeCancelReplyCmd.java
@@ -0,0 +1,33 @@
+package com.ard.tianyu.netty.command.manual;
+
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+
+/**
+ * 取消返航回复指令
+ *
+ * @author liusuyi
+ * @date 2024年10月26日15:43
+ **/
+@Data
+public class ReturnHomeCancelReplyCmd extends BaseCmd {
+
+ private final byte encryptFlag = 0x00; // 加密标志
+ private final byte actionCode = 0x13; // 动作编号
+ private final byte result; // 执行结果
+ private final Integer errorCode; // 错误码
+
+ public ReturnHomeCancelReplyCmd(String boxSn, Byte result, Integer errorCode) {
+ setDataHeader((short) 0x6A77);
+ setDataLength((short) 23);
+ setBoxSn(boxSn.getBytes());
+ setCmdCode((byte) 0xD1);
+ this.result = result;
+ this.errorCode = errorCode;
+ }
+
+ public void encode(ByteBuf out) {
+
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java b/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java
index 10b9d63..27fe205 100644
--- a/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java
@@ -5,8 +5,7 @@
import com.ard.tianyu.netty.command.camera.CapturePicReplyCmd;
import com.ard.tianyu.netty.command.camera.RecordStartReplyCmd;
import com.ard.tianyu.netty.command.camera.RecordStopReplyCmd;
-import com.ard.tianyu.netty.command.manual.ReturnHomeReplyCmd;
-import com.ard.tianyu.netty.command.manual.TakeOffReplyCmd;
+import com.ard.tianyu.netty.command.manual.*;
import com.ard.tianyu.netty.command.notice.BoxPowerStatusReplyCmd;
import com.ard.tianyu.netty.command.notice.FlyWayEndReplyCmd;
import com.ard.tianyu.netty.command.notice.UavReadyReplyCmd;
@@ -112,6 +111,60 @@
baseCmd = new ReturnHomeReplyCmd(boxSn, result, errorCode);
log.debug("返航回复: {}", boxSn);
break;
+ case 0x13:
+ result = in.readByte();
+ errorCode = in.readInt();
+ uavData = new byte[15];
+ in.readBytes(uavData);
+ boxSn = new String(uavData);
+ baseCmd = new ReturnHomeCancelReplyCmd(boxSn, result, errorCode);
+ log.debug("取消返航回复: {}", boxSn);
+ break;
+ case 0x14:
+ result = in.readByte();
+ errorCode = in.readInt();
+ uavData = new byte[15];
+ in.readBytes(uavData);
+ boxSn = new String(uavData);
+ baseCmd = new LandReplyCmd(boxSn, result, errorCode);
+ log.debug("降落回复: {}", boxSn);
+ break;
+ case 0x15:
+ result = in.readByte();
+ errorCode = in.readInt();
+ uavData = new byte[15];
+ in.readBytes(uavData);
+ boxSn = new String(uavData);
+ baseCmd = new LandCancelReplyCmd(boxSn, result, errorCode);
+ log.debug("取消降落回复: {}", boxSn);
+ break;
+ case 0x29:
+ result = in.readByte();
+ errorCode = in.readInt();
+ uavData = new byte[15];
+ in.readBytes(uavData);
+ boxSn = new String(uavData);
+ baseCmd = new LandForcedReplyCmd(boxSn, result, errorCode);
+ log.debug("强制降落回复: {}", boxSn);
+ break;
+ case 0x32:
+ result = in.readByte();
+ errorCode = in.readInt();
+ uavData = new byte[15];
+ in.readBytes(uavData);
+ boxSn = new String(uavData);
+ baseCmd = new EmergencyBrakeReplyCmd(boxSn, result, errorCode);
+ log.debug("紧急制动回复: {}", boxSn);
+ break;
+ case 0x39:
+ result = in.readByte();
+ errorCode = in.readInt();
+ uavData = new byte[15];
+ in.readBytes(uavData);
+ boxSn = new String(uavData);
+ baseCmd = new PointControlReachedReplyCmd(boxSn, result, errorCode);
+ log.debug("到达指点飞行位置回复: {}", boxSn);
+ break;
case 0x22:
result = in.readByte();
errorCode = in.readInt();
diff --git a/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java b/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
index 2308965..612fcb2 100644
--- a/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
+++ b/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
@@ -7,9 +7,7 @@
import com.ard.tianyu.model.dto.control.AbsAngleControlDTO;
import com.ard.tianyu.model.dto.control.AngleControlDTO;
import com.ard.tianyu.model.dto.control.SpeedControlDTO;
-import com.ard.tianyu.model.dto.manual.ReturnHomeDTO;
-import com.ard.tianyu.model.dto.manual.SwitchUavControlDTO;
-import com.ard.tianyu.model.dto.manual.TakeOffDTO;
+import com.ard.tianyu.model.dto.manual.*;
import com.ard.tianyu.model.dto.signal.SignalInfo;
import com.ard.tianyu.model.dto.state.UavState;
import com.ard.tianyu.model.dto.telemetry.TelemetryData;
@@ -138,6 +136,47 @@
* 返航
*/
void returnHome(ReturnHomeDTO returnHomeDTO);
+
+ /**
+ * 取消返航
+ */
+ void returnHomeCancel(ReturnHomeCancelDTO returnHomeCancelDTO);
+
+ /**
+ * 降落
+ */
+ void land(LandDTO landDTO);
+
+ /**
+ * 取消降落
+ */
+ void landCancel(LandCancelDTO landCancelDTO);
+
+ /**
+ * 强制降落
+ */
+ void landForced(LandForcedDTO landForcedDTO);
+
+ /**
+ * 方向控制
+ */
+ void flyControl(FlyControlDTO flyControlDTO);
+
+ /**
+ * 指点飞行控制
+ */
+ void flyPointControl(FlyPointControlDTO flyPointControlDTO);
+
+ /**
+ * 停止指点飞行控制
+ */
+ void flyPointControlCancel(FlyPointControlCancelDTO flyPointControlCancelDTO);
+
+ /**
+ * 紧急制动
+ */
+ void emeragencyBrake(EmeragencyBrakeDTO emeragencyBrakeDTO);
+
/**
* 获取无人机状态
*/
diff --git a/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java b/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
index f995b0f..88d749c 100644
--- a/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
@@ -15,9 +15,7 @@
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.manual.ReturnHomeDTO;
-import com.ard.tianyu.model.dto.manual.SwitchUavControlDTO;
-import com.ard.tianyu.model.dto.manual.TakeOffDTO;
+import com.ard.tianyu.model.dto.manual.*;
import com.ard.tianyu.model.dto.signal.SignalInfo;
import com.ard.tianyu.model.dto.state.UavState;
import com.ard.tianyu.model.dto.telemetry.TelemetryData;
@@ -38,6 +36,7 @@
import com.ard.tianyu.netty.command.register.*;
import com.ard.tianyu.netty.handler.ErrorCodeEnum;
import com.ard.tianyu.service.ITyService;
+import com.ard.tianyu.websocket.utils.WebSocketUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import lombok.extern.slf4j.Slf4j;
@@ -300,6 +299,78 @@
}
/**
+ * 取消返航
+ */
+ @Override
+ public void returnHomeCancel(ReturnHomeCancelDTO returnHomeCancelDTO) {
+ ReturnHomeCancelCmd returnHomeCancelCmd = new ReturnHomeCancelCmd(returnHomeCancelDTO);
+ this.sendMessage(tyConfiguration.getIpPort(), returnHomeCancelCmd);
+ }
+
+ /**
+ * 降落
+ */
+ @Override
+ public void land(LandDTO landDTO) {
+ LandCmd landCmd = new LandCmd(landDTO);
+ this.sendMessage(tyConfiguration.getIpPort(), landCmd);
+ }
+
+ /**
+ * 取消降落
+ */
+ @Override
+ public void landCancel(LandCancelDTO landCancelDTO) {
+ LandCancelCmd landCancelCmd = new LandCancelCmd(landCancelDTO);
+ this.sendMessage(tyConfiguration.getIpPort(), landCancelCmd);
+ }
+
+ /**
+ * 强制降落
+ */
+ @Override
+ public void landForced(LandForcedDTO landForcedDTO) {
+ LandForcedCmd landForcedCmd = new LandForcedCmd(landForcedDTO);
+ this.sendMessage(tyConfiguration.getIpPort(), landForcedCmd);
+ }
+
+ /**
+ * 方向控制
+ */
+ @Override
+ public void flyControl(FlyControlDTO flyControlDTO) {
+ FlyControlCmd flyControlCmd = new FlyControlCmd(flyControlDTO);
+ this.sendMessage(tyConfiguration.getIpPort(), flyControlCmd);
+ }
+
+ /**
+ * 指点飞行控制
+ */
+ @Override
+ public void flyPointControl(FlyPointControlDTO flyPointControlDTO) {
+ FlyPointControlCmd flyPointControlCmd = new FlyPointControlCmd(flyPointControlDTO);
+ this.sendMessage(tyConfiguration.getIpPort(), flyPointControlCmd);
+ }
+
+ /**
+ * 停止指点飞行控制
+ */
+ @Override
+ public void flyPointControlCancel(FlyPointControlCancelDTO flyPointControlCancelDTO) {
+ FlyPointControlCancelCmd flyPointControlCancelCmd = new FlyPointControlCancelCmd(flyPointControlCancelDTO);
+ this.sendMessage(tyConfiguration.getIpPort(), flyPointControlCancelCmd);
+ }
+
+ /**
+ * 紧急制动
+ */
+ @Override
+ public void emeragencyBrake(EmeragencyBrakeDTO emeragencyBrakeDTO) {
+ EmergencyBrakeCmd emergencyBrakeCmd=new EmergencyBrakeCmd(emeragencyBrakeDTO);
+ this.sendMessage(tyConfiguration.getIpPort(), emergencyBrakeCmd);
+ }
+
+ /**
* 获取无人机状态
*/
@Override
@@ -362,6 +433,7 @@
UavState uavState = UavStateConverter.convertProtoToEntity(uavStateCmd.getUavState());
UavStateCache.putUavState(uavState);
logPrint("无人机状态", uavState.getBoxSn());
+ WebSocketUtil.sendMessageAll(uavState);
break;
case (byte) 0xA9:
// 处理无人机遥测消息
@@ -419,6 +491,36 @@
ReturnHomeReplyCmd returnHomeReplyCmd = (ReturnHomeReplyCmd) tyCommand;
logPrint("无人机返航", returnHomeReplyCmd.getResult(), returnHomeReplyCmd.getErrorCode());
}
+ //取消返航回复
+ if (tyCommand instanceof ReturnHomeCancelReplyCmd) {
+ ReturnHomeCancelReplyCmd returnHomeCancelReplyCmd = (ReturnHomeCancelReplyCmd) tyCommand;
+ logPrint("取消无人机返航", returnHomeCancelReplyCmd.getResult(), returnHomeCancelReplyCmd.getErrorCode());
+ }
+ //降落回复
+ if (tyCommand instanceof LandReplyCmd) {
+ LandReplyCmd landReplyCmd = (LandReplyCmd) tyCommand;
+ logPrint("降落", landReplyCmd.getResult(), landReplyCmd.getErrorCode());
+ }
+ //取消降落回复
+ if (tyCommand instanceof LandCancelReplyCmd) {
+ LandCancelReplyCmd landCancelReplyCmd = (LandCancelReplyCmd) tyCommand;
+ logPrint("取消降落", landCancelReplyCmd.getResult(), landCancelReplyCmd.getErrorCode());
+ }
+ //强制降落回复
+ if (tyCommand instanceof LandForcedReplyCmd) {
+ LandForcedReplyCmd landForcedReplyCmd = (LandForcedReplyCmd) tyCommand;
+ logPrint("强制降落", landForcedReplyCmd.getResult(), landForcedReplyCmd.getErrorCode());
+ }
+ //到达指点飞行位置回复
+ if (tyCommand instanceof PointControlReachedReplyCmd) {
+ PointControlReachedReplyCmd pointControlReachedReplyCmd = (PointControlReachedReplyCmd) tyCommand;
+ logPrint("到达指点飞行位置", pointControlReachedReplyCmd.getResult(), pointControlReachedReplyCmd.getErrorCode());
+ }
+ //紧急制动回复
+ if (tyCommand instanceof EmergencyBrakeReplyCmd) {
+ EmergencyBrakeReplyCmd emergencyBrakeReplyCmd = (EmergencyBrakeReplyCmd) tyCommand;
+ logPrint("紧急制动回复", emergencyBrakeReplyCmd.getResult(), emergencyBrakeReplyCmd.getErrorCode());
+ }
break;
default:
// 处理其他消息
@@ -430,6 +532,7 @@
private void logPrint(String message, Object obj) {
log.debug("收到{}回复{}", message, obj);
}
+
//公共日志打印
private void logPrint(String message, byte result, Integer errorCode) {
log.info("收到{}回复:{} 错误码:{}【{}】",
diff --git a/ard-work/src/main/java/com/ard/tianyu/websocket/config/WebSocketConfig.java b/ard-work/src/main/java/com/ard/tianyu/websocket/config/WebSocketConfig.java
new file mode 100644
index 0000000..e43f086
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/websocket/config/WebSocketConfig.java
@@ -0,0 +1,27 @@
+package com.ard.tianyu.websocket.config;
+
+import com.ard.tianyu.websocket.handler.TyMessageHandler;
+import com.ard.tianyu.websocket.interceptor.TyHandshakeInterceptor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import javax.annotation.Resource;
+
+@Configuration
+@EnableWebSocket
+public class WebSocketConfig implements WebSocketConfigurer {
+
+ @Resource
+ private TyMessageHandler tyMessageHandler;
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ //添加myWebSocketHandler消息处理对象以及websocket连接地址
+ registry.addHandler(tyMessageHandler, "/ws/**")
+ //设置允许跨域访问
+ .setAllowedOrigins("*")
+ //添加拦截器可实现用户链接前进行权限校验等操作
+ .addInterceptors(new TyHandshakeInterceptor());
+ }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/websocket/handler/TyMessageHandler.java b/ard-work/src/main/java/com/ard/tianyu/websocket/handler/TyMessageHandler.java
new file mode 100644
index 0000000..58b5969
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/websocket/handler/TyMessageHandler.java
@@ -0,0 +1,39 @@
+package com.ard.tianyu.websocket.handler;
+
+import com.ard.tianyu.websocket.utils.WebSocketUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.CloseStatus;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+import org.springframework.web.socket.handler.TextWebSocketHandler;
+
+@Component
+@Slf4j
+public class TyMessageHandler extends TextWebSocketHandler {
+
+ @Override
+ public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+ // 处理接收到的消息
+ String payload = message.getPayload();
+ log.info("【websocket】Received message: " + payload);
+ log.info("【websocket】size: " + WebSocketUtil.ONLINE_USER_SESSIONS.size());
+ }
+
+ @Override
+ public void afterConnectionEstablished(WebSocketSession session) {
+ log.info("【websocket】Connected: " + session.getId());
+ String userId = (String) session.getAttributes().get("userId");
+ WebSocketUtil.ONLINE_USER_SESSIONS.put(userId, session);
+ log.info("【websocket】size: " + WebSocketUtil.ONLINE_USER_SESSIONS.size());
+
+ }
+
+ @Override
+ public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
+ log.info("【websocket】Disconnected: " + session.getId());
+ String userId = (String) session.getAttributes().get("userId");
+ WebSocketUtil.ONLINE_USER_SESSIONS.remove(userId);
+ log.info("【websocket】size: " + WebSocketUtil.ONLINE_USER_SESSIONS.size());
+ }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/websocket/interceptor/TyHandshakeInterceptor.java b/ard-work/src/main/java/com/ard/tianyu/websocket/interceptor/TyHandshakeInterceptor.java
new file mode 100644
index 0000000..b324841
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/websocket/interceptor/TyHandshakeInterceptor.java
@@ -0,0 +1,35 @@
+package com.ard.tianyu.websocket.interceptor;
+
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+import java.util.Map;
+
+public class TyHandshakeInterceptor implements HandshakeInterceptor {
+
+ @Override
+ public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
+ WebSocketHandler wsHandler, Map<String, Object> attributes){
+ //从路径中获取userId
+ String path = request.getURI().getPath();
+ String[] segments = path.split("/");
+ if (segments.length > 2) {
+ String userId = segments[segments.length - 1];
+ attributes.put("userId", userId);
+ }
+ //从header中获取userId
+// String userId = request.getHeaders().getFirst("userId");
+// if (userId != null)
+// {
+// attributes.put("userId", userId);
+// }
+ return true;
+ }
+
+ @Override
+ public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
+ WebSocketHandler wsHandler, Exception ex) {
+ }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/websocket/utils/WebSocketUtil.java b/ard-work/src/main/java/com/ard/tianyu/websocket/utils/WebSocketUtil.java
new file mode 100644
index 0000000..dc78204
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/websocket/utils/WebSocketUtil.java
@@ -0,0 +1,141 @@
+package com.ard.tianyu.websocket.utils;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @ClassName WebSocketUtils
+ * @Description: websocket工具类
+ * @Author 刘苏义
+ * @Date 2023/1/27 7:46
+ * @Version 1.0
+ */
+@Slf4j
+public final class WebSocketUtil {
+
+ // 存储 websocket session
+ public static final ConcurrentMap<String, WebSocketSession> ONLINE_USER_SESSIONS = new ConcurrentHashMap<>();
+
+ /**
+ * @param session 用户 session
+ * @param message 发送内容
+ */
+ public static void sendMessage(WebSocketSession session, String message) {
+ if (session == null) {
+ return;
+ }
+ final InetSocketAddress remoteAddress = session.getRemoteAddress();
+ if (remoteAddress == null) {
+ return;
+ }
+ synchronized (session) {
+ try {
+ log.debug("发送消息:" + message);
+ session.sendMessage(new TextMessage(String.join(", ", message)));
+ } catch (IOException e) {
+ log.error("sendMessage IOException ", e);
+ }
+ }
+ }
+
+ /**
+ * @param session 用户 session
+ * @param message 发送内容
+ */
+ public static void sendMessage(WebSocketSession session, Map message) {
+ if (session == null) {
+ return;
+ }
+ final InetSocketAddress remoteAddress = session.getRemoteAddress();
+ if (remoteAddress == null) {
+ return;
+ }
+ synchronized (session) {
+ try {
+ session.sendMessage(new TextMessage(JSONObject.toJSONString(message)));
+ } catch (IOException e) {
+ log.error("sendMessage IOException ", e);
+ }
+ }
+ }
+
+ public static void sendMessage(WebSocketSession session, List message) {
+ if (session == null) {
+ return;
+ }
+ final InetSocketAddress remoteAddress = session.getRemoteAddress();
+ if (remoteAddress == null) {
+ return;
+ }
+ synchronized (session) {
+ try {
+ session.sendMessage(new TextMessage(JSONObject.toJSONString(message)));
+ } catch (IOException e) {
+ log.error("sendMessage IOException ", e);
+ }
+ }
+ }
+
+ /**
+ * 推送消息到其他客户端
+ *
+ * @param message
+ */
+ public static void sendMessageAll(String message) {
+ ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, message));
+ }
+
+ /**
+ * 推送消息到其他客户端
+ *
+ * @param message
+ */
+ public static void sendMessageAll(Map message) {
+ JSONObject jsonObject = new JSONObject(message);
+ ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, jsonObject.toString()));
+ }
+ /**
+ * 推送消息到其他客户端
+ *
+ * @param message
+ */
+ public static void sendMessageAll(Object message) {
+ String jsonMessage = JSONObject.toJSONString(message); // 确保对象转换为 JSON 字符串
+ ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, jsonMessage));
+ }
+ /**
+ * 推送消息到其他客户端
+ *
+ * @param message
+ */
+ public static void sendMessageAll(List message) {
+ ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, JSON.toJSONString(message)));
+ }
+ /**
+ * @Author 刘苏义
+ * @Description 发送消息给userId_前缀的人
+ * @Date 2024/7/16 10:24
+ * @Param
+ * @return
+ */
+ public static void sendMessagePrefix(String targetId, String message) {
+ String regex = "^" + Pattern.quote(targetId) + "_\\d+$";
+ Pattern pattern = Pattern.compile(regex);
+ ONLINE_USER_SESSIONS.entrySet().stream().filter(entry -> {
+ Matcher matcher = pattern.matcher(entry.getKey());
+ return matcher.matches();
+ }).map(Map.Entry::getValue).forEach(session -> WebSocketUtil.sendMessage(session, message));
+ }
+}
\ No newline at end of file
--
Gitblit v1.9.3