Merge remote-tracking branch 'origin/feature/beidou' into feature/beidou
This commit is contained in:
commit
74a0747a3c
@ -5,6 +5,9 @@ import com.imdroid.common.util.ByteUtil;
|
|||||||
import com.imdroid.common.util.StringUtil;
|
import com.imdroid.common.util.StringUtil;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.lang.Math.*;
|
import static java.lang.Math.*;
|
||||||
|
|
||||||
@ -13,6 +16,110 @@ public class RtcmGgaUtil {
|
|||||||
//gga样本:*后面跟的是校验和,其中76代表校验和,对$和*之间的数据(不包括这两个字符)按字节进行异或运算(二进制)的结果
|
//gga样本:*后面跟的是校验和,其中76代表校验和,对$和*之间的数据(不包括这两个字符)按字节进行异或运算(二进制)的结果
|
||||||
private static final String ggaExample = "$GNGGA,020850.50,2258.10508,N,11317.67958,E,4,12,0.74,3.9,M,-5.4,M,1.3,0000*76";
|
private static final String ggaExample = "$GNGGA,020850.50,2258.10508,N,11317.67958,E,4,12,0.74,3.9,M,-5.4,M,1.3,0000*76";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取多条rtcm
|
||||||
|
* 因为存在d331...rtcm...d331...rtcm..这样的数据
|
||||||
|
* 还存在d331...rtcm rtcm rtcm...这样的数据
|
||||||
|
* @param hex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<String> getRtcms(String hex){
|
||||||
|
return splitStartWith(hex,"d300","d301","d302").stream()
|
||||||
|
.map(com.imdroid.sideslope.bd.RtcmGgaUtil::getRtcm)
|
||||||
|
.filter(s -> s != null && !s.isEmpty())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取一条rtcm
|
||||||
|
* @param hex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getRtcm(String hex){
|
||||||
|
try {
|
||||||
|
int index = getIndex(hex,"d300","d301","d302");
|
||||||
|
if (index != -1 && index < hex.length()-6) {
|
||||||
|
//d300数据长度
|
||||||
|
int length = Integer.parseInt(hex.substring(index + 3, index + 6), 16);
|
||||||
|
if(index + (3+length +3)*2 <= hex.length()){
|
||||||
|
return hex.substring(index, index + (3 + length + 3) * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getIndex(String... regex){
|
||||||
|
for (int i = 1; i < regex.length; i++) {
|
||||||
|
if(regex[0].contains(regex[i])){
|
||||||
|
return regex[0].indexOf(regex[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按前缀切割分段
|
||||||
|
* @param regex 第一个是要处理的数据,其他是要检测的前缀
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<String> splitStartWith(String... regex){
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
try{
|
||||||
|
List<Integer> indexs = getIndexs(regex);
|
||||||
|
int start = 0;
|
||||||
|
for (int i = 0; i < indexs.size(); i++) {
|
||||||
|
if(indexs.get(i) != 0){
|
||||||
|
list.add(regex[0].substring(start,indexs.get(i)));
|
||||||
|
start = indexs.get(i);
|
||||||
|
}
|
||||||
|
if(i == indexs.size() -1){
|
||||||
|
list.add(regex[0].substring(indexs.get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按多个规则搜索索引
|
||||||
|
* @param regex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<Integer> getIndexs(String... regex){
|
||||||
|
List<Integer> list =new ArrayList<>();
|
||||||
|
for (int i = 1; i < regex.length; i++) {
|
||||||
|
list.addAll(findAllIndex(regex[0],0,regex[i]));
|
||||||
|
}
|
||||||
|
list.sort((o1, o2) -> o1-o2);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按规则搜索所有索引
|
||||||
|
* @param string
|
||||||
|
* @param index
|
||||||
|
* @param findStr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<Integer> findAllIndex(String string, int index, String findStr){
|
||||||
|
List<Integer> list =new ArrayList<>();
|
||||||
|
int num = string.indexOf(findStr,index);
|
||||||
|
if(num != -1){
|
||||||
|
list.add(num);
|
||||||
|
//递归进行查找
|
||||||
|
List myList = findAllIndex(string,num+1,findStr);
|
||||||
|
list.addAll(myList);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取rtcm数据类型
|
* 获取rtcm数据类型
|
||||||
* @param bytes
|
* @param bytes
|
||||||
|
|||||||
@ -4,13 +4,17 @@ import com.imdroid.common.util.DataTypeUtil;
|
|||||||
import com.imdroid.common.util.ThreadManager;
|
import com.imdroid.common.util.ThreadManager;
|
||||||
import com.imdroid.secapi.client.BeidouClient;
|
import com.imdroid.secapi.client.BeidouClient;
|
||||||
import com.imdroid.secapi.dto.GnssDevice;
|
import com.imdroid.secapi.dto.GnssDevice;
|
||||||
|
import com.imdroid.common.util.ByteUtil;
|
||||||
import com.imdroid.sideslope.bd.Gga;
|
import com.imdroid.sideslope.bd.Gga;
|
||||||
import com.imdroid.sideslope.message.D331RtcmMessage;
|
import com.imdroid.sideslope.message.D331RtcmMessage;
|
||||||
|
import com.imdroid.sideslope.ntrip.UdpNtripServer;
|
||||||
import com.imdroid.sideslope.sal.Device;
|
import com.imdroid.sideslope.sal.Device;
|
||||||
import com.imdroid.sideslope.sal.DeviceService;
|
import com.imdroid.sideslope.sal.DeviceService;
|
||||||
import com.imdroid.sideslope.server.DeviceChannel;
|
import com.imdroid.sideslope.server.DeviceChannel;
|
||||||
import com.imdroid.sideslope.server.OnlineChannels;
|
import com.imdroid.sideslope.server.OnlineChannels;
|
||||||
import com.imdroid.sideslope.service.DataPersistService;
|
import com.imdroid.sideslope.service.DataPersistService;
|
||||||
|
import com.imdroid.sideslope.bd.RtcmGgaUtil;
|
||||||
|
//import com.imdroid.common.util.RtcmGgaUtil;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -21,6 +25,8 @@ import org.springframework.stereotype.Component;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Layton
|
* @author Layton
|
||||||
@ -37,13 +43,19 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
|||||||
private BeidouClient beidouClient;
|
private BeidouClient beidouClient;
|
||||||
@Autowired
|
@Autowired
|
||||||
private DataPersistService dataPersistService;
|
private DataPersistService dataPersistService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void execute(D331RtcmMessage message) {
|
public Void execute(D331RtcmMessage message) {
|
||||||
String id = message.getId();
|
String id = message.getId();
|
||||||
|
byte[] srcdata = message.getSrcData();
|
||||||
|
String rtcm = ByteUtil.bytesToHexString(srcdata);
|
||||||
// 补齐tenantId
|
// 补齐tenantId
|
||||||
Device deviceBs = deviceService.findByDeviceId(id);
|
Device deviceBs = deviceService.findByDeviceId(id);
|
||||||
if(deviceBs == null || deviceBs.getOpMode() == GnssDevice.OP_MODE_UNUSE) return null;
|
if(deviceBs == null || deviceBs.getOpMode() == GnssDevice.OP_MODE_UNUSE) return null;
|
||||||
|
|
||||||
|
// 添加NTRIP处理
|
||||||
|
ntrip(id, rtcm);
|
||||||
|
|
||||||
// 推送基站数据
|
// 推送基站数据
|
||||||
if(deviceBs.getOpMode() == GnssDevice.OP_MODE_USE) {
|
if(deviceBs.getOpMode() == GnssDevice.OP_MODE_USE) {
|
||||||
byte[] forwardBytes = message.getSrcData();
|
byte[] forwardBytes = message.getSrcData();
|
||||||
@ -79,8 +91,8 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
|||||||
if(deviceBs.getD3xxbytes()>0){
|
if(deviceBs.getD3xxbytes()>0){
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
if(deviceBs.getLastRxTime().isBefore(now.minusMinutes(1)) &&
|
if(deviceBs.getLastRxTime().isBefore(now.minusMinutes(1)) &&
|
||||||
(deviceBs.getLastD3f2Time() == null ||
|
(deviceBs.getLastD3f2Time() == null ||
|
||||||
deviceBs.getLastD3f2Time().isBefore(now.minusMinutes(30)))) {
|
deviceBs.getLastD3f2Time().isBefore(now.minusMinutes(30)))) {
|
||||||
// new cycle
|
// new cycle
|
||||||
logger.info("device {} rx {} d331 in a cycle while not d3f0f2",deviceBs.getDeviceId(),deviceBs.getD3xxCount());
|
logger.info("device {} rx {} d331 in a cycle while not d3f0f2",deviceBs.getDeviceId(),deviceBs.getD3xxCount());
|
||||||
|
|
||||||
@ -115,11 +127,9 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
|||||||
Gga gga = message.getGga();
|
Gga gga = message.getGga();
|
||||||
if(gga != null) {
|
if(gga != null) {
|
||||||
deviceBs.updateSatelitesNum(gga.getSatellitesInUsed());
|
deviceBs.updateSatelitesNum(gga.getSatellitesInUsed());
|
||||||
//if(gga.isFixed()) { //基站的quality不会是4
|
deviceBs.setLatitude(gga.getLatitude());
|
||||||
deviceBs.setLatitude(gga.getLatitude());
|
deviceBs.setLongitude(gga.getLongitude());
|
||||||
deviceBs.setLongitude(gga.getLongitude());
|
deviceBs.setAltitude(gga.getAltitude());
|
||||||
deviceBs.setAltitude(gga.getAltitude());
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadManager.getFixedThreadPool().submit(() -> {
|
ThreadManager.getFixedThreadPool().submit(() -> {
|
||||||
@ -133,8 +143,29 @@ public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void>
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ntrip(String mountpoint, String hexData) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// 将原始字节转换为16进制字符串用于RTCM提取
|
||||||
|
//String hexData = ByteUtil.bytesToHexString(rawData);
|
||||||
|
System.out.println(hexData);
|
||||||
|
|
||||||
|
// 提取RTCM数据并发送到NtripServer,使用设备ID作为挂载点
|
||||||
|
Optional.ofNullable(RtcmGgaUtil.getRtcms(hexData))
|
||||||
|
.ifPresent(rtcm -> {
|
||||||
|
System.out.println("挂载点: " + mountpoint);
|
||||||
|
System.out.println("RTCM数据: " + rtcm);
|
||||||
|
UdpNtripServer.send(mountpoint, rtcm);
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("处理NTRIP数据失败, 挂载点: {}, 错误: {}", mountpoint, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getMessageType() {
|
public Class<?> getMessageType() {
|
||||||
return D331RtcmMessage.class;
|
return D331RtcmMessage.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package com.imdroid.sideslope.ntrip;
|
||||||
|
|
||||||
|
import com.imdroid.common.util.HttpUtils;
|
||||||
|
import com.imdroid.common.util.ThreadManager;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
/**
|
||||||
|
* @author likongyong
|
||||||
|
* @date 2023/10/19 11:49
|
||||||
|
*/
|
||||||
|
public class HttpNtripServer {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(HttpNtripServer.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改挂载点获取xingyu差分的gga
|
||||||
|
* @param mount
|
||||||
|
* @param gga
|
||||||
|
*/
|
||||||
|
public static void sendGGA(String mount, String gga){
|
||||||
|
ThreadManager.getSingleThreadPool(HttpNtripServer.class.getName()).execute(()->{
|
||||||
|
try{
|
||||||
|
String url = "http://localhost:11001/ntrip/sendGGA/" + mount + "/" + gga;
|
||||||
|
String result = HttpUtils.getUrl(url);
|
||||||
|
logger.debug("{} send gga {} {}",mount, gga, result);
|
||||||
|
}catch (Exception e){
|
||||||
|
logger.error(e.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
package com.imdroid.sideslope.ntrip;
|
||||||
|
|
||||||
|
import com.imdroid.common.util.ByteUtil;
|
||||||
|
import com.imdroid.common.util.ThreadManager;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地udp发送差分数据到ntrip-forward-server项目
|
||||||
|
*/
|
||||||
|
public class UdpNtripServer {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(UdpNtripServer.class);
|
||||||
|
|
||||||
|
private static DatagramSocket socket;
|
||||||
|
private static DatagramPacket outPacket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向某挂载点提供差分信息
|
||||||
|
* @param mount 挂载点名称
|
||||||
|
* @param hexRtcm 差分信息16进制字符串
|
||||||
|
*/
|
||||||
|
public static void send(String mount, String hexRtcm){
|
||||||
|
ThreadManager.getSingleThreadPool(UdpNtripServer.class.getName()).execute(()->{
|
||||||
|
try{
|
||||||
|
//随机端口
|
||||||
|
if(socket == null) socket = new DatagramSocket();
|
||||||
|
if(outPacket == null) outPacket = new DatagramPacket(new byte[0],0, InetAddress.getByName("localhost"),11100);
|
||||||
|
outPacket.setData(encode(ByteUtil.addBytes(mount.getBytes(), ByteUtil.hexStringTobyte(hexRtcm))));
|
||||||
|
socket.send(outPacket);
|
||||||
|
}catch (Exception e){
|
||||||
|
socket = null;
|
||||||
|
outPacket = null;
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向某挂载点提供差分信息
|
||||||
|
* @param mount 挂载点名称
|
||||||
|
* @param hexRtcm 差分信息16进制字符串
|
||||||
|
*/
|
||||||
|
public static void send(String mount, List<String> hexRtcm){
|
||||||
|
logger.debug(mount + ":" + hexRtcm.size());
|
||||||
|
for (String s : hexRtcm) {
|
||||||
|
send(mount,s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//加入校验位,用于校验数据是否完整
|
||||||
|
private static byte[] encode(byte[] bytes) {
|
||||||
|
byte[] bytes1 = new byte[bytes.length + 1];
|
||||||
|
//校验位
|
||||||
|
byte b = bytes[0];
|
||||||
|
bytes1[0] = bytes[0];
|
||||||
|
for (int i = 1; i < bytes.length; i++) {
|
||||||
|
b ^= bytes[i];
|
||||||
|
bytes1[i] = bytes[i];
|
||||||
|
}
|
||||||
|
bytes1[bytes1.length - 1] = b;
|
||||||
|
return bytes1;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user