1、针对遮挡严重的场景做了优化

2、增加模拟终端子模块,便于算法验证
This commit is contained in:
weidong 2024-04-17 15:31:33 +08:00
parent c88d37c072
commit 40ae325fe6
23 changed files with 836 additions and 647 deletions

View File

@ -14,6 +14,7 @@
<module>sec-beidou-rtcm</module> <module>sec-beidou-rtcm</module>
<module>sec-api</module> <module>sec-api</module>
<module>sec-beidou-fwd</module> <module>sec-beidou-fwd</module>
<module>sec-test-device</module>
</modules> </modules>
<properties> <properties>

View File

@ -12,6 +12,9 @@ public interface RtcmClient {
@PostMapping("/device_param_changed") @PostMapping("/device_param_changed")
HttpResp deviceParamChanged(@RequestParam(name = "deviceId") String deviceId); HttpResp deviceParamChanged(@RequestParam(name = "deviceId") String deviceId);
@PostMapping("/group_param_changed")
HttpResp groupParamChanged();
@PostMapping("/warning_param_changed") @PostMapping("/warning_param_changed")
HttpResp warningParamChanged(); HttpResp warningParamChanged();
} }

View File

@ -3,6 +3,18 @@ package com.imdroid.sideslope.bd;
public interface FocusCalculator { public interface FocusCalculator {
void reset(); void reset();
void addXyz(double[] xyz); void addXyz(double[] xyz);
void addTilt(Tilt tilt);
void addDelayMs(int ms);
int[] getB562Stat(); int[] getB562Stat();
double[] resultB562(double[] last); double[] resultB562(double[] last);
double[] result9250();
double[] ekfResult(double[] b562Xyz, double[] tiltXyz);
Tilt avgTilt();
int getAvgDelayMs();
Tilt getTilt0();
double[] getPosition0();
double getR();
boolean isShocked();
} }

View File

@ -1,5 +1,8 @@
package com.imdroid.sideslope.bd; package com.imdroid.sideslope.bd;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
/** /**
@ -11,34 +14,38 @@ import java.util.*;
* 6. * 6.
*/ */
public class FocusCalculator1 implements FocusCalculator{ public class FocusCalculator1 implements FocusCalculator{
private final Logger logger = LoggerFactory.getLogger(FocusCalculator1.class);
private final List<double[]> list = Collections.synchronizedList(new ArrayList<>()); // b562算法相关b562固定解的点计算球心初始半径迭代步长最少点数
private final List<Tilt> tilts = Collections.synchronizedList(new ArrayList<>()); final List<double[]> pointList = Collections.synchronizedList(new ArrayList<>());
private Tilt tilt0;//初始状态 int gravityMinCount = 50;
private double[] position0; int gravityMaxCount = 300;
private double r = 10;//杆的长度cm 20230718 测试改为10 double gravityInitR = 0.5;
//private boolean flag = false; // 是否是第一次计算 double pointSelectedRate = 0.5;
private final List<Point> pointList = new ArrayList<>(); double iterStep = 0.1;
//public static double[] lastFocus = null;// // 惯导算法相关
private int delay_ms = 0; final List<Tilt> tilts = Collections.synchronizedList(new ArrayList<>());
private int counter = 0; Tilt tilt0;//初始状态
private boolean isShock = false; double[] position0;
double height = 200;
private final double shockThreshold = 1.5; boolean isShock = false;
final double shockThreshold = 1.5;
private int counterNoB562 = 0;
private int counterNoFixed = 0;
private int counterFixedResult = 0;
//其他
int delay_ms = 0;
int delay_counter = 0;
int counterNoB562 = 0;
int counterNoFixed = 0;
int counterFixedResult = 0;
/** /**
* 构建计算器如果tilt0和position0是null那么计算过程将不考虑与tilts数据融合 * 构建计算器如果tilt0和position0是null那么计算过程将不考虑与tilts数据融合
* @param r 杆的长度单位厘米 * @param height 杆的长度单位厘米
* @param tilt0 一个小时前的tilt平均值用一小时的avgTilt计算得到如果第一次用null * @param tilt0 一个小时前的tilt平均值用一小时的avgTilt计算得到如果第一次用null
* @param position0 一个小时前的xyz三维坐标值用一小时前的ekf计算得到的那个如果第一次用null * @param position0 一个小时前的xyz三维坐标值用一小时前的ekf计算得到的那个如果第一次用null
*/ */
public FocusCalculator1(double r, Tilt tilt0, double[] position0){ public FocusCalculator1(double height, Tilt tilt0, double[] position0){
this.r = r; this.height = height;
this.tilt0 = tilt0; this.tilt0 = tilt0;
this.position0 = position0; this.position0 = position0;
this.isShock = false; this.isShock = false;
@ -53,15 +60,15 @@ public class FocusCalculator1 implements FocusCalculator{
@Override @Override
public void reset(){ public void reset(){
list.clear();
pointList.clear(); pointList.clear();
tilts.clear();
counterNoB562 = 0; counterNoB562 = 0;
counterNoFixed = 0; counterNoFixed = 0;
counterFixedResult = 0; counterFixedResult = 0;
} }
/** /**
* 加入list * 加入pointList
* @param xyz * @param xyz
*/ */
@Override @Override
@ -71,10 +78,10 @@ public class FocusCalculator1 implements FocusCalculator{
else { else {
counterFixedResult ++; counterFixedResult ++;
if (filter(xyz)) { if (filter(xyz)) {
list.add(xyz); pointList.add(xyz);
} }
if (list.size() > 300) { if (pointList.size() > gravityMaxCount) {
list.remove(0); pointList.remove(0);
} }
} }
} }
@ -86,70 +93,68 @@ public class FocusCalculator1 implements FocusCalculator{
/** /**
* 计算得到最终结果 * 计算本轮固定解的重心
* 1如果本轮固定解数少于50个则直接计算均值
* 2如果大于50个
* a找出离上次距离最近的50个点计算初始重心
* b以初始重心为球心初始半径为0.5画球找出所有在球内的点
* c重新计算这个球的重心半径增加0.1再次找出所有在球内的点直到筛选出不少于总数50%的点
* d计算这些点的均值
* @return * @return
*/ */
@Override @Override
public double[] resultB562(double[] r9250Result){ public double[] resultB562(double[] lastResult){
int count = 50; double r = gravityInitR;//初始球半径
double rate = 0.5;
try { try {
double r = 0.5;//初始球半径 if(pointList.size() >= gravityMinCount){
if(list.size() >= count){ // 筛选出离上次解算结果最近的50个点计算初始球心
List<Point> results = new ArrayList<>(); // 如果没有上次位置选最后50个点
if (r9250Result != null && r9250Result.length > 0){ // 为便于排序使用Point对象
List<Point> selectPoints = new ArrayList<>();
if (lastResult != null && lastResult.length > 0){
// 计算所有点位与变量之间的距离并存入集合 // 计算所有点位与变量之间的距离并存入集合
pointList.clear(); for (double[] point : pointList) {
for (double[] point : list) { Point pointObj = new Point(point[0],point[1],point[2]);
Point point1 = new Point(point[0],point[1],point[2]); pointObj.setXDistance(disXY(point,lastResult)); // 设置该点到变量的水平距离
point1.setXDistance(disXY(point,r9250Result)); // 设置该点到变量的水平距离 pointObj.setZDistance(Math.abs(point[2] - lastResult[2])); // 设置该点到变量的垂直距离
point1.setZDistance(Math.abs(point[2] - r9250Result[2])); // 设置该点到变量的垂直距离 selectPoints.add(pointObj); // 将点位加入集合
results.add(point1); // 将点位加入集合
} }
Collections.sort(results, Comparator.comparing(Point::getXDistance));//排序 Collections.sort(selectPoints, Comparator.comparing(Point::getXDistance));//排序
results = results.subList(0, Math.min(50, results.size())); selectPoints = selectPoints.subList(0, Math.min(50, selectPoints.size()));
}else { }else {
for (int i = list.size()-count; i < list.size(); i++) { for (int i = pointList.size()-gravityMinCount; i < pointList.size(); i++) {
results.add(new Point(list.get(i)[0],list.get(i)[1],list.get(i)[2])); selectPoints.add(new Point(pointList.get(i)[0],pointList.get(i)[1],pointList.get(i)[2]));
} }
//flag = true; //flag = true;
} }
// 求初始重心 // 求初始重心
double[] focus = focusPoint(results); double[] focus = focusPointObj(selectPoints);
//重心 // 迭代计算重心直到选出50%的点
int iterNum = 0; int iterNum = 0;
if(globeProportion(focus,r) < rate){ List<double[]> pointList;
if(globeProportion(focus,r) < pointSelectedRate){
do{ do{
iterNum++; iterNum++;
r += 0.1; r += iterStep;
//球附近点集个数有可能为0继续计算会导致focus结果出现NaN //球附近点集个数有可能为0继续计算会导致focus结果出现NaN
List<double[]> doubles1 = globeFilter(focus, r); pointList = globeFilter(focus, r);
if(doubles1.size() == 0){ if(pointList.size() == 0) continue;
continue; focus = focusPoint(pointList);
} }while (globeProportion(focus,r) < pointSelectedRate);
focus = focus(doubles1); logger.info("calc focus iter num:{}, point num:{}",iterNum,pointList.size());
}while (globeProportion(focus,r) < rate);
System.out.println("calc focus iter num:"+iterNum);
// if (flag){
// lastFocus = new double[3];
// lastFocus = focus;
// }
return focus; return focus;
}else{ }else{
// if (flag){ logger.info("calc focus iter num:0, point num:{}",selectPoints.size());
// lastFocus = new double[3];
// lastFocus = focus;
// }
return focus; return focus;
} }
} }
}catch (Exception e){ }catch (Exception e){
//如果计算过程中修改list可能引发异常 //如果计算过程中修改pointList可能引发异常
e.printStackTrace(); e.printStackTrace();
} }
return resultB562Sub(); return resultB562Sub();
@ -159,10 +164,10 @@ public class FocusCalculator1 implements FocusCalculator{
* resultB562替补方法尽量不返回空 * resultB562替补方法尽量不返回空
* @return x,y,z,有效点数 * @return x,y,z,有效点数
*/ */
private double[] resultB562Sub(){ double[] resultB562Sub(){
if(list.size() > 0){ if(pointList.size() > 0){
//重心 //重心
return focus(list); return focusPoint(pointList);
} }
return null; return null;
} }
@ -172,7 +177,7 @@ public class FocusCalculator1 implements FocusCalculator{
* @param xyz * @param xyz
* @return true表示数据正常 * @return true表示数据正常
*/ */
private boolean filter(double[] xyz){ boolean filter(double[] xyz){
double a = xyz[0]*xyz[1]*xyz[2]; double a = xyz[0]*xyz[1]*xyz[2];
if(a == 0 || Double.isInfinite(a) || Double.isNaN(a)){ if(a == 0 || Double.isInfinite(a) || Double.isNaN(a)){
return false; return false;
@ -185,7 +190,7 @@ public class FocusCalculator1 implements FocusCalculator{
* @param list * @param list
* @return * @return
*/ */
private double[] focus(List<double[]> list){ double[] focusPoint(List<double[]> list){
double sumX = 0; double sumX = 0;
double sumY = 0; double sumY = 0;
double sumZ = 0; double sumZ = 0;
@ -198,7 +203,7 @@ public class FocusCalculator1 implements FocusCalculator{
return new double[]{sumX/count,sumY/count,sumZ/count}; return new double[]{sumX/count,sumY/count,sumZ/count};
} }
private double[] focusPoint(List<Point> list){ double[] focusPointObj(List<Point> list){
double sumX = 0; double sumX = 0;
double sumY = 0; double sumY = 0;
double sumZ = 0; double sumZ = 0;
@ -231,15 +236,15 @@ public class FocusCalculator1 implements FocusCalculator{
* @param r * @param r
* @return * @return
*/ */
private double globeProportion(double[] focus, double r){ double globeProportion(double[] focus, double r){
int in = 0;//在球内的个数 int in = 0;//在球内的个数
for (double[] doubles : list) { for (double[] doubles : pointList) {
double dis = dis(doubles, focus); double dis = dis(doubles, focus);
if(dis < r){ if(dis < r){
in += 1; in += 1;
} }
} }
double proportion = 1.00*in/list.size(); double proportion = 1.00*in/pointList.size();
return proportion; return proportion;
} }
@ -249,9 +254,9 @@ public class FocusCalculator1 implements FocusCalculator{
* @param r * @param r
* @return * @return
*/ */
private List<double[]> globeFilter(double[] focus, double r){ List<double[]> globeFilter(double[] focus, double r){
ArrayList<double[]> arrayList = new ArrayList<>(); ArrayList<double[]> arrayList = new ArrayList<>();
for (double[] doubles1 : list) { for (double[] doubles1 : pointList) {
if(dis(doubles1,focus) < r){ if(dis(doubles1,focus) < r){
arrayList.add(doubles1); arrayList.add(doubles1);
} }
@ -266,6 +271,7 @@ public class FocusCalculator1 implements FocusCalculator{
* 3.可用点数无用9250 * 3.可用点数无用9250
* @return * @return
*/ */
@Override
public double[] ekfResult(double[] b562Xyz, double[] tiltXyz){ public double[] ekfResult(double[] b562Xyz, double[] tiltXyz){
if(tiltXyz == null){ if(tiltXyz == null){
return b562Xyz; return b562Xyz;
@ -275,15 +281,15 @@ public class FocusCalculator1 implements FocusCalculator{
} }
double b562Variance; double b562Variance;
double tiltVariance = 5; //Sherlock 230802 2-5 减小惯导的长周期影响 double tiltVariance = 5; //Sherlock 230802 2-5 减小惯导的长周期影响
if(list.size() >= 50){ if(pointList.size() >= 50){
b562Variance = 1; b562Variance = 1;
}else if(list.size() >= 40){ }else if(pointList.size() >= 40){
b562Variance = 3; b562Variance = 3;
}else if(list.size() >= 30){ }else if(pointList.size() >= 30){
b562Variance = 9; b562Variance = 9;
}else if(list.size() >= 20){ }else if(pointList.size() >= 20){
b562Variance = 30; b562Variance = 30;
}else if(list.size() >= 10){ }else if(pointList.size() >= 10){
b562Variance = 60; b562Variance = 60;
}else{ }else{
b562Variance = 90; b562Variance = 90;
@ -303,77 +309,72 @@ public class FocusCalculator1 implements FocusCalculator{
* 加入tilts * 加入tilts
* @param tilt * @param tilt
*/ */
@Override
public void addTilt(Tilt tilt){ public void addTilt(Tilt tilt){
tilts.add(tilt); tilts.add(tilt);
if(tilt.getShock() > shockThreshold) isShock = true; if(tilt.getShock() > shockThreshold) isShock = true;
if(tilts.size() > 300){ if(tilts.size() > gravityMaxCount){
tilts.remove(0); tilts.remove(0);
} }
} }
@Override
public boolean isShocked() { public boolean isShocked() {
return isShock; return isShock;
} }
/** @Override
* 取平均
* @return
*/
public Tilt avgTilt() { public Tilt avgTilt() {
if (tilts.size() == 0) { if (tilts.size() == 0) {
return null; return null;
} }
try {
Iterator<Tilt> iterator = tilts.iterator(); Iterator<Tilt> iterator = tilts.iterator();
int size = tilts.size(); double roll = 0;
double sumP = 0; double pitch = 0;
double sumR = 0; double yaw = 0;
double sumY = 0;
while (iterator.hasNext()) { while (iterator.hasNext()) {
Tilt tilt = iterator.next(); Tilt tilt = iterator.next();
sumP += Math.sin(tilt.getPitch()*Math.PI/180); roll += tilt.getRoll();
sumR += Math.sin(tilt.getRoll()*Math.PI/180); pitch += tilt.getPitch();
sumY += Math.sin(tilt.getYaw()*Math.PI/180); yaw += tilt.getYaw();
} }
double pitch = (Math.asin(sumP/size) * 180/Math.PI + 360)%360;
double roll = (Math.asin(sumR/size) * 180/Math.PI + 360)%360;
double yaw = (Math.asin(sumY/size) * 180/Math.PI + 360)%360;
return new Tilt(pitch,roll,yaw); return new Tilt(pitch,roll,yaw);
}catch (Exception e){
e.printStackTrace();
}
return null;
} }
@Override
public double[] result9250(){ public double[] result9250(){
Tilt avg = avgTilt(); Tilt avg = avgTilt();
if(tilt0 == null || position0 == null || r == 0 || avg == null){ if(tilt0 == null || position0 == null || height == 0 || avg == null){
return null; return null;
} }
return TiltUtil.toPosition(avg,tilt0,position0,r); return TiltUtil.toPosition(avg,tilt0,position0,height);
} }
@Override
public Tilt getTilt0(){ public Tilt getTilt0(){
return tilt0; return tilt0;
} }
@Override
public double[] getPosition0(){ public double[] getPosition0(){
return position0; return position0;
} }
@Override
public double getR(){ public double getR(){
return r; return height;
} }
@Override
public void addDelayMs(int ms){ public void addDelayMs(int ms){
delay_ms += ms; delay_ms += ms;
counter ++; delay_counter ++;
} }
@Override
public int getAvgDelayMs(){ public int getAvgDelayMs(){
return delay_ms/counter; return delay_ms/delay_counter;
} }
} }

View File

@ -1,5 +1,6 @@
package com.imdroid.sideslope.bd; package com.imdroid.sideslope.bd;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
/** /**
@ -10,243 +11,79 @@ import java.util.*;
* 5.否则扩大半径0.01再求重心包容百分之68此重心为所求 * 5.否则扩大半径0.01再求重心包容百分之68此重心为所求
* 6. * 6.
*/ */
public class FocusCalculator2 implements FocusCalculator{ public class FocusCalculator2 extends FocusCalculator1{
final static int MAX_B562_NUM = 3600;
final static int B562_EXPIRED_HOUR = 2;
final List<LocalDateTime> pointTimeList = Collections.synchronizedList(new ArrayList<>());
private final List<double[]> list = Collections.synchronizedList(new ArrayList<>()); /**
* 构建计算器如果tilt0和position0是null那么计算过程将不考虑与tilts数据融合
* @param height 杆的长度单位厘米
* @param tilt0 一个小时前的tilt平均值用一小时的avgTilt计算得到如果第一次用null
* @param position0 一个小时前的xyz三维坐标值用一小时前的ekf计算得到的那个如果第一次用null
*/
public FocusCalculator2(double height, Tilt tilt0, double[] position0){
super(height,tilt0,position0);
iterStep = 0.2;
gravityMaxCount = MAX_B562_NUM;
}
private final List<Point> pointList = new ArrayList<>(); public FocusCalculator2(){
private int counterNoB562 = 0;
private int counterNoFixed = 0;
private int counterFixedResult = 0;
}
@Override @Override
public void reset(){ public void reset(){
list.clear(); //pointList.clear();
pointList.clear();
counterNoB562 = 0; counterNoB562 = 0;
counterNoFixed = 0; counterNoFixed = 0;
counterFixedResult = 0; counterFixedResult = 0;
} }
/** /**
* 加入list * 加入pointList
* @param xyz * @param xyz
*/ */
@Override @Override
public void addXyz(double[] xyz){ public void addXyz(double[] xyz){
LocalDateTime now = LocalDateTime.now();
Iterator<LocalDateTime> iterPointTime = pointTimeList.iterator();
Iterator<double[]> iterPoint = pointList.iterator();
while(iterPointTime.hasNext() && iterPoint.hasNext()){
LocalDateTime pointTime = iterPointTime.next();
if(now.isAfter(pointTime.plusHours(B562_EXPIRED_HOUR))){
iterPointTime.remove();
iterPoint.remove();
}
else{
break;
}
}
if((int)xyz[3] == UBXUtil.NO_B562) counterNoB562++; if((int)xyz[3] == UBXUtil.NO_B562) counterNoB562++;
else if((int)xyz[3] == UBXUtil.NO_FIX_RESULT) counterNoFixed++; else if((int)xyz[3] == UBXUtil.NO_FIX_RESULT) counterNoFixed++;
else { else {
counterFixedResult ++; counterFixedResult ++;
if (filter(xyz)) { if (filter(xyz)) {
list.add(xyz); pointList.add(xyz);
pointTimeList.add(now);
} }
if (list.size() > 300) { if (pointList.size() > gravityMaxCount) {
list.remove(0); pointList.remove(0);
pointTimeList.remove(0);
} }
} }
} }
private boolean filter(double[] xyz){ public double[] resultB562(double[] lastResult){
double a = xyz[0]*xyz[1]*xyz[2]; if(counterFixedResult<30) return null;
if(a == 0 || Double.isInfinite(a) || Double.isNaN(a)){ else return super.resultB562(lastResult);
return false;
}
return true;
} }
@Override @Override
public int[] getB562Stat(){ public int[] getB562Stat(){
return new int[]{counterFixedResult,counterNoFixed,counterNoB562}; int[] b562Stat = new int[]{counterFixedResult,counterNoFixed,counterNoB562};
} reset();
return b562Stat;
/**
* 计算得到最终结果
* @return
*/
public double[] resultB562_2() {
// 求全体样本的重心
double e = 0;
double n = 0;
double d = 0;
for(double[] point: list){
e += point[0];
n += point[1];
d += point[2];
}
e /= list.size();
n /= list.size();
d /= list.size();
double g = 0;
int iterNum = 0;
while(Math.abs(g-e)>0.2){
g = e;
e = gravity(g, 0.3, 0);
iterNum ++;
if(iterNum>=10) break;
}
//System.out.println("e iter num: "+iterNum);
g = 0;
iterNum = 0;
while(Math.abs(g-n)>0.2){
g = n;
n = gravity(g, 0.26, 0);
iterNum ++;
if(iterNum>=10) break;
}
//System.out.println("n iter num: "+iterNum);
g = 0;
iterNum = 0;
while(Math.abs(g-d)>0.4){
g = d;
d = gravity(g, 0.87, 0);
iterNum ++;
if(iterNum>=10) break;
}
//System.out.println("e iter num: "+iterNum);
return new double[]{e,n,d};
}
double gravity(double g, double r, int index){
//筛选出半径为r=0.144的圆内的点
double newG = 0;
List<Double> list2 = new ArrayList<>();
for(double[] point: list){
if(Math.abs(point[index]-g)<=r){
list2.add(point[index]);
newG += point[index];
}
}
System.out.println("sub set: " + list2.size());
if(list2.size()>0) newG /= list2.size();
return newG;
}
@Override
public double[] resultB562(double[] last) {
double[] g = {0, 0, 0};
if(last != null) g=last;
else {
for (double[] xyz : list) {
g[0] += xyz[0];
g[1] += xyz[1];
g[2] += xyz[2];
}
g[0] /= list.size();
g[1] /= list.size();
g[2] /= list.size();
}
double[] g2 = {0,0,0};
int iterNum = 0;
while(isLarge(g,g2,2, 4)){
g2 = g;
g = gravity3(g);
iterNum ++;
if(iterNum>=10) break;
}
System.out.println("e iter num: "+iterNum);
return g;
}
boolean isLarge(double[] p1, double[] p2, double xy, double z){
//return true;
return (Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1]))>xy ||
Math.abs(p1[2]-p2[2])>z);
}
double[] gravity2(double[] g){
//筛选出半径为r=0.144的圆内的点
List<Point> points = new ArrayList<>();
for(double[] xyz: list){
Point point = new Point(xyz[0], xyz[1], xyz[2]);
point.setXDistance(Math.sqrt((xyz[0]-g[0])*(xyz[0]-g[0])+(xyz[1]-g[1])*(xyz[1]-g[1])));
point.setZDistance(Math.abs(xyz[2]-g[2]));
points.add(point);
}
double[] newG = {0,0,0};
int i=0;
int calcNum = points.size()*5/10;
Collections.sort(points, Comparator.comparing(Point::getXDistance));//升序排序
for(Point point:points){
newG[0] += point.getX();
newG[1] += point.getY();
i++;
if(i>=calcNum) {
newG[0] /= calcNum;
newG[1] /= calcNum;
break;
}
}
Collections.sort(points, Comparator.comparing(Point::getZDistance));//升序排序
i=0;
for(Point point:points){
newG[2] += point.getZ();
i++;
if(i>=calcNum) {
newG[2] /= calcNum;
break;
}
}
return newG;
}
double[] gravity3(double[] g){
//筛选出半径为r=0.144的圆内的点
List<Point> points = new ArrayList<>();
for(double[] xyz: list){
Point point = new Point(xyz[0], xyz[1], xyz[2]);
point.setXDistance(Math.abs(xyz[0]-g[0]));
point.setYDistance(Math.abs(xyz[1]-g[1]));
point.setZDistance(Math.abs(xyz[2]-g[2]));
points.add(point);
}
double[] newG = {0,0,0};
int i=0;
int calcNum = points.size()*5/10;
Collections.sort(points, Comparator.comparing(Point::getXDistance));//升序排序
for(Point point:points){
newG[0] += point.getX();
i++;
if(i>=calcNum) {
newG[0] /= calcNum;
break;
}
}
Collections.sort(points, Comparator.comparing(Point::getYDistance));//升序排序
i=0;
for(Point point:points){
newG[1] += point.getY();
i++;
if(i>=calcNum) {
newG[1] /= calcNum;
break;
}
}
Collections.sort(points, Comparator.comparing(Point::getZDistance));//升序排序
i=0;
for(Point point:points){
newG[2] += point.getZ();
i++;
if(i>=calcNum) {
newG[2] /= calcNum;
break;
}
}
return newG;
} }
} }

View File

@ -20,8 +20,6 @@ import java.util.concurrent.ConcurrentHashMap;
public class GNSSCalcFilterService { public class GNSSCalcFilterService {
private final Logger logger = LoggerFactory.getLogger(GNSSCalcFilterService.class); private final Logger logger = LoggerFactory.getLogger(GNSSCalcFilterService.class);
@Resource(name = "local")
DeviceService gnssDeviceRepository;
@Autowired @Autowired
private GnssGroupCalcMapper groupCalcMapper; private GnssGroupCalcMapper groupCalcMapper;
@Autowired @Autowired
@ -44,18 +42,13 @@ public class GNSSCalcFilterService {
final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public void calc(GnssCalcData locationRecord, boolean isExceed) { public void calc(Device gnssDevice, GnssGroupCalc groupCalc, GnssCalcData locationRecord, boolean isExceed) {
String deviceId = locationRecord.getDeviceid(); String deviceId = locationRecord.getDeviceid();
Device gnssDevice = gnssDeviceRepository.findByDeviceId(deviceId);
if(gnssDevice == null) return;
//补充解算记录的设备信息 //补充解算记录的设备信息
locationRecord.setTenantid(gnssDevice.getTenantId()); locationRecord.setTenantid(gnssDevice.getTenantId());
locationRecord.setEnabled(true); locationRecord.setEnabled(true);
// 获取平滑参数
GnssGroupCalc groupCalc = getCalcParams(gnssDevice.getCalcGroupId());
// 计算平滑周期 // 计算平滑周期
int filterCycle = groupCalc.getFilter_hour(); int filterCycle = groupCalc.getFilter_hour();
VaryFilterCycle varyCycle = autoCycleDevices.get(deviceId); VaryFilterCycle varyCycle = autoCycleDevices.get(deviceId);
@ -76,20 +69,6 @@ public class GNSSCalcFilterService {
} }
GnssGroupCalc getCalcParams(int calcGroupId){
GnssGroupCalc calcParam = groupCalcMapper.selectById(calcGroupId);
if(calcParam == null){
calcParam = new GnssGroupCalc();
calcParam.setAuto_filter(false);
calcParam.setFilter_hour(FILTER_DEFAULT_CYCLE_HOUR);
calcParam.setFilter_min_hour(FILTER_MIN_CYCLE_HOUR);
calcParam.setXy_threshold(XY_THRESHOLD);
calcParam.setZ_threshold(Z_THRESHOLD);
calcParam.setAuto_threshold(AUTO_THRESHOLD);
}
return calcParam;
}
/** /**
* 计算东北天的最近融合数据的加权平均, 刘畅20230725 copy avgEND; id>20, 滤波参数6h 25h * 计算东北天的最近融合数据的加权平均, 刘畅20230725 copy avgEND; id>20, 滤波参数6h 25h
*/ */
@ -223,12 +202,8 @@ public class GNSSCalcFilterService {
} }
} }
public LocalDateTime updateRpos(String deviceId, LocalDateTime afterTime){ public LocalDateTime updateRpos(Device gnssDevice, GnssGroupCalc groupCalc,LocalDateTime afterTime){
// 获取平滑参数 String deviceId=gnssDevice.getDeviceId();
Device gnssDevice = gnssDeviceRepository.findByDeviceId(deviceId);
if(gnssDevice == null) return afterTime;
GnssGroupCalc groupCalc = getCalcParams(gnssDevice.getCalcGroupId());
// 平滑处理 // 平滑处理
LocalDateTime beforTime = afterTime.plusHours(groupCalc.getFilter_hour()); LocalDateTime beforTime = afterTime.plusHours(groupCalc.getFilter_hour());
QueryWrapper<GnssCalcData> query = new QueryWrapper<>(); QueryWrapper<GnssCalcData> query = new QueryWrapper<>();

View File

@ -1,7 +1,8 @@
package com.imdroid.sideslope.calc; package com.imdroid.sideslope.calc;
import com.imdroid.sideslope.bd.Tilt; import com.imdroid.secapi.dto.GnssGroupCalc;
import com.imdroid.sideslope.message.D341LocationMessage; import com.imdroid.sideslope.message.D341LocationMessage;
import com.imdroid.sideslope.sal.Device;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -18,19 +19,6 @@ public interface GNSSDataCalcService {
/** /**
* 单轮解算结束计算平滑值 * 单轮解算结束计算平滑值
*/ */
void calSingleDone(String deviceId, Integer tenantId, LocalDateTime resultTime); void calSingleDone(Device device, GnssGroupCalc groupCalc, LocalDateTime resultTime);
/**
* 根据GNSS数据的中间结果计算出最终结果
*
* @param deviceId 设备id
* @return x,y,z三轴数据
*/
//double[] calcResult(String deviceId,double[] b562Xyz, double[] tiltXyz);
/**
* 根据GNSS数据的中间结果计算Tilt的平均值
* @param deviceid 设备id
* @return Tilt
*/
Tilt calcAvgTilt(String deviceid);
} }

View File

@ -5,13 +5,17 @@ import com.imdroid.secapi.dto.*;
import com.imdroid.sideslope.message.BaseMessage; import com.imdroid.sideslope.message.BaseMessage;
import com.imdroid.sideslope.message.D341LocationMessage; import com.imdroid.sideslope.message.D341LocationMessage;
import com.imdroid.sideslope.message.D342LocationMessage; import com.imdroid.sideslope.message.D342LocationMessage;
import com.imdroid.sideslope.sal.Device;
import com.imdroid.sideslope.sal.DeviceService;
import com.imdroid.sideslope.service.DataPersistService; import com.imdroid.sideslope.service.DataPersistService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
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 javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -22,7 +26,7 @@ public class MultiLineGNSSCalcService {
LocalDateTime createTime; LocalDateTime createTime;
LocalDateTime uploadTime; LocalDateTime uploadTime;
} }
private static final Logger logger = LoggerFactory.getLogger(SingleLineGNSSCalcService.class); private static final Logger logger = LoggerFactory.getLogger(MultiLineGNSSCalcService.class);
private static final Map<String, D342Time> deviceMap = new ConcurrentHashMap<>(); private static final Map<String, D342Time> deviceMap = new ConcurrentHashMap<>();
private static final Map<String, ResendRecord> fwdRecordMap = new ConcurrentHashMap<>(); private static final Map<String, ResendRecord> fwdRecordMap = new ConcurrentHashMap<>();
@ -36,6 +40,24 @@ public class MultiLineGNSSCalcService {
private BeidouClient beidouClient; private BeidouClient beidouClient;
@Autowired @Autowired
DataPersistService dataPersistService; DataPersistService dataPersistService;
@Resource(name = "local")
private DeviceService deviceService;
@Autowired
GnssGroupCalcMapper groupCalcMapper;
List<GnssGroupCalc> groupCalcList;
GnssGroupCalc getGroupCalc(int groupId){
if(groupCalcList == null){
groupCalcList = groupCalcMapper.selectList(null);
}
if(groupCalcList != null){
for(GnssGroupCalc groupCalc:groupCalcList){
if(groupCalc.getId() == groupId) return groupCalc;
}
}
return null;
}
public void calc(D342LocationMessage d342Message){ public void calc(D342LocationMessage d342Message){
// 如果时间跨度大于1分钟或者不含d341则计算平滑值 // 如果时间跨度大于1分钟或者不含d341则计算平滑值
@ -56,7 +78,9 @@ public class MultiLineGNSSCalcService {
if (msgTime.isAfter(lastD342Time.createTime.plusMinutes(4))) { if (msgTime.isAfter(lastD342Time.createTime.plusMinutes(4))) {
logger.info(deviceId + " d341 cycle done!"); logger.info(deviceId + " d341 cycle done!");
// 计算上轮结果 // 计算上轮结果
calcService.calSingleDone(deviceId, d342Message.getTenantId(), lastD342Time.createTime); Device device = deviceService.findByDeviceId(deviceId);
GnssGroupCalc groupCalc = getGroupCalc(device.getCalcGroupId());
calcService.calSingleDone(device, groupCalc, lastD342Time.createTime);
} }
} }
else{ else{
@ -105,9 +129,11 @@ public class MultiLineGNSSCalcService {
} }
// 计算上轮结果 // 计算上轮结果
calcService.calSingleDone(deviceId, tenantId, lastDate); Device device = deviceService.findByDeviceId(deviceId);
GnssGroupCalc groupCalc = getGroupCalc(device.getCalcGroupId());
calcService.calSingleDone(device, groupCalc, lastDate);
// 重算最近的 // 重算最近的
lastDate = gnssCalcFilterService.updateRpos(deviceId,lastDate); lastDate = gnssCalcFilterService.updateRpos(device,groupCalc,lastDate);
// 记录转发表更新为upload done // 记录转发表更新为upload done
ResendRecord fwdRecord = fwdRecordMap.get(deviceId); ResendRecord fwdRecord = fwdRecordMap.get(deviceId);
if(fwdRecord != null){ if(fwdRecord != null){
@ -159,4 +185,9 @@ public class MultiLineGNSSCalcService {
} }
else return null; else return null;
} }
public void refreshGroupCalc(){
groupCalcList = groupCalcMapper.selectList(null);
logger.info("group paras changed");
}
} }

View File

@ -2,6 +2,8 @@ package com.imdroid.sideslope.calc;
import com.imdroid.common.util.ThreadManager; import com.imdroid.common.util.ThreadManager;
import com.imdroid.secapi.dto.GnssCalcData; import com.imdroid.secapi.dto.GnssCalcData;
import com.imdroid.secapi.dto.GnssGroupCalc;
import com.imdroid.secapi.dto.GnssGroupCalcMapper;
import com.imdroid.sideslope.bd.*; import com.imdroid.sideslope.bd.*;
import com.imdroid.sideslope.message.D341LocationMessage; import com.imdroid.sideslope.message.D341LocationMessage;
import com.imdroid.sideslope.sal.Device; import com.imdroid.sideslope.sal.Device;
@ -15,6 +17,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.*; import java.util.concurrent.*;
/** /**
@ -26,7 +29,7 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
private static final Logger logger = LoggerFactory.getLogger(SingleLineGNSSCalcService.class); private static final Logger logger = LoggerFactory.getLogger(SingleLineGNSSCalcService.class);
private static final Map<String, FocusCalculator1> calculatorMap = new ConcurrentHashMap<>(); private static final Map<String, FocusCalculator> calculatorMap = new ConcurrentHashMap<>();
private static final Map<String, ScheduledFuture<?>> timerMap = new ConcurrentHashMap<>(); private static final Map<String, ScheduledFuture<?>> timerMap = new ConcurrentHashMap<>();
@ -36,8 +39,6 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
private static final Map<String, Boolean> cleanTiltStatusMap = new ConcurrentHashMap<>(); private static final Map<String, Boolean> cleanTiltStatusMap = new ConcurrentHashMap<>();
private static final Map<String, Boolean> cleanPositionStatusMap = new ConcurrentHashMap<>();
@Autowired @Autowired
WarningService warningService; WarningService warningService;
@ -47,26 +48,53 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
@Resource(name = "local") @Resource(name = "local")
private DeviceService deviceService; private DeviceService deviceService;
@Autowired
GnssGroupCalcMapper groupCalcMapper;
List<GnssGroupCalc> groupCalcList;
GnssGroupCalc getGroupCalc(int groupId){
if(groupCalcList == null){
groupCalcList = groupCalcMapper.selectList(null);
}
if(groupCalcList != null){
for(GnssGroupCalc groupCalc:groupCalcList){
if(groupCalc.getId() == groupId) return groupCalc;
}
}
return null;
}
@Override @Override
public double[] calcSingle(D341LocationMessage message, boolean completeWhenIdle) { public double[] calcSingle(D341LocationMessage message, boolean completeWhenIdle) {
String deviceId = message.getId(); String deviceId = message.getId();
if(completeWhenIdle) resultOutputTimer(deviceId, message.getTenantId(), message.getCreateTime()); Device device = deviceService.findByDeviceId(deviceId);
if(device == null) return null;
GnssGroupCalc groupCalc = getGroupCalc(device.getCalcGroupId());
if(completeWhenIdle) resultOutputTimer(device, groupCalc, message.getCreateTime());
//todo 创建FocusCalculator对象需获取该测站的杆长度上一小时的Tilt平均值上一小时的测站相对坐标融合值ekfResult //todo 创建FocusCalculator对象需获取该测站的杆长度上一小时的Tilt平均值上一小时的测站相对坐标融合值ekfResult
FocusCalculator1 focusCalculator = calculatorMap.computeIfAbsent(deviceId, s -> new FocusCalculator1(150,tiltMap.get(deviceId), FocusCalculator focusCalculator;
positionMap.get(deviceId))); /*if(groupCalc!=null && groupCalc.getVer() == 2){
focusCalculator = calculatorMap.computeIfAbsent(deviceId,
s -> new FocusCalculator2(200,tiltMap.get(deviceId),positionMap.get(deviceId)));
}
else {*/
focusCalculator = calculatorMap.computeIfAbsent(deviceId,
s -> new FocusCalculator1(200, tiltMap.get(deviceId),positionMap.get(deviceId)));
//}
// 读取惯导 // 读取惯导
Tilt tilt = message.getTilt(); Tilt tilt = message.getTilt();
focusCalculator.addTilt(tilt); focusCalculator.addTilt(tilt);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("测站" + deviceId + "的9250单次解析结果:{}", tilt + "," + Arrays.toString(TiltUtil.toPosition(tilt, focusCalculator.getTilt0(), focusCalculator.getPosition0(), focusCalculator.getR()))); logger.debug("测站" + deviceId + "惯导单次解析结果:{}", tilt);
} }
// 计算延迟 // 延迟
focusCalculator.addDelayMs(message.getPps()); focusCalculator.addDelayMs(message.getPps());
//计算到单次相对位置xyz并记录 // 单次b562
double[] doubles = message.getB562_loc(); double[] doubles = message.getB562_loc();
focusCalculator.addXyz(doubles); focusCalculator.addXyz(doubles);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
@ -76,10 +104,10 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
} }
@Override @Override
public void calSingleDone(String deviceId, Integer tenantId, LocalDateTime resultTime) { public void calSingleDone(Device device, GnssGroupCalc groupCalc, LocalDateTime resultTime) {
ThreadManager.getScheduledThreadPool().schedule(() -> { ThreadManager.getScheduledThreadPool().schedule(() -> {
try { try {
calCycleResult(deviceId, tenantId, resultTime); calCycleResult(device, groupCalc, resultTime);
} catch (Exception e) { } catch (Exception e) {
logger.error(e.toString()); logger.error(e.toString());
} }
@ -87,9 +115,9 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
} }
private void resultOutputTimer(String deviceId, Integer tenantId, LocalDateTime date){ private void resultOutputTimer(Device device, GnssGroupCalc groupCalc,LocalDateTime date){
//40秒没数据后输出结果 //40秒没数据后输出结果
ScheduledFuture<?> future = timerMap.get(deviceId); ScheduledFuture<?> future = timerMap.get(device.getDeviceId());
if (future != null && !future.isDone()) { if (future != null && !future.isDone()) {
future.cancel(true); future.cancel(true);
future = null; future = null;
@ -97,41 +125,37 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
future = ThreadManager.getScheduledThreadPool().schedule(() -> { future = ThreadManager.getScheduledThreadPool().schedule(() -> {
try { try {
calCycleResult(deviceId, tenantId, date); calCycleResult(device, groupCalc,date);
// 清除统计 // 清除统计
Device device = deviceService.findByDeviceId(deviceId); device.clearStat();
if(device != null) device.clearStat();
} catch (Exception e) { } catch (Exception e) {
logger.error(e.toString()); logger.error(e.toString());
} }
},40, TimeUnit.SECONDS); },20, TimeUnit.SECONDS);
timerMap.put(deviceId, future); timerMap.put(device.getDeviceId(), future);
} }
private void calCycleResult(String deviceId, Integer tenantId, LocalDateTime resultTime) { private void calCycleResult(Device device, GnssGroupCalc groupCalc, LocalDateTime resultTime) {
FocusCalculator1 focusCalculator = calculatorMap.get(deviceId); String deviceId = device.getDeviceId();
Integer tenantId = device.getTenantId();
FocusCalculator focusCalculator = calculatorMap.get(deviceId);
if(focusCalculator == null) return; if(focusCalculator == null) return;
// 1.检查b562有效数如果过少产生告警
warningService.checkB562Num(deviceId, tenantId,
focusCalculator.getB562Stat());
// 2.数据处理参考上次的位置计算b562重心 // 数据处理参考上次的位置计算b562重心
double[] lastEfk = null; double[] lastEfk = positionMap.get(deviceId);
if(positionMap.containsKey(deviceId)){
lastEfk = positionMap.get(deviceId);
}
double[] b562Result = focusCalculator.resultB562(lastEfk); double[] b562Result = focusCalculator.resultB562(lastEfk);
double[] r9250Result = null; double[] r9250Result = null; // 倾角转换成杆顶到杆底的位移
//判断 取到的b562 和上次融合坐标做判断如果距离>100mm 不计算9250 double[] mergeResult = null;
if (lastEfk != null && b562Result!=null && FocusCalculator1.disXY(b562Result,lastEfk)<100){ //判断 取到的b562 和上次融合坐标做判断如果距离>200mm 不计算融合值
if (lastEfk != null && b562Result!=null && FocusCalculator1.disXY(b562Result,lastEfk)<200){
r9250Result = focusCalculator.result9250(); r9250Result = focusCalculator.result9250();
mergeResult = focusCalculator.ekfResult(b562Result,r9250Result);//融合位置
} }
double[] result = focusCalculator.ekfResult(b562Result,r9250Result); Tilt tilt = focusCalculator.avgTilt();
Tilt tilt = calcAvgTilt(deviceId);
logger.info("测站 {} 的b562相对坐标重心:{}", deviceId, Arrays.toString(b562Result)); logger.info("测站 {} 的b562相对坐标重心:{}", deviceId, Arrays.toString(b562Result));
logger.info("测站 {} 的9250相对坐标:{}", deviceId, Arrays.toString(r9250Result)); logger.info("测站 {} 的惯导相对坐标:{}", deviceId, Arrays.toString(r9250Result));
logger.info("测站 {} 的相对坐标融合值:{}", deviceId, Arrays.toString(result)); logger.info("测站 {} 的相对坐标融合值:{}", deviceId, Arrays.toString(mergeResult));
logger.info("测站 {} 的Tilt平均值:{}", deviceId, tilt); logger.info("测站 {} 的Tilt平均值:{}", deviceId, tilt);
logger.info("测站 {} 的平均延迟:{}ms", deviceId, focusCalculator.getAvgDelayMs()); logger.info("测站 {} 的平均延迟:{}ms", deviceId, focusCalculator.getAvgDelayMs());
@ -143,30 +167,25 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
} else { } else {
tiltMap.put(deviceId, tilt); tiltMap.put(deviceId, tilt);
} }
} }/*
if (result != null && b562Result != null) { if (mergeResult != null && b562Result != null) {
//这里检查一下result过滤1千米外非正常数据 //这里检查一下result过滤1千米外非正常数据
if(focusCalculator.dis(result,b562Result) < 1000_00) { if(focusCalculator.dis(mergeResult,b562Result) < 1000_00) {
if (Boolean.TRUE.equals(cleanPositionStatusMap.get(deviceId))) { if (Boolean.TRUE.equals(cleanPositionStatusMap.get(deviceId))) {
// 置为false下一次计算时就可以正常设置值到positionMap了 // 置为false下一次计算时就可以正常设置值到positionMap了
cleanPositionStatusMap.put(deviceId, Boolean.FALSE); cleanPositionStatusMap.put(deviceId, Boolean.FALSE);
logger.info("置为false下一次计算时就可以正常设置值到positionMap了"); logger.info("置为false下一次计算时就可以正常设置值到positionMap了");
} else { } else {
positionMap.put(deviceId, result); positionMap.put(deviceId, mergeResult);
} }
postLocationRecord(deviceId, b562Result, r9250Result, result, resultTime, postLocationRecord(deviceId, b562Result, r9250Result, mergeResult, resultTime,
focusCalculator.getAvgDelayMs(), focusCalculator.isShocked()); focusCalculator.getAvgDelayMs(), focusCalculator.isShocked());
}else{ }else{
logger.error("融合值异常"); logger.error("融合值异常");
} }
} }*/
focusCalculator.reset(); if (b562Result != null) {
calculatorMap.remove(deviceId); positionMap.put(deviceId, b562Result);
}
private void postLocationRecord(String deviceId, double[] b562Result, double[] r9250Result, double[] result,
LocalDateTime resultTime, int delay, boolean isShocked) {
GnssCalcData locationRecord = new GnssCalcData(); GnssCalcData locationRecord = new GnssCalcData();
locationRecord.setCreatetime(resultTime); locationRecord.setCreatetime(resultTime);
locationRecord.setUpdatetime(LocalDateTime.now()); //通过这里可以区分补传记录 locationRecord.setUpdatetime(LocalDateTime.now()); //通过这里可以区分补传记录
@ -182,29 +201,28 @@ public class SingleLineGNSSCalcService implements GNSSDataCalcService {
locationRecord.setR9250n(r9250Result[1]); locationRecord.setR9250n(r9250Result[1]);
locationRecord.setR9250d(r9250Result[2]); locationRecord.setR9250d(r9250Result[2]);
} }
/*
locationRecord.setPps(delay); if(mergeResult!=null){
gnssCalcFilterService.calc(locationRecord, isShocked); locationRecord.setMpose(mergeResult[0]);
locationRecord.setMposn(mergeResult[1]);
locationRecord.setMposd(mergeResult[2]);
}
*/
locationRecord.setPps(focusCalculator.getAvgDelayMs());
gnssCalcFilterService.calc(device, groupCalc, locationRecord, focusCalculator.isShocked());
} }
@Override // 检查b562有效数如果过少产生告警
public Tilt calcAvgTilt(String deviceId) { warningService.checkB562Num(deviceId, tenantId,
FocusCalculator1 focusCalculator = calculatorMap.get(deviceId); focusCalculator.getB562Stat());
if (focusCalculator != null) {
return focusCalculator.avgTilt(); focusCalculator.reset();
} //calculatorMap.remove(deviceId);
return null;
} }
/*** public void refreshGroupCalc(){
* 清零不需要滤波窗口是按时间来选取历史数据的只要超过4小时或一天即使中间没有数据也不会用 groupCalcList = groupCalcMapper.selectList(null);
* 超过filterCycle的数据 logger.info("group paras changed");
}
public void cleanTiltByDeviceId(String deviceId) {
logger.info("清零[{}]", deviceId);
tiltMap.remove(deviceId);
positionMap.remove(deviceId);
cleanTiltStatusMap.put(deviceId, Boolean.TRUE);
cleanPositionStatusMap.put(deviceId, Boolean.TRUE);
}*/
} }

View File

@ -1,6 +1,8 @@
package com.imdroid.sideslope.web; package com.imdroid.sideslope.web;
import com.imdroid.secapi.client.HttpResp; import com.imdroid.secapi.client.HttpResp;
import com.imdroid.sideslope.calc.MultiLineGNSSCalcService;
import com.imdroid.sideslope.calc.SingleLineGNSSCalcService;
import com.imdroid.sideslope.sal.LocalDeviceServiceImpl; import com.imdroid.sideslope.sal.LocalDeviceServiceImpl;
import com.imdroid.sideslope.server.DeviceChannel; import com.imdroid.sideslope.server.DeviceChannel;
import com.imdroid.sideslope.server.OnlineChannels; import com.imdroid.sideslope.server.OnlineChannels;
@ -33,6 +35,10 @@ public class ApiController {
@Autowired @Autowired
WarningService warningService; WarningService warningService;
@Autowired
SingleLineGNSSCalcService calcService;
@Autowired
MultiLineGNSSCalcService multiCalcService;
@PostMapping(value = "/config") @PostMapping(value = "/config")
public HttpResp config(String deviceId, String configuration) { public HttpResp config(String deviceId, String configuration) {
@ -74,6 +80,16 @@ public class ApiController {
return resp; return resp;
} }
@PostMapping("/group_param_changed")
public HttpResp groupParamChanged(){
calcService.refreshGroupCalc();
multiCalcService.refreshGroupCalc();
HttpResp resp = new HttpResp();
resp.setResponseMessage("succeed");
return resp;
}
@PostMapping("/warning_param_changed") @PostMapping("/warning_param_changed")
public HttpResp warningParamChanged(){ public HttpResp warningParamChanged(){
warningService.refreshCfg(); warningService.refreshCfg();

View File

@ -1,188 +0,0 @@
import com.imdroid.sideslope.bd.FocusCalculator;
import com.imdroid.sideslope.bd.Point;
import org.ejml.simple.SimpleMatrix;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class FocusCalculator3 implements FocusCalculator {
private final List<double[]> list = Collections.synchronizedList(new ArrayList<>());
private final List<Double> listE = Collections.synchronizedList(new ArrayList<>());
private final List<Double> listN = Collections.synchronizedList(new ArrayList<>());
private final List<Double> listD = Collections.synchronizedList(new ArrayList<>());
private final List<Point> pointList = new ArrayList<>();
@Override
public void reset(){
list.removeAll(list);
pointList.removeAll(pointList);
listE.removeAll(listE);
listD.removeAll(listD);
listN.removeAll(listN);
}
/**
* 加入list
* @param xyz
*/
@Override
public void addXyz(double[] xyz){
if(filter(xyz)){
list.add(xyz);
}
if(list.size() > 300){
list.remove(0);
}
}
private boolean filter(double[] xyz){
double a = xyz[0]*xyz[1]*xyz[2];
if(a == 0 || Double.isInfinite(a) || Double.isNaN(a)){
return false;
}
return true;
}
@Override
public int[] getB562Stat(){
return new int[]{0,0,0};
}
@Override
public double[] resultB562(double[] last) {
double[] g = {0, 0, 0};
if(last != null) g=last;
else {
for (double[] xyz : list) {
g[0] += xyz[0];
g[1] += xyz[1];
g[2] += xyz[2];
}
g[0] /= list.size();
g[1] /= list.size();
g[2] /= list.size();
}
makeMatrixList(g);
double[] l = listE.stream().mapToDouble(Double::doubleValue).toArray();
double e = igg3(l);
l = listN.stream().mapToDouble(Double::doubleValue).toArray();
double n = igg3(l);
l = listD.stream().mapToDouble(Double::doubleValue).toArray();
double d = igg3(l);
return new double[]{e,n,d};
}
void makeMatrixList(double[] g){
//筛选出半径为r=0.144的圆内的点
List<Point> points = new ArrayList<>();
for(double[] xyz: list){
Point point = new Point(xyz[0], xyz[1], xyz[2]);
point.setXDistance(Math.abs(xyz[0]-g[0]));
point.setYDistance(Math.abs(xyz[1]-g[1]));
point.setZDistance(Math.abs(xyz[2]-g[2]));
points.add(point);
}
int calcNum = points.size()*5/10;
Collections.sort(points, Comparator.comparing(Point::getXDistance));//升序排序
for(Point point:points){
listE.add(point.getX());
if(listE.size()>=calcNum) {
break;
}
}
Collections.sort(points, Comparator.comparing(Point::getYDistance));//升序排序
for(Point point:points){
listN.add(point.getY());
if(listN.size()>=calcNum) {
break;
}
}
Collections.sort(points, Comparator.comparing(Point::getZDistance));//升序排序
for(Point point:points){
listD.add(point.getZ());
if(listD.size()>=calcNum) {
break;
}
}
}
public static double igg3(double[] l) {
SimpleMatrix L = new SimpleMatrix(l.length,1,false,l);
SimpleMatrix B = new SimpleMatrix(l.length,1);
B.fill(1);
SimpleMatrix P = new SimpleMatrix(l.length, l.length);
for(int i=0; i<l.length;i++){
//P.set(i,i,1/l[i]);
P.set(i,i,1);
}
double x_prev=0;
double x0=0;
for(int i=0;i<l.length;i++){
x0 += l[i];
}
x0 /= l.length;
L = L.minus(x0);
SimpleMatrix W,N,X,V,Q,Qvv;
SimpleMatrix sigma0;
double s0;
double k0=1.0, k1=5, k=1.0;
int iterNum = 0;
while(iterNum<10){
W = B.transpose().mult(P).mult(L); //W=B'*P*l;
N = B.transpose().mult(P).mult(B); //N=B'*P*B;
X = N.invert().mult(W); //x=inv(N)*W;% 待估参数向量
V = B.mult(X).minus(L); //v=B*x-l;% 残差向量
sigma0 = V.transpose().mult(P).mult(V).divide((l.length-1));
s0 = Math.sqrt(sigma0.get(0,0));//sigma0=sqrt(v'*P*v/(10-1));% 单位权中误差
//System.out.println(X);
//System.out.println(s0);
Q = P.invert();//Q=inv(P);
Qvv = Q.minus(B.mult(N.invert().mult(B.transpose())));//Qvv=Q-B*inv(N)*B';
for(int i=0; i<l.length; i++){
double v = V.get(i)/(s0*Math.sqrt(Qvv.get(i,i))); //v_=v(i)/(sigma0*sqrt(Qvv(i,i)));
if(Math.abs(v) < k0){
k = 1.0;
}
else if(Math.abs(v) > k1){
k = 1e-8;
}
else{
k=(k1-Math.abs(v))/(k1-k0);
k=k*k*(k0/Math.abs(v));
}
P.set(i,i,P.get(i,i)*k); //P(i,i)=P(i,i)*k;
}
if(x_prev==0) {
x_prev = X.get(0);
}
else if(Math.abs(x_prev-X.get(0))<0.1) {
break;
}
x_prev = X.get(0);
iterNum++;
}
//x=x0+x_prev;%求出的最后长度 初值+改正数
return (x0+x_prev);
}
}

View File

@ -22,8 +22,7 @@ import java.util.ListIterator;
classes = { classes = {
FocusCalculatorTest.class, FocusCalculatorTest.class,
FocusCalculator1.class, FocusCalculator1.class,
FocusCalculator2.class, FocusCalculator2.class
FocusCalculator3.class
} }
) )

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
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.imdroid.beidou.common.HttpResult; import com.imdroid.beidou.common.HttpResult;
import com.imdroid.secapi.client.RtcmClient;
import com.imdroid.secapi.dto.*; import com.imdroid.secapi.dto.*;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -18,9 +19,10 @@ public class GnssGroupController extends BasicController {
GnssGroupMapper gnssGroupMapper; GnssGroupMapper gnssGroupMapper;
@Autowired @Autowired
GnssGroupCalcMapper gnssGroupCalcMapper; GnssGroupCalcMapper gnssGroupCalcMapper;
@Autowired @Autowired
GnssDeviceMapper deviceMapper; GnssDeviceMapper deviceMapper;
@Autowired
RtcmClient rtcmClient;
/********* 推送页面 *********/ /********* 推送页面 *********/
@RequestMapping("/page/table/gnss_add_group") @RequestMapping("/page/table/gnss_add_group")
@ -125,7 +127,10 @@ public class GnssGroupController extends BasicController {
} }
if (num == 0) { if (num == 0) {
return HttpResult.failed(); return HttpResult.failed();
} else return HttpResult.ok(); } else{
rtcmClient.groupParamChanged();
return HttpResult.ok();
}
} }
@PostMapping("/gnss/group/delete_calc") @PostMapping("/gnss/group/delete_calc")
@ -141,7 +146,10 @@ public class GnssGroupController extends BasicController {
int num = gnssGroupCalcMapper.deleteById(del_id); int num = gnssGroupCalcMapper.deleteById(del_id);
if (num == 0) { if (num == 0) {
return HttpResult.failed(); return HttpResult.failed();
} else return HttpResult.ok(); } else{
rtcmClient.groupParamChanged();
return HttpResult.ok();
}
} }
} }

View File

@ -76,7 +76,7 @@ public class DatasetCleaner {
void checkFwdDataset(){ void checkFwdDataset(){
long before = System.currentTimeMillis() - long before = System.currentTimeMillis() -
(long)365 * 24 * 3600 * 1000; (long)180 * 24 * 3600 * 1000;
Timestamp t = new Timestamp(before); Timestamp t = new Timestamp(before);
int count = fwdRecordMapper.deleteTimeBefore(t); int count = fwdRecordMapper.deleteTimeBefore(t);
log.info("clean fwd dataset num: "+count); log.info("clean fwd dataset num: "+count);

View File

@ -92,9 +92,9 @@
{field: 'rpose', title: '相对东', templet: "<div>{{d.rpose==null?'':d.rpose.toFixed(2)}}</div>"}, {field: 'rpose', title: '相对东', templet: "<div>{{d.rpose==null?'':d.rpose.toFixed(2)}}</div>"},
{field: 'rposn', title: '相对北', templet: "<div>{{d.rposn==null?'':d.rposn.toFixed(2)}}</div>"}, {field: 'rposn', title: '相对北', templet: "<div>{{d.rposn==null?'':d.rposn.toFixed(2)}}</div>"},
{field: 'rposd', title: '相对天', templet: "<div>{{d.rposd==null?'':d.rposd.toFixed(2)}}</div>"}, {field: 'rposd', title: '相对天', templet: "<div>{{d.rposd==null?'':d.rposd.toFixed(2)}}</div>"},
{field: 'auxe', title: '辅助东', templet: "<div>{{d.auxe==null?'':d.auxe.toFixed(2)}}</div>"}, //{field: 'auxe', title: '辅助东', templet: "<div>{{d.auxe==null?'':d.auxe.toFixed(2)}}</div>"},
{field: 'auxn', title: '辅助北', templet: "<div>{{d.auxn==null?'':d.auxn.toFixed(2)}}</div>"}, //{field: 'auxn', title: '辅助北', templet: "<div>{{d.auxn==null?'':d.auxn.toFixed(2)}}</div>"},
{field: 'auxd', title: '辅助天', templet: "<div>{{d.auxd==null?'':d.auxd.toFixed(2)}}</div>"}, //{field: 'auxd', title: '辅助天', templet: "<div>{{d.auxd==null?'':d.auxd.toFixed(2)}}</div>"},
{field: 'enabled', title: '有效',templet: '#enabledTrans'}, {field: 'enabled', title: '有效',templet: '#enabledTrans'},
{field: 'pps', title: '平均延迟'} {field: 'pps', title: '平均延迟'}
]; ];

128
sec-test-device/pom.xml Normal file
View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.imdroid</groupId>
<artifactId>security-monitor</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>sec-test-device</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.78.Final</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.imdroid</groupId>
<artifactId>sec-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.imdroid</groupId>
<artifactId>sec-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<!--mqtt相关依赖-->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>central</id>
<name>ali-mirror</name>
<url>https://maven.aliyun.com/repository/central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>

View File

@ -0,0 +1,24 @@
package com.imdroid.beidou.test_device;
import com.imdroid.beidou.test_device.task.BeidouDevice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
* @author Layton
* @date 2023/1/31 20:33
*/
@SpringBootApplication(scanBasePackages = {"com.imdroid"})
@ComponentScan({"com.imdroid.*"})
public class BeidouTestApp {
public static void main(String[] args) {
SpringApplication.run(BeidouTestApp.class, args);
BeidouDevice beidouDevice = new BeidouDevice();
beidouDevice.connectServer();
beidouDevice.run();
}
}

View File

@ -0,0 +1,127 @@
package com.imdroid.beidou.test_device.service;
import com.imdroid.common.util.ThreadManager;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
public class TCPClient {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private String host;
private int port;
private Bootstrap bootstrap;
private EventLoopGroup group;
private Channel channel;
LocalDateTime connectTime = LocalDateTime.now();
TCPListener listener;
public void start() {
new Thread(this::connect, "forwarder tcp-client").start();
}
public void init(String dest_addr, int dest_port, TCPListener listener) {
this.host = dest_addr;
this.port = dest_port;
this.listener = listener;
//客户端需要一个事件循环组
group = new NioEventLoopGroup();
//创建客户端启动对象
// bootstrap 可重用, 只需在NettyClient实例化的时候初始化即可.
bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//加入处理器
ch.pipeline().addLast(new TcpMessageHandler(TCPClient.this));
}
});
}
public void connect() {
logger.info("netty client starting");
//启动客户端去连接服务器端
try {
ChannelFuture cf = bootstrap.connect(host, port);
cf.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
//重连交给后端线程执行
future.channel().eventLoop().schedule(() -> {
logger.info("tcp client reconnect");
try {
connect();
} catch (Exception e) {
e.printStackTrace();
}
}, 5000, TimeUnit.MILLISECONDS);
} else {
logger.info("tcp client start success!");
}
}
});
//对通道关闭进行监听
this.channel = cf.channel();
this.channel.closeFuture().sync();
} catch (Exception e) {
logger.error("netty client error:", e);
}
}
public void writeAndFlush(String json) {
ByteBuf sendBuffer = Unpooled.buffer();
sendBuffer.writeBytes(json.getBytes(StandardCharsets.UTF_8));
channel.writeAndFlush(sendBuffer).addListener(future -> {
if (future.isSuccess()) {
logger.info("send to tcp:"+host+" succeed.");
} else {
logger.info("send to tcp:"+host+" failed.");
if(listener!=null){
listener.onMessage("failed");
}
}
});
}
public void onConnected(){
connectTime = LocalDateTime.now();
}
public void onDisconnect(){
if(connectTime.isBefore(LocalDateTime.now().minusMinutes(1))) {
connect();
}
else{
ThreadManager.getScheduledThreadPool().schedule(() -> {
try {
connect();
} catch (Exception e) {
logger.error(e.toString());
}
},60, TimeUnit.SECONDS);
}
}
public void onMessage(String msg){
if(listener!=null){
listener.onMessage(msg);
}
}
}

View File

@ -0,0 +1,7 @@
package com.imdroid.beidou.test_device.service;
public interface TCPListener {
void onConnected();
void onDisconnect();
void onMessage(String msg);
}

View File

@ -0,0 +1,52 @@
package com.imdroid.beidou.test_device.service;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
/**
* @author Layton
* @date 2023/2/18 20:36
*/
public class TcpMessageHandler extends SimpleChannelInboundHandler<ByteBuf> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final TCPClient tcpClient;
public TcpMessageHandler(TCPClient tcpClient) {
this.tcpClient = tcpClient;
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf buf) throws Exception {
String msg = buf.toString(Charset.defaultCharset());
tcpClient.onMessage(msg);
if (logger.isDebugEnabled()) {
logger.debug("receive server message:" + msg);
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
logger.info("tcp channel active");
tcpClient.onConnected();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
logger.info("tcp channel inactive");
tcpClient.onDisconnect();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.error("TcpMessageHandler error: {}", cause.toString());
ctx.close();
}
}

View File

@ -0,0 +1,41 @@
package com.imdroid.beidou.test_device.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private DatagramSocket socket;
private InetAddress inetAddress;
private String host;
private int port;
public void init(String host, int port) {
this.host = host;
this.port = port;
try {
logger.info("UDP client init "+host + ":" + port);
this.socket = new DatagramSocket();
this.inetAddress = InetAddress.getByName(host);
} catch (Exception e) {
logger.error("初始化udp客户端失败", e);
}
}
public void sendData(byte[] data) {
try {
DatagramPacket packet = new DatagramPacket(data, data.length, inetAddress, port);
socket.send(packet);
} catch (Exception e) {
logger.error("udp推送gnss数据异常:", e);
}
}
}

View File

@ -0,0 +1,87 @@
package com.imdroid.beidou.test_device.task;
import com.imdroid.beidou.test_device.service.UDPClient;
import com.imdroid.common.util.ByteUtil;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class BeidouDevice {
private String host="127.0.0.1";
private int port=9903;
UDPClient udpClient;
public void connectServer(){
udpClient = new UDPClient();
udpClient.init(host, port);
}
public void run(){
try{
//execute("C:\\Users\\wd\\Desktop\\log\\b562_2412270_1xx.log");
//execute("C:\\Users\\wd\\Desktop\\log\\b562_2412270_2xx.log");
//execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_1xx.log");
//execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_2xx.log");
//execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_3xx.log");
//execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_4xx.log");
//execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_5xx.log");
//execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_6xx.log");
execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_0416_1.log");
execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_0416_2.log");
execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_0416_1xx.log");
execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_0416_2xx.log");
execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_0416_3xx.log");
execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_0416_4xx.log");
execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_0416_5xx.log");
execute("C:\\Users\\wd\\Desktop\\log\\b562_2412254_0416_6xx.log");
}
catch (Exception e){
}
System.out.println("finish!");
}
public void execute(String dataFileName) throws IOException {
FileReader fr=null;
BufferedReader br=null;
try {
fr = new FileReader(dataFileName);
br = new BufferedReader(fr);
String line = "";
String[] arrs = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
long lastTime = 0;
int b562Count = 0;
int cycleCount = 0;
while ((line = br.readLine()) != null) {
arrs = line.split(" ");
if(arrs.length != 3) continue;
Date time = sdf.parse(arrs[0] + " " + arrs[1]);
if (lastTime!=0 && Math.abs(time.getTime() - lastTime) > 60 * 1000) {//超过1分钟为一个周期
Thread.sleep(30 * 1000);
cycleCount++;
System.out.println(time+" cycle "+cycleCount+", b562 num "+b562Count);
}
udpClient.sendData(ByteUtil.hexStringTobyte(arrs[2]));
b562Count++;
lastTime = time.getTime();
Thread.sleep(100);
}
br.close();
fr.close();
}
catch (Exception e){
e.printStackTrace();
if(br!=null) br.close();
if(fr!=null) fr.close();
}
}
}

View File

@ -0,0 +1,22 @@
server.port=9916
server.servlet.context-path=/gnss
spring.application.name=test-gnss
spring.application.build=20240106
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = none
spring.jpa.database-platform = org.hibernate.dialect.MySQLDialect
spring.datasource.url = jdbc:mysql://localhost:3306/beidou?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
spring.datasource.username = admin
spring.datasource.password = DBMgr_2022
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.jackson.dateFormat = yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone = GMT+8
app.format.date = yyyy-MM-dd
app.format.time = HH:mm:ss
app.format.datetime = yyyy-MM-dd HH:mm:ss
mybatis-plus.configuration.map-underscore-to-camel-case=false