Jelajahi Sumber

按照开发新的发送协议修改发送逻辑

allen 2 bulan lalu
induk
melakukan
108667e208

+ 51 - 10
uavps-framework/src/main/java/com/uavps/framework/udp/UdpClientService.java

@@ -1,11 +1,15 @@
 package com.uavps.framework.udp;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
 
 /**
  * @Author MBQ
@@ -16,23 +20,60 @@ import java.net.InetAddress;
 @Component
 public class UdpClientService {
 
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private static final int BUFF_SIZE = 1000; // 总缓冲区大小 接收方设置的是1024,但是按1024发送回报错。。。
+    private static final int HEADER_SIZE = 4;   // 序号占4字节
+    private static final int DATA_SIZE = BUFF_SIZE - HEADER_SIZE; // 有效数据大小(1020字节)
+    private static final int PORT = 9010; // 有效数据大小(1020字节)
+
     public void send(String message) {
         try {
-            //创建客户端对象,随机一个端口
             DatagramSocket socket = new DatagramSocket();
-            System.out.println("udp客户端发送数据:" + message);
+            InetAddress address = InetAddress.getByName("localhost");
+
+            byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
+            int totalBytes = messageBytes.length;
+            int totalChunks = (int) Math.ceil((double) totalBytes / DATA_SIZE);
+
+            for (int index = 0; index < totalChunks; index++) {
+                // 生成4字节ASCII序号(如 "0001")
+                String indexStr = String.format("%04d", index); // 固定4位,前面补0
+                byte[] indexBytes = indexStr.getBytes(StandardCharsets.UTF_8);
+
+                // 计算当前分片的数据范围
+                int start = index * DATA_SIZE;
+                int end = Math.min(start + DATA_SIZE, totalBytes);
+                byte[] chunkData = new byte[end - start];
+                System.arraycopy(messageBytes, start, chunkData, 0, chunkData.length);
+
+                // 合并序号和数据
+                ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFF_SIZE);
+                baos.write(indexBytes); // 写入4字节ASCII序号
+                baos.write(chunkData);  // 写入数据
+
+                // 发送分片
+                byte[] sendData = baos.toByteArray();
+                DatagramPacket packet = new DatagramPacket(sendData, sendData.length, address, PORT);
+                socket.send(packet);
+                logger.info("Sent chunk: {}, size: {}", indexStr, sendData.length);
+            }
+
+            // 发送结束包(序号为总块数,内容为 "END")
+            String endIndexStr = String.format("%04d", totalChunks);
+            byte[] endDataBytes = "END".getBytes(StandardCharsets.UTF_8);
 
-            //封装数据
-            byte[] data = message.getBytes();
-            DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 9010);
+            ByteArrayOutputStream endBaos = new ByteArrayOutputStream(BUFF_SIZE);
+            endBaos.write(endDataBytes);  // 写入 "END"
 
-            //发送数据
-            socket.send(packet);
+            byte[] endPacketData = endBaos.toByteArray();
+            DatagramPacket endPacket = new DatagramPacket(endPacketData, endPacketData.length, address, PORT);
+            socket.send(endPacket);
+            logger.info("Sent END chunk: {}", endIndexStr);
 
-            //释放资源
-            socket.close();
         } catch (IOException e) {
-            e.printStackTrace();
+            logger.error("UdpClientService send error", e);
+            throw new RuntimeException(e);
         }
     }
 }

+ 138 - 16
uavps-system/src/main/java/com/uavps/system/domain/UavpsTask.java

@@ -1,7 +1,20 @@
 package com.uavps.system.domain;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.uavps.common.annotation.Excel;
+import com.uavps.common.core.domain.BaseEntity;
+import com.uavps.system.domain.dto.CustomizedMultiTargetFormationDTO;
+import com.uavps.system.domain.dto.FixedMultiTargetFormationDTO;
+import com.uavps.system.domain.dto.PlatformUavDTO;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * 任务数据对象 uavps_task
@@ -13,6 +26,14 @@ public class UavpsTask extends BaseEntity
 {
     private static final long serialVersionUID = 1L;
 
+
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    public static final String START = "start";
+    public static final String CHANGE = "change";
+    public static final String DISAPPEAR = "disappear";
+    public static final String SHOW = "show";
+
     /** 业务ID */
     private Long bizId;
 
@@ -36,14 +57,32 @@ public class UavpsTask extends BaseEntity
     private BigDecimal noiseMean;
 
     /** 固定翼平台无人机数据 */
+    /** 固定编队目标数据 */
+    @JsonIgnore
     private String platformUavStr;
 
+
     /** 固定编队目标数据 */
+    /** 固定编队目标数据 */
+    @JsonIgnore
     private String fixedMultiTargetFormationStr;
 
     /** 自定义编队目标数据 */
+    /** 固定编队目标数据 */
+    @JsonIgnore
     private String customizedMultiTargetFormationStr;
 
+    /** 固定翼平台无人机数据 */
+    private PlatformUavDTO platformUav;
+
+    /** 固定编队目标数据 */
+    private FixedMultiTargetFormationDTO fixedMultiTargetFormation;
+
+    /** 自定义编队目标数据 */
+    private List<CustomizedMultiTargetFormationDTO> customizedMultiTargetFormation;
+
+    private List<Integer> numbers = new ArrayList<>();
+
     public void setBizId(Long bizId) 
     {
         this.bizId = bizId;
@@ -135,23 +174,106 @@ public class UavpsTask extends BaseEntity
         return customizedMultiTargetFormationStr;
     }
 
+    public PlatformUavDTO getPlatformUav() {
+        if (platformUav == null && StringUtils.isNotEmpty(platformUavStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                this.platformUav = mapper.readValue(this.platformUavStr, PlatformUavDTO.class);
+            } catch (Exception e) {
+                logger.error("UavpsTask.getPlatformUav error", e);
+            }
+        }
+        return platformUav;
+    }
+
+    public void setPlatformUav(PlatformUavDTO platformUav) {
+        this.platformUav = platformUav;
+        if (platformUav != null && StringUtils.isEmpty(this.platformUavStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                String json = mapper.writeValueAsString(platformUav);
+                this.platformUavStr = json;
+            } catch (Exception e) {
+                logger.error("UavpsTask.setPlatformUav error", e);
+            }
+        }
+    }
+
+    public FixedMultiTargetFormationDTO getFixedMultiTargetFormation() {
+        if (fixedMultiTargetFormation == null && StringUtils.isNotEmpty(fixedMultiTargetFormationStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                fixedMultiTargetFormation = mapper.readValue(this.fixedMultiTargetFormationStr, FixedMultiTargetFormationDTO.class);
+            } catch (Exception e) {
+                logger.error("UavpsTask.getPlatformUav error", e);
+            }
+        }
+        return fixedMultiTargetFormation;
+    }
+
+    public void setFixedMultiTargetFormation(FixedMultiTargetFormationDTO fixedMultiTargetFormation) {
+        this.fixedMultiTargetFormation = fixedMultiTargetFormation;
+        if (fixedMultiTargetFormation != null && StringUtils.isEmpty(this.fixedMultiTargetFormationStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            String json = null;
+            try {
+                json = mapper.writeValueAsString(fixedMultiTargetFormation);
+            } catch (Exception e) {
+                logger.error("UavpsTask.setPlatformUav error", e);
+            }
+            this.fixedMultiTargetFormationStr = json;
+        }
+    }
+
+    public List<CustomizedMultiTargetFormationDTO> getCustomizedMultiTargetFormation() {
+        if (customizedMultiTargetFormation == null && StringUtils.isNotEmpty(customizedMultiTargetFormationStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                this.customizedMultiTargetFormation = mapper.readValue(customizedMultiTargetFormationStr, new TypeReference<List<CustomizedMultiTargetFormationDTO>>() {});
+            } catch (Exception e) {
+                logger.error("UavpsTask.getCustomizedMultiTargetFormation error", e);
+            }
+        }
+        return customizedMultiTargetFormation;
+    }
+
+    public void setCustomizedMultiTargetFormation(List<CustomizedMultiTargetFormationDTO> customizedMultiTargetFormation) {
+        this.customizedMultiTargetFormation = customizedMultiTargetFormation;
+        if (customizedMultiTargetFormation != null && StringUtils.isEmpty(this.customizedMultiTargetFormationStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                customizedMultiTargetFormationStr = mapper.writeValueAsString(customizedMultiTargetFormation);
+            } catch (Exception e) {
+                logger.error("UavpsTask.setCustomizedMultiTargetFormation error", e);
+            }
+        }
+    }
+
+    public List<Integer> getNumbers() {
+        return numbers;
+    }
+
+    public void setNumbers(List<Integer> numbers) {
+        this.numbers = numbers;
+    }
+
     @Override
     public String toString() {
-        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
-            .append("bizId", getBizId())
-            .append("bizName", getBizName())
-            .append("bizType", getBizType())
-            .append("multiTarget", getMultiTarget())
-            .append("noseType", getNoseType())
-            .append("noiseVariance", getNoiseVariance())
-            .append("noiseMean", getNoiseMean())
-            .append("platformUavStr", getPlatformUavStr())
-            .append("fixedMultiTargetFormationStr", getFixedMultiTargetFormationStr())
-            .append("customizedMultiTargetFormationStr", getCustomizedMultiTargetFormationStr())
-            .append("createBy", getCreateBy())
-            .append("createTime", getCreateTime())
-            .append("updateBy", getUpdateBy())
-            .append("updateTime", getUpdateTime())
-            .toString();
+        return "UavpsTask{" +
+                "bizId=" + bizId +
+                ", bizName='" + bizName + '\'' +
+                ", bizType='" + bizType + '\'' +
+                ", multiTarget='" + multiTarget + '\'' +
+                ", noseType='" + noseType + '\'' +
+                ", noiseVariance=" + noiseVariance +
+                ", noiseMean=" + noiseMean +
+                ", platformUavStr='" + platformUavStr + '\'' +
+                ", fixedMultiTargetFormationStr='" + fixedMultiTargetFormationStr + '\'' +
+                ", customizedMultiTargetFormationStr='" + customizedMultiTargetFormationStr + '\'' +
+                ", platformUav=" + platformUav +
+                ", fixedMultiTargetFormation=" + fixedMultiTargetFormation +
+                ", customizedMultiTargetFormation=" + customizedMultiTargetFormation +
+                ", numbers=" + numbers +
+                '}';
     }
 }

+ 25 - 42
uavps-web/src/views/system/task/index.vue

@@ -1,11 +1,11 @@
 <template>
   <div class="app-container">
     <el-form
-      v-show="showSearch"
-      ref="queryForm"
       :model="queryParams"
+      ref="queryForm"
       size="small"
       :inline="true"
+      v-show="showSearch"
       label-width="68px"
     >
       <el-form-item label="任务名称" prop="bizName">
@@ -16,20 +16,6 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="多目标类型" prop="multiTarget">
-        <el-select
-          v-model="queryParams.multiTarget"
-          placeholder="请选择多目标类型"
-          clearable
-        >
-          <el-option
-            v-for="dict in dict.type.uavps_target_formation_type"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
       <el-form-item label="创建时间">
         <el-date-picker
           v-model="daterangeCreateTime"
@@ -39,7 +25,7 @@
           range-separator="-"
           start-placeholder="开始日期"
           end-placeholder="结束日期"
-        />
+        ></el-date-picker>
       </el-form-item>
       <el-form-item>
         <el-button
@@ -58,51 +44,54 @@
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
-          v-hasPermi="['system:task:add']"
           type="primary"
           plain
           icon="el-icon-plus"
           size="mini"
           @click="handleAdd"
+          v-hasPermi="['system:task:add']"
           >新增</el-button
         >
       </el-col>
       <el-col :span="1.5">
         <el-button
-          v-hasPermi="['system:task:edit']"
           type="success"
           plain
           icon="el-icon-edit"
           size="mini"
           :disabled="single"
           @click="handleUpdate"
+          v-hasPermi="['system:task:edit']"
           >修改</el-button
         >
       </el-col>
       <el-col :span="1.5">
         <el-button
-          v-hasPermi="['system:task:remove']"
           type="danger"
           plain
           icon="el-icon-delete"
           size="mini"
           :disabled="multiple"
           @click="handleDelete"
+          v-hasPermi="['system:task:remove']"
           >删除</el-button
         >
       </el-col>
       <el-col :span="1.5">
         <el-button
-          v-hasPermi="['system:task:export']"
           type="warning"
           plain
           icon="el-icon-download"
           size="mini"
           @click="handleExport"
+          v-hasPermi="['system:task:export']"
           >导出</el-button
         >
       </el-col>
-      <right-toolbar :show-search.sync="showSearch" @queryTable="getList" />
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
     </el-row>
 
     <el-table
@@ -113,14 +102,6 @@
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="业务ID" align="center" prop="bizId" />
       <el-table-column label="任务名称" align="center" prop="bizName" />
-      <el-table-column label="多目标类型" align="center" prop="multiTarget">
-        <template slot-scope="scope">
-          <dict-tag
-            :options="dict.type.uavps_target_formation_type"
-            :value="scope.row.multiTarget"
-          />
-        </template>
-      </el-table-column>
       <el-table-column
         label="创建时间"
         align="center"
@@ -164,11 +145,11 @@
             >修改</el-button
           >
           <el-button
-            v-hasPermi="['system:task:remove']"
             size="mini"
             type="text"
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
+            v-hasPermi="['system:task:remove']"
             >删除</el-button
           >
         </template>
@@ -196,7 +177,7 @@
               :key="dict.value"
               :label="dict.label"
               :value="dict.value"
-            />
+            ></el-option>
           </el-select>
         </el-form-item>
         <el-form-item label="多目标类型" prop="multiTarget">
@@ -206,9 +187,15 @@
               :key="dict.value"
               :label="dict.label"
               :value="dict.value"
-            />
+            ></el-option>
           </el-select>
         </el-form-item>
+        <el-form-item label="噪声类型" prop="noiseVariance">
+          <el-input v-model="form.noiseVariance" placeholder="请输入噪声类型" />
+        </el-form-item>
+        <el-form-item label="噪声类型" prop="noiseMean">
+          <el-input v-model="form.noiseMean" placeholder="请输入噪声类型" />
+        </el-form-item>
         <el-form-item label="固定翼平台无人机数据" prop="platformUavStr">
           <el-input
             v-model="form.platformUavStr"
@@ -299,14 +286,7 @@ export default {
       // 表单参数
       form: {},
       // 表单校验
-      rules: {
-        bizType: [
-          { required: true, message: "业务类型不能为空", trigger: "change" },
-        ],
-        multiTarget: [
-          { required: true, message: "多目标类型不能为空", trigger: "change" },
-        ],
-      },
+      rules: {},
       parameterId: 0,
       showTrajectory: false,
       webSocket: null,
@@ -320,7 +300,7 @@ export default {
     getList() {
       this.loading = true;
       this.queryParams.params = {};
-      if (this.daterangeCreateTime != null && this.daterangeCreateTime != "") {
+      if (null != this.daterangeCreateTime && "" != this.daterangeCreateTime) {
         this.queryParams.params["beginCreateTime"] =
           this.daterangeCreateTime[0];
         this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
@@ -343,6 +323,9 @@ export default {
         bizName: null,
         bizType: null,
         multiTarget: null,
+        noseType: null,
+        noiseVariance: null,
+        noiseMean: null,
         platformUavStr: null,
         fixedMultiTargetFormationStr: null,
         customizedMultiTargetFormationStr: null,