Browse Source

修改了球机跟踪代码 根据雷达轨迹数据去操作球机跟踪

v1
GG 1 year ago
parent
commit
f50a453c8b
  1. 492
      military/military-module-system/src/main/java/com/zgx/MilitaryZMQApplication.java
  2. 31
      military/military-module-system/src/main/java/com/zgx/modules/military/entity/RadarTrackModel.java
  3. 129
      military/military-module-system/src/main/java/com/zgx/modules/military/service/impl/MsCameraSettingServiceImpl.java

492
military/military-module-system/src/main/java/com/zgx/MilitaryZMQApplication.java

@ -50,6 +50,8 @@ import java.awt.geom.Point2D;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.ConnectException;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
@ -76,7 +78,6 @@ public class MilitaryZMQApplication implements ApplicationRunner {
IMsAlarmSettingsService msAlarmSettingsService;
@Autowired
IMsFaultRecordService msFaultRecordService;
@Autowired
IMsCameraSettingService msCameraSettingService;
@ -155,7 +156,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
redisUtil.hset("alarm_settings", "targetHeight", alarmSettings.getTargetHeight());
}
//1.监听雷达(雷远)预警信息
/* //1.监听雷达(雷远)预警信息
ZmqSubThread radarLYInfoThread = new ZmqSubThread(address, recvPort, radarLY) {
@Override
public void dealWithData(byte[] data) throws ParseException {
@ -540,9 +541,9 @@ public class MilitaryZMQApplication implements ApplicationRunner {
}
}
};
new Thread(radarSYInfoThread).start();
new Thread(radarSYInfoThread).start();*/
//3.监听电子围网(智安)报警信息
/* //3.监听电子围网(智安)报警信息
ZmqSubThread fenceZAInfoThread = new ZmqSubThread(address, recvPort, fenceZA) {
@Override
public void dealWithData(byte[] data) throws ParseException {
@ -655,7 +656,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
faultRecord.setContent(content.toString());
faultRecord.setHappenTime(new Date(jsonObject.getLongValue("timestamp")));
msFaultRecordService.save(faultRecord);
/*//根据IP获取对应设数据记录设备线程
*//*//根据IP获取对应设数据记录设备线程
TcpClient tcpClient = ThreadManager.getTcpClientMap().get(String.valueOf(redisUtil.hget("dataRecordServer", "ip")));
if (tcpClient != null) {
//将报警数据发送给大系统
@ -668,7 +669,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
AlarmType2.BREAK.getCode(),
9999,
System.currentTimeMillis());
tcpClient.send(alarmInfo);*/
tcpClient.send(alarmInfo);*//*
}
}
break;
@ -677,7 +678,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
}
}
};
new Thread(fenceZAInfoThread).start();
new Thread(fenceZAInfoThread).start();*/
//todo 新增代码 目标位置信息
@ -691,7 +692,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
public void dealWithData(byte[] data) throws ParseException {
log.info(Thread.currentThread().getName() + "接收到数据:" + new String(data));
JSONObject jsonObject = JSON.parseObject(new String(data));
log.info("1.jsonObject:" + jsonObject.toString());
log.info("case4 : jsonObject:" + jsonObject.toString());
//查询雷达信息 雷达经纬度(113.455074,22.122197)
QueryWrapper<MsDeviceInfo> queryWrapper = new QueryWrapper<>();
@ -711,7 +712,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
//获取目标经纬度 targetLonLat:(113.457415,22.094953)
GEOIntersectPointUtils.LatLon targetLonLat = GEOUtils.getLocationByLocationAndAngleAndDistance(deviceInfo.getLon(), deviceInfo.getLat(), azimuth, distance);//计算目标点经纬度
//todo : 打印目标经纬度
log.info("2.目标经纬度targetLonLat:" + targetLonLat);
log.info("case4 : 目标经纬度targetLonLat:" + targetLonLat);
//判断该设备是否有关联光电,有则查询光电信息
MsDeviceInfo cameraInfo = null;
@ -782,7 +783,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
double fov = Math.toDegrees(Math.atan(h / d)) * 2 * 100;
//todo 打印光电水平所需偏转角
/* log.info("3.获取光电水平初始偏转角cameraInitAzimuth" + cameraInfo.getInitAzimuth().toString());
/* log.info("3.获取光电水平初始偏转角cameraInitAzimuth" + cameraInfo.getInitAzimuth().toString());
log.info("4.PTZStatus-pan:" + redisUtil.hget("PTZStatus", "pan").toString());
log.info("5.获取光电水平偏转角cameraAzimuth:" + cameraAzimuth);
log.info("6.计算目标绝对方位角targetAzimuth:" + targetAzimuth);
@ -796,7 +797,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
log.info("10.目标平均高度height:" + h);
log.info("11.目标距离dis:" + d);
log.info("12.计算视场角:" + fov);*/
log.info("视场角:" + fov);
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())),
@ -808,50 +809,173 @@ public class MilitaryZMQApplication implements ApplicationRunner {
//todo : 联动控制球机
log.info("联动控制球机:");
MsCameraSetting cameraSetting = null;
if (cameraInfo.getRelateType() == 6) {//雷达通过relate_type==2 和relate_id去绑定光电 需要在ms_device_info表中中添加并绑定光电信息
//根据关联id查询光电信息
cameraSetting = msCameraSettingService.getById(cameraInfo.getRelateId());
if (cameraSetting == null) {
log.info("查询不到关联的球机设备");
}
List<MsCameraSetting> cameraSettings=null;//todo : 查询所有的球机 暂时查询本项目数据库 实际可能查询别的项目数据库
LambdaQueryWrapper<MsCameraSetting> cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>();
cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType,2);//只查询球机的信息 type:2 球机 type:1 枪击 type:10 故障
//todo : 用于调整球机初始角
//cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType,5);//只查询球机的信息
cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper);
if (cameraSettings==null|| cameraSettings.isEmpty()){
return;
}
//1、若设备关联球机,则进行联动定位
if (cameraSetting != null) {
//todo : 计算PTZ
log.info("case4 : 遍历相机列表 寻找最近的点的球机去跟踪");
log.info("case4 : "+JSON.toJSONString(cameraSettings));
//todo : 未优化算法(减少相机数量)
/* double minDis=GEOUtils.GetDistance(cameraSettings.get(0).getLongitude().doubleValue(),cameraSettings.get(0).getLatitude().doubleValue(), targetLonLat.getLon(), targetLonLat.getLat());
int index=0;
for (int i = 1; i < cameraSettings.size(); i++) {
MsCameraSetting cameraSetting = cameraSettings.get(i);
//todo : 1.计算距离 选最近球机 进行跟踪
BigDecimal cameraHeight = cameraSetting.getHeight();
BigDecimal labelHeight = new BigDecimal(1.5);//todo : 暂时写死 实际应该查表
BigDecimal labelHeight = new BigDecimal(h);
double heightDiff = cameraHeight.subtract(labelHeight).doubleValue();
if (heightDiff < 0) {
return;
log.info("IP:"+cameraSetting.getIp()+"与目标的高度差:"+heightDiff+"小于0");
} else{
BigDecimal longitude = cameraSetting.getLongitude();//经度
BigDecimal latitude = cameraSetting.getLatitude();//纬度
double zDis = GEOUtils.GetDistance(longitude.doubleValue(), latitude.doubleValue(), targetLonLat.getLon(), targetLonLat.getLat());
log.info("下标i:"+i+ " 相机IP:"+ cameraSetting.getIp() +" 距离当前相机:"+zDis);
//todo : 更新距离最小的数据 如果数据是按顺序的 可以判断当数据比前一个数据变大的时候就终止 取前一个数据
if (zDis<minDis){
minDis=zDis;
index=i;
}
}
}*/
// todo : 优化1.0
// 计算距离最近的球机
MsCameraSetting msCameraSetting=null;//最近球机信息
double nearestDistance=0;//最近距离
double heightDiff=0;//最近球机的高度差
//Map cameraList=new HashMap();//保存距离目标球机的顺序
for (MsCameraSetting cameraSetting : cameraSettings) {
// todo : 判断该球机是否满足照射范围 不满足的话还可以找第二近的球机 如果放到后面才判断高度差 就无法找第二近的去跟踪了
BigDecimal cameraHeight = cameraSetting.getHeight();//球机高度
BigDecimal labelHeight = new BigDecimal(h);//目标高度
double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差
if (tempHeightDiff<0){
log.info("case4 :"+"ip="+cameraSetting.getIp() + " tempHeightDiff < 0 超过球机照射范围");
}else {
double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(),cameraSetting.getLatitude().doubleValue(),targetLonLat.getLon(),targetLonLat.getLat());
// 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息
if (msCameraSetting==null){
msCameraSetting=cameraSetting;
nearestDistance=temp;
continue;
}
// 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息
if (nearestDistance>temp){
msCameraSetting=cameraSetting;
nearestDistance=temp;
heightDiff=tempHeightDiff;
}
}
}
/*MsCameraSetting msCameraSetting = getNearestDistanceCamera(cameraSettings, h, targetLonLat.getLon(), targetLonLat.getLat());
double nearestDistance= GEOUtils.GetDistance(msCameraSetting.getLongitude().doubleValue(),msCameraSetting.getLatitude().doubleValue(),targetLonLat.getLon(),targetLonLat.getLat());
double heightDiff= msCameraSetting.getHeight().subtract(BigDecimal.valueOf(h)).doubleValue();
*/ //判断两点的距离是否超过有效距离,超过则丢掉
if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) {
log.info("case4 :"+"超过跟踪的最大距离"+redisUtil.hget("alarm_settings", "inOutEffectDistance").toString());
return;
}
//MsCameraSetting msCameraSetting = cameraSettings.get(index);
log.info("case4 :"+" 相机IP:"+ msCameraSetting.getIp() +" 最短距离nearestDistance:"+nearestDistance);
log.info("case4 :"+"距离最近的相机:"+JSON.toJSONString(msCameraSetting));
/* //todo : 计算PTZ
//球机高度
BigDecimal cameraHeight = msCameraSetting.getHeight();
//目标高度
BigDecimal labelHeight = new BigDecimal(h);
//球机与目标的高度差
double heightDiff = cameraHeight.subtract(labelHeight).doubleValue();
//高度差小于0 则说明目标在球机上方 超过球机照射范围
if (heightDiff < 0) {
log.info("heightDiff < 0 超过球机照射范围");
return;
}*/
//1.先控制球机照射目标
log.info("【尝试使用ptzControllerByLatLonAndDistance】");
msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(),
msCameraSetting.getUser(),
msCameraSetting.getPassword(),
msCameraSetting.getMaxElevation(),
msCameraSetting.getZeroAzimuth(),
heightDiff,
msCameraSetting.getZoomFactor(),
msCameraSetting.getLongitude().doubleValue(),
msCameraSetting.getLatitude().doubleValue(),
targetLonLat.getLon(),
targetLonLat.getLat(),
msCameraSetting.getStyle());//style用于区分品牌类型 1:海康 2:宇视
log.info("case4 :"+"【参数信息】");
log.info("cameraSetting.getUser():"+msCameraSetting.getUser());
log.info("cameraSetting.getPassword():"+msCameraSetting.getPassword());
log.info("cameraSetting.getMaxElevation():"+msCameraSetting.getMaxElevation());
log.info("cameraSetting.getZeroAzimuth():"+msCameraSetting.getZeroAzimuth());
log.info("heightDiff:"+heightDiff);
log.info("cameraSetting.getZoomFactor():"+msCameraSetting.getZoomFactor());
log.info("cameraSetting.getLongitude():"+msCameraSetting.getLongitude().doubleValue());
log.info("cameraSetting.getLatitude():"+msCameraSetting.getLatitude().doubleValue());
log.info("targetLonLat.getLon()"+targetLonLat.getLon());
log.info("targetLonLat.getLat()"+targetLonLat.getLat());
//todo : 2.水平跟踪目标 目标详细信息再redis中 当雷达开启目标跟踪后 将发case3数据 订阅case3数据后 将目标详细数据缓存到redis中
log.info("------case4将球机转到目标位置-------");
DecimalFormat decimalFormat = new DecimalFormat("#.00");//保留两位小数
String longitude = decimalFormat.format(targetLonLat.getLon());
String latitude = decimalFormat.format(targetLonLat.getLat());
//获取轨迹信息
//String redisKey = "tracks"+"_"+longitude+"_"+latitude;
int redisAzimuth=(int)azimuth;
String redisKey = "tracks:"+redisAzimuth;
log.info("case4 :"+"longitude:"+longitude+" "+"latitude"+latitude+"azimuth"+redisAzimuth);
// todo : 1.通过船速和航向控制球机转动(不采用)
/* float targetSpeed = Float.parseFloat(redisUtil.hget(redisKey, "targetSpeed").toString());//航速
float targetCourse =Float.parseFloat(redisUtil.hget(redisKey, "targetCourse").toString());//航向
log.info("【尝试使用ptzControllerByLatLonAndDistance】");
msCameraSettingService.ptzControllerByLatLon(cameraSetting.getIp(),
cameraSetting.getUser(),
cameraSetting.getPassword(),
cameraSetting.getMaxElevation(),
cameraSetting.getZeroAzimuth(),
heightDiff,
cameraSetting.getZoomFactor(),
cameraSetting.getLongitude().doubleValue(),
cameraSetting.getLatitude().doubleValue(),
targetLonLat.getLon(),
targetLonLat.getLat());
log.info("【参数信息】");
log.info("cameraSetting.getUser():"+cameraSetting.getUser());
log.info("cameraSetting.getPassword():"+cameraSetting.getPassword());
log.info("cameraSetting.getMaxElevation():"+cameraSetting.getMaxElevation());
log.info("cameraSetting.getZeroAzimuth():"+cameraSetting.getZeroAzimuth());
log.info("heightDiff:"+heightDiff);
log.info("cameraSetting.getZoomFactor():"+cameraSetting.getZoomFactor());
log.info("cameraSetting.getLongitude():"+cameraSetting.getLongitude().doubleValue());
log.info("cameraSetting.getLatitude():"+cameraSetting.getLatitude().doubleValue());
log.info("targetLonLat.getLon()"+targetLonLat.getLon());
log.info("targetLonLat.getLat()"+targetLonLat.getLat());
log.info("targetCourse 航向:"+String.valueOf(targetSpeed));
log.info("targetSpeed 航速:"+String.valueOf(targetCourse));
double ySpend = Math.cos(Math.toRadians(targetCourse))*targetSpeed; //正数 上 负数 下
log.info("ySpend 方向:"+String.valueOf(ySpend));
String instruct="stop";
//todo : 待优化
if (ySpend>=0){ //160 下 330 上
instruct="right";//(-1, 0, 0)
}else {
instruct="left";//(1, 0, 0)
}
//todo : 速度的计算 根据航速和航向
float speed= (float) (targetSpeed * msCameraSetting.getLeftAngle());
log.info("相机水平转动速度:"+String.valueOf(speed)+"方向:"+instruct);
msCameraSettingService.ptzControl(msCameraSetting.getIp(), msCameraSetting.getUser(), msCameraSetting.getPassword(),instruct,speed);
*/
//todo : 2.通过不断更新的船经纬度信息控制球机转动
/* redisUtil.hget(redisKey,"targetLon");
redisUtil.hget(redisKey,"targetLat");*/
int trackId = (int) redisUtil.hget(redisKey, "trackId");//根据方位角 找到 轨迹Id
redisUtil.hset("trackingTargetId", String.valueOf(trackId),msCameraSetting.getIp());//将该轨迹 和 定位该轨迹的球机 保存到跟踪队列中
log.info("正在跟踪的trackId:"+trackId);
//todo : 根据trackId更新的数据转动球机
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
@ -861,25 +985,295 @@ public class MilitaryZMQApplication implements ApplicationRunner {
};
new Thread(nyGuideCamPosThread).start();
//todo : 新增代码 球机联动
/**
* address : 172.20.0.77 (ZMQ发布地址)
* port : 5151
* topic : RadarTrack(todo : 暂时写死 后续通过配置文件配置)
*/
ZmqSubThread radarTrackThread = new ZmqSubThread(address, recvPort, "RadarTrack") { //todo ip为radar-gui服务运行的机器
@Override
public void dealWithData(byte[] data) throws ParseException {
log.info(Thread.currentThread().getName() + "接收到数据:" + new String(data));
JSONObject jsonObject = JSON.parseObject(new String(data));
log.info("case3 :"+"1.RadarTrack数据:" + jsonObject.toString());
String radarTarcksJsonString = (String) jsonObject.get("radarTracks");
List<RadarTrackModel> radarTrackModels = JSONObject.parseArray(radarTarcksJsonString, RadarTrackModel.class);
log.info(JSON.toJSONString(radarTrackModels));
RadarTrackModel radarTrackModel = radarTrackModels.get(0);
log.info("case3 :"+JSON.toJSONString(radarTrackModel));
//将经纬度作为key去定位
DecimalFormat decimalFormat = new DecimalFormat("#.00");
String longitude = decimalFormat.format(radarTrackModel.getLongitude());
String latitude = decimalFormat.format(radarTrackModel.getLatitude());
String azimuth = decimalFormat.format(radarTrackModel.getAzimuth());
log.info("longitude:"+longitude+"latitude:"+latitude+"azimuth:"+azimuth);
//将每个目标轨迹信息进行缓存
//String redisKey = "tracks"+"_"+longitude+"_"+latitude;//经纬度来进行缓存
float redisAzimuth=Float.parseFloat(azimuth);
String redisKey = "tracks:"+(int)redisAzimuth;//方位角进行缓存
//String redisKey = "tracks";//方位角进行缓存
//todo : 将雷达轨迹数据持续进行缓存 后续根据当用户点击雷达图的目标时 持续跟踪最新的该目标信息(存在的问题 : 雷达数据不更新)
log.info("redisKey:"+redisKey);
//缓存 Azimuth =》 船信息
redisUtil.hset(redisKey,"targetLon",radarTrackModel.getLongitude());
redisUtil.hset(redisKey,"targetLat",radarTrackModel.getLatitude());
redisUtil.hset(redisKey,"targetDis",radarTrackModel.getDis());
redisUtil.hset(redisKey,"targetAzimuth",radarTrackModel.getAzimuth());
redisUtil.hset(redisKey,"targetCourse",radarTrackModel.getCourse());
redisUtil.hset(redisKey,"targetSpeed",radarTrackModel.getSpeed());
redisUtil.hset(redisKey,"trackId",radarTrackModel.getTrackId());
//缓存 TrackId =》 船信息 (todo:如果雷达case 4数据可以多发一个trackId 就无需多缓存azimuth)
String trackIdKey = "trackIds:"+radarTrackModel.getTrackId();
redisUtil.hset(trackIdKey,"targetLon",radarTrackModel.getLongitude());
redisUtil.hset(trackIdKey,"targetLat",radarTrackModel.getLatitude());
redisUtil.hset(trackIdKey,"targetDis",radarTrackModel.getDis());
redisUtil.hset(trackIdKey,"targetAzimuth",radarTrackModel.getAzimuth());
redisUtil.hset(trackIdKey,"targetCourse",radarTrackModel.getCourse());
redisUtil.hset(trackIdKey,"targetSpeed",radarTrackModel.getSpeed());
redisUtil.hset(trackIdKey,"trackId",radarTrackModel.getTrackId());
//redis中存在正在跟踪的轨迹目标信息
String ip = (String) redisUtil.hget("trackingTargetId", String.valueOf(radarTrackModel.getTrackId()));//获取并判断雷达传过来的轨迹数据 看是否该轨迹在跟踪目标队列中
log.info("查询当前轨迹是否处于跟踪状态"+ip);
if (ip!=null){// 该轨迹处于跟踪状态
// todo : 2.0
//计算最近球机
List<MsCameraSetting> cameraSettings=null;//todo : 查询所有的球机 暂时查询本项目数据库 实际可能查询别的项目数据库
LambdaQueryWrapper<MsCameraSetting> cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>();
cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType,2);//只查询球机的信息 type:2 球机 type:1 枪击 type:10 故障
//todo : 用于调整球机初始角
//cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType,5);//只查询球机的信息
cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper);
if (cameraSettings==null|| cameraSettings.isEmpty()){
return;
}
log.info("遍历相机列表 寻找最近的点的球机去跟踪");
log.info(JSON.toJSONString(cameraSettings));
MsCameraSetting msCameraSetting=null;//最近球机信息
double nearestDistance=0;//最近距离
double heightDiff=0;//最近球机的高度差
double targetHeight = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString());
//Map cameraList=new HashMap();//保存距离目标球机的顺序
for (MsCameraSetting cameraSetting : cameraSettings) {
// todo : 判断该球机是否满足照射范围 不满足的话还可以找第二近的球机 如果放到后面才判断高度差 就无法找第二近的去跟踪了
BigDecimal cameraHeight = cameraSetting.getHeight();//球机高度
BigDecimal labelHeight = new BigDecimal(targetHeight);//目标高度
double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差
if (tempHeightDiff<0){
log.info("case3 :"+"ip="+cameraSetting.getIp() + " tempHeightDiff < 0 超过球机照射范围");
}else {
double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(),cameraSetting.getLatitude().doubleValue(),(double) redisUtil.hget("trackIds:"+radarTrackModel.getTrackId(), "targetLon"),(double) redisUtil.hget("trackIds:"+radarTrackModel.getTrackId(), "targetLat"));
// 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息
if (msCameraSetting==null){
msCameraSetting=cameraSetting;
nearestDistance=temp;
continue;
}
// 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息
if (nearestDistance>temp){
msCameraSetting=cameraSetting;
nearestDistance=temp;
heightDiff=tempHeightDiff;
}
}
}
//判断两点的距离是否超过有效距离,超过则丢掉
if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) {
log.info("case3 :"+"超过跟踪的最大距离"+redisUtil.hget("alarm_settings", "inOutEffectDistance").toString());
return;
}
//MsCameraSetting msCameraSetting = cameraSettings.get(index);
log.info("case3 :"+" 相机IP:"+ msCameraSetting.getIp() +" 最短距离nearestDistance:"+nearestDistance);
log.info("case3 :"+"距离最近的相机:"+JSON.toJSONString(msCameraSetting));
//todo : 1.0
String trackIdKey2 = "trackIds:"+radarTrackModel.getTrackId();//获取该轨迹对应的最新数据
double targetLon = (double) redisUtil.hget(trackIdKey2, "targetLon");
double targetLat = (double) redisUtil.hget(trackIdKey2, "targetLat");
//LambdaQueryWrapper<MsCameraSetting> lambdaQueryWrapper = new LambdaQueryWrapper<MsCameraSetting>().eq(MsCameraSetting::getIp, ip);
//MsCameraSetting msCameraSetting = msCameraSettingService.getOne(lambdaQueryWrapper);
//控制球机照射目标
log.info("case3 :"+"【尝试使用ptzControllerByLatLonAndDistance】");
msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(),
msCameraSetting.getUser(),
msCameraSetting.getPassword(),
msCameraSetting.getMaxElevation(),
msCameraSetting.getZeroAzimuth(),
heightDiff,
msCameraSetting.getZoomFactor(),
msCameraSetting.getLongitude().doubleValue(),
msCameraSetting.getLatitude().doubleValue(),
targetLon,
targetLat,
msCameraSetting.getStyle());//style用于区分品牌类型 1:海康 2:宇视
log.info("【参数信息】");
log.info("cameraSetting.getUser():"+msCameraSetting.getUser());
log.info("cameraSetting.getPassword():"+msCameraSetting.getPassword());
log.info("cameraSetting.getMaxElevation():"+msCameraSetting.getMaxElevation());
log.info("cameraSetting.getZeroAzimuth():"+msCameraSetting.getZeroAzimuth());
log.info("heightDiff:"+heightDiff);
log.info("cameraSetting.getZoomFactor():"+msCameraSetting.getZoomFactor());
log.info("cameraSetting.getLongitude():"+msCameraSetting.getLongitude().doubleValue());
log.info("cameraSetting.getLatitude():"+msCameraSetting.getLatitude().doubleValue());
log.info("targetLonLat.getLon()"+targetLon);
log.info("targetLonLat.getLat()"+targetLat);
log.info("case3 :"+"已控制球机照过去 等待下一次轨迹信息 在进行下次定位");
}
}
};
new Thread(radarTrackThread).start();
}
public static void main(String[] args) throws SOAPException, ConnectException {
float speed=10.45f;
System.out.println(speed*1000L);
long result= (long) (speed*1000L);
System.out.println(result);
RadarTrackModel radarTrackModel =new RadarTrackModel();
radarTrackModel.setDis(1);
log.info(JSON.toJSONString(radarTrackModel));
String a="314.8044";
float b= Float.parseFloat(a);
System.out.println(b);
float azimuth=314.80445f;
int redisAzimuth=(int)azimuth;
System.out.println(redisAzimuth);
double targetSpeed=1.0831853;
double targetCourse=330;
double degree=Math.toRadians(targetCourse);
double cos=Math.cos(degree);
double ySpend = Math.cos(targetCourse)*targetSpeed;
System.out.println(degree);
System.out.println(cos);
System.out.println(ySpend);
System.out.println("--------------------");
/* System.out.println(System.getProperty("user.dir") + "\\lib\\hk\\win64\\HCNetSDK.dll");
de.onvif.soap.OnvifDevice onvifDevice = new OnvifDevice("192.168.1.71","admin","hk123456");
PtzDevices ptzDevices = onvifDevice.getPtz();
String token = onvifDevice.getDevices().getProfiles().get(0).getToken();
String token = onvifDevice.getDevices().getProfiles().get(0).getToken();*/
// boolean absoluteMoveSupported = ptzDevices.isAbsoluteMoveSupported(token);
/* System.out.println(absoluteMoveSupported);
ptzDevices.absoluteMove(token,0.5f,0.5f,0.5f);
ptzDevices.relativeMove(token,0,0,0.5f);*/
ptzDevices.absoluteMove(token,0.5f,0f,0f);
/* ptzDevices.absoluteMove(token,0.5f,0f,0f);
ptzDevices.relativeMove(token,0,0,0.5f);
ptzDevices.continuousMove(token,0.5f , 0f, 0f);
//ptzDevices.stopMove(token);
PTZStatus status = ptzDevices.getStatus(token);
PTZStatus status = ptzDevices.getStatus(token);*/
JSONObject jsonObject = new JSONObject();
jsonObject.put("flag",1);
jsonObject.put("sourceId","AgilTrack_cat010bsz");
jsonObject.put("utc",System.currentTimeMillis());
List<RadarTrackModel> radarTracks=new ArrayList<>();
RadarTrackModel radarTrack = new RadarTrackModel();
radarTrack.setDis(100);
radarTrack.setAzimuth(315);
radarTrack.setRadarId(10);
radarTrack.setSpeed(10);
radarTrack.setLatitude(22.180616f);
radarTrack.setLongitude(113.40126f);
radarTracks.add(radarTrack);
jsonObject.put("radarTracks",JSON.toJSONString(radarTracks));
String jsonString = JSON.toJSONString(jsonObject);
byte[] data=jsonString.getBytes();
JSONObject jsonObject2 = JSON.parseObject(new String(data));
log.info("1.RadarTrack数据:" + jsonObject2.toString());
String radarTarcksJsonString = (String) jsonObject2.get("radarTracks");
List<RadarTrackModel> radarTrackModels = JSONObject.parseArray(radarTarcksJsonString, RadarTrackModel.class);
float latitude = radarTrackModels.get(0).getLatitude();
float longitude = radarTrackModels.get(0).getLongitude();
DecimalFormat decimalFormat = new DecimalFormat("#.00");
String l = decimalFormat.format(latitude);
String r = decimalFormat.format(longitude);
System.out.println(latitude);
System.out.println(longitude);
System.out.println(l);
System.out.println(r);
System.out.println(radarTrackModels);
float ab=1.0831853f;
log.info(String.valueOf(ab));
}
/**
* 获取最近球机
* @param cameraSettings 所有球机
* @param targetHeight 目标高度
* @param targetLon 目标经度
* @param targetLat 目标纬度
* @return
*/
public MsCameraSetting getNearestDistanceCamera(List<MsCameraSetting> cameraSettings,double targetHeight,double targetLon,double targetLat){
// todo : 优化1.0
// 计算距离最近的球机
MsCameraSetting msCameraSetting=null;//最近球机信息
double nearestDistance=0;//最近距离
double heightDiff=0;//最近球机的高度差
//Map cameraList=new HashMap();//保存距离目标球机的顺序
for (MsCameraSetting cameraSetting : cameraSettings) {
// todo : 判断该球机是否满足照射范围 不满足的话还可以找第二近的球机 如果放到后面才判断高度差 就无法找第二近的去跟踪了
BigDecimal cameraHeight = cameraSetting.getHeight();//球机高度
BigDecimal labelHeight = new BigDecimal(targetHeight);//目标高度
double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差
if (tempHeightDiff<0){
log.info("ip="+cameraSetting.getIp() + " tempHeightDiff < 0 超过球机照射范围");
}else {
double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(),cameraSetting.getLatitude().doubleValue(),targetLon,targetLat);
// 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息
if (msCameraSetting==null){
msCameraSetting=cameraSetting;
nearestDistance=temp;
continue;
}
// 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息
if (nearestDistance>temp){
msCameraSetting=cameraSetting;
nearestDistance=temp;
heightDiff=tempHeightDiff;
}
}
}
//判断两点的距离是否超过有效距离,超过则丢掉
if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) {
log.info("超过跟踪的最大距离"+redisUtil.hget("alarm_settings", "inOutEffectDistance").toString());
}
return msCameraSetting;
}
/**
* 计算围网报警有效区域围网外5米 + 雷达测角误差±1°造成的距离偏差
*

31
military/military-module-system/src/main/java/com/zgx/modules/military/entity/RadarTrackModel.java

@ -0,0 +1,31 @@
package com.zgx.modules.military.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.apache.ibatis.annotations.ConstructorArgs;
import java.beans.ConstructorProperties;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class RadarTrackModel {
private int radarId;
private long timestamp;
private int trackId;
private char trackState;
private int dis;
private float azimuth;
private float speed;
private float course;
private float longitude;
private float latitude;
private float altitude;
private char type;
private int deviceOwnerId;
private int counter;
private int timeoutToNext;
}

129
military/military-module-system/src/main/java/com/zgx/modules/military/service/impl/MsCameraSettingServiceImpl.java

@ -144,39 +144,42 @@ public class MsCameraSettingServiceImpl extends ServiceImpl<MsCameraSettingMappe
String cameraUser,
String cameraPassword,
double yOffsetAngle,//最大俯仰角
double zOffsetAngle,
double yHeight,
double factor,
double zOffsetAngle,//初始水平角度
double yHeight,//球机高度
double factor,//聚焦因子
double lon1,//相机经度
double lat1,//相机纬度
double lon2,//目标经度
double lat2){//目标纬度
double lat2,//目标纬度
int style){ //相机产商类型
try {
// 登录设备
onvifDevice = new de.onvif.soap.OnvifDevice(cameraIP, cameraUser, cameraPassword);
PtzDevices ptzDevices = onvifDevice.getPtz();
String token = onvifDevice.getDevices().getProfiles().get(0).getToken();
//计算PTZ值
double zAngle = GEOUtils.position(lon1, lat1, lon2, lat2);
double zDis = GEOUtils.GetDistance(lon1, lat1, lon2, lat2);
double yAngle = GEOUtils.upAngle(yHeight, zDis);//球机需要转动的垂直角度
double focusDis = Math.sqrt(yHeight * yHeight + zDis * zDis);
log.info("【ptzControllerByLatLon】");
//初步计算
double zAngle = GEOUtils.position(lon1, lat1, lon2, lat2);//计算球机需要转动的水平角度
double zDis = GEOUtils.GetDistance(lon1, lat1, lon2, lat2);//todo : 计算距离(前面已经计算过 重复计算问题)
double yAngle = GEOUtils.upAngle(yHeight, zDis);//计算球机需要转动的垂直角度
double focusDis = Math.sqrt(yHeight * yHeight + zDis * zDis);//计算球机距离目标的距离
log.info("【ptzControllerByLatLon 初步计算的值(未调整)】");
log.info("zAngle:"+zAngle);
log.info("zDis:"+zDis);
log.info("yAngle:"+yAngle);
log.info("focusDis:"+focusDis);
/* PTZVo ptzVo = ptzCal(yOffsetAngle, zOffsetAngle, focusDis, yAngle, zAngle, factor);
log.info("【计算后的ptzVo】"+ptzVo.toString());
ptzDevices.absoluteMove(token, (float) ptzVo.getPanValue(), (float) ptzVo.getTileValue(), (float) ptzVo.getZoomValue());*/
//计算PTZ值(根据数据库设置的初始值进行进一步计算) -1<P<1 -1<T<1 0<Z<1
PTZVo ptzVo = new PTZVo();
if (style==1){
ptzVo = ptzCal1(yOffsetAngle, zOffsetAngle, focusDis, yAngle, zAngle, factor);//todo : 海康计算方法
}else if(style==2){
ptzVo = ptzCal2(yOffsetAngle, zOffsetAngle, focusDis, yAngle, zAngle, factor);//todo : 宇视计算方法
}
//todo : 新增测试代码
PTZVo ptzVo2 = ptzCal2(yOffsetAngle, zOffsetAngle, focusDis, yAngle, zAngle, factor);//todo : 修改了ptz值的计算
log.info("【计算后的ptzVo2】"+ptzVo2.toString());
ptzDevices.absoluteMove(token, (float) ptzVo2.getPanValue(), (float) ptzVo2.getTileValue(), (float) ptzVo2.getZoomValue());
log.info("【计算后的ptzVo】"+ptzVo.toString());
ptzDevices.absoluteMove(token, (float) ptzVo.getPanValue(), (float) ptzVo.getTileValue(), (float) ptzVo.getZoomValue());
} catch (ConnectException | SOAPException e) {
e.printStackTrace();
@ -255,7 +258,6 @@ public class MsCameraSettingServiceImpl extends ServiceImpl<MsCameraSettingMappe
}
return result;
}
@Override
public Result<?> ptzControl(String cameraIP, String cameraUser, String cameraPassword, String instruct, float speed) {
Result<?> result = new Result<>();
@ -545,8 +547,64 @@ public class MsCameraSettingServiceImpl extends ServiceImpl<MsCameraSettingMappe
return ptzVo;
}
//todo : 宇视
/**
* 计算ptz2的值
*
* @param yOffsetAngle 最大仰角
* @param zOffsetAngle 水平初始角
* @param distance 相机与目标距离
* @param yAngle 相机与视野垂直夹角垂直移动角度
* @param zAngle 相机与视野水平夹角水平移动角度
* @param factor 变倍因子
* @return
*/
public PTZVo ptzCal2(double yOffsetAngle,//最大仰角
double zOffsetAngle,//水平初始角
double distance,
double yAngle,//球机需要转动的垂直角度
double zAngle,
double factor) {
PTZVo ptzVo = new PTZVo();
double zReal = (zAngle + 360 - zOffsetAngle) % 360;
double panValue = 0f;
double tiltValue = 0f;
double commonAngle = 180.00f;
double commonAngle1 = (yOffsetAngle + 90.00f) / 2.00f; //55 或者 67.5
if (zReal < 180) {
if (zReal <= 0) {
panValue = 0f;
} else {
panValue = zReal / commonAngle;
}
} else {
panValue = (zReal - commonAngle) / commonAngle - 1;
}
if (yAngle > commonAngle1) {
if (yAngle > commonAngle1 * 2) { // yAngle < 90 yOffsetAngle <
tiltValue = 1;
} else {
tiltValue = ((yAngle - commonAngle1) / commonAngle1) * (-1);
}
} else {
tiltValue = (yAngle - commonAngle1) / commonAngle1;
}
ptzVo.setPanValue(panValue);
ptzVo.setTileValue(tiltValue);
double zoomValue = factor * distance * 0.01;
if (zoomValue > 1) {
zoomValue = 1;
}
if (zoomValue < factor) {
zoomValue = factor;
}
ptzVo.setZoomValue(zoomValue);
return ptzVo;
}
// todo : 自己计算PTZ值
// todo : 计算海康PTZ值
/**
* 计算ptz2的值
*
@ -558,26 +616,23 @@ public class MsCameraSettingServiceImpl extends ServiceImpl<MsCameraSettingMappe
* @param factor 变倍因子
* @return
*/
private PTZVo ptzCal2(double yOffsetAngle,//最大仰角
public PTZVo ptzCal1(double yOffsetAngle,//最大仰角
double zOffsetAngle,//水平初始角
double distance,
double yAngle,//球机需要转动的垂直角度
double zAngle,//根据球机经纬度和目标经纬度计算得出水平角
double factor) {
//todo : 之前T值的计算被替换 代码还没删除
PTZVo ptzVo = new PTZVo();
double zReal = (zAngle + 360 - zOffsetAngle) % 360;
double panValue = 0f;
double tiltValue = 0f;
double commonAngle = 180.00f;
//double commonAngle1 = (yOffsetAngle + 90.00f) / 2.00f; //55 或者 90
double commonAngle1 = yOffsetAngle;
//todo : P算法
//todo : T算法
double T=(-1)*(yAngle-45.00f)/45.00f;
double commonAngle1 = yOffsetAngle;//todo : 获取数据库的值 是否要写死(待定) 不写死的话 要在后续T值的设置时要进行范围限制 不能-1<T<1
//todo : P算法
if (zReal < 180) {
if (zReal <= 0) {
panValue = 0f;
@ -587,6 +642,11 @@ public class MsCameraSettingServiceImpl extends ServiceImpl<MsCameraSettingMappe
} else {
panValue = (zReal - commonAngle) / commonAngle - 1;
}
//todo : T算法 (yAngle-45)/45 * (-1)
double T=(-1)*(yAngle-commonAngle1)/commonAngle1;
if (yAngle > commonAngle1) { //yAngle的取值范围是0-90 一般是89度左右
if (yAngle > commonAngle1 * 2) {
tiltValue = 1;
@ -605,12 +665,12 @@ public class MsCameraSettingServiceImpl extends ServiceImpl<MsCameraSettingMappe
double zoomValue = factor * distance * 0.01; //todo : 测试调小范围 zoomValue:需要在0-1 factor:0.01 distance:800-8000
//todo : 目标超过2.5km 就会导致球机俯仰角抬不上去 只能通过页面缩小 保障看到船
if (zoomValue > 0.25){
/* if (zoomValue > 0.25){
zoomValue = 0.24;
}
/* if (zoomValue > 1) {
zoomValue = 1;
}*/
if (zoomValue > 1) {
zoomValue = 1;
}
if (zoomValue < factor) {
zoomValue = factor;
}
@ -632,13 +692,6 @@ public class MsCameraSettingServiceImpl extends ServiceImpl<MsCameraSettingMappe
});
}
public static void main(String[] args) {
double factor=0.01;
double distance=8760;
double zoomValue = factor * distance * 0.01;
System.out.println(zoomValue);
}
@Override
public void onResponse(OnvifDevice onvifDevice, OnvifResponse onvifResponse) {

Loading…
Cancel
Save