GG 4 months ago
parent
commit
8341bb74d1
  1. 33
      src/main/java/com/zgx/iot/MilitaryZMQApplication.java
  2. 376
      src/main/java/com/zgx/iot/mq/mqtt/handle/RadarHandler.java

33
src/main/java/com/zgx/iot/MilitaryZMQApplication.java

@ -116,7 +116,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
public void run(ApplicationArguments args) throws Exception {
//判断缓存是否存在报警参数,无则从数据库查询并放入缓存
/* //判断缓存是否存在报警参数,无则从数据库查询并放入缓存
if (!redisUtil.hasKey("alarm_settings")) {
MsAlarmSettings alarmSettings = msAlarmSettingsService.list().get(0);
redisUtil.hset("alarm_settings", "lineEffectTime", alarmSettings.getLineEffectTime());
@ -125,31 +125,7 @@ public class MilitaryZMQApplication implements ApplicationRunner {
redisUtil.hset("alarm_settings", "fenceEffectTime", alarmSettings.getFenceEffectTime());
redisUtil.hset("alarm_settings", "inOutEffectDistance", alarmSettings.getInOutEffectDistance());
redisUtil.hset("alarm_settings", "targetHeight", alarmSettings.getTargetHeight());
//测试数据
/* RadarTrackModel radarTrackModel = new RadarTrackModel();
radarTrackModel.setLongitude(113.485085f);
radarTrackModel.setLatitude(22.050129f);
radarTrackModel.setDis(8560);
radarTrackModel.setAzimuth(158.7832f);
radarTrackModel.setCourse(169.96576f);
radarTrackModel.setSpeed(3.2160966f);
radarTrackModel.setTrackId(1);
radarTrackModel.setAltitude(5.770267f);
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());
redisUtil.hset(trackIdKey, "trackAltitude", radarTrackModel.getAltitude());
redisUtil.hset("PTZStatus", "pan", 331.0400085449219);
redisUtil.hset("PTZStatus", "tilt", 24.100000381469727);
redisUtil.hset("PTZStatus", "ptRunState", 4104);*/
}
}*/
//todo 新增代码 目标位置信息
@ -544,7 +520,6 @@ public class MilitaryZMQApplication implements ApplicationRunner {
//保存有轨迹的Id
redisUtil.zAdd("updatedIds", String.valueOf(radarTrackModel.getTrackId()), (double) System.currentTimeMillis());
//缓存 TrackId =》 船具体信息
String trackIdKey = "trackIds:" + radarTrackModel.getTrackId();
redisUtil.hset(trackIdKey, "targetLon", radarTrackModel.getLongitude());
@ -560,8 +535,8 @@ public class MilitaryZMQApplication implements ApplicationRunner {
String trackingId = (String) redisUtil.get("trackingId");//获取跟踪目标Id
String cameraIp = (String) redisUtil.get("trackingCameraIp");//获取跟踪球机的Ip
if (trackingId != null && trackingId.equals(String.valueOf(radarTrackModel.getTrackId()))) {// 该轨迹处于跟踪状态
// 该轨迹处于跟踪状态
if (trackingId != null && trackingId.equals(String.valueOf(radarTrackModel.getTrackId()))) {
//log.info("当前轨迹处于跟踪列表中" + cameraIp);
List<MsCameraSetting> cameraSettings = null;

376
src/main/java/com/zgx/iot/mq/mqtt/handle/RadarHandler.java

@ -69,7 +69,6 @@ public class RadarHandler {
private final String removeTrackIdsTopic = "/remove/trackIds";
public RadarHandler(IDtDeviceInfoService msDeviceInfoService, IMsCameraSettingService msCameraSettingService, IMsAlarmSettingsService msAlarmSettingsService, RedisUtil redisUtil) {
// 初使化时将已静态化的Service实例化
this.msDeviceInfoService = msDeviceInfoService;
@ -78,361 +77,6 @@ public class RadarHandler {
this.redisUtil = redisUtil;
}
/* public void targetHandler(TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException {
//获取目标id 和是否跟踪
String trackTargetId = String.valueOf(trackingTarget.getTrackId());
boolean trackStatus = trackingTarget.isTrackStatus();
String trackIdKey = "trackIds:" + trackTargetId;
//目标经纬度
float targetLon = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLon").toString());
float targetLat = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLat").toString());
//目标距离(基于雷达)
int distance = Integer.parseInt(redisUtil.hget(trackIdKey, "targetDis").toString());
log.info("目标经纬度:" + targetLon + "," + targetLat);
//查询光电信息
DtDeviceInfo cameraInfo = null;
LambdaQueryWrapper<DtDeviceInfo> photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>();
photoelectricLambdaQueryWrapper.eq(DtDeviceInfo::getDeviceType, DeviceType.PHOTOELECTRIC.getValue()) //光电类型
.eq(DtDeviceInfo::getDeviceStatus, 1);//1-启用状态
List<DtDeviceInfo> photoelectricDevices = msDeviceInfoService.list(photoelectricLambdaQueryWrapper);//查出所有光电
if (CollectionUtils.isEmpty(photoelectricDevices)) {
log.info("查询不到光电设备");
}
cameraInfo = photoelectricDevices.get(0);//todo : 是否需要计算最近的光电
log.info("光电设备信息:" + cameraInfo);
//1、若设备关联光电,则进行联动定位
if (cameraInfo != null) {
//根据IP获取对应光电线程
TcpClient tcpClient = ThreadManager.getTcpClientMap().get(cameraInfo.getDeviceIp());
//停止跟踪
if (!trackStatus) {
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null)
)
);
return;
}
double cameraAzimuth = cameraInfo.getInitAzimuth() + Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString());
//计算目标基于光电的方位角
double targetAzimuth = GEOUtils.getAzimuth(cameraInfo.getDeviceLon(),
cameraInfo.getDeviceLat(),
targetLon,
targetLat
);
//计算光电水平所需方位角
double differAzimuth = targetAzimuth - cameraAzimuth;
//计算方位角
double horAngle = Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()) + differAzimuth;
horAngle = horAngle >= 0 ? horAngle : (360 + horAngle);
//计算俯仰角(上27000-36000中间0-9000下)
double verAngle = Math.toDegrees(Math.asin((double) cameraInfo.getDeviceHeight() / distance));
verAngle = verAngle + cameraInfo.getInitPitch();
//停止跟踪
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null)
)
);
//转动光电到指定位置
//当光电已经处于跟踪状态时,以下操作不会生效
//根据目标位置进行定位(角度实际上送值 : 100倍整数值)
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())),
0, 51, null,
null, null, 45,
(int) (horAngle * 100), (int) (verAngle * 100), null)
)
);
//目标高度 平均高度 在ms_alarm_settings表中设置 船的平均高度 高度越高视场角越大
double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString());
//计算目标距离光点的距离
double d = GEOUtils.GetDistance(targetLon, targetLat, cameraInfo.getDeviceLon(), cameraInfo.getDeviceLat());
//计算视场角,100为分辨率/像素
double fov = Math.toDegrees(Math.atan(h / d)) * 2 * 100;
log.info("目标平均高度:" + h + " 目标距离光电:" + d);
log.info("水平方位角:" + horAngle + " 俯仰角:" + verAngle + " 视场角:" + fov);
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())),
0, 42, null,
null, null, null,
null, null, (int) (fov * 100))
)
);
//球机联动
log.info("联动控制球机:");
LambdaQueryWrapper<MsCameraSetting> cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>();
cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 1)//1-球机类型
.eq(MsCameraSetting::getStatus, 0);//0-启用状态
List<MsCameraSetting> cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper);
if (CollectionUtils.isEmpty(cameraSettings)) {
log.info("没有可联动的球机");
}
MsCameraSetting msCameraSetting = getNearestCamera(cameraSettings, (double) targetLon, (double) targetLat);
//将光电信息封装成rtspUrl返回前端
String rtspUrl = getRtspUrl(cameraInfo.getDeviceIp(), cameraInfo.getUsername(), cameraInfo.getPassword(), 3);//光电
//String rtspUrlTest = "rtsp://admin:hk123456@192.168.1.71:554/";//光电
//String rtspUrl=getRtspUrl(msCameraSetting.getIp(), msCameraSetting.getUser(),msCameraSetting.getPassword(),msCameraSetting.getFactory());//球机
//相机数据发送mqtt给前端展示
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("longitude", cameraInfo.getDeviceLon());
jsonObject1.put("latitude", cameraInfo.getDeviceLat());
jsonObject1.put("deviceName", cameraInfo.getDeviceName());
jsonObject1.put("deviceStatus", cameraInfo.getDeviceStatus());
jsonObject1.put("deviceType", cameraInfo.getDeviceType());
jsonObject1.put("rtspUrl", rtspUrl);
//jsonObject1.put("rtspUrl", msCameraSetting.getPreRtsp());
//jsonObject1.put("rtspUrl", msCameraSetting.getAnalysisRtsp());
MilitaryMqttApplication.pubMessage(jsonObject1.toJSONString(), trackDeviceInfoTopic);
log.info("发送rtsp地址给前端----------" + "消息:" + jsonObject1.toJSONString() + " 主题:" + trackDeviceInfoTopic);
//控制球机照射目标
cameraToTarget(targetLon,targetLat,msCameraSetting);
log.info("跟踪球机的主要参数信息:");
log.info("1.IP: " + msCameraSetting.getIp());
log.info("2.用户名: " + msCameraSetting.getUser());
log.info("3.密码: " + msCameraSetting.getPassword());
log.info("4.最大俯仰角: " + msCameraSetting.getMaxElevation());
log.info("5.初始方位角: " + msCameraSetting.getZeroAzimuth());
log.info("6.品牌: " + (msCameraSetting.getFactory() == 1 ? "海康" : "宇视"));
//将需要跟踪的目标进行保存 并且保存跟踪该目标的球机IP
redisUtil.hset("trackingTargetId", trackTargetId, msCameraSetting.getIp());
log.info("正在跟踪的trackId:" + trackTargetId + "跟踪的球机" + msCameraSetting.getIp());
}
}*/
/* public void targetHandler(TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException {
//获取目标id 和是否跟踪
String trackTargetId = String.valueOf(trackingTarget.getTrackId());
boolean trackStatus = trackingTarget.isTrackStatus();
String trackIdKey = "trackIds:" + trackTargetId;
//目标经纬度
float targetLon = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLon").toString());
float targetLat = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLat").toString());
//目标距离(基于雷达)
int distance = Integer.parseInt(redisUtil.hget(trackIdKey, "targetDis").toString());
log.info("目标经纬度:" + targetLon + "," + targetLat);
//查询光电信息
MsCameraSetting cameraInfo = null;
LambdaQueryWrapper<MsCameraSetting> photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>();
photoelectricLambdaQueryWrapper.eq(MsCameraSetting::getType, 3) //3-光电类型
.eq(MsCameraSetting::getStatus, 1);//1-启用状态
List<MsCameraSetting> photoelectricDevices = msCameraSettingService.list(photoelectricLambdaQueryWrapper);//查出所有光电
if (CollectionUtils.isEmpty(photoelectricDevices)) {
log.info("查询不到光电设备");
}
cameraInfo = photoelectricDevices.get(0);//todo : 是否需要计算最近的光电
log.info("光电设备信息:" + cameraInfo);
//1、若设备关联光电,则进行联动定位
if (cameraInfo != null) {
//根据IP获取对应光电线程
TcpClient tcpClient = ThreadManager.getTcpClientMap().get(cameraInfo.getIp());
//停止跟踪
if (!trackStatus) {
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null)
)
);
return;
}
double cameraAzimuth = cameraInfo.getZeroAzimuth() + Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString());
//计算目标基于光电的方位角
double targetAzimuth = GEOUtils.getAzimuth(cameraInfo.getLongitude().doubleValue(),
cameraInfo.getLatitude().doubleValue(),
targetLon,
targetLat
);
//计算光电水平所需方位角
double differAzimuth = targetAzimuth - cameraAzimuth;
//计算方位角
double horAngle = Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()) + differAzimuth;
horAngle = horAngle >= 0 ? horAngle : (360 + horAngle);
//计算俯仰角(上27000-36000中间0-9000下)
//double verAngle = Math.toDegrees(Math.asin((double) cameraInfo.getHeight() / distance));
double verAngle = Math.toDegrees(Math.asin((cameraInfo.getHeight().doubleValue() / distance)));
verAngle = verAngle + cameraInfo.getFixedAngle();
log.info("【停止跟踪】");
//停止跟踪
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null)
)
);
//转动光电到指定位置
//当光电已经处于跟踪状态时,以下操作不会生效
//根据目标位置进行定位(角度实际上送值 : 100倍整数值)
log.info("【转动光电到指定位置】");
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())),
0, 51, null,
null, null, 45,
(int) (horAngle * 100), (int) (verAngle * 100), null)
)
);
//目标高度 平均高度 在ms_alarm_settings表中设置 船的平均高度 高度越高视场角越大
double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString());
//计算目标距离光点的距离
double d = GEOUtils.GetDistance(targetLon, targetLat, cameraInfo.getLongitude().doubleValue(), cameraInfo.getLatitude().doubleValue());
//计算视场角,100为分辨率/像素
double fov = Math.toDegrees(Math.atan(h / d)) * 2 * 100;
log.info("目标平均高度:" + h + " 目标距离光电:" + d);
log.info("水平方位角:" + horAngle + " 俯仰角:" + verAngle + " 视场角:" + fov);
log.info("【调整光电视场角】");
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())),
0, 42, null,
null, null, null,
null, null, (int) (fov * 100))
)
);
//球机联动
log.info("联动控制球机:");
LambdaQueryWrapper<MsCameraSetting> cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>();
cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 1)//1-球机类型
.eq(MsCameraSetting::getStatus, 1);//1-启用状态
List<MsCameraSetting> cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper);
if (CollectionUtils.isEmpty(cameraSettings)) {
log.info("没有可联动的球机");
}
log.info("case4 : 遍历相机列表 寻找最近的点的球机去跟踪");
// 计算距离最近的球机
MsCameraSetting msCameraSetting = null;//最近球机信息
double nearestDistance = 0;//最近距离
double heightDiff = 0;//最近球机的高度差
for (MsCameraSetting cameraSetting : cameraSettings) {
// 判断该球机是否满足照射范围 不满足的话还可以找第二近的球机 如果放到后面才判断高度差 就无法找第二近的去跟踪了
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(), targetLon, targetLat);
log.info("当前的球机" + cameraSetting.getIp() + "与目标的距离:" + temp);
// 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息
if (msCameraSetting == null) {
msCameraSetting = cameraSetting;
nearestDistance = temp;
continue;
}
// 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息
if (nearestDistance > temp) {
msCameraSetting = cameraSetting;
nearestDistance = temp;
heightDiff = tempHeightDiff;
}
}
}
//没有找到跟踪的球机
if (msCameraSetting == null) {
log.info("没有可跟踪的球机");
}
//判断两点的距离是否超过有效距离,超过则丢掉
if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) {
log.info("case4 :" + "目标超过跟踪的最大距离" + redisUtil.hget("alarm_settings", "inOutEffectDistance").toString());
}
log.info("case4 :" + " 相机IP:" + msCameraSetting.getIp() + " 最短距离nearestDistance:" + nearestDistance);
log.info("case4 :" + "距离最近的相机:" + JSON.toJSONString(msCameraSetting));
//控制球机照射目标
log.info("case4【尝试使用ptzControllerByLatLonAndDistance】将球机转到目标位置");
//将光电信息封装成rtspUrl返回前端
String rtspUrl = getRtspUrl(cameraInfo.getIp(), cameraInfo.getUser(), cameraInfo.getPassword(), 3);//光电
//String rtspUrlTest = "rtsp://admin:hk123456@192.168.1.71:554/";//光电
//String rtspUrl=getRtspUrl(msCameraSetting.getIp(), msCameraSetting.getPort(), msCameraSetting.getUser(),msCameraSetting.getPassword(),msCameraSetting.getFactory());//球机
//轨迹数据发送mqtt给前端使用
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("longitude", cameraInfo.getLongitude());
jsonObject1.put("latitude", cameraInfo.getLatitude());
jsonObject1.put("deviceName", cameraInfo.getCameraName());
jsonObject1.put("deviceStatus", cameraInfo.getStatus());
jsonObject1.put("deviceType", cameraInfo.getType());
jsonObject1.put("rtspUrl", cameraInfo.getPreRtsp());
jsonObject1.put("videoUrl", cameraInfo.getVideoUrl());
//jsonObject1.put("rtspUrl", rtspUrlTest);
MilitaryMqttApplication.pubMessage(jsonObject1.toJSONString(), trackDeviceInfoTopic);
log.info("发送rtsp地址给前端----------" + "消息:" + jsonObject1.toJSONString() + " 主题:" + trackDeviceInfoTopic);
msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(),
msCameraSetting.getUser(),
msCameraSetting.getPassword(),
msCameraSetting.getMaxElevation(),
msCameraSetting.getZeroAzimuth(),
heightDiff,
msCameraSetting.getZoomFactor(),
msCameraSetting.getLongitude().doubleValue(),
msCameraSetting.getLatitude().doubleValue(),
targetLon,
targetLat,
msCameraSetting.getFactory());//factory用于区分品牌类型 1:海康 2:宇视
log.info("跟踪球机的主要参数信息:");
log.info("1.IP: " + msCameraSetting.getIp());
log.info("2.用户名: " + msCameraSetting.getUser());
log.info("3.密码: " + msCameraSetting.getPassword());
log.info("4.最大俯仰角: " + msCameraSetting.getMaxElevation());
log.info("5.初始方位角: " + msCameraSetting.getZeroAzimuth());
log.info("6.品牌: " + (msCameraSetting.getFactory() == 1 ? "海康" : "宇视"));
//将需要跟踪的目标进行保存 并且保存跟踪该目标的球机IP 跟踪有效时间设置为1h
redisUtil.hset("trackingTargetId", trackTargetId, msCameraSetting.getIp(), 60 * 5);
log.info("正在跟踪的trackId:" + trackTargetId + "跟踪的球机" + msCameraSetting.getIp());
}
}*/
/* public void targetHandler(TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException{
angleTest();
}*/
public void targetHandler(TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException {
//获取目标id 和是否跟踪
@ -445,7 +89,6 @@ public class RadarHandler {
float targetLat = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLat").toString());
//目标距离(基于雷达)
int distance = Integer.parseInt(redisUtil.hget(trackIdKey, "targetDis").toString());
@ -643,6 +286,7 @@ public class RadarHandler {
/**
* 相机转动到指定位置
*
* @param targetLon
* @param targetLat
* @param msCameraSetting
@ -669,6 +313,7 @@ public class RadarHandler {
/**
* 相机转动到指定位置
*
* @param targetLon
* @param targetLat
* @param ip
@ -698,6 +343,7 @@ public class RadarHandler {
/**
* 生成rtsp
*
* @param ip
* @param user
* @param password
@ -818,4 +464,20 @@ public class RadarHandler {
}
}
public void ivpTrackingCtrl(Float x, Float y, Float w, Float h, String ip) throws UnsupportedEncodingException {
//根据IP获取对应光电线程
TcpClient tcpClient = ThreadManager.getTcpClientMap().get(ip);
JSONObject trackingRect = new JSONObject();
trackingRect.put("x",x);
trackingRect.put("y",y);
trackingRect.put("w",w);
trackingRect.put("h",h);
tcpClient.send(
HPDataParser.send(
HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, true, trackingRect)
)
);
}
}

Loading…
Cancel
Save