|
|
|
@ -2,18 +2,24 @@ package com.platform.service.clientmanage;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.platform.info.GlobalData;
|
|
|
|
|
import com.platform.info.enums.CommandTypeEnum;
|
|
|
|
|
import com.platform.info.enums.RemoteFrameEnum;
|
|
|
|
|
import com.platform.info.enums.UavTypeEnum;
|
|
|
|
|
import com.platform.info.mapping.HaborUavMap;
|
|
|
|
|
import com.platform.info.mapping.UavIdMap;
|
|
|
|
|
import com.platform.util.ByteUtils;
|
|
|
|
|
import com.platform.util.JSONUtils;
|
|
|
|
|
import io.netty.buffer.ByteBuf;
|
|
|
|
|
import io.netty.buffer.ByteBufUtil;
|
|
|
|
|
import io.netty.buffer.PooledByteBufAllocator;
|
|
|
|
|
import io.netty.channel.Channel;
|
|
|
|
|
import lombok.Data;
|
|
|
|
|
import lombok.Getter;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Author : shiyi
|
|
|
|
|
* @Date : 2024/9/18 10:38
|
|
|
|
@ -23,53 +29,90 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
public class HaborClient981A extends HaborClient {
|
|
|
|
|
|
|
|
|
|
private static final byte[] UPPER_DATA_3_4 = new byte[]{0x02, 0x01};
|
|
|
|
|
/**常发数据内容*/
|
|
|
|
|
private static final byte C0 = 0x00; // 常发数据自定义特征字
|
|
|
|
|
private static final byte[] COMMON_DATA_7_30 = new byte[]{
|
|
|
|
|
0x00, 0x00, 0x00, // 飞行开关指令7~9, 初始化或无指令3个0x00
|
|
|
|
|
0x00, 0x00, 0x00, 0x00, // 飞行连续指令,中心指控不管,10~13
|
|
|
|
|
|
|
|
|
|
/**常发数据内容,被填入ByteBuf初始内容,所有飞机共用, 禁止修改*/
|
|
|
|
|
private static final byte C0 = 0x01; // 空白数据自定义特征字
|
|
|
|
|
private static final byte[] COMMON_DATA_14_29 = new byte[]{
|
|
|
|
|
0x21, C0, C0, C0, C0, // 14~29
|
|
|
|
|
C0, C0, C0, C0, C0,
|
|
|
|
|
C0, C0, C0, C0, C0, C0,
|
|
|
|
|
0x00 // 30
|
|
|
|
|
};
|
|
|
|
|
/**控制帧数据内容*/
|
|
|
|
|
private static final byte C1 = 0x01; // 常发数据自定义特征字
|
|
|
|
|
private static final byte[] CONTROL_DATA_7_30 = new byte[]{
|
|
|
|
|
0x00, 0x00, 0x00, // 飞行开关指令7~9, 初始化或无指令3个0x00
|
|
|
|
|
0x00, 0x00, 0x00, 0x00, // 飞行连续指令,中心指控不管,10~13
|
|
|
|
|
|
|
|
|
|
/**控制帧数据内容,被填入ByteBuf初始内容,*/
|
|
|
|
|
private static final byte C1 = 0x02; // 空白数据自定义特征字
|
|
|
|
|
private static final byte[] CONTROL_DATA_14_29 = new byte[]{
|
|
|
|
|
0x21, C1, C1, C1, C1, // 14~29
|
|
|
|
|
C1, C1, C1, C1, C1,
|
|
|
|
|
C1, C1, C1, C1, C1, C1,
|
|
|
|
|
0x00 // 30
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// /**装订帧数据内容*/
|
|
|
|
|
// private static final byte C2 = 0x03; // 空白数据自定义特征字
|
|
|
|
|
// private static final byte[] BIND_DATA_7_30 = new byte[]{
|
|
|
|
|
// 0x00, 0x00, 0x00, // 飞行开关指令7~9, 初始化或无指令3个0x00
|
|
|
|
|
// 0x00, 0x00, 0x00, 0x00, // 飞行连续指令,中心指控不管,10~13
|
|
|
|
|
// C2, C2, C2, C2, C2, // 14~29, 由中心指控填充
|
|
|
|
|
// C2, C2, C2, C2, C2,
|
|
|
|
|
// C2, C2, C2, C2, C2, C2,
|
|
|
|
|
// 0x00 // 30
|
|
|
|
|
// };
|
|
|
|
|
//
|
|
|
|
|
// /**查询帧数据内容*/
|
|
|
|
|
// private static final byte C3 = 0x04; // 空白数据自定义特征字
|
|
|
|
|
// private static final byte[] QUERY_DATA_7_30 = new byte[]{
|
|
|
|
|
// 0x00, 0x00, 0x00, // 飞行开关指令7~9, 初始化或无指令3个0x00
|
|
|
|
|
// 0x00, 0x00, 0x00, 0x00, // 飞行连续指令,中心指控不管,10~13
|
|
|
|
|
// C2, C2, C2, C2, C2, // 14~29, 由中心指控填充
|
|
|
|
|
// C2, C2, C2, C2, C2,
|
|
|
|
|
// C2, C2, C2, C2, C2, C2,
|
|
|
|
|
// 0x00 // 30
|
|
|
|
|
// };
|
|
|
|
|
//
|
|
|
|
|
// /**航线帧数据内容*/
|
|
|
|
|
// private static final byte C4 = 0x05; // 空白数据自定义特征字
|
|
|
|
|
// private static final byte[] BIND_DATA_7_30 = new byte[]{
|
|
|
|
|
// 0x00, 0x00, 0x00, // 飞行开关指令7~9, 初始化或无指令3个0x00
|
|
|
|
|
// 0x00, 0x00, 0x00, 0x00, // 飞行连续指令,中心指控不管,10~13
|
|
|
|
|
// C2, C2, C2, C2, C2, // 14~29, 由中心指控填充
|
|
|
|
|
// C2, C2, C2, C2, C2,
|
|
|
|
|
// C2, C2, C2, C2, C2, C2,
|
|
|
|
|
// 0x00 // 30
|
|
|
|
|
// };
|
|
|
|
|
/**控制指令帧*/
|
|
|
|
|
public HaborClient981A(String haborSn, Channel channel) {
|
|
|
|
|
super(haborSn, channel);
|
|
|
|
|
uavType = UavTypeEnum.FP981A;
|
|
|
|
|
uavId = HaborUavMap.getUavIdByHaborSn(haborSn);
|
|
|
|
|
uavType = UavIdMap.getUavType(uavId);
|
|
|
|
|
fkId = (byte) UavIdMap.getFkId(uavId);
|
|
|
|
|
super.commonDataFreq = 1; // 发送频率, 每秒发送帧数
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void resourceAllocate() {
|
|
|
|
|
// 常发数据帧初始化
|
|
|
|
|
commonDataBuf = PooledByteBufAllocator.DEFAULT.buffer(FRAME_SIZE);
|
|
|
|
|
commonDataBuf.writeBytes(HaborClient.HEAD);
|
|
|
|
|
commonDataBuf.writeBytes(UPPER_DATA_3_4);
|
|
|
|
|
commonDataBuf.writeByte(fkId);
|
|
|
|
|
commonDataBuf.writeByte(0);
|
|
|
|
|
commonDataBuf.writeBytes(COMMON_DATA_7_30);
|
|
|
|
|
commonDataBuf = new CommonDataBuf(FRAME_SIZE);
|
|
|
|
|
initByteBuf(commonDataBuf);
|
|
|
|
|
commonDataBuf.buf.writerIndex(13).writeBytes(COMMON_DATA_14_29); // 写入7-30字节
|
|
|
|
|
|
|
|
|
|
// 开关指令数据帧初始化
|
|
|
|
|
controlDataBuf = PooledByteBufAllocator.DEFAULT.buffer(FRAME_SIZE);
|
|
|
|
|
controlDataBuf.writeBytes(HaborClient.HEAD);
|
|
|
|
|
controlDataBuf.writeBytes(UPPER_DATA_3_4);
|
|
|
|
|
controlDataBuf.writeByte(fkId);
|
|
|
|
|
controlDataBuf.writeByte(0);
|
|
|
|
|
controlDataBuf.writeBytes(CONTROL_DATA_7_30);
|
|
|
|
|
controlDataBuf = new ControlDataBuf(FRAME_SIZE);
|
|
|
|
|
initByteBuf(controlDataBuf);
|
|
|
|
|
controlDataBuf.buf.writerIndex(13).writeBytes(CONTROL_DATA_14_29);
|
|
|
|
|
|
|
|
|
|
// 参数装订指令数据帧初始化
|
|
|
|
|
bindDataBuf = new BindDataBuf(FRAME_SIZE);
|
|
|
|
|
initByteBuf(bindDataBuf);
|
|
|
|
|
|
|
|
|
|
// 参数查询指令数据帧初始化
|
|
|
|
|
queryDataBuf = new QueryDataBuf(FRAME_SIZE);
|
|
|
|
|
initByteBuf(queryDataBuf);
|
|
|
|
|
|
|
|
|
|
// 航线装订指令数据帧初始化
|
|
|
|
|
routeDataBuf = new RouteDataBuf(FRAME_SIZE);
|
|
|
|
|
initByteBuf(routeDataBuf);
|
|
|
|
|
|
|
|
|
|
dataBufToSend = commonDataBuf; // note 默认发送常发数据帧
|
|
|
|
|
|
|
|
|
|
// 中心指控数据帧初始化
|
|
|
|
|
cacHeadLength = 5 // 魔术2 + 版本号1 + 序列化算法1 + 帧类型1
|
|
|
|
@ -91,9 +134,23 @@ public class HaborClient981A extends HaborClient {
|
|
|
|
|
telemetryBufHeadToCac.writeShort(0);
|
|
|
|
|
telemetryBufHeadToCac.writeInt(FRAME_SIZE);
|
|
|
|
|
|
|
|
|
|
lastControl = new LastCommandRecord();
|
|
|
|
|
lastBind = new LastCommandRecord();
|
|
|
|
|
lastQuery = new LastCommandRecord();
|
|
|
|
|
previousControl = new CommandRecord(CommandTypeEnum.CONTROL,this,16);
|
|
|
|
|
previousParamBind = new CommandRecord(CommandTypeEnum.PARAM_BIND, this, 16);
|
|
|
|
|
previousParamQuery = new CommandRecord(CommandTypeEnum.PARAM_QUERY, this, 16);
|
|
|
|
|
previousRouteBind = new CommandQueueRecord(CommandTypeEnum.ROUTE_BIND, this, 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**初始化发送帧内容*/
|
|
|
|
|
private void initByteBuf(DataByteBuf dataByteBuf) {
|
|
|
|
|
ByteBuf buf = dataByteBuf.buf;
|
|
|
|
|
buf.writerIndex(0);
|
|
|
|
|
buf.setZero(0, FRAME_SIZE); // 先全部赋0,非0数在下面修改
|
|
|
|
|
buf.writeBytes(HaborClient.HEAD);
|
|
|
|
|
buf.writeBytes(UPPER_DATA_3_4);
|
|
|
|
|
buf.writeByte(fkId);
|
|
|
|
|
// 10-13字节 默认为0x00
|
|
|
|
|
// 14-29字节 在外部动态赋值
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@ -121,37 +178,117 @@ public class HaborClient981A extends HaborClient {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
commonDataBuf.setByte(5, frameIdx.getAndIncrement()); // 帧序号
|
|
|
|
|
addCRC16(commonDataBuf);
|
|
|
|
|
channel.writeAndFlush(commonDataBuf.retain());
|
|
|
|
|
log.debug("{}-{}发送常发帧: {}", sn, uavType, ByteBufUtil.hexDump(commonDataBuf));
|
|
|
|
|
}
|
|
|
|
|
dataBufToSend.buf.setByte(5, frameIdx.getAndIncrement()); // 帧序号
|
|
|
|
|
addCRC16(dataBufToSend.buf); // 统一添加CRC校验
|
|
|
|
|
channel.writeAndFlush(dataBufToSend.buf.retain());
|
|
|
|
|
dataBufToSend.addSendCount();
|
|
|
|
|
|
|
|
|
|
/**下发控制指令*/
|
|
|
|
|
@Override
|
|
|
|
|
public void writeControlCommand(String controlUniId, byte controlCommand) {
|
|
|
|
|
pauseSendCommonData();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
controlDataBuf.setByte(6, controlCommand); // 控制指令
|
|
|
|
|
controlDataBuf.setByte(7, controlCommand); // 控制指令
|
|
|
|
|
controlDataBuf.setByte(8, controlCommand); // 控制指令
|
|
|
|
|
addCRC16(controlDataBuf);
|
|
|
|
|
for (int i = 0; i < commandNumber(controlCommand); i++) {
|
|
|
|
|
controlDataBuf.setByte(5, frameIdx.getAndIncrement()); // 帧序号
|
|
|
|
|
channel.writeAndFlush(controlDataBuf.retain());
|
|
|
|
|
log.debug("{}-{}发送控制指令帧({}): {}", sn, uavType, ByteUtils.byteToHex(controlCommand), ByteBufUtil.hexDump(controlDataBuf));
|
|
|
|
|
if (dataBufToSend instanceof CommonDataBuf) {
|
|
|
|
|
log.debug("[cac] {} 发送常发帧: {}", shortInfo(), ByteBufUtil.hexDump(dataBufToSend.buf));
|
|
|
|
|
}
|
|
|
|
|
if (dataBufToSend instanceof ControlDataBuf) {
|
|
|
|
|
log.info("[cac] {} 发送控制指令: {}", shortInfo(), ByteBufUtil.hexDump(dataBufToSend.buf));
|
|
|
|
|
if (dataBufToSend.getSendCount() >= ((ControlDataBuf) dataBufToSend).needCount) {
|
|
|
|
|
log.info("[cac] {} 控制指令发送完毕", shortInfo());
|
|
|
|
|
switchToCommonData();
|
|
|
|
|
}
|
|
|
|
|
lastControl.recordCommand(controlCommand, controlUniId, controlDataBuf.slice(13,16)); // 记录控制指令
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("{}-{}发送控制指令帧({})异常: {}", sn, uavType, ByteUtils.byteToHex(controlCommand), e.getMessage());
|
|
|
|
|
} finally {
|
|
|
|
|
resumeSendCommonData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dataBufToSend instanceof QueryDataBuf) {
|
|
|
|
|
log.info("[cac] {} 发送查询指令: {}", shortInfo(), ByteBufUtil.hexDump(dataBufToSend.buf));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dataBufToSend instanceof BindDataBuf) {
|
|
|
|
|
log.info("[cac] {} 发送参数装订指令: {}", shortInfo(), ByteBufUtil.hexDump(dataBufToSend.buf));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dataBufToSend instanceof RouteDataBuf) {
|
|
|
|
|
log.info("[cac] {} 发送航线装订指令: {}", shortInfo(), ByteBufUtil.hexDump(dataBufToSend.buf));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下发控制指令
|
|
|
|
|
* @param commandCode 第14字节的指令码
|
|
|
|
|
* @param controlUniId 指令唯一码
|
|
|
|
|
* */
|
|
|
|
|
@Override
|
|
|
|
|
public void writeControlCommand(byte commandCode, String controlUniId) {
|
|
|
|
|
controlDataBuf.buf.setByte(6, commandCode); // 控制指令
|
|
|
|
|
controlDataBuf.buf.setByte(7, commandCode); // 控制指令
|
|
|
|
|
controlDataBuf.buf.setByte(8, commandCode); // 控制指令
|
|
|
|
|
controlDataBuf.needCount = commandNumber(commandCode); // 设置需要发送的次数
|
|
|
|
|
setCurrentSendData(controlDataBuf); // 设置当前发送的数据类型
|
|
|
|
|
previousControl.recordCommand(commandCode, controlUniId, controlDataBuf.buf.slice(13,16)); // 记录控制指令
|
|
|
|
|
// for (int i = 0; i < commandNumber(commandCode); i++) {
|
|
|
|
|
// controlDataBuf.setByte(5, frameIdx.getAndIncrement()); // 帧序号
|
|
|
|
|
// channel.writeAndFlush(controlDataBuf.retain());
|
|
|
|
|
// log.debug("{}-{}发送控制指令帧({}): {}", sn, uavType, ByteUtils.byteToHex(commandCode), ByteBufUtil.hexDump(controlDataBuf));
|
|
|
|
|
// }
|
|
|
|
|
// previousControl.recordCommand(commandCode, controlUniId, controlDataBuf.slice(13,16)); // 记录控制指令
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下发参数装订指令
|
|
|
|
|
* @param commandCode 第14字节的指令码
|
|
|
|
|
* @param commandContent 14-29字节内容
|
|
|
|
|
* @param controlUniId 指令唯一码
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public void writeParamBindCommand(byte commandCode, byte[] commandContent, String controlUniId) {
|
|
|
|
|
// try {
|
|
|
|
|
bindDataBuf.buf.setBytes(13, commandContent);
|
|
|
|
|
setCurrentSendData(bindDataBuf); // 设置当前发送的数据类型
|
|
|
|
|
previousParamBind.recordCommand(commandCode, controlUniId, bindDataBuf.buf.slice(13,16)); // 记录参数装订指令
|
|
|
|
|
// } catch (Exception e) {
|
|
|
|
|
// log.error("{}-{}发送参数装订指令帧({})异常: {}", sn, uavType, ByteUtils.byteToHex(commandCode), e.getMessage());
|
|
|
|
|
// } finally {
|
|
|
|
|
// resumeSendCommonData();
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下发参数查询指令
|
|
|
|
|
* @param commandCode 第14字节的指令码
|
|
|
|
|
* @param commandContent 14-29字节内容
|
|
|
|
|
* @param controlUniId 指令唯一码
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public void writeParamQueryCommand(byte commandCode, byte[] commandContent, String controlUniId) {
|
|
|
|
|
queryDataBuf.buf.setBytes(13, commandContent);
|
|
|
|
|
setCurrentSendData(queryDataBuf); // 设置当前发送的数据类型
|
|
|
|
|
previousParamQuery.recordCommand(commandCode, controlUniId, queryDataBuf.buf.slice(13,16)); // 记录参数查询指令
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 逐个航点下发参数查询指令
|
|
|
|
|
* @param commandCode 第14字节的指令码
|
|
|
|
|
* @param commandContent 14-29字节内容
|
|
|
|
|
* @param controlUniId 指令唯一码
|
|
|
|
|
*/
|
|
|
|
|
private void writeRouteBindCommand0(byte commandCode, byte[] commandContent, String controlUniId) {
|
|
|
|
|
routeDataBuf.buf.setBytes(13, commandContent);
|
|
|
|
|
setCurrentSendData(routeDataBuf); // 设置当前发送的数据类型
|
|
|
|
|
previousRouteBind.recordCommand(commandCode, controlUniId, routeDataBuf.buf.slice(13,16)); // 记录参数查询指令
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void process(ByteBuf msg) {
|
|
|
|
|
/**
|
|
|
|
|
* 下发参数查询指令
|
|
|
|
|
* @param commandCode 第14字节的指令码
|
|
|
|
|
* @param routeInfoList 14-29字节内容列表
|
|
|
|
|
* @param controlUniId 指令唯一码
|
|
|
|
|
*/
|
|
|
|
|
public void writeRouteBindCommand(byte commandCode, List<byte[]> routeInfoList, String controlUniId) {
|
|
|
|
|
previousRouteBind.initCommandQueue(routeInfoList);
|
|
|
|
|
writeRouteBindCommand0(commandCode, routeInfoList.get(0), controlUniId); //发送第一个节点
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**注入回报帧处理*/
|
|
|
|
|
@Override
|
|
|
|
|
protected void processInjectResponse(ByteBuf msg) {
|
|
|
|
|
if (msg.getByte(0) != HEAD[0] && msg.getByte(1) != HEAD[1]) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -160,32 +297,122 @@ public class HaborClient981A extends HaborClient {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (LastCommandRecord.WATING_RESULT == lastControl.getState()) {
|
|
|
|
|
if (lastControl.commandMatch(msg.slice(13,16))) {
|
|
|
|
|
// lastControl.notifyControlCommandResult();
|
|
|
|
|
log.info("[cac] 控制指令回报成功");
|
|
|
|
|
lastControl.clearCommand();
|
|
|
|
|
return;
|
|
|
|
|
if (checkControlResponse(msg)) return; // 检查控制指令回报
|
|
|
|
|
if (checkParamBindResponse(msg)) return; // 检查参数装订回报
|
|
|
|
|
if (checkParamQueryResponse(msg)) return; // 检查参数查询回报
|
|
|
|
|
if (checkRouteBindResponse(msg)) return; // 检查航线装订回报
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 检查控制指令回报*/
|
|
|
|
|
private boolean checkControlResponse(ByteBuf msg) {
|
|
|
|
|
if (CommandRecord.WAITING_RESULT == previousControl.getState()) {
|
|
|
|
|
previousControl.addReceiveFrameCount();
|
|
|
|
|
if (previousControl.commandMatch(msg.slice(13,16))) {
|
|
|
|
|
try {
|
|
|
|
|
// previousControl.notifyControlCommandResult();
|
|
|
|
|
log.info("[cac] {} 控制指令成功结果回报...", shortInfo());
|
|
|
|
|
previousControl.clearCommand();
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.warn("[cac] {} 控制指令回报处理异常:{}",shortInfo(), e.getMessage());
|
|
|
|
|
} finally {
|
|
|
|
|
switchToCommonData(); // 恢复常发数据帧
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// else {
|
|
|
|
|
// if (previousControl.isTimeout()) {
|
|
|
|
|
// log.info("[cac] {} 控制指令回报失败, 超时", shortInfo());
|
|
|
|
|
// previousControl.clearCommand();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (LastCommandRecord.WATING_RESULT == lastBind.getState()) {
|
|
|
|
|
if (lastBind.commandMatch(msg.slice(13,16))) {
|
|
|
|
|
lastBind.notifyParamBindCommandResult();
|
|
|
|
|
lastBind.clearCommand();
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/** 检查参数装订回报*/
|
|
|
|
|
private boolean checkParamBindResponse(ByteBuf msg) {
|
|
|
|
|
if (CommandRecord.WAITING_RESULT == previousParamBind.getState()) {
|
|
|
|
|
previousParamBind.addReceiveFrameCount();
|
|
|
|
|
if (previousParamBind.commandMatch(msg.slice(13,16))) {
|
|
|
|
|
try {
|
|
|
|
|
// previousParamBind.notifyParamBindCommandResult(true);
|
|
|
|
|
log.info("[cac] {} 指令装订成功结果回报...", shortInfo());
|
|
|
|
|
previousParamBind.clearCommand();
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.warn("[cac] {} 指令装订结果回报处理异常:{}",shortInfo(), e.getMessage());
|
|
|
|
|
} finally {
|
|
|
|
|
switchToCommonData(); // 恢复常发数据帧
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// else {
|
|
|
|
|
// if (previousParamBind.isTimeout()) {
|
|
|
|
|
// log.info("[cac] {} 指令装订失败, 超过最大帧数仍未回报", shortInfo());
|
|
|
|
|
// previousParamBind.clearCommand();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (LastCommandRecord.WATING_RESULT == lastQuery.getState()) {
|
|
|
|
|
if (lastQuery.commandMatch(msg.slice(13,16))) {
|
|
|
|
|
lastQuery.notifyParamQueryCommandResult();
|
|
|
|
|
lastQuery.clearCommand();
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/**检查参数查询回报*/
|
|
|
|
|
private boolean checkParamQueryResponse(ByteBuf msg) {
|
|
|
|
|
if (CommandRecord.WAITING_RESULT == previousParamQuery.getState()) {
|
|
|
|
|
previousParamQuery.addReceiveFrameCount();
|
|
|
|
|
if (previousParamQuery.commandMatch(msg.slice(13,16))) {
|
|
|
|
|
try {
|
|
|
|
|
UavTakeOffParamQueryResultParam981A uavTakeOffParamQueryResultParam = new UavTakeOffParamQueryResultParam981A(msg.slice(13,16));
|
|
|
|
|
// previousParamQuery.notifyParamQueryCommandResult(true, uavTakeOffParamQueryResultParam);
|
|
|
|
|
log.info("[cac] {} 指令查询成功结果回报...", shortInfo());
|
|
|
|
|
previousParamQuery.clearCommand();
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.warn("[cac] {} 指令查询结果回报处理异常:{}",shortInfo(), e.getMessage());
|
|
|
|
|
} finally {
|
|
|
|
|
switchToCommonData(); // 恢复常发数据帧
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// else {
|
|
|
|
|
// if (previousControl.isTimeout()) {
|
|
|
|
|
// log.info("[cac] {} 指令查询结果回报失败, 超过最大帧数仍未回报", shortInfo());
|
|
|
|
|
// previousControl.clearCommand();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**检查航线装订回报*/
|
|
|
|
|
private boolean checkRouteBindResponse(ByteBuf msg) {
|
|
|
|
|
if (CommandQueueRecord.WAITING_NEXT == previousRouteBind.getState()) {
|
|
|
|
|
previousRouteBind.addReceiveFrameCount();
|
|
|
|
|
if (previousRouteBind.commandMatch(msg.slice(13, 16))) {
|
|
|
|
|
if (previousRouteBind.completeOrWaitNext()) { // 如果指令列表均已回报,则判定成功,向中心指控回报, 并恢复常发帧
|
|
|
|
|
try {
|
|
|
|
|
// previousRouteBind.notifyParamBindCommandResult(true);
|
|
|
|
|
log.info("[cac] {} 航线装订成功结果成功", shortInfo());
|
|
|
|
|
previousRouteBind.clearCommand();
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.warn("[cac] {} 航线装订结果回报处理异常:{}", shortInfo(), e.getMessage());
|
|
|
|
|
} finally {
|
|
|
|
|
switchToCommonData(); // 恢复常发数据帧
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 仍有航点未装订
|
|
|
|
|
writeRouteBindCommand0(previousRouteBind.code, previousRouteBind.commandQueue.peek(), previousControl.commandUniId);
|
|
|
|
|
log.debug("[cac] {} 当前航点装订成功,剩余航点:{}", shortInfo(), previousRouteBind.commandQueue.size());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// else {
|
|
|
|
|
// if (previousRouteBind.isTimeout()) {
|
|
|
|
|
// log.info("[cac] {} 航线装订结果失败, 超过最大帧数仍未回报", shortInfo());
|
|
|
|
|
// previousRouteBind.clearCommand();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/**开关指令帧数控制*/
|
|
|
|
|
private int commandNumber(byte controlCommand) {
|
|
|
|
|
switch (controlCommand) {
|
|
|
|
|
case (byte) 0xA7: // 解锁
|
|
|
|
@ -198,4 +425,101 @@ public class HaborClient981A extends HaborClient {
|
|
|
|
|
return 5;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 查询指令回报结果参数类, 各型号分开定义*/
|
|
|
|
|
@Data
|
|
|
|
|
private static class UavTakeOffParamQueryResultParam981A extends UavTakeOffParamQueryResultParam {
|
|
|
|
|
/**
|
|
|
|
|
* 起飞高度,单位m,精确到小数点后2位; 原数据分辨率 0.1
|
|
|
|
|
*/
|
|
|
|
|
private int takeoffAltitude;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 起飞油门,精确到整数; 原数据分辨率 1
|
|
|
|
|
*/
|
|
|
|
|
private int takeoffThrottle;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 最大飞行速度,单位m/s,精确到小数点后2位; 原数据分辨率 0.1
|
|
|
|
|
*/
|
|
|
|
|
private int maxFlightSpeed;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 爬升速度限幅,单位m/s,精确到小数点后2位; 原数据分辨率 0.1
|
|
|
|
|
*/
|
|
|
|
|
private int climbSpeedLimit;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下降速度限幅,单位m/s,精确到小数点后2位; 原数据分辨率 0.1
|
|
|
|
|
*/
|
|
|
|
|
private int descentSpeedLimit;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 返航安全高度,单位m,精确到小数点后2位; 原数据分辨率 0.1
|
|
|
|
|
*/
|
|
|
|
|
private int safeReturnAltitude;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 断链返航时间,单位min,精确到小数点后1位; 原数据分辨率 0.1
|
|
|
|
|
*/
|
|
|
|
|
private int linkLossLaunchTime;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 高度上调下限,单位m,精确到整数; 原数据分辨率 1
|
|
|
|
|
*/
|
|
|
|
|
private int minAscendingAltitude;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 高度下调下限,单位m,精确到整数; 原数据分辨率 1
|
|
|
|
|
*/
|
|
|
|
|
private int minDescendingAltitude;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 机场航向,单位°,精确到小数点后2位; 原数据分辨率 0.1
|
|
|
|
|
*/
|
|
|
|
|
private int runwayHeading;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 空投高度,单位m,精确到小数点后2位; 原数据分辨率 1
|
|
|
|
|
*/
|
|
|
|
|
private int airDropAltitude;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 电池类型,0或1; 原数据分辨率 1
|
|
|
|
|
*/
|
|
|
|
|
private int batteryType;
|
|
|
|
|
|
|
|
|
|
public UavTakeOffParamQueryResultParam981A(ByteBuf dataBufSlice) {
|
|
|
|
|
int idx = 1;
|
|
|
|
|
takeoffAltitude = (int) (dataBufSlice.getUnsignedShortLE(idx) * 0.1 * 100);
|
|
|
|
|
idx += 2;
|
|
|
|
|
takeoffThrottle = dataBufSlice.getUnsignedByte(idx);
|
|
|
|
|
idx += 1;
|
|
|
|
|
maxFlightSpeed = (int) (dataBufSlice.getUnsignedByte(idx) * 0.1 * 100);
|
|
|
|
|
idx += 1;
|
|
|
|
|
climbSpeedLimit = (int) (dataBufSlice.getUnsignedByte(idx) * 0.1 * 100);
|
|
|
|
|
idx += 1;
|
|
|
|
|
descentSpeedLimit = (int) (dataBufSlice.getByte(idx) * 0.1 * 100);
|
|
|
|
|
idx += 1;
|
|
|
|
|
safeReturnAltitude = (int) (dataBufSlice.getUnsignedShortLE(idx) * 0.1 * 100);
|
|
|
|
|
idx += 2;
|
|
|
|
|
linkLossLaunchTime = dataBufSlice.getUnsignedByte(idx);
|
|
|
|
|
idx += 1;
|
|
|
|
|
minAscendingAltitude = dataBufSlice.getUnsignedByte(idx);
|
|
|
|
|
idx += 1;
|
|
|
|
|
minDescendingAltitude = dataBufSlice.getUnsignedByte(idx);
|
|
|
|
|
idx += 1;
|
|
|
|
|
runwayHeading = (int) (dataBufSlice.getUnsignedShortLE(idx) * 0.01 * 100);
|
|
|
|
|
idx += 2;
|
|
|
|
|
airDropAltitude = dataBufSlice.getUnsignedByte(idx);
|
|
|
|
|
idx += 1;
|
|
|
|
|
batteryType = dataBufSlice.getUnsignedByte(idx);
|
|
|
|
|
idx += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String toJsonStr() throws IOException {
|
|
|
|
|
return JSONUtils.obj2json(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|