作者 钟来

模块整理

正在显示 24 个修改的文件 包含 770 行增加433 行删除
... ... @@ -18,8 +18,8 @@ public class OperatingData {
public static SysConfig sysConfig = new SysConfig(); //系统配置
public static CameraData cameraData = new CameraData(); //摄像头数据
public static CameraConfig cameraConfig = new CameraConfig() ; //摄像头配置
public static DevicedatRequest devicedat = new DevicedatRequest() ; //投料机数据
public static FeederConfig feederConfig = new FeederConfig() ; //投料机配置
public static FeederData feederData = new FeederData() ; //投料机配置
public static RegisterConfig registerConfig = new RegisterConfig(); //数据解析字典
public static void setClassObjecValue(Object value,IfOperatingDataValueIsNotNull ifOperatingDataValueIsNotNull) throws IllegalAccessException {
... ... @@ -39,6 +39,8 @@ public class OperatingData {
ifOperatingDataValueIsNotNull.exeValue(field.getName(),object);
}
}
operatingDataType.upFile();
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
... ... @@ -117,6 +121,29 @@ public class CameraConfig implements OperatingDataType{
*/
private Boolean feedingControl;
/**
* 鱼群规模配置,从小到大:鱼群未聚集,鱼群小量聚集,鱼群中量聚集,鱼群大量聚集
*/
private Double[] fishSchoolSizeConfig;
/**
* 鱼群规模配置,从小到大:鱼群未聚集,鱼群小量聚集,鱼群中量聚集,鱼群大量聚集
*/
private String[] fishSchoolSizeConfigString;
/**
* 采集尺度(分钟)
*/
private Integer collectionScale;
/**
* 步长(秒,小于采集尺度)
*/
private Integer scaleStep;
/**
* 停止尺度之内的面积之和触发的条件(百分比)
*/
private Integer stopTriggeringConditions;
public CameraConfig creteDefault()
{
... ... @@ -145,7 +172,11 @@ public class CameraConfig implements OperatingDataType{
this.identificationFrequency = 1000l;
this.fishGroupImageRecognition = true;
this.feedingControl = true;
this.fishSchoolSizeConfig = new Double[]{200.0,1000.0,2000.0,3000.0};
this.fishSchoolSizeConfigString = new String[]{"鱼群未聚","鱼群小量聚集","鱼群中量聚集","鱼群大量聚集"};
this.collectionScale = 5;
this.scaleStep = 60;
this.stopTriggeringConditions = 30;
return this;
}
... ... @@ -153,4 +184,10 @@ public class CameraConfig implements OperatingDataType{
public void setValue(Field field, Object value) throws IllegalAccessException {
field.set(this,value);
}
@Override
public void upFile() {
File cameraConfigFile = new File("cameraConfig");
FileUtil.writeString(ConfigurationParameterService.gson.toJson(this),cameraConfigFile,"UTF-8");
}
}
... ...
... ... @@ -3,6 +3,9 @@ package com.zhonglai.luhui.smart.feeder.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;
/**
* 摄像头数据
*/
... ... @@ -38,6 +41,11 @@ public class CameraData {
/**
* 鱼群数量
*/
private Integer size;
/**
* 当前斜率的差值
*/
private Double slopeDifference;
... ... @@ -74,4 +82,23 @@ public class CameraData {
*/
private Boolean fishGroupImageRecognIsRun = false;
/**
* 鱼群规模
*/
private Integer fishSchoolSize = 0;
/**
* 尺度之内的面积之和
*/
private Double scaleAreaSum=0.0;
/**
* 尺度之内的面积集合
*/
private List<Double> scaleAreaList = new ArrayList<>();
/**
* 尺度之内的面积之和曲线的峰值
*/
private Double scaleAreaSumMax = 0.0;
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.File;
import java.lang.reflect.Field;
import java.util.List;
@Data
@Accessors(chain = true) //链式写法
public class FeederConfig implements OperatingDataType{
private SerialPortConfig serialPortConfig;
private Condata condata;
private List<Integer[]> timer; //开启、关闭、使能 8:00开启-9:00关闭,状态:启用
public FeederConfig creteDefault()
{
serialPortConfig = new SerialPortConfig().defaultSerialPortConfig();
... ... @@ -20,4 +30,10 @@ public class FeederConfig implements OperatingDataType{
public void setValue(Field field, Object value) throws IllegalAccessException {
field.set(this,value);
}
@Override
public void upFile() {
File feederConfigFile = new File("feederConfig");
FileUtil.writeString(ConfigurationParameterService.gson.toJson(this),feederConfigFile,"UTF-8");
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
import com.zhonglai.luhui.smart.feeder.dto.mqtt.Info;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true) //链式写法
public class FeederData {
private String type; //设备网络型号 字符串("4G.hs")
private Integer signal; //信号量
private Integer machstate; //机器状态
private Integer battlevel; //电池电量
private Info info;
}
... ...
... ... @@ -4,4 +4,6 @@ import java.lang.reflect.Field;
public interface OperatingDataType {
public void setValue(Field field,Object value) throws IllegalAccessException;
public void upFile();
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.domain.Register;
import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
... ... @@ -117,4 +121,10 @@ public class RegisterConfig implements OperatingDataType{
public void setValue(Field field, Object value) throws IllegalAccessException {
field.set(this,value);
}
@Override
public void upFile() {
File registerFile = new File("register");
FileUtil.writeString(ConfigurationParameterService.gson.toJson(this),registerFile,"UTF-8");
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.File;
import java.lang.reflect.Field;
/**
... ... @@ -37,4 +41,10 @@ public class SysConfig implements OperatingDataType{
public void setValue(Field field, Object value) throws IllegalAccessException {
field.set(this,value);
}
@Override
public void upFile() {
File sysConfigFile = new File("sysConfig");
FileUtil.writeString(ConfigurationParameterService.gson.toJson(this),sysConfigFile,"UTF-8");
}
}
... ...
... ... @@ -10,5 +10,10 @@ public class CameracontrolRequest {
private String cmd; //操作指令 devicedata
private String type; //设备网络型号 字符串("4G.hs")
/**
* 是否摄像头推流
*/
private Integer is_push_camera;
private CameraConfig cameraConfig;
}
... ...
... ... @@ -14,6 +14,9 @@ public class DevicedatRequest {
private Integer signal; //信号量
private Integer machstate; //机器状态
private Integer battlevel; //电池电量
private String intelligentFeedingLog; //智能投喂日志
private Condata condata;
private Info info;
private List<Integer[]> timer; //开启、关闭、使能 8:00开启-9:00关闭,状态:启用
... ... @@ -21,6 +24,7 @@ public class DevicedatRequest {
private SysConfig sysConfig;
private CameraData cameraData;
private CameraConfig cameraConfig;
private FeederConfig feederConfig;
private SerialPortConfig serialPortConfig;
private RegisterConfig registerConfig;
}
... ...
... ... @@ -2,6 +2,9 @@ package com.zhonglai.luhui.smart.feeder.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.domain.Register;
... ... @@ -20,6 +23,8 @@ import java.util.Map;
*/
public class ConfigurationParameterService {
public static Gson gson = (new GsonBuilder()).setVersion(1.0D).disableInnerClassSerialization().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).setDateFormat("yyyy-MM-dd").setPrettyPrinting().create();
public static Map<Integer,List<Register>> registerMap = new HashMap<>(); //解析的数据字典
public static Map<String,Register> controlMap = new HashMap<>(); //控制的数据字典
... ... @@ -32,7 +37,7 @@ public class ConfigurationParameterService {
{
sysConfigFile.createNewFile();
SysConfig sysConfig = new SysConfig().creteDefault();
FileUtil.writeString(GsonConstructor.get().toJson(sysConfig),sysConfigFile,"UTF-8");
FileUtil.writeString(gson.toJson(sysConfig),sysConfigFile,"UTF-8");
BeanUtil.copyProperties(sysConfig,OperatingData.sysConfig);
}else{
String str = FileUtil.readUtf8String(sysConfigFile);
... ... @@ -45,7 +50,7 @@ public class ConfigurationParameterService {
{
cameraConfigFile.createNewFile();
CameraConfig cameraConfig = new CameraConfig().creteDefault();
FileUtil.writeString(GsonConstructor.get().toJson(cameraConfig),cameraConfigFile,"UTF-8");
FileUtil.writeString(gson.toJson(cameraConfig),cameraConfigFile,"UTF-8");
BeanUtil.copyProperties(cameraConfig,OperatingData.cameraConfig);
}else{
CameraConfig cameraConfig = GsonConstructor.get().fromJson(FileUtil.readUtf8String(cameraConfigFile),CameraConfig.class);
... ... @@ -57,7 +62,7 @@ public class ConfigurationParameterService {
{
feederConfigFile.createNewFile();
FeederConfig feederConfig = new FeederConfig().creteDefault();
FileUtil.writeString(GsonConstructor.get().toJson(feederConfig),feederConfigFile,"UTF-8");
FileUtil.writeString(gson.toJson(feederConfig),feederConfigFile,"UTF-8");
BeanUtil.copyProperties(feederConfig,OperatingData.feederConfig);
}else{
FeederConfig feederConfig = GsonConstructor.get().fromJson(FileUtil.readUtf8String(feederConfigFile),FeederConfig.class);
... ... @@ -69,7 +74,7 @@ public class ConfigurationParameterService {
{
registerFile.createNewFile();
RegisterConfig registerConfig = new RegisterConfig().creteDefault();
FileUtil.writeString(GsonConstructor.get().toJson(registerConfig),registerFile,"UTF-8");
FileUtil.writeString(gson.toJson(registerConfig),registerFile,"UTF-8");
BeanUtil.copyProperties(registerConfig,OperatingData.registerConfig);
}else{
RegisterConfig registerConfig = GsonConstructor.get().fromJson(FileUtil.readUtf8String(registerFile),RegisterConfig.class);
... ...
package com.zhonglai.luhui.smart.feeder.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
... ... @@ -42,15 +43,19 @@ public class DateListenService {
public void run()
{
//更新投料机数据
ScheduledConfig.scheduler.scheduleAtFixedRate(() -> {
ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.readAll());
Map<String,Object> data = analysisDataService.analysis(modbusDto);
if(null != data && data.size() != 0)
{
Condata condata = BeanUtil.mapToBean(data, Condata.class,false,null);
Info info = BeanUtil.mapToBean(data, Info.class,false,null);
OperatingData.devicedat.setCondata(condata);
OperatingData.devicedat.setInfo(info);
if(ObjectUtil.notEqual(OperatingData.feederConfig.getCondata(),condata))
{
OperatingData.feederConfig.setCondata(condata);
reportCondata();
}
OperatingData.feederData.setInfo(info);
List<Integer[]> timerList = new ArrayList<>();
for(String key:data.keySet())
... ... @@ -64,7 +69,11 @@ public class DateListenService {
if(null != timerList && timerList.size() != 0)
{
OperatingData.devicedat.setTimer(timerList);
if(ObjectUtil.notEqual(OperatingData.feederConfig.getTimer(),timerList))
{
OperatingData.feederConfig.setTimer(timerList);
reportTimer();
}
}
}
},1,10, TimeUnit.SECONDS);
... ... @@ -82,71 +91,13 @@ public class DateListenService {
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setCondata(OperatingData.devicedat.getCondata());
devicedatRequest.setInfo(OperatingData.devicedat.getInfo());
devicedatRequest.setTimer(OperatingData.devicedat.getTimer());
devicedatRequest.setInfo(OperatingData.feederData.getInfo());
CameraData cameraData = BeanUtil.copyProperties(OperatingData.cameraData,CameraData.class,"scaleAreaList");
devicedatRequest.setCameraData(cameraData);
String str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
if(str.length()>=1024)
{
System.out.println("超标了");
}
CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
Thread.sleep(10000);
devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setSysConfig(OperatingData.sysConfig);
devicedatRequest.setFeederConfig(OperatingData.feederConfig);
str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
if(str.length()>=1024)
{
System.out.println("超标了");
}
cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
Thread.sleep(10000);
devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setCameraData(OperatingData.cameraData);
devicedatRequest.setCameraConfig(OperatingData.cameraConfig);
str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
if(str.length()>=1024)
{
System.out.println("超标了");
}
cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
if(OperatingData.sysConfig.getIfRegisterConfig())
{
Thread.sleep(10000);
devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setRegisterConfig(OperatingData.registerConfig);
str = GsonConstructor.get().toJson(devicedatRequest);
cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
}
}
}catch (Exception e)
{
... ... @@ -154,7 +105,153 @@ public class DateListenService {
}
}
},1,10, TimeUnit.SECONDS);
},1,60, TimeUnit.SECONDS);
//上报参数
ScheduledConfig.scheduler.schedule(() -> {
try {
Thread.sleep(10000);
reportSerialPortConfig();
Thread.sleep(10000);
reportSysConfig();
Thread.sleep(10000);
reportCameraConfig();
Thread.sleep(10000);
reportRegisterConfig();
} catch (Exception e) {
throw new RuntimeException(e);
}
},0,TimeUnit.SECONDS);
}
/**
* 上报智能投喂数据
*/
public void reportIntelligentFeeding(String intelligentFeedingLog)
{
DevicedatRequest devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("activitydata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setIntelligentFeedingLog(intelligentFeedingLog);
String str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
}
/**
* 上报投料机控制参数
*/
public void reportCondata()
{
DevicedatRequest devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setCondata(OperatingData.feederConfig.getCondata());
String str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
}
/**
* 上报投料机定时参数
*/
public void reportTimer()
{
DevicedatRequest devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setTimer(OperatingData.feederConfig.getTimer());
String str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
}
/**
* 上报串口参数
*/
public void reportSerialPortConfig()
{
DevicedatRequest devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setSerialPortConfig(OperatingData.feederConfig.getSerialPortConfig());
String str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
}
/**
* 上报系统参数
*/
public void reportSysConfig()
{
DevicedatRequest devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setSysConfig(OperatingData.sysConfig);
String str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
}
/**
* 上报摄像头参数
* @throws Exception
*/
public void reportCameraConfig() {
DevicedatRequest devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setCameraConfig(OperatingData.cameraConfig);
String str = GsonConstructor.get().toJson(devicedatRequest);
System.out.println(str);
CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
}
/**
* 上报寄存器参数
*/
public void reportRegisterConfig()
{
if(OperatingData.sysConfig.getIfRegisterConfig())
{
DevicedatRequest devicedatRequest = new DevicedatRequest();
devicedatRequest.setCmd("devicedata");
devicedatRequest.setType("4G.hs");
devicedatRequest.setSignal(4);
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setRegisterConfig(OperatingData.registerConfig);
String str = GsonConstructor.get().toJson(devicedatRequest);
CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
}
}
public static void main(String[] args) {
... ... @@ -166,14 +263,14 @@ public class DateListenService {
devicedatRequest.setMachstate(1);
devicedatRequest.setBattlevel(4);
devicedatRequest.setCondata(OperatingData.devicedat.getCondata());
devicedatRequest.setInfo(OperatingData.devicedat.getInfo());
devicedatRequest.setTimer(OperatingData.devicedat.getTimer());
devicedatRequest.setCondata(OperatingData.feederConfig.getCondata());
devicedatRequest.setInfo(OperatingData.feederData.getInfo());
devicedatRequest.setTimer(OperatingData.feederConfig.getTimer());
devicedatRequest.setSysConfig(OperatingData.sysConfig);
devicedatRequest.setCameraData(OperatingData.cameraData);
devicedatRequest.setCameraConfig(OperatingData.cameraConfig);
devicedatRequest.setFeederConfig(OperatingData.feederConfig);
devicedatRequest.setSerialPortConfig(OperatingData.feederConfig.getSerialPortConfig());
System.out.println(GsonConstructor.get().toJson(devicedatRequest));
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
import com.ruoyi.common.utils.DateUtils;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig;
import com.zhonglai.luhui.smart.feeder.dto.*;
... ... @@ -30,12 +31,10 @@ public class DeviceService {
//投料控制
ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
if (OperatingData.cameraConfig.getFeedingControl()) {
Condata condata = OperatingData.devicedat.getCondata();
Condata condata = OperatingData.feederConfig.getCondata();
CameraData cameraData = OperatingData.cameraData;
logger.info("摄像头识别档位{},投料机的档位{},斜率{},斜率差值{},面积{},开关是否打开{}",cameraData.getNowGear(),condata.getRunspeed(),cameraData.getSlope(),cameraData.getAbsValue(),cameraData.getArea(),null == condata.getRunstate()?"未知":condata.getRunstate());
getGearFromAbsValue();
if(null !=condata && 1==condata.getRunstate()) //数据状态出来了,并且设备已经启动
{
if(1==condata.getRunmode()) //只有手动模式才能控制
... ... @@ -52,6 +51,21 @@ public class DeviceService {
ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runspeed,cameraData.getNowGear())); //较准档位
if(null!=modbusDto)
{
String time = DateUtils.getTime();
String[] ss = OperatingData.cameraConfig.getFishSchoolSizeConfigString();
String fishSchoolSize = ss[OperatingData.cameraData.getFishSchoolSize()];
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(time);
stringBuffer.append(" ");
stringBuffer.append(fishSchoolSize);
stringBuffer.append(",智能调整档位");
stringBuffer.append(condata.getRunspeed());
stringBuffer.append("为");
stringBuffer.append(cameraData.getNowGear());
stringBuffer.append("档投喂");
InitService.dateListenService.reportIntelligentFeeding(stringBuffer.toString());
condata.setRunspeed(cameraData.getNowGear());
}
}
... ... @@ -60,30 +74,12 @@ public class DeviceService {
},1,1, TimeUnit.SECONDS);
}
/**
* 根据斜率计算档位
* @return
*/
private Integer getGearFromAbsValue()
public void stop()
{
Double absValue = OperatingData.cameraData.getAbsValue();
Integer gear = null;
List<FishCurveControlCondition> list = OperatingData.cameraConfig.getAbsValue_command();
if(null != list && list.size() != 0)
{
list.sort(Comparator.comparing(FishCurveControlCondition::getSartAbsValue));//以 sartAbsValue 升序排序
for(FishCurveControlCondition fishCurveControlCondition:list) //根据斜率找到档位
{
if(absValue>=fishCurveControlCondition.getSartAbsValue()) //向下查找
{
gear = fishCurveControlCondition.getGear();
}
}
}
OperatingData.cameraData.setNowGear(gear);
return gear;
OperatingData.cameraConfig.setFeedingControl(false);
}
public void start()
{
OperatingData.cameraConfig.setFeedingControl(true);
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
import com.ruoyi.common.utils.DateUtils;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig;
import com.zhonglai.luhui.smart.feeder.dto.CameraConfig;
import com.zhonglai.luhui.smart.feeder.opencv.OpenCVUtil;
import com.zhonglai.luhui.smart.feeder.dto.FishCurveControlCondition;
import com.zhonglai.luhui.smart.feeder.service.device.CameraHandle;
import com.zhonglai.luhui.smart.feeder.service.device.handle.CameraRtspHandle;
import org.bytedeco.opencv.opencv_core.Point2f;
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.video.BackgroundSubtractorMOG2;
import org.opencv.video.Video;
import org.opencv.videoio.VideoCapture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import static com.zhonglai.luhui.smart.feeder.service.InitService.*;
... ... @@ -44,6 +37,25 @@ public class FishGroupImageRecognitionService {
private static Mat thresh = new Mat(); //二值化图片
private SrsService srsService;
private Integer endTime = 0;
private ScheduledFuture scheduledFuture;
public void startPushimg(int time)
{
if(null == srsService)
{
srsService = new SrsService();
try {
srsService.init(640,480);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
endTime=DateUtils.getNowTimeMilly()+time;
}
public FishGroupImageRecognitionService()
{
... ... @@ -52,28 +64,44 @@ public class FishGroupImageRecognitionService {
public void run()
{
ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
scheduledFuture = ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
if (!OperatingData.cameraData.getFishGroupImageRecognIsRun())
{
start();
OperatingData.cameraData.setFishGroupImageRecognIsRun(false);
}
},1,1,TimeUnit.SECONDS);
}
// 创建FrameConverter对象
private void start()
public void start()
{
CameraHandle cameraHandle = InitService.cameraHandle;
if(!cameraHandle.isOpen())
{
cameraHandle.init();
if (!cameraHandle.init())
{
return;
}
}
OperatingData.cameraData.setFishGroupImageRecognIsRun(true);
brightnessIdentifyFishRegion();
}
public void stop()
{
OperatingData.cameraData.setFishGroupImageRecognIsRun(false);
scheduledFuture.cancel(true);
while (!scheduledFuture.isCancelled())
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
/**
* 亮度查找水面,透明度过滤鱼群
... ... @@ -82,32 +110,50 @@ public class FishGroupImageRecognitionService {
{
logger.info("启动鱼群识别");
Long time =1000l;
if(null != OperatingData.cameraConfig.getIdentificationFrequency())
{
time = OperatingData.cameraConfig.getIdentificationFrequency();
}
while (cameraHandle.isOpen())
while (OperatingData.cameraConfig.getFishGroupImageRecognition() && cameraHandle.isOpen() && OperatingData.cameraData.getFishGroupImageRecognIsRun())
{
Long time =1000l;
if(null != OperatingData.cameraConfig.getIdentificationFrequency())
{
time = OperatingData.cameraConfig.getIdentificationFrequency();
}
try {
Boolean fishGroupImageRecognition = OperatingData.cameraConfig.getFishGroupImageRecognition();
frame = CameraRtspHandle.mat.clone();
Boolean isread = false;
if(null != frame)
{
isread = true;
}
logger.info("逐帧处理视频,开始处理的判断参数:鱼群图像识别是否开启 {}、摄像头是否可读取 {}",fishGroupImageRecognition,isread);
if(!isread )
if( null != CameraRtspHandle.mat)
{
logger.info("摄像头不可读取");
frame.release();
return;
}
if (fishGroupImageRecognition && isread) {
yidong(frame);
frame = CameraRtspHandle.mat.clone();
Boolean isread = false;
if(null != frame)
{
isread = true;
}
logger.info("逐帧处理视频,开始处理的判断参数:鱼群图像识别是否开启 {}、摄像头是否可读取 {}",OperatingData.cameraConfig.getFishGroupImageRecognition(),isread);
if(!isread )
{
logger.info("摄像头不可读取");
frame.release();
return;
}
if (isread) {
yidong(frame,time);
// getGearFromAbsValue();
//推送或者显示图片
if(OperatingData.cameraData.is_push_camera())
{
if(null != srsService && endTime-DateUtils.getNowTimeMilly()>0)
{
srsService.push(frame);
}else {
if(null != srsService)
{
srsService.stop();
srsService = null;
OperatingData.cameraData.set_push_camera(false);
}
}
}
}
}
}catch (Exception e)
{
logger.error("识别错误",e);
... ... @@ -123,13 +169,14 @@ public class FishGroupImageRecognitionService {
}
}
}
OperatingData.cameraData.setFishGroupImageRecognIsRun(false);
}
/**
* 检测移动
* @return
*/
private void yidong(Mat image)
private void yidong(Mat image,Long time)
{
if(!image.empty())
{
... ... @@ -147,12 +194,14 @@ public class FishGroupImageRecognitionService {
double[] dsTotal = new double[5];
contours.removeIf(matOfPoint -> {
Rect rect = Imgproc.boundingRect(matOfPoint);
matOfPoint.release();
if(rect.width!=image.width() && rect.width>OperatingData.cameraConfig.getCalloutBoxWidthMin())
{
double[] ds = count(image,rect);
if(filterate(ds))
{
dsTotal[0]+=ds[0];
... ... @@ -172,7 +221,7 @@ public class FishGroupImageRecognitionService {
double brightness = dsTotal[0]/dsTotal[4];
double reflection= dsTotal[1]/dsTotal[4];
double transparencyMeasure= dsTotal[2]/dsTotal[4];
double area= dsTotal[3]/dsTotal[4];
double area = dsTotal[3]/dsTotal[4];
//计算斜率
double slope = area - (null==OperatingData.cameraData.getArea()?area:OperatingData.cameraData.getArea());
... ... @@ -188,13 +237,97 @@ public class FishGroupImageRecognitionService {
OperatingData.cameraData.setSlope(slope);
OperatingData.cameraData.setSlopeDifference(slopeDifference);
OperatingData.cameraData.setAbsValue(absValue);
OperatingData.cameraData.setSize(new Double(dsTotal[4]).intValue());
List<Double> scaleAreaList = OperatingData.cameraData.getScaleAreaList();
//计算尺度之内的面积集合的大小
int size = new Double((OperatingData.cameraConfig.getCollectionScale()*60*1000l)/time).intValue();
//如何集合满了,就吧第一个挤出去,然后放在集合最后
if(scaleAreaList.size()>=size)
{
scaleAreaList.remove(0);
}
scaleAreaList.add(dsTotal[4]);
//计算鱼群规模
Double[] fishSchoolSizeConfig = OperatingData.cameraConfig.getFishSchoolSizeConfig();
int grade = 0;
double fishSchoolSize = area*dsTotal[4];
System.out.println("=======鱼群规模:"+fishSchoolSize+"=========");
for (int i=0;i<fishSchoolSizeConfig.length;i++)
{
if(fishSchoolSize-fishSchoolSizeConfig[i]>0)
{
grade = i+1;
}
}
if(OperatingData.cameraData.getFishSchoolSize()!=grade)
{
OperatingData.cameraData.setFishSchoolSize(grade);
int finalGrade = grade;
ScheduledConfig.scheduler.schedule(() -> {
String nowtime = DateUtils.getTime();
String[] ss = OperatingData.cameraConfig.getFishSchoolSizeConfigString();
String fishSchoolSizeStr = ss[finalGrade];
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(nowtime);
stringBuffer.append(" ");
stringBuffer.append(fishSchoolSizeStr);
// stringBuffer.append(",当前档位:");
// stringBuffer.append(null==OperatingData.cameraData.getNowGear()?0:OperatingData.cameraData.getNowGear());
// stringBuffer.append("档");
InitService.dateListenService.reportIntelligentFeeding(stringBuffer.toString());
},0, TimeUnit.SECONDS);
}
}
}
}
/**
* 根据斜率计算档位
* @return
*/
private Integer getGearFromAbsValue()
{
Double absValue = OperatingData.cameraData.getAbsValue();
if(null == absValue)
{
return 0;
}
Integer gear = OperatingData.cameraData.getNowGear();
if(null == OperatingData.cameraData.getNowGear())
{
OperatingData.cameraData.setNowGear(0);
gear = 0;
}
List<FishCurveControlCondition> list = OperatingData.cameraConfig.getAbsValue_command();
if(null != list && list.size() != 0)
{
list.sort(Comparator.comparing(FishCurveControlCondition::getSartAbsValue));//以 sartAbsValue 升序排序
for(FishCurveControlCondition fishCurveControlCondition:list) //根据斜率找到档位
{
if(absValue>=fishCurveControlCondition.getSartAbsValue()) //向下查找
{
gear = fishCurveControlCondition.getGear();
}
}
}
if(OperatingData.cameraData.getNowGear()-gear!=0)
{
OperatingData.cameraData.setNowGear(gear);
}
return gear;
}
private static Mat hsvImage = new Mat();
private static Mat grayImage = new Mat();
private static Scalar meanGray = Core.mean(grayImage);
/**
* 运算
* @param image
... ... @@ -215,6 +348,7 @@ public class FishGroupImageRecognitionService {
double reflection = minMaxLocResult.maxVal;
// 计算灰度均值
Scalar meanGray = Core.mean(grayImage);
double meanGrayValue = meanGray.val[0];
// 将灰度均值映射到0到255范围内作为透明度度量(较低的灰度值表示较高的透明度,反之亦然)
double transparencyMeasure = 255 - meanGrayValue;
... ...
... ... @@ -13,7 +13,11 @@ public class InitService {
public static NettyClient nettyClient;
public static DeviceService deviceService;
public static ScaleStepMethodService scaleStepMethodService;
public static DateListenService dateListenService;
public static FishGroupImageRecognitionService fishGroupImageRecognitionService;
/**
* 加载配置
*/
... ... @@ -33,7 +37,7 @@ public class InitService {
* mq远程登录
*/
nettyClient = new NettyClient();
nettyClient.start();
nettyClient.run();
/**
* 初始化海康的摄像头
... ... @@ -43,14 +47,16 @@ public class InitService {
/**
* 图像识别
*/
new FishGroupImageRecognitionService().run();
fishGroupImageRecognitionService = new FishGroupImageRecognitionService();
fishGroupImageRecognitionService.run();
//鱼群图像识别控制投料控制
deviceService = new DeviceService(serialPortService);
deviceService.run();
scaleStepMethodService = new ScaleStepMethodService(serialPortService);
scaleStepMethodService.run();
//数据上报
new DateListenService(serialPortService).run();
dateListenService = new DateListenService(serialPortService);
dateListenService.run();
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
import com.ruoyi.common.utils.DateUtils;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig;
import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;
import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* 尺度步长法
*/
public class ScaleStepMethodService {
private ScheduledFuture scheduledFuture;
private SerialPortService serialPortService;
public ScaleStepMethodService(SerialPortService serialPortService)
{
this.serialPortService = serialPortService;
}
public void run()
{
scheduledFuture = ScheduledConfig.scheduler.scheduleAtFixedRate(() -> {
if( OperatingData.cameraData.getScaleAreaList().size()==0)
{
return;
}
// 使用Java 8流计算列表总和
double sum = OperatingData.cameraData.getScaleAreaList().stream().mapToDouble(Double::doubleValue).sum();
OperatingData.cameraData.setScaleAreaSum(sum);
if(sum - OperatingData.cameraData.getScaleAreaSumMax()>0)
{
OperatingData.cameraData.setScaleAreaSumMax(sum);
}
String nowtime = DateUtils.getTime();
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(nowtime);
stringBuffer.append(" ");
//如果鱼群急剧减少,就停止投料
if (((OperatingData.cameraData.getScaleAreaSumMax()*OperatingData.cameraConfig.getStopTriggeringConditions())/100)-sum>=0)
{
Condata condata = OperatingData.feederConfig.getCondata();
stringBuffer.append("发现鱼群急剧减少,");
if(null != condata)
{
if( condata.getRunstate()==1)
{
stringBuffer.append("投料机处于运行状态,");
if (OperatingData.cameraConfig.getFeedingControl())
{
//发送停止投料指令
if (serialPortService.isOpen())
{
serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,0));
stringBuffer.append("发送停止投料指令,");
}else{
stringBuffer.append("投料机串口未打开,无法发送停止投料指令,");
}
}else {
stringBuffer.append("投料机串口未打开,无法发送停止投料指令,");
}
}else {
stringBuffer.append("鱼群图像识别投料控制未开启,不用操作投料机,");
}
}else {
stringBuffer.append("投料机串口未打开,无法发送停止投料指令,");
}
stringBuffer.append("当前鱼群状态:");
stringBuffer.append("尺度之内的面积之和:");
stringBuffer.append(OperatingData.cameraData.getScaleAreaSum());
stringBuffer.append(",尺度之内的面积之和曲线的峰值:");
stringBuffer.append(OperatingData.cameraData.getScaleAreaSumMax());
InitService.dateListenService.reportIntelligentFeeding(stringBuffer.toString());
}
//如果鱼群急剧增加,。。。
if (OperatingData.cameraData.getScaleAreaSumMax()-((OperatingData.cameraData.getScaleAreaSumMax()*OperatingData.cameraConfig.getStopTriggeringConditions())/100)-sum>=0)
{
stringBuffer.append("发现鱼群急剧增加,");
stringBuffer.append("当前鱼群状态:");
stringBuffer.append("尺度之内的面积之和:");
stringBuffer.append(OperatingData.cameraData.getScaleAreaSum());
stringBuffer.append(",尺度之内的面积之和曲线的峰值:");
stringBuffer.append(OperatingData.cameraData.getScaleAreaSumMax());
InitService.dateListenService.reportIntelligentFeeding(stringBuffer.toString());
}
},0, OperatingData.cameraConfig.getScaleStep(), TimeUnit.SECONDS);
}
public void stop()
{
scheduledFuture.cancel(true);
while (!scheduledFuture.isCancelled())
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
... ...
... ... @@ -2,6 +2,7 @@ package com.zhonglai.luhui.smart.feeder.service;
import com.ruoyi.common.utils.DateUtils;
import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.draw.FishRegionPanel;
import com.zhonglai.luhui.smart.feeder.dto.VeiwDto;
import com.zhonglai.luhui.smart.feeder.opencv.OpenCVUtil;
... ... @@ -27,19 +28,12 @@ import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Service
public class SrsService {
private static final Logger log = LoggerFactory.getLogger(SrsService.class);
private static final String MP4_FILE_PATH = "C:\\Users\\123\\Pictures\\2.mp4";
@Value("${sys.srs_push_address}")
private String SRS_PUSH_ADDRESS;
private static String SRS_PUSH_ADDRESS = "rtmp://119.23.218.181:21935/live/";
// private String SRS_PUSH_ADDRESS="rtmp://119.23.218.181:21935/live/70094a59d1d991d";
@Autowired
private ScheduledExecutorService scheduledExecutorService;
@Autowired
private FishGroupImageRecognitionService fishGroupImageRecognitionService;
private FFmpegFrameRecorder recorder;
... ... @@ -49,34 +43,22 @@ public class SrsService {
return converter.convert(frame);
}
private boolean isPush = false;
private boolean displaySrc = false;
private int endTime = 0;
public boolean isDisplaySrc() {
return displaySrc;
}
public void setDisplaySrc(boolean displaySrc) {
this.displaySrc = displaySrc;
}
public void run(int time) throws Exception {
endTime = DateUtils.getNowTimeMilly()+time;
if(!isPush)
{
isPush = true;
init(640,480+200);
// scheduledExecutorService.schedule(() -> {
// while (endTime-DateUtils.getNowTimeMilly()>0)
// {
// Mat mat = drawChart(fishGroupImageRecognitionService.getVeiwDto().getFrame(),fishGroupImageRecognitionService.getVeiwDto().getAbsValue());
// push(mat);
// mat.release();
// }
// stop();
// },1, TimeUnit.SECONDS);
}
if(endTime-DateUtils.getNowTimeMilly()>0)
{
}else {
stop();
}
}
public void stop()
... ... @@ -86,21 +68,6 @@ public class SrsService {
close();
}
public void timepush(Mat frame,Double absValue)
{
if(isPush)
{
if(endTime-DateUtils.getNowTimeMilly()>0)
{
Mat mat = drawChart(frame,absValue);
push(mat);
mat.release();
}else {
stop();
}
}
}
public SrsService init(int frameWidth,int frameHeight) throws Exception
{
... ... @@ -110,7 +77,7 @@ public class SrsService {
);
// 实例化FFmpegFrameRecorder,将SRS的推送地址传入
recorder = new FFmpegFrameRecorder(SRS_PUSH_ADDRESS,
recorder = new FFmpegFrameRecorder(SRS_PUSH_ADDRESS+ OperatingData.sysConfig.getNettyConfig().getClientId(),
frameWidth,
frameHeight);
... ... @@ -124,64 +91,12 @@ public class SrsService {
// 调用av_guess_format方法,确定视频输出时的封装方式,
// 媒体上下文对象的内存分配,
// 编码器的各项参数设置
recorder.start();
recorder.setCloseOutputStream(true);
recorder.start();
return this;
}
public Mat drawChart(Mat src,double area)
{
// 创建一个新的Mat对象,它的高度为200,它的宽度与原来的Mat对象相同
Mat curveArea = Mat.zeros(200, src.cols(), src.type());
// 计算曲线的y坐标
int y = (int) (200 - (area * 200) / (src.cols() * src.rows()));
System.out.println(y);
// 声明曲线的控制点
MatOfPoint curve = new MatOfPoint();
// 创建曲线的控制点数组
List<Point> points = addPoint(curveArea,area);
// 将控制点数组设置给曲线
Point[] pointArray = points.toArray(new Point[0]);
curve.fromArray(pointArray);
// 绘制曲线
List<MatOfPoint> curveList = new ArrayList<>();
curveList.add(curve);
Imgproc.polylines(curveArea, curveList, false, new Scalar(255, 255, 255), 2);
// 将curveArea拼接到原来的Mat对象上
Mat pushmat = new Mat();
List<Mat> mats = new ArrayList<>();
if(displaySrc)
{
mats.add(src);
}
mats.add(curveArea);
Core.vconcat(mats, pushmat);
// 文字位置
Point org = new Point(50, 50);
// 字体类型
int fontFace = Imgproc.FONT_HERSHEY_SIMPLEX;
// 字体比例
double fontScale = 1;
// 文字颜色(黑色)
Scalar color = new Scalar(139, 0, 139);
// 添加文字
Imgproc.putText(pushmat, "area:"+area, org, fontFace, fontScale, color);
curveArea.release();
curve.release();
return pushmat;
}
public void push(Mat pushmat) {
OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
Frame frame = converter.convert(pushmat);
... ... @@ -204,151 +119,12 @@ public class SrsService {
{
// 关闭帧录制器
try {
recorder.release();
recorder.close();
} catch (FrameRecorder.Exception e) {
throw new RuntimeException(e);
}
recorder = null;
}
}
// 创建一个MatOfPoint对象来表示曲线
private List<Integer> listArea = new ArrayList<>();
/**
* 根据反光查找水面
* @return
*/
public Mat fish(Mat src) {
//读取和预处理图像
Mat gray = new Mat();
Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY); // 转为灰度图像
//水面反射检测
Mat threshold = new Mat();
double maxValue = 255; // 阈值
Imgproc.threshold(gray, threshold,100, maxValue, Imgproc.THRESH_BINARY); // 阈值化
//鱼群检测
Mat hierarchy = new Mat();
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(threshold, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE); // 寻找轮廓
//计算鱼群区域大小
double area = getArea(contours);
Mat mat = drawChart(src,area);
return mat;
}
private static Image convertMatToImage(Mat mat) {
BufferedImage bufferedImage = OpenCVUtils.matToBufferedImage(mat);
return bufferedImage.getScaledInstance(mat.width(), mat.height(), Image.SCALE_SMOOTH);
}
int maxSize = 100;
private List<Point> addPoint(Mat src, double area)
{
int panelWidth = src.width();
int panelHeight = src.height();
if(listArea.size()==maxSize)
{
listArea.remove(0);
}
int max = new Double(area).intValue();
int min = new Double(area).intValue();
if(listArea.size()>0)
{
max = listArea.stream().max(Integer::compare).get();
min = listArea.stream().min(Integer::compare).get();
}
List<Point> points= new ArrayList<>();
for (int i = 0; i < listArea.size(); i++) {
int dataPoint = listArea.get(i);
int x = (int) ((double) i / listArea.size() * panelWidth);
int y = (int) ((double) (dataPoint - min) / (max - min) * panelHeight);
if (i != 0) {
points.add(new Point(x,y));
}
}
listArea.add(new Double(area).intValue());
return points;
}
/**
* 计算鱼群面积
* @param contours
* @return
*/
private double getArea(List<MatOfPoint> contours) {
// 找到最大区域
double maxArea = 0;
int maxAreaIndex = -1;
double allArea = 0;
for (int i = 0; i < contours.size(); i++) {
double area = Imgproc.contourArea(contours.get(i));
if (area > maxArea) {
maxArea = area;
maxAreaIndex = i;
}
allArea += area;
}
//删除最大
if(-1 != maxAreaIndex)
{
contours.remove(maxAreaIndex);
}
// 返回总面积
return allArea;
}
public static void main(String[] args) {
// OpenCVConfig.loadOpenCv(args);
// SrsService srsService = new SrsService();
// FishRegionPanel fishRegionPanel = new FishRegionPanel();
// int i=0;
// while (i++<10)
// {
// VideoCapture videoCapture = OpenCVUtil.readVideoCaptureForVideo("");
// Mat previousFrame = new Mat();
// if (!videoCapture.read(previousFrame)) {
// System.out.println("无法读取视频帧");
// return;
// }
//
// try {
// if(null == srsService.recorder || !srsService.recorder.isInterleaved())
// {
// srsService.init(previousFrame.width(),previousFrame.height());
// }
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
//
// Mat src = new Mat();
// while (videoCapture.read(src))
// {
// Mat mat = srsService.fish(src);
// fishRegionPanel.getLblImage().setIcon(new ImageIcon(convertMatToImage(mat)));
// fishRegionPanel.getFrame().repaint();
// OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
// Frame frame = converter.convert(mat);
// srsService.push(frame);
// }
//
// }
// srsService.close();
}
}
... ...
... ... @@ -65,6 +65,15 @@ public class SerialPortService {
serialPort.setComPortParameters(serialPortConfig.getBaudrate(), serialPortConfig.getDataBits(), serialPortConfig.getStopBits(), serialPortConfig.getParity());//一次性设置所有的串口参数,第一个参数为波特率,默认9600;第二个参数为每一位的大小,默认8,可以输入5到8之间的值;第三个参数为停止位大小,只接受内置常量,可以选择(ONE_STOP_BIT, ONE_POINT_FIVE_STOP_BITS, TWO_STOP_BITS);第四位为校验位,同样只接受内置常量,可以选择 NO_PARITY, EVEN_PARITY, ODD_PARITY, MARK_PARITY,SPACE_PARITY。
}
public boolean isOpen()
{
if(null != serialPort && serialPort.isOpen())
{
return true;
}
return false;
}
public boolean open()
{
if(null == serialPort || !serialPort.isOpen())
... ...
... ... @@ -30,6 +30,8 @@ public class CameraRtspHandle implements CameraHandle {
public static Mat mat;
private boolean isclose = false;
public CameraRtspHandle()
{
init();
... ... @@ -38,6 +40,7 @@ public class CameraRtspHandle implements CameraHandle {
@Override
public boolean init() {
if(isOpen())
{
return true;
... ... @@ -72,8 +75,9 @@ public class CameraRtspHandle implements CameraHandle {
}
converter2 = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();
Thread.sleep(3000);
isclose = false;
Thread thread = new Thread(() -> {
while (isOpen()) {
while (isOpen() && !isclose) {
try {
mat = getMat();
} catch (Exception e) {
... ... @@ -82,7 +86,6 @@ public class CameraRtspHandle implements CameraHandle {
}
});
thread.start();
return true;
} catch (Exception e) {
logger.error("摄像头初始化失败",e);
... ... @@ -91,9 +94,10 @@ public class CameraRtspHandle implements CameraHandle {
}
private boolean iniLocal() throws FFmpegFrameGrabber.Exception, InterruptedException {
File file = new File("2.pm4");
File file = new File("2.mp4");
if(!file.exists())
{
logger.info("{}未找到",file.getAbsolutePath());
return false;
}
grabber = new FFmpegFrameGrabber(file);
... ... @@ -187,22 +191,32 @@ public class CameraRtspHandle implements CameraHandle {
}
private Frame getFrame() {
Frame frame = null;
try {
frame = grabber.grabImage();
if (frame == null || frame.imageHeight==0) {
//TODO:连续n次为null,进行重连
logger.info("读取不到画面,当前grabber状态:hasAudio {},hasVideo {},isCloseInputStream {},isDeinterlace {},isTriggerMode {}",grabber.hasAudio(),grabber.hasVideo(),grabber.isCloseInputStream(),grabber.isDeinterlace(),grabber.isTriggerMode());
if(isOpen())
{
Frame frame = null;
try {
frame = grabber.grabImage();
if (frame == null || frame.imageHeight==0) {
if(null == frame && OperatingData.cameraConfig.getCameraInterfaceType().toLowerCase().equals("local"))
{
grabber.restart();
frame = grabber.grabImage();
return frame;
}
//TODO:连续n次为null,进行重连
logger.info("读取不到画面,当前grabber状态:hasAudio {},hasVideo {},isCloseInputStream {},isDeinterlace {},isTriggerMode {}",grabber.hasAudio(),grabber.hasVideo(),grabber.isCloseInputStream(),grabber.isDeinterlace(),grabber.isTriggerMode());
return null;
}
else{
return frame;
}
} catch (Exception e) {
logger.error("抓取摄像头帧失败",e);
return null;
}
else{
return frame;
}
} catch (Exception e) {
logger.error("抓取摄像头帧失败",e);
return null;
}
return null;
}
public Frame compress(Frame frame)
... ... @@ -223,13 +237,21 @@ public class CameraRtspHandle implements CameraHandle {
if(grabber.hasAudio() && grabber.hasVideo())
{
try {
Frame filteredFrame = compress(grabber.grabImage());
Frame frame = grabber.grabImage();
if(null == frame)
{
grabber.restart();
frame = grabber.grabImage();
}
Frame filteredFrame = compress(frame);
if(null != filteredFrame)
{
pushVideo.display(filteredFrame);
}
} catch (FFmpegFrameGrabber.Exception e) {
logger.info("无法显示");
} catch (FrameGrabber.Exception e) {
throw new RuntimeException(e);
}
}
... ... @@ -349,6 +371,7 @@ public class CameraRtspHandle implements CameraHandle {
}
}
private static String getCameraIp(String ip) throws Exception {
// 1.创建组播socket,加入指定的组播地址和端口
InetAddress group = InetAddress.getByName("239.255.255.250");
... ... @@ -394,6 +417,12 @@ public class CameraRtspHandle implements CameraHandle {
public void close()
{
isclose = true;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if(null != grabber)
{
try {
... ...
... ... @@ -10,6 +10,8 @@ import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.regex.Matcher;
... ... @@ -19,6 +21,9 @@ import java.util.regex.Pattern;
* 协议解析
*/
public class AgreementHandler extends MessageToMessageDecoder<String> {
private static final Logger logger = LoggerFactory.getLogger(AgreementHandler.class);
private CfgdataService cfgdataService = new CfgdataService();
private ManualcontrolService manualcontrolService = new ManualcontrolService();
... ... @@ -33,6 +38,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
logger.info("设备上线");
nettyClient.setCtx(ctx);
// 连接建立时的处理,发送请求注册消息给服务器
JsonObject jsonObject = new JsonObject();
... ... @@ -42,11 +48,8 @@ public class AgreementHandler extends MessageToMessageDecoder<String> {
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Thread.sleep(3000);
nettyClient.close();
Thread.sleep(3000);
nettyClient.start();
public void channelInactive(ChannelHandlerContext ctx) {
logger.info("设备离线");
}
private static boolean checkAgreement(String data)
... ... @@ -65,7 +68,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> {
@Override
protected void decode(ChannelHandlerContext ctx, String msg, List<Object> out) throws Exception {
try {
System.out.println("读取到数据:"+msg);
logger.info("读取到数据:{}",msg);
if(StringUtils.isNotBlank(msg) && checkAgreement(msg))
{
CmdDto cmdDto = new CmdDto(msg);
... ... @@ -92,6 +95,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> {
}
}catch (Exception e)
{
logger.error("读取数据异常",e);
}
}
}
... ...
... ... @@ -3,14 +3,11 @@ package com.zhonglai.luhui.smart.feeder.service.feeder;
import com.google.gson.JsonObject;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.dto.CameraConfig;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederBackstateTtpe;
import com.zhonglai.luhui.smart.feeder.dto.mqtt.CameracontrolRequest;
import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
import com.zhonglai.luhui.smart.feeder.service.InitService;
import com.zhonglai.luhui.smart.feeder.service.device.handle.CameraRtspHandle;
import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
... ... @@ -21,34 +18,53 @@ public class CameracontrolService {
private static final Logger logger = LoggerFactory.getLogger(CameracontrolService.class);
public void noticeFeeder(ChannelHandlerContext ctx,CmdDto cmdDto)
{
if(!InitService.cameraHandle.isOpen())
if(null != InitService.cameraHandle && !InitService.cameraHandle.isOpen())
{
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.cameraErr,0);
MessageUtil.sendFeederResponseMessage(ctx,"cameracontrolOK", FeederBackstateTtpe.cameraErr,0);
return;
}
JsonObject data = cmdDto.getJsonObject();
if (null == data || data.size()==0)
{
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0xE2);
MessageUtil.sendFeederResponseMessage(ctx,"cameracontrolOK", FeederBackstateTtpe.success,0xE2);
return;
}
try {
CameracontrolRequest cameracontrolRequest = GsonConstructor.get().fromJson(data.toString(), CameracontrolRequest.class);
OperatingData.setClassObjecValue(cameracontrolRequest.getCameraConfig(), (fieldname, fieldObject) -> {
switch (fieldname)
{
case "cameraInterfaceType":
((CameraRtspHandle)InitService.cameraHandle).close();
InitService.cameraHandle.init();
break;
}
});
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0);
if(null != cameracontrolRequest.getCameraConfig())
{
OperatingData.setClassObjecValue(cameracontrolRequest.getCameraConfig(), (fieldname, fieldObject) -> {
switch (fieldname)
{
case "cameraInterfaceType":
InitService.fishGroupImageRecognitionService.stop();
InitService.scaleStepMethodService.stop();
((CameraRtspHandle)InitService.cameraHandle).close();
if(InitService.cameraHandle.init())
{
InitService.fishGroupImageRecognitionService.run();
InitService.scaleStepMethodService.run();
}
break;
case "scaleStep":
InitService.scaleStepMethodService.stop();
InitService.scaleStepMethodService.run();
break;
}
});
}
if(null != cameracontrolRequest.getIs_push_camera() && 0!=cameracontrolRequest.getIs_push_camera())
{
InitService.fishGroupImageRecognitionService.startPushimg(cameracontrolRequest.getIs_push_camera()*60);
OperatingData.cameraData.set_push_camera(true);
}
MessageUtil.sendFeederResponseMessage(ctx,"cameracontrolOK", FeederBackstateTtpe.success,0);
}catch (Exception e)
{
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.runErr,0);
MessageUtil.sendFeederResponseMessage(ctx,"cameracontrolOK", FeederBackstateTtpe.runErr,0);
}
}
... ...
... ... @@ -46,7 +46,8 @@ public class CfgdataService {
try {
String commd = FeederCommdUtil.controlData( FeederCommd06ResponseType.valueOf(fieldname),(Integer) fieldObject);
logger.info("远程发送指令{}",commd);
InitService.serialPortService.sendStrData(commd);
InitService.serialPortService.sendStrData(commd); //通知串口
InitService.dateListenService.reportCondata(); //通知服务器
}catch (Exception e)
{
logger.error("发送指令失败:"+GsonConstructor.get().toJson(fieldname),e);
... ... @@ -73,6 +74,7 @@ public class CfgdataService {
feederTimer.setTimer_is_close(1);
InitService.serialPortService.sendHexData(FeederCommdUtil.controlTimer((i/2)+1,feederTimer));
}
InitService.dateListenService.reportTimer(); //通知服务器
}
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0);
}catch (Exception e)
... ...
... ... @@ -25,14 +25,14 @@ public class ManualcontrolService {
{
if(!InitService.serialPortService.open())
{
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.serialPortErr,0);
MessageUtil.sendFeederResponseMessage(ctx,"manualcontrolOK", FeederBackstateTtpe.serialPortErr,0);
return;
}
JsonObject data = cmdDto.getJsonObject();
if (null == data || data.size()==0)
{
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0xE2);
MessageUtil.sendFeederResponseMessage(ctx,"manualcontrolOK", FeederBackstateTtpe.success,0xE2);
return;
}
try {
... ... @@ -42,18 +42,19 @@ public class ManualcontrolService {
String commd = FeederCommdUtil.controlData( FeederCommd06ResponseType.valueOf(fieldname),(Integer) fieldObject);
logger.info("远程发送指令{}",commd);
InitService.serialPortService.sendStrData(commd);
InitService.dateListenService.reportCondata(); //通知服务器
}catch (Exception e)
{
logger.error("发送指令失败:"+GsonConstructor.get().toJson(fieldname),e);
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.serialPortCommandSendErr,0);
MessageUtil.sendFeederResponseMessage(ctx,"manualcontrolOK", FeederBackstateTtpe.serialPortCommandSendErr,0);
throw new RuntimeException(e);
}
});
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0);
MessageUtil.sendFeederResponseMessage(ctx,"manualcontrolOK", FeederBackstateTtpe.success,0);
}catch (Exception e)
{
MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.runErr,0);
MessageUtil.sendFeederResponseMessage(ctx,"manualcontrolOK", FeederBackstateTtpe.runErr,0);
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service.netty;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig;
import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
import com.zhonglai.luhui.smart.feeder.service.InitService;
import com.zhonglai.luhui.smart.feeder.service.feeder.AgreementHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
... ... @@ -13,6 +15,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
public class NettyClient {
private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);
... ... @@ -22,7 +25,19 @@ public class NettyClient {
private EventLoopGroup groupThread;
private Channel channel;
public void start() {
public void run()
{
ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
if(!isOpen())
{
close();
start();
}
},1,1,TimeUnit.SECONDS);
}
private void start() {
// 创建EventLoopGroup,用于处理客户端的I/O操作
groupThread = new NioEventLoopGroup();
... ... @@ -89,6 +104,15 @@ public class NettyClient {
return ctx;
}
public boolean isOpen()
{
if(null != ctx && ctx.channel().isActive() && ctx.channel().isOpen())
{
return true;
}
return false;
}
public void setCtx(ChannelHandlerContext ctx) {
this.ctx = ctx;
}
... ...