优化任务执行代码

This commit is contained in:
longguancheng 2026-01-20 15:47:03 +08:00
parent 877cba6f6b
commit d6a94a8496
12 changed files with 196 additions and 188 deletions

2
.idea/.gitignore vendored
View File

@ -17,9 +17,9 @@
*.class *.class
# 忽略日志文件 # 忽略日志文件
/log/
*.log *.log
# 忽略系统生成文件 # 忽略系统生成文件
.DS_Store .DS_Store
Thumbs.db Thumbs.db

View File

@ -1,9 +1,9 @@
package com.zhangy.skyeye.device.controller; package com.zhangy.skyeye.device.controller;
import com.zhangy.skyeye.device.dto.PayloadPageDTO;
import com.zhangy.skyeye.device.dto.PayloadQueryDTO; import com.zhangy.skyeye.device.dto.PayloadQueryDTO;
import com.zhangy.skyeye.device.entity.SkyeyePayload; import com.zhangy.skyeye.device.entity.SkyeyePayload;
import com.zhangy.skyeye.device.service.IPayloadService; import com.zhangy.skyeye.device.service.IPayloadService;
import com.zhangy.skyeye.device.dto.PayloadPageDTO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -36,6 +36,7 @@ public class PayloadController {
/** /**
* 查询可用的雷达未执行任务且已连接 * 查询可用的雷达未执行任务且已连接
*
* @return * @return
*/ */
@GetMapping("/getEnableList") @GetMapping("/getEnableList")

View File

@ -6,7 +6,6 @@ import com.zhangy.skyeye.common.extend.dto.QueryDTO;
import com.zhangy.skyeye.common.extend.enums.EnumUtil; import com.zhangy.skyeye.common.extend.enums.EnumUtil;
import com.zhangy.skyeye.common.extend.exception.ServiceException; import com.zhangy.skyeye.common.extend.exception.ServiceException;
import com.zhangy.skyeye.common.extend.util.ObjectUtil; import com.zhangy.skyeye.common.extend.util.ObjectUtil;
import com.zhangy.skyeye.redis.utils.RedisUtil;
import com.zhangy.skyeye.device.consts.PayloadTypeEnum; import com.zhangy.skyeye.device.consts.PayloadTypeEnum;
import com.zhangy.skyeye.device.dto.PayloadQueryDTO; import com.zhangy.skyeye.device.dto.PayloadQueryDTO;
import com.zhangy.skyeye.device.entity.SkyeyePayload; import com.zhangy.skyeye.device.entity.SkyeyePayload;
@ -18,6 +17,7 @@ import com.zhangy.skyeye.jm.dto.JmUavStatusDTO;
import com.zhangy.skyeye.jm.service.JmJobStatusService; import com.zhangy.skyeye.jm.service.JmJobStatusService;
import com.zhangy.skyeye.publics.consts.CacheKey; import com.zhangy.skyeye.publics.consts.CacheKey;
import com.zhangy.skyeye.publics.consts.ExecStatusEnum; import com.zhangy.skyeye.publics.consts.ExecStatusEnum;
import com.zhangy.skyeye.redis.utils.RedisUtil;
import com.zhangy.skyeye.sar.service.ISarControlService; import com.zhangy.skyeye.sar.service.ISarControlService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
@ -57,9 +57,7 @@ public class PayloadServiceImpl implements IPayloadService {
PayloadQueryDTO payloadQueryDTO = new PayloadQueryDTO(); PayloadQueryDTO payloadQueryDTO = new PayloadQueryDTO();
payloadQueryDTO.setType(PayloadTypeEnum.SAR.getCode()); payloadQueryDTO.setType(PayloadTypeEnum.SAR.getCode());
List<SkyeyePayload> sarList = selectList(payloadQueryDTO); List<SkyeyePayload> sarList = selectList(payloadQueryDTO);
sarList.forEach(e -> { sarList.forEach(this::cacheSar);
cacheSar(e);
});
} }
private void cacheSar(SkyeyePayload e) { private void cacheSar(SkyeyePayload e) {
@ -116,6 +114,7 @@ public class PayloadServiceImpl implements IPayloadService {
/** /**
* 先判断该设备同IP编号是否已删除过是则更新否则新增 * 先判断该设备同IP编号是否已删除过是则更新否则新增
*
* @param e * @param e
* @return * @return
*/ */
@ -151,6 +150,7 @@ public class PayloadServiceImpl implements IPayloadService {
/** /**
* 保存前校验 * 保存前校验
*
* @param e * @param e
* @return 返回已逻辑删除的载荷 * @return 返回已逻辑删除的载荷
*/ */
@ -176,7 +176,7 @@ public class PayloadServiceImpl implements IPayloadService {
.stream() .stream()
.flatMap(vo -> vo.getUavMap().values().stream()) .flatMap(vo -> vo.getUavMap().values().stream())
.filter(vo -> vo.getSarStatus() != ExecStatusEnum.OVER) .filter(vo -> vo.getSarStatus() != ExecStatusEnum.OVER)
.map(vo -> vo.getSarId()) .map(JmUavStatusDTO::getSarId)
.collect(Collectors.toList()); .collect(Collectors.toList());
// 任务中的不可删除 // 任务中的不可删除
for (Long sarId : id) { for (Long sarId : id) {

View File

@ -5,65 +5,86 @@ import com.zhangy.skyeye.common.extend.exception.ServiceException;
import com.zhangy.skyeye.device.consts.PayloadTypeEnum; import com.zhangy.skyeye.device.consts.PayloadTypeEnum;
import com.zhangy.skyeye.jm.entity.JmAirline; import com.zhangy.skyeye.jm.entity.JmAirline;
import com.zhangy.skyeye.jm.entity.JmJobPayload; import com.zhangy.skyeye.jm.entity.JmJobPayload;
import com.zhangy.skyeye.jm.entity.JmJobUav;
import com.zhangy.skyeye.publics.consts.ExecStatusEnum; import com.zhangy.skyeye.publics.consts.ExecStatusEnum;
import lombok.Data; import lombok.Data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* 任务状态 - 任务 * 任务状态 - 任务
*/ */
@Data @Data
public class JmJobStatusDTO { public class JmJobStatusDTO {
/**
* 任务配置ID
*/
private Long id; private Long id;
private ExecStatusEnum status; private ExecStatusEnum status;
private Map<Long, JmUavStatusDTO> uavMap; private Map<Long, JmUavStatusDTO> uavMap;
public static JmJobStatusDTO parse(JmJobDTO e) { /**
* JmJobDTO 转换为前端 DTO
*/
public static JmJobStatusDTO parse(JmJobDTO job) {
if (job.getStatus() == null) throw ServiceException.noLog("任务状态不能为空");
JmJobStatusDTO vo = new JmJobStatusDTO(); JmJobStatusDTO vo = new JmJobStatusDTO();
long jobConfId = e.getConfId(); vo.setId(job.getConfId());
vo.setId(jobConfId); vo.setStatus(EnumUtil.parseEx(ExecStatusEnum.class, job.getStatus()));
Integer jobStatus = e.getStatus(); // 构建 UAV Map
if (jobStatus == null) { Map<Long, JmUavStatusDTO> uavMap = new HashMap<>();
throw ServiceException.noLog("任务状态不能为空"); for (JmJobUav uav : job.getUavList()) {
uavMap.put(uav.getUavId(), parseUav(uav, job));
} }
vo.setStatus(EnumUtil.parseEx(ExecStatusEnum.class, jobStatus)); vo.setUavMap(uavMap);
vo.setUavMap(e.getUavList() return vo;
.stream() }
.map(u -> {
/**
* 将单个 UAV 对象转换为 DTO包括 SAR 信息和航线列表
*/
private static JmUavStatusDTO parseUav(JmJobUav uav, JmJobDTO job) {
JmUavStatusDTO uVo = new JmUavStatusDTO(); JmUavStatusDTO uVo = new JmUavStatusDTO();
long uavId = u.getUavId(); // UAV 基本信息
uVo.setUavId(uavId); uVo.setUavId(uav.getUavId());
// sar uVo.setHomeAlt(uav.getStartAltitude());
JmJobPayload sar = u.getPayloadList() uVo.setHomeLon(uav.getStartLon());
.stream() uVo.setHomeLat(uav.getStartLat());
uVo.setJobId(job.getConfId());
uVo.setJobExecId(job.getExecId());
uVo.setJobName(job.getName());
uVo.setUavName(uav.getUavName());
// 找到 UAV SAR Payload
JmJobPayload sar = uav.getPayloadList().stream()
.filter(p -> PayloadTypeEnum.SAR.getCode().equals(p.getType())) .filter(p -> PayloadTypeEnum.SAR.getCode().equals(p.getType()))
.findFirst() .findFirst()
.get(); .orElseThrow(() -> new ServiceException("SAR payload不存在"));
long sarId = sar.getPayloadId(); uVo.setSarId(sar.getPayloadId());
uVo.setSarId(sarId);
uVo.setSarIp(sar.getIp()); uVo.setSarIp(sar.getIp());
uVo.setSarImageLight(sar.getImageLight()); uVo.setSarImageLight(sar.getImageLight());
// smp uVo.setSarName(sar.getPayloadName());
uVo.setHomeAlt(u.getStartAltitude()); // uVo.setSarStatus(ExecStatusEnum.parseEx(sar.getStatus()));
uVo.setHomeLon(u.getStartLon()); // 构建航线 DTO 列表同时计算总距离
uVo.setHomeLat(u.getStartLat()); int totalDistance = 0;
Integer sarStatus = sar.getStatus(); List<JmAirlineStatusDTO> airlines = new ArrayList<>();
if (sarStatus == null) { for (JmAirline a : uav.getAirlineList()) {
throw new ServiceException("sar状态不能为空"); airlines.add(parseAirline(a, job.getConfId(), uav.getUavId(), sar.getPayloadId()));
totalDistance += a.getDistance();
} }
// uVo.setSarStatus(ExecStatusEnum.parseEx(sarStatus)); uVo.setAirlineList(airlines);
uVo.setAirlineList(u.getAirlineList() uVo.setDistance(totalDistance);
.stream()
.map(a -> { return uVo;
}
/**
* 将单条航线对象转换为 DTO
*/
private static JmAirlineStatusDTO parseAirline(JmAirline a, long jobId, long uavId, long payloadId) {
if (a.getStatus() == null) throw ServiceException.noLog("航线状态不能为空");
JmAirlineStatusDTO aVo = new JmAirlineStatusDTO(); JmAirlineStatusDTO aVo = new JmAirlineStatusDTO();
// 航线基础信息
aVo.setConfId(a.getConfId()); aVo.setConfId(a.getConfId());
aVo.setExecId(a.getExecId()); aVo.setExecId(a.getExecId());
aVo.setNo(a.getFlightNo()); aVo.setNo(a.getFlightNo());
@ -73,29 +94,12 @@ public class JmJobStatusDTO {
aVo.setStartHeight(a.getStartHeight()); aVo.setStartHeight(a.getStartHeight());
aVo.setTargetHeading(a.getTargetHeading()); aVo.setTargetHeading(a.getTargetHeading());
aVo.setDirection(a.getDirection()); aVo.setDirection(a.getDirection());
aVo.setJobId(jobConfId); // 关联任务和 UAV
aVo.setJobId(jobId);
aVo.setUavId(uavId); aVo.setUavId(uavId);
aVo.setPayloadId(sarId); aVo.setPayloadId(payloadId);
Integer airlineStatus = a.getStatus(); // 状态枚举
if (airlineStatus == null) { aVo.setStatus(EnumUtil.parseEx(ExecStatusEnum.class, a.getStatus()));
throw ServiceException.noLog("航线状态不能为空");
}
aVo.setStatus(EnumUtil.parseEx(ExecStatusEnum.class, airlineStatus));
return aVo; return aVo;
})
.collect(Collectors.toList())
);
uVo.setDistance(u.getAirlineList().stream().mapToInt(JmAirline::getDistance).sum());
// 向前端推送图像时需要
uVo.setJobId(jobConfId);
uVo.setJobExecId(e.getExecId());
uVo.setJobName(e.getName());
uVo.setUavName(u.getUavName());
uVo.setSarName(sar.getPayloadName());
return uVo;
})
.collect(Collectors.toMap(uVo -> uVo.getUavId(), Function.identity()))
);
return vo;
} }
} }

View File

@ -7,7 +7,10 @@ import com.zhangy.skyeye.common.extend.util.ObjectUtil;
import com.zhangy.skyeye.device.service.IPayloadService; import com.zhangy.skyeye.device.service.IPayloadService;
import com.zhangy.skyeye.jm.dto.JmJobDTO; import com.zhangy.skyeye.jm.dto.JmJobDTO;
import com.zhangy.skyeye.jm.dto.JmJobQueryDTO; import com.zhangy.skyeye.jm.dto.JmJobQueryDTO;
import com.zhangy.skyeye.jm.entity.*; import com.zhangy.skyeye.jm.entity.JmAirlineExec;
import com.zhangy.skyeye.jm.entity.JmJobExec;
import com.zhangy.skyeye.jm.entity.JmJobPoint;
import com.zhangy.skyeye.jm.entity.JmJobUav;
import com.zhangy.skyeye.jm.event.JmJobStatusInitEvent; import com.zhangy.skyeye.jm.event.JmJobStatusInitEvent;
import com.zhangy.skyeye.jm.mapper.JmJobExecMapper; import com.zhangy.skyeye.jm.mapper.JmJobExecMapper;
import com.zhangy.skyeye.jm.service.*; import com.zhangy.skyeye.jm.service.*;
@ -74,6 +77,7 @@ public class JmJobExecServiceImpl implements JmJobExecService {
/** /**
* 查询进行中的任务 * 查询进行中的任务
*
* @return * @return
*/ */
@Override @Override
@ -125,40 +129,36 @@ public class JmJobExecServiceImpl implements JmJobExecService {
@Transactional @Transactional
@Override @Override
public void save(JmJobDTO dto) { public void save(JmJobDTO dto) {
Long jobConfigId = dto.getId(); // 1. 保存任务执行信息
// 任务 JmJobExec jobExec = new JmJobExec();
JmJobExec e = new JmJobExec(); jobExec.setConfId(dto.getId());
e.setStatus(dto.getStatus()); jobExec.setStatus(dto.getStatus());
e.setBeginTime(dto.getBeginTime()); jobExec.setBeginTime(dto.getBeginTime());
e.setConfId(jobConfigId); jobExec.setType(dto.getType());
e.setType(dto.getType()); jobExecMapper.insert(jobExec);
jobExecMapper.insert(e); long execId = jobExec.getId();
long execId = e.getId(); // 2. 构建并保存航线执行列表
// 航线 List<JmAirlineExec> airlineExecList = dto.getUavList().stream()
List<JmAirlineExec> airlineExecList = dto.getUavList() .flatMap(uav -> uav.getAirlineList().stream()
.stream()
.flatMap(uav -> {
return uav.getAirlineList()
.stream()
.map(airline -> { .map(airline -> {
JmAirlineExec ae = new JmAirlineExec(); JmAirlineExec ae = new JmAirlineExec();
ae.setConfId(airline.getId()); ae.setConfId(airline.getId());
ae.setStatus(ExecStatusEnum.NOT.getValue());
ae.setJobId(execId); ae.setJobId(execId);
ae.setStatus(ExecStatusEnum.NOT.getValue());
return ae; return ae;
}); }))
}).collect(Collectors.toList()); .collect(Collectors.toList());
jmAirlineExecService.insert(airlineExecList); jmAirlineExecService.insert(airlineExecList);
// 回写航线执行ID // 3. 回写航线执行ID
// 航线配置ID 航线执行ID Map<Long, Long> airlineIdMap = airlineExecList.stream()
Map<Long, Long> airlineIdMap = airlineExecList.stream().collect(Collectors.toMap(a -> a.getConfId(), a -> a.getId(), (x, y) -> y)); .collect(Collectors.toMap(JmAirlineExec::getConfId, JmAirlineExec::getId));
dto.getUavList().forEach(uav -> { dto.getUavList().forEach(uav -> uav.getAirlineList().forEach(airline ->
uav.getAirlineList().forEach(a -> a.setExecId(airlineIdMap.get(a.getId()))); airline.setExecId(airlineIdMap.get(airline.getId()))));
}); // 4. 回写任务执行ID
// 回写任务执行ID
dto.setExecId(execId); dto.setExecId(execId);
} }
@Override @Override
public void updateNotNull(JmJobExec e) { public void updateNotNull(JmJobExec e) {
Long jobExecId = e.getId(); Long jobExecId = e.getId();

View File

@ -1,6 +1,7 @@
package com.zhangy.skyeye.jm.service.impl; package com.zhangy.skyeye.jm.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhangy.skyeye.common.extend.enums.EnumUtil; import com.zhangy.skyeye.common.extend.enums.EnumUtil;
@ -378,11 +379,9 @@ public class JmJobServiceImpl implements JmJobService {
// SarBackImageFrameDTO.i = 1; // SarBackImageFrameDTO.i = 1;
// 校验无人机载荷 // 校验无人机载荷
jobStatusService.checkDeviceForNewJob(job.getUavList()); jobStatusService.checkDeviceForNewJob(job.getUavList());
Long jobId = job.getId(); // 保存任务状态
// 更新任务状态
job.setStatus(ExecStatusEnum.PROCESSING.getValue()); job.setStatus(ExecStatusEnum.PROCESSING.getValue());
job.setBeginTime(new Date()); job.setBeginTime(DateUtil.date());
// add exec
jmJobExecService.save(job); jmJobExecService.save(job);
try { try {
// 1.发送航线到雷达 // 1.发送航线到雷达

View File

@ -2,6 +2,7 @@ package com.zhangy.skyeye.jm.service.impl;
import com.zhangy.skyeye.common.extend.exception.ServiceException; import com.zhangy.skyeye.common.extend.exception.ServiceException;
import com.zhangy.skyeye.jm.dto.*; import com.zhangy.skyeye.jm.dto.*;
import com.zhangy.skyeye.jm.entity.JmJobPayload;
import com.zhangy.skyeye.jm.entity.JmJobUav; import com.zhangy.skyeye.jm.entity.JmJobUav;
import com.zhangy.skyeye.jm.event.JmAirlineStatusEvent; import com.zhangy.skyeye.jm.event.JmAirlineStatusEvent;
import com.zhangy.skyeye.jm.event.JmJobStatusEvent; import com.zhangy.skyeye.jm.event.JmJobStatusEvent;
@ -12,7 +13,6 @@ import com.zhangy.skyeye.publics.consts.ExecStatusEnum;
import com.zhangy.skyeye.publics.consts.WebSocketKey; import com.zhangy.skyeye.publics.consts.WebSocketKey;
import com.zhangy.skyeye.publics.utils.CoordUtil; import com.zhangy.skyeye.publics.utils.CoordUtil;
import com.zhangy.skyeye.sar.listen.SarImageUdpProcessor; import com.zhangy.skyeye.sar.listen.SarImageUdpProcessor;
// import com.zhangy.skyeye.smp.service.ISmpSubscriptService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
@ -158,27 +158,29 @@ public class JmJobStatusServiceImpl implements JmJobStatusService {
} }
@Override @Override
public void checkDeviceForNewJob(List<JmJobUav> uavList) { public void checkDeviceForNewJob(List<JmJobUav> newJobUavs) {
// 查询未完成的无人机载荷 // 收集正在执行任务的无人机ID和载荷ID
Set<Long> uavIds = new HashSet<>(); Set<Long> runningUavIds = new HashSet<>();
Set<Long> sarIds = new HashSet<>(); Set<Long> runningPayloadIds = new HashSet<>();
getAll().stream().flatMap(vo -> vo.getUavMap().values().stream()) for (JmJobStatusDTO job : getAll()) {
.forEach(vo -> { for (JmUavStatusDTO value : job.getUavMap().values()) {
if (vo.getSarStatus() != ExecStatusEnum.OVER) { if (value.getSarStatus() != ExecStatusEnum.OVER) {
uavIds.add(vo.getUavId()); runningUavIds.add(value.getUavId());
sarIds.add(vo.getSarId()); runningPayloadIds.add(value.getSarId());
} }
}); }
uavList.forEach(u -> { }
if (uavIds.contains(u.getUavId())) { // 校验新任务中的无人机和载荷是否冲突
for (JmJobUav newUav : newJobUavs) {
if (runningUavIds.contains(newUav.getUavId())) {
throw ServiceException.warnLog("无人机正在任务中,无法执行新任务"); throw ServiceException.warnLog("无人机正在任务中,无法执行新任务");
} }
u.getPayloadList().forEach(p -> { for (JmJobPayload payload : newUav.getPayloadList()) {
if (sarIds.contains(p.getPayloadId())) { if (runningPayloadIds.contains(payload.getPayloadId())) {
throw ServiceException.warnLog("载荷正在任务中,无法执行新任务"); throw ServiceException.warnLog("载荷正在任务中,无法执行新任务");
} }
}); }
}); }
} }
/** /**
@ -314,6 +316,7 @@ public class JmJobStatusServiceImpl implements JmJobStatusService {
/** /**
* 获取任务完成度 * 获取任务完成度
*
* @return * @return
*/ */
private int getCompletion(JmJobStatusDTO job) { private int getCompletion(JmJobStatusDTO job) {

View File

@ -69,7 +69,7 @@ public class SarControlContext {
@PostConstruct @PostConstruct
public void log() { public void log() {
log.info("雷达传图类型:" + imgType); log.info("雷达传图类型:{}", imgType);
} }
/** /**

View File

@ -1,6 +1,5 @@
package com.zhangy.skyeye.sar.listen; package com.zhangy.skyeye.sar.listen;
import com.zhangy.skyeye.common.extend.exception.ServiceException;
import com.zhangy.skyeye.jm.dto.JmAirlineStatusDTO; import com.zhangy.skyeye.jm.dto.JmAirlineStatusDTO;
import com.zhangy.skyeye.jm.entity.JmImage; import com.zhangy.skyeye.jm.entity.JmImage;
import com.zhangy.skyeye.jm.service.JmJobStatusService; import com.zhangy.skyeye.jm.service.JmJobStatusService;
@ -10,12 +9,10 @@ import com.zhangy.skyeye.sar.dto.SarImagePacketDTO;
import com.zhangy.skyeye.sar.dto.SarImagePacketGroupDTO; import com.zhangy.skyeye.sar.dto.SarImagePacketGroupDTO;
import com.zhangy.skyeye.sar.service.ISarImageService; import com.zhangy.skyeye.sar.service.ISarImageService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.security.MD5Encoder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.Map; import java.util.Map;
@ -57,6 +54,7 @@ public class SarImageUdpProcessor extends SarAbstractUdpProcessor<SarImagePacket
/** /**
* 判断是否可以合并回图帧首包不能丢 * 判断是否可以合并回图帧首包不能丢
*
* @param group * @param group
* @return * @return
*/ */
@ -72,6 +70,7 @@ public class SarImageUdpProcessor extends SarAbstractUdpProcessor<SarImagePacket
* 合并后删除frameMap的分包数据 * 合并后删除frameMap的分包数据
* 使用ByteBuffer替代ByteArrayOutputStream以减少内存分配ByteArrayOutputStream toByteArray()底层用Arrays.copyOf实现 * 使用ByteBuffer替代ByteArrayOutputStream以减少内存分配ByteArrayOutputStream toByteArray()底层用Arrays.copyOf实现
* 有性能开销ByteBuffer的array()无需拷贝数组 * 有性能开销ByteBuffer的array()无需拷贝数组
*
* @param group * @param group
* @return * @return
*/ */
@ -97,7 +96,6 @@ public class SarImageUdpProcessor extends SarAbstractUdpProcessor<SarImagePacket
@Override @Override
public SarImagePacketGroupDTO putPacket(String sourceIp, SarImagePacketDTO packet) { public SarImagePacketGroupDTO putPacket(String sourceIp, SarImagePacketDTO packet) {
//System.out.println("udp:" + packet.getSessionId() + "," + packet.getPacketNo());
// 1.包放入缓冲区 // 1.包放入缓冲区
long sessionId = packet.getSessionId(); long sessionId = packet.getSessionId();
SarImagePacketGroupDTO group; SarImagePacketGroupDTO group;
@ -114,12 +112,11 @@ public class SarImageUdpProcessor extends SarAbstractUdpProcessor<SarImagePacket
group.setAirlineExecId(currAirline.getExecId()); group.setAirlineExecId(currAirline.getExecId());
put(sourceIp, sessionId, group); put(sourceIp, sessionId, group);
} }
//System.out.println(packet);
// 2.判断是否全部包到达是则合并 // 2.判断是否全部包到达是则合并
SarImagePacketDTO last = group.getLastPacket(); SarImagePacketDTO last = group.getLastPacket();
// 若所有包已收到则合并 // 若所有包已收到则合并
if (last != null && last.isLast() && group.getPackets().size() == group.getMaxNo() + 1) { if (last != null && last.isLast() && group.getPackets().size() == group.getMaxNo() + 1) {
log.info("[UDP] sesionid="+ packet.getSessionId() + "全部到达合并!"); log.info("[UDP] sesionid=" + packet.getSessionId() + "全部到达合并!");
byte[] framePacketData = join(group); byte[] framePacketData = join(group);
afterJoin(framePacketData, group); afterJoin(framePacketData, group);
remove(sourceIp, sessionId); remove(sourceIp, sessionId);
@ -137,15 +134,16 @@ public class SarImageUdpProcessor extends SarAbstractUdpProcessor<SarImagePacket
protected void expireProcess(SarImagePacketGroupDTO group) { protected void expireProcess(SarImagePacketGroupDTO group) {
// 定时判断超过 PACKET_TIMEOUT 时间未收到新包且符合生成条件则合成图 // 定时判断超过 PACKET_TIMEOUT 时间未收到新包且符合生成条件则合成图
if (canJoin(group)) { if (canJoin(group)) {
log.info("[UDP] sesionid="+ group.getSessionId() + "超时合并!"); log.info("[UDP] sesionid {} 超时合并!", group.getSessionId());
byte[] framePacketData = join(group); byte[] framePacketData = join(group);
afterJoin(framePacketData, group); afterJoin(framePacketData, group);
} else { // 超时且无法合并丢弃 } else {
// 超时且无法合并丢弃
Map<Integer, SarImagePacketDTO> packets = group.getPackets(); Map<Integer, SarImagePacketDTO> packets = group.getPackets();
if (packets.size() == 1 && packets.values().iterator().next().isLast()) { if (packets.size() == 1 && packets.values().iterator().next().isLast()) {
// 雷达传图有bug每帧的尾包会多发一个丢弃且不打印日志 // 雷达传图有bug每帧的尾包会多发一个丢弃且不打印日志
} else { } else {
log.warn(getText() + "-移除超时帧: {}", group.getSessionId()); log.warn("{}-移除超时帧: {}", getText(), group.getSessionId());
} }
} }
} }

View File

@ -1,15 +1,15 @@
package com.zhangy.skyeye.sar.service.impl; package com.zhangy.skyeye.sar.service.impl;
import com.zhangy.skyeye.jm.dto.JmAirlineStatusDTO;
import com.zhangy.skyeye.jm.dto.JmUavStatusDTO; import com.zhangy.skyeye.jm.dto.JmUavStatusDTO;
import com.zhangy.skyeye.jm.entity.JmImage; import com.zhangy.skyeye.jm.entity.JmImage;
import com.zhangy.skyeye.jm.service.JmJobStatusService; import com.zhangy.skyeye.jm.service.JmJobStatusService;
import com.zhangy.skyeye.jm.dto.JmAirlineStatusDTO;
import com.zhangy.skyeye.publics.consts.WebSocketKey; import com.zhangy.skyeye.publics.consts.WebSocketKey;
import com.zhangy.skyeye.publics.service.SysFileTypeService; import com.zhangy.skyeye.publics.service.SysFileTypeService;
import com.zhangy.skyeye.sar.dto.JmSarWaveWsDTO;
import com.zhangy.skyeye.sar.dto.SarBackWaveFrameDTO; import com.zhangy.skyeye.sar.dto.SarBackWaveFrameDTO;
import com.zhangy.skyeye.sar.service.ISarBackWsService; import com.zhangy.skyeye.sar.service.ISarBackWsService;
import com.zhangy.skyeye.sar.service.SarWsAsyncService; import com.zhangy.skyeye.sar.service.SarWsAsyncService;
import com.zhangy.skyeye.sar.dto.JmSarWaveWsDTO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.messaging.simp.SimpMessagingTemplate;

View File

@ -1,20 +1,23 @@
package com.zhangy.skyeye.sar.service.impl; package com.zhangy.skyeye.sar.service.impl;
import com.zhangy.skyeye.common.extend.util.JsonUtil; import com.zhangy.skyeye.common.extend.util.JsonUtil;
import com.zhangy.skyeye.redis.utils.RedisUtil;
import com.zhangy.skyeye.jm.dto.JmJobDTO; import com.zhangy.skyeye.jm.dto.JmJobDTO;
import com.zhangy.skyeye.publics.consts.CacheKey;
import com.zhangy.skyeye.sar.control.SarControlContext;
import com.zhangy.skyeye.sar.enums.SarControlTypeEnum;
import com.zhangy.skyeye.jm.entity.JmJobPayload;
import com.zhangy.skyeye.jm.dto.JmSarStatusDTO; import com.zhangy.skyeye.jm.dto.JmSarStatusDTO;
import com.zhangy.skyeye.sar.service.ISarControlService; import com.zhangy.skyeye.jm.entity.JmJobPayload;
import com.zhangy.skyeye.jm.entity.JmJobUav;
import com.zhangy.skyeye.publics.consts.CacheKey;
import com.zhangy.skyeye.redis.utils.RedisUtil;
import com.zhangy.skyeye.sar.control.SarControlContext;
import com.zhangy.skyeye.sar.dto.SarControlParamDTO; import com.zhangy.skyeye.sar.dto.SarControlParamDTO;
import com.zhangy.skyeye.sar.enums.SarControlTypeEnum;
import com.zhangy.skyeye.sar.service.ISarControlService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Optional;
/** /**
* 控制指令 * 控制指令
*/ */
@ -30,35 +33,34 @@ public class SarControlServiceImpl implements ISarControlService {
@Override @Override
public void sendUdp(JmJobDTO job) { public void sendUdp(JmJobDTO job) {
if (job == null) { if (job == null || job.getUavList() == null) return;
return;
}
job.getUavList().forEach(uav -> { job.getUavList().forEach(uav -> {
JmJobPayload sar = uav.getSar0(); JmJobPayload sar = uav.getSar0();
if (sar == null) return;
SarControlParamDTO param = new SarControlParamDTO(); SarControlParamDTO param = new SarControlParamDTO();
// 载荷参数 -> 雷达控制参数
param.setIp(sar.getIp()); param.setIp(sar.getIp());
param.setAirlineList(uav.getAirlineList()); param.setAirlineList(uav.getAirlineList());
param.setAutoFocus(sar.getAutoFocus()); param.setAutoFocus(sar.getAutoFocus());
param.setMoto(sar.getMoto()); param.setMoto(sar.getMoto());
param.setImageBit(sar.getImageBit()); param.setImageBit(sar.getImageBit());
double startAltitude = uav.getStartAltitude();
param.getAirlineList().forEach(a -> {
// 雷达参数中的高度转为海拔高度
a.setFlightEndHeight(a.getFlightEndHeight() + startAltitude);
a.setFlightStartHeight(a.getFlightStartHeight() + startAltitude);
a.setGroundStartHeight(a.getGroundStartHeight() + startAltitude);
a.setTargetCentroidHeight(a.getTargetCentroidHeight() + startAltitude);
});
param.setResolution(sar.getResolution()); param.setResolution(sar.getResolution());
param.setControlType(SarControlTypeEnum.AUTO); param.setControlType(SarControlTypeEnum.AUTO);
double startAltitude = uav.getStartAltitude();
// 高度加上起始高度
Optional.ofNullable(param.getAirlineList())
.ifPresent(list -> list.forEach(a -> {
a.setFlightStartHeight(a.getFlightStartHeight() + startAltitude);
a.setFlightEndHeight(a.getFlightEndHeight() + startAltitude);
a.setGroundStartHeight(a.getGroundStartHeight() + startAltitude);
a.setTargetCentroidHeight(a.getTargetCentroidHeight() + startAltitude);
}));
param.checkOrSetData(); param.checkOrSetData();
log.info("上传雷达:" + JsonUtil.toString(param)); log.info("上传雷达:{}", JsonUtil.toString(param));
sendUdp(param); sendUdp(param);
}); });
} }
@Override @Override
public void sendUdp(SarControlParamDTO param) { public void sendUdp(SarControlParamDTO param) {
udpSendContext.execute(param); udpSendContext.execute(param);

1
frontend/.gitignore vendored
View File

@ -19,3 +19,4 @@ pack/
package-lock.json package-lock.json
.DS_Store .DS_Store
.history .history
/*.lock