|
|
|
@ -21,7 +21,7 @@ ConfPath g_conf_path;
|
|
|
|
|
SysConf g_sys_conf; //系统配置参数
|
|
|
|
|
ModbusConf g_modbus_conf; //modbus地址参数
|
|
|
|
|
|
|
|
|
|
PLCDevice* m_PLCDevice;
|
|
|
|
|
PLCDevice *m_PLCDevice,*m_PLCTCPDevice;
|
|
|
|
|
bool g_plc_dialog_open; //是否打开plc配置对话框
|
|
|
|
|
|
|
|
|
|
QDateTime g_ts_start;
|
|
|
|
@ -67,6 +67,7 @@ SyncQueue<_UDPSendInfo>* UDP_Info_queue;
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef __TCPSend
|
|
|
|
|
SyncQueue<_TCPSendInfo>* TCP_Info_queue;
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
bool flag = false;
|
|
|
|
|
SyncQueue<_XMLExportDataInfo>* export_XMLData_Info_queue;
|
|
|
|
@ -113,44 +114,53 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
InitPtrMat();
|
|
|
|
|
read_conf(g_conf_path);
|
|
|
|
|
|
|
|
|
|
if (!g_conf_path.config_path.isEmpty()) {
|
|
|
|
|
if (!g_conf_path.config_path.isEmpty()) {//判断conf路径是否存在, 空 isEmpty=1,不空 isEmpty=0
|
|
|
|
|
// 如果非空
|
|
|
|
|
QDir* dirinfo = new QDir(g_conf_path.config_path);
|
|
|
|
|
if (!dirinfo->exists()) {
|
|
|
|
|
// 如果文件夹信息不存在
|
|
|
|
|
delete dirinfo, dirinfo = nullptr;
|
|
|
|
|
g_conf_path.config_path = "D:/conf";
|
|
|
|
|
g_conf_path.config_path = DEFAULT_CONFPATH_PATH;
|
|
|
|
|
}
|
|
|
|
|
delete dirinfo, dirinfo = nullptr;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
g_conf_path.config_path = "D:/conf";
|
|
|
|
|
{
|
|
|
|
|
#ifdef __DEBUGPATH
|
|
|
|
|
g_conf_path.config_path = "../conf/conf.txt";
|
|
|
|
|
#else
|
|
|
|
|
g_conf_path.config_path = DEFAULT_CONFPATH_PATH;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool update_rotate = false;
|
|
|
|
|
if (!read_rotate_message()) {
|
|
|
|
|
if (!read_rotate_message()) {//读取旋转参数
|
|
|
|
|
update_rotate = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QThread* hThread = new QThread();
|
|
|
|
|
CLog* clogWorkThread = new CLog();
|
|
|
|
|
clogWorkThread->moveToThread(hThread);
|
|
|
|
|
connect(this, &Cigarette::destroyed, hThread, &QThread::quit);
|
|
|
|
|
connect(hThread, &QThread::finished, clogWorkThread, &CLog::deleteLater);
|
|
|
|
|
connect(this, &Cigarette::sengMsgToClog, clogWorkThread, &CLog::recMegFromCigarette);
|
|
|
|
|
QThread* hThread = new QThread();//主线程
|
|
|
|
|
CLog* clogWorkThread = new CLog();//日志线程
|
|
|
|
|
clogWorkThread->moveToThread(hThread);//将日志线程依附到主线程(相当于父类)
|
|
|
|
|
connect(this, &Cigarette::destroyed, hThread, &QThread::quit);//Cigarette退出系统了,或这个类崩溃了;清除Qt所有线程
|
|
|
|
|
connect(hThread, &QThread::finished, clogWorkThread, &CLog::deleteLater);//Qt类结束,清除日志类
|
|
|
|
|
connect(this, &Cigarette::sengMsgToClog, clogWorkThread, &CLog::recMegFromCigarette);// sengMsgToClog 写日志的信号,recMegFromCigarette 写日志操作
|
|
|
|
|
hThread->start();
|
|
|
|
|
|
|
|
|
|
emit sengMsgToClog("Application Start.");
|
|
|
|
|
|
|
|
|
|
//初始化队列
|
|
|
|
|
//保存队列
|
|
|
|
|
g_save_queue = new SyncQueue<std::pair<std::string, cv::Mat>>(Queue_Size);
|
|
|
|
|
g_save_queue->name = "save queue";
|
|
|
|
|
#ifdef __UDPSend
|
|
|
|
|
UDP_Info_queue = new SyncQueue<_UDPSendInfo>(Queue_Size);
|
|
|
|
|
UDP_Info_queue->name = "UDP Info queue";
|
|
|
|
|
#endif
|
|
|
|
|
//TCP队列
|
|
|
|
|
#ifdef __TCPSend
|
|
|
|
|
TCP_Info_queue = new SyncQueue<_TCPSendInfo>(Queue_Size);
|
|
|
|
|
TCP_Info_queue->name = "TCP Info queue";
|
|
|
|
|
#endif
|
|
|
|
|
//FTP数据队列
|
|
|
|
|
#ifdef __ExportData
|
|
|
|
|
export_XMLData_Info_queue = new SyncQueue<_XMLExportDataInfo>(Queue_Size);
|
|
|
|
|
export_XMLData_Info_queue->name = "Export Data Info queue";
|
|
|
|
@ -158,6 +168,7 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
last_shift = 256;
|
|
|
|
|
work_camera_nums = 0;
|
|
|
|
|
|
|
|
|
|
//相机公共队列(合成图片)
|
|
|
|
|
#ifdef SYNC_CAMERA
|
|
|
|
|
g_image_sync_queue = new SyncQueue<std::vector<std::pair<int, cv::Mat>>>(Queue_Size);
|
|
|
|
|
g_image_sync_queue->name = format("sync_image");
|
|
|
|
@ -165,20 +176,26 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
for (int i = 0; i < NumberOfSupportedCameras; i++)
|
|
|
|
|
{
|
|
|
|
|
#ifndef SYNC_CAMERA
|
|
|
|
|
//相机单独队列
|
|
|
|
|
g_image_queue[i] = new SyncQueue<std::pair<int, cv::Mat> >(Queue_Size);
|
|
|
|
|
g_image_queue[i]->name = format("image_%d", i);
|
|
|
|
|
#endif
|
|
|
|
|
//结果队列
|
|
|
|
|
g_result_queue[i] = new ASyncQueue<bool>(Queue_Size);
|
|
|
|
|
g_result_queue[i]->name = format("result_%d", i);
|
|
|
|
|
//结果延后队列
|
|
|
|
|
g_result_wait_queue[i] = new ASyncQueue<bool>(Queue_Size);
|
|
|
|
|
g_result_wait_queue[i]->name = format("result_wait%d", i);
|
|
|
|
|
//两个结果队列
|
|
|
|
|
g_double_queue[i] = new ASyncQueue<bool>(Queue_Size);
|
|
|
|
|
g_double_queue[i]->name = format("double_wait%d", i);
|
|
|
|
|
//拍照队列
|
|
|
|
|
g_shooted_queue[i] = new ASyncQueue<bool>(Queue_Size);
|
|
|
|
|
g_shooted_queue[i]->name = format("shooted_%d", i);
|
|
|
|
|
//调试队列
|
|
|
|
|
g_debug_queue[i] = new SyncQueue<cv::Mat>(Queue_Size);
|
|
|
|
|
g_debug_queue[i]->name = format("debug_%d", i);
|
|
|
|
|
if (update_rotate) {
|
|
|
|
|
if (update_rotate) {//未读到旋转参数,进行初始化
|
|
|
|
|
rotationAngle[i] = cv::ROTATE_90_COUNTERCLOCKWISE + 1;
|
|
|
|
|
isNeedRotate[i] = false;
|
|
|
|
|
}
|
|
|
|
@ -196,7 +213,7 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
g_op_time = OP_TIME;
|
|
|
|
|
g_op_pswd = read_op_pswd();
|
|
|
|
|
|
|
|
|
|
g_working = false;
|
|
|
|
|
g_working = false;//调试标志
|
|
|
|
|
g_debug_mode = false;
|
|
|
|
|
|
|
|
|
|
g_alarm_msg << QStringLiteral("无报警") /// 0
|
|
|
|
@ -219,14 +236,14 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < NumberOfSupportedCameras; i++)
|
|
|
|
|
{
|
|
|
|
|
g_display_label_conf[i].g_max[0] = false;
|
|
|
|
|
g_display_label_conf[i].g_max[0] = false;//视图最大化
|
|
|
|
|
g_display_label_conf[i].g_max[1] = false;
|
|
|
|
|
OpenWithUserID[i] = 0xff;
|
|
|
|
|
production_number[i] = 0;
|
|
|
|
|
lcdNumber_total_mat[i]->display(production_number[i]);
|
|
|
|
|
OpenWithUserID[i] = 0xff;//没用
|
|
|
|
|
production_number[i] = 0;//检测个数
|
|
|
|
|
lcdNumber_total_mat[i]->display(production_number[i]);//display 显示到界面
|
|
|
|
|
ok[i] = 0;
|
|
|
|
|
ng[i] = 0;
|
|
|
|
|
g_display_label_conf[i].g_last_mat[0] = cv::Mat::zeros(20, 20, CV_8UC3);
|
|
|
|
|
g_display_label_conf[i].g_last_mat[0] = cv::Mat::zeros(20, 20, CV_8UC3);//放大后的图片
|
|
|
|
|
g_display_label_conf[i].g_last_mat[1] = cv::Mat::zeros(20, 20, CV_8UC3);
|
|
|
|
|
#ifdef DRAW_RECT
|
|
|
|
|
DrawRect_init(i);
|
|
|
|
@ -256,12 +273,15 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
g_modbus_conf.debug = 0;
|
|
|
|
|
g_modbus_conf.reset = 0;
|
|
|
|
|
g_modbus_conf.alarm = 0;
|
|
|
|
|
g_modbus_conf.heart = 0;
|
|
|
|
|
read_modbus_config(g_modbus_conf); //初始化modbus地址
|
|
|
|
|
|
|
|
|
|
//保存图片线程
|
|
|
|
|
saveThread.init();
|
|
|
|
|
saveThread.init();//初始化
|
|
|
|
|
#ifdef __TCPSend
|
|
|
|
|
#ifdef __ExportData
|
|
|
|
|
connect(&saveThread, &SaveThread::sendDataToExport, &exportDataThread, &ExportDataThread::GetDataFromSaveThread);
|
|
|
|
|
connect(&sync_work_thread, &SyncWorkThread::sendDataToCompress, &exportDataThread, &ExportDataThread::GetDataFromSaveThread);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
saveThread.start_work();
|
|
|
|
|
#ifdef __UDPSend
|
|
|
|
@ -273,22 +293,31 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
connect(rThread, &threadReceive::sendMsgToCigratte, this, &Cigarette::recMsgFromUdp);
|
|
|
|
|
rThread->start_work();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//初始化TCP数据传输线程
|
|
|
|
|
#ifdef __TCPSend
|
|
|
|
|
std::string serverIp = g_sys_conf.TcpIP;
|
|
|
|
|
int serverPort = g_sys_conf.TcpPort;
|
|
|
|
|
tcpSendThread.init(TCP_Info_queue, serverIp, serverPort);
|
|
|
|
|
tcpSendThread.start_work();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef __ExportData
|
|
|
|
|
exportDataThread.init();
|
|
|
|
|
#endif
|
|
|
|
|
//初始化FTP数据传输线程
|
|
|
|
|
#ifdef __ExportData
|
|
|
|
|
string ftpip = g_sys_conf.FtpIP;
|
|
|
|
|
int ftpport = g_sys_conf.FtpPort;
|
|
|
|
|
string ftpusername = g_sys_conf.FtpUserName;
|
|
|
|
|
string ftpuserpwd = g_sys_conf.FtpUserPwd;
|
|
|
|
|
exportDataThread.init(ftpip,ftpport,ftpusername,ftpuserpwd);
|
|
|
|
|
connect(this, &Cigarette::sendMsgToExportData, &exportDataThread, &ExportDataThread::EDrecMsgFromCigarette);
|
|
|
|
|
exportDataThread.start_work();
|
|
|
|
|
//connect(this, &Cigarette::sendMsgToExportData, &exportDataThread, &ExportDataThread::EDrecMsgFromCigarette);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//初始化通讯PLC
|
|
|
|
|
m_PLCDevice = new PLCDevice;
|
|
|
|
|
PLCDevice::init_plc(m_PLCDevice);
|
|
|
|
|
|
|
|
|
|
m_PLCTCPDevice = new PLCDevice;
|
|
|
|
|
PLCDevice::init_plc_tcp(m_PLCTCPDevice);
|
|
|
|
|
if (m_PLCDevice->g_plc_ok)
|
|
|
|
|
{
|
|
|
|
|
printf("Connected to dev!\n");
|
|
|
|
@ -315,26 +344,27 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
}
|
|
|
|
|
std::cout << " Enumerate Cameras..." << std::endl;
|
|
|
|
|
|
|
|
|
|
EnumerateCameras((SingleCamInfoStruct*)&SingleCamInfo, true, g_sys_conf);
|
|
|
|
|
EnumerateCameras((SingleCamInfoStruct*)&SingleCamInfo, true, g_sys_conf);//枚举相机
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 剔除值清0
|
|
|
|
|
int ret = m_PLCDevice->write_bit_2_plc(g_modbus_conf.shift, 1);//给PLC发送换班消息
|
|
|
|
|
|
|
|
|
|
#ifdef SYNC_CAMERA
|
|
|
|
|
CreatWorkThread(0, 0, this);
|
|
|
|
|
CreatWorkThread(0, 0, this);//创建相机公共工作线程
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//创建相机工作线程
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < NumberOfSupportedCameras; i++)
|
|
|
|
|
{
|
|
|
|
|
if (SingleCamInfo[i].Detect) {
|
|
|
|
|
work_camera_nums++;
|
|
|
|
|
//读取模型文件
|
|
|
|
|
if (SingleCamInfo[i].Detect) {//检测相机是否存在
|
|
|
|
|
work_camera_nums++;//相机数量
|
|
|
|
|
cam_status_mat[i]->setStyleSheet(tr("background-color: rgb(0, 170, 0);"));
|
|
|
|
|
QString model_path, model_name;
|
|
|
|
|
if (g_sys_conf.model_path.isEmpty()) {
|
|
|
|
|
model_path = "D:/model";
|
|
|
|
|
g_sys_conf.model_path = "D:/model";
|
|
|
|
|
model_path = DEFAULT_MODEL_PATH;
|
|
|
|
|
g_sys_conf.model_path = DEFAULT_MODEL_PATH;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
model_path = g_sys_conf.model_path;
|
|
|
|
@ -352,14 +382,15 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
#ifdef SYNC_CAMERA
|
|
|
|
|
//调试模式线程
|
|
|
|
|
debug_thread[i].init(g_debug_queue[i], i);
|
|
|
|
|
connect(&debug_thread[i], SIGNAL(notify(int, int, cv::Mat)), this, SLOT(OnNotifyHub(int, int, cv::Mat)));
|
|
|
|
|
debug_thread[i].start_work();
|
|
|
|
|
#else
|
|
|
|
|
CreatWorkThread(SingleCamInfo[i].CamClass, i, this);
|
|
|
|
|
CreatWorkThread(SingleCamInfo[i].CamClass, i, this);//创建相机单独工作线程
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
else {//报警信息
|
|
|
|
|
QDateTime ts_start = QDateTime::currentDateTime();
|
|
|
|
|
QTime time = QTime::currentTime();
|
|
|
|
|
QDateTime local(ts_start);
|
|
|
|
@ -428,9 +459,9 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
sThread.sendData("LockOk", g_sys_conf.FeedbackPort);
|
|
|
|
|
#endif
|
|
|
|
|
DisableDebugMode();
|
|
|
|
|
|
|
|
|
|
//读取PLC信息等
|
|
|
|
|
m_pTimer = new QTimer(this);
|
|
|
|
|
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(handleTimeout()));
|
|
|
|
|
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(handleTimeout()));//SIGNAL(timeout())周期性,触发SLOT(handleTimeout());周期为start(1000);
|
|
|
|
|
m_pTimer->start(1000);
|
|
|
|
|
|
|
|
|
|
m_delay = new QTimer(this);//换班防连击
|
|
|
|
@ -440,19 +471,28 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
m_sendMsg_delay = new QTimer(this);
|
|
|
|
|
connect(m_sendMsg_delay, SIGNAL(timeout()), this, SLOT(sendLatestData()));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//SIGNAL信号函数与SLOT槽函数,参数必须对应
|
|
|
|
|
//无参信号对应无参槽函数
|
|
|
|
|
//检查操作员时间
|
|
|
|
|
m_op_delay = new QTimer(this);
|
|
|
|
|
connect(m_op_delay, SIGNAL(timeout()), this, SLOT(op_timeout()));
|
|
|
|
|
|
|
|
|
|
//检查管理员时间
|
|
|
|
|
m_admin_delay = new QTimer(this);
|
|
|
|
|
connect(m_admin_delay, SIGNAL(timeout()), this, SLOT(admin_timeout()));
|
|
|
|
|
|
|
|
|
|
//定时自动清理照片
|
|
|
|
|
clean_pTimer = new QTimer(this);
|
|
|
|
|
connect(clean_pTimer, SIGNAL(timeout()), this, SLOT(CleanThreadStartAuto()));
|
|
|
|
|
clean_pTimer->start(3600000);
|
|
|
|
|
//报警标签双击消警
|
|
|
|
|
connect(ui.label_alarm, SIGNAL(QlabelDoubleClick()), this, SLOT(OnCancelAlarm()));//
|
|
|
|
|
|
|
|
|
|
connect(ui.label_alarm, SIGNAL(QlabelDoubleClick()), this, SLOT(OnCancelAlarm()));//报警标签双击消警
|
|
|
|
|
//心跳检测
|
|
|
|
|
heartbeat_pTimer = new QTimer(this);
|
|
|
|
|
connect(heartbeat_pTimer, SIGNAL(timeout()), this, SLOT(heartbeat()));
|
|
|
|
|
heartbeat_pTimer->start(5000);
|
|
|
|
|
|
|
|
|
|
//无参对有参需要利用信号转发器QSignalMapper(this)
|
|
|
|
|
//信号转发器
|
|
|
|
|
image_lable_DBsignalMapper0 = new QSignalMapper(this);
|
|
|
|
|
image_lable_DBsignalMapper1 = new QSignalMapper(this);
|
|
|
|
|
image_lable_TPsignalMapper0 = new QSignalMapper(this);
|
|
|
|
@ -461,11 +501,14 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
pTimer_Cam_signalMapper = new QSignalMapper(this);
|
|
|
|
|
toolButton_cam_signalMapper = new QSignalMapper(this);
|
|
|
|
|
RotateReleased_signalMapper = new QSignalMapper(this);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < NumberOfSupportedCameras; i++)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
//SIGNAL信号函数与SLOT槽函数,参数必须对应
|
|
|
|
|
|
|
|
|
|
m_pTimer_Cam_mat[i] = new QTimer(this);
|
|
|
|
|
connect(m_pTimer_Cam_mat[i], SIGNAL(timeout()), pTimer_Cam_signalMapper, SLOT(map()));
|
|
|
|
|
pTimer_Cam_signalMapper->setMapping(m_pTimer_Cam_mat[i], i);
|
|
|
|
|
pTimer_Cam_signalMapper->setMapping(m_pTimer_Cam_mat[i], i);//此句执行后map()=>mapped(int);相当于无参变有参
|
|
|
|
|
|
|
|
|
|
connect(display_lable_mat[i][0], SIGNAL(QlabelDoubleClick()), image_lable_DBsignalMapper0, SLOT(map()));
|
|
|
|
|
image_lable_DBsignalMapper0->setMapping(display_lable_mat[i][0], i << 4 | 0);
|
|
|
|
@ -489,6 +532,8 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
RotateReleased_signalMapper->setMapping(rotate_mat[i], i);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//SIGNAL信号函数与SLOT槽函数,参数必须对应
|
|
|
|
|
//有参对有参
|
|
|
|
|
connect(toolButton_cam_signalMapper, SIGNAL(mapped(int)), this, SLOT(OnToolButtonCamReleasedHub(int)));
|
|
|
|
|
//connect(pTimer_Cam_signalMapper, SIGNAL(mapped(int)), this, SLOT(OpenCamTimeoutHub(int)));
|
|
|
|
|
connect(image_lable_DBsignalMapper0, SIGNAL(mapped(int)), this, SLOT(OnDBClickHub(int)));
|
|
|
|
@ -531,9 +576,11 @@ Cigarette::Cigarette(QWidget* parent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_PLCDevice->g_plc_ok) {
|
|
|
|
|
BeforeWork(g_sys_conf.shoot);
|
|
|
|
|
BeforeWork(g_sys_conf.shoot);//预热
|
|
|
|
|
int ret = m_PLCDevice->write_bit_2_plc(g_modbus_conf.work, 1);
|
|
|
|
|
ui.label_title->setStyleSheet(tr("background-color: rgb(0, 170, 0);"));
|
|
|
|
|
ui.label_title_2->setStyleSheet(tr("background-color: rgb(0, 170, 0);"));
|
|
|
|
|
ui.label_title_2->setText(QStringLiteral("运行中"));
|
|
|
|
|
#ifdef __UDPSend
|
|
|
|
|
sThread.sendData("Work", g_sys_conf.FeedbackPort);
|
|
|
|
|
#endif
|
|
|
|
@ -601,6 +648,8 @@ void Cigarette::start_work()
|
|
|
|
|
ret = m_PLCDevice->write_bit_2_plc( g_modbus_conf.work, 1);*/
|
|
|
|
|
//printf("write:\t%d\n", ret);
|
|
|
|
|
ui.label_title->setStyleSheet(tr("background-color: rgb(0, 170, 0);"));
|
|
|
|
|
ui.label_title_2->setStyleSheet(tr("background-color: rgb(0, 170, 0);"));
|
|
|
|
|
ui.label_title_2->setText(QStringLiteral("运行中"));
|
|
|
|
|
#ifdef __UDPSend
|
|
|
|
|
sThread.sendData("Work", g_sys_conf.FeedbackPort);
|
|
|
|
|
#endif
|
|
|
|
@ -617,6 +666,8 @@ void Cigarette::start_work()
|
|
|
|
|
//开始按钮
|
|
|
|
|
void Cigarette::on_btn_start_released()
|
|
|
|
|
{
|
|
|
|
|
uint16_t data[2] = { 1111,0 };
|
|
|
|
|
m_PLCTCPDevice->write_2_plc(0, 70, data);//条盒
|
|
|
|
|
emit sengMsgToClog("Start to work.");
|
|
|
|
|
if (!g_admin_mode)
|
|
|
|
|
{
|
|
|
|
@ -651,6 +702,8 @@ void Cigarette::pause_work()
|
|
|
|
|
int ret = m_PLCDevice->write_bit_2_plc(g_modbus_conf.work, 0);
|
|
|
|
|
//printf("write:\t%d\n", ret);
|
|
|
|
|
ui.label_title->setStyleSheet(tr("background-color: rgb(255, 255, 0);"));
|
|
|
|
|
ui.label_title_2->setStyleSheet(tr("background-color: rgb(255, 255, 0);"));
|
|
|
|
|
ui.label_title_2->setText(QStringLiteral("未运行"));
|
|
|
|
|
#ifdef __UDPSend
|
|
|
|
|
sThread.sendData("NoWork", g_sys_conf.FeedbackPort);
|
|
|
|
|
#endif
|
|
|
|
@ -721,6 +774,10 @@ void Cigarette::Exit()
|
|
|
|
|
m_PLCDevice->disconnect_plc();
|
|
|
|
|
delete m_PLCDevice;
|
|
|
|
|
}
|
|
|
|
|
if (m_PLCTCPDevice) {
|
|
|
|
|
m_PLCTCPDevice->disconnect_plc();
|
|
|
|
|
delete m_PLCTCPDevice;
|
|
|
|
|
}
|
|
|
|
|
qApp->quit();
|
|
|
|
|
this->close();
|
|
|
|
|
|
|
|
|
@ -994,7 +1051,7 @@ void Cigarette::OnToolButtonCamReleasedHub(int Num)
|
|
|
|
|
QMessageBox::information(NULL, QStringLiteral("权限检查"), QStringLiteral("请先点击解锁按钮,进入管理员模式"), QMessageBox::Ok);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//重连相机
|
|
|
|
|
void Cigarette::ReconnectCamHub(int Num)
|
|
|
|
|
{
|
|
|
|
|
//close
|
|
|
|
@ -1007,7 +1064,6 @@ void Cigarette::ReconnectCamHub(int Num)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Cigarette::OpenCamTimeoutHub(int Num) //重新打开相机
|
|
|
|
|
{
|
|
|
|
|
//open
|
|
|
|
@ -1024,14 +1080,14 @@ void Cigarette::OnKey(QKeyEvent* event)
|
|
|
|
|
int Cnt = CurOpLabel & 0x0f;
|
|
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> locker(g_display_label_conf[Num].lock);
|
|
|
|
|
if (event->key() == Qt::Key_Escape && event->isAutoRepeat() == false)
|
|
|
|
|
if (event->key() == Qt::Key_Escape && event->isAutoRepeat() == false)//画框Esc清除参数
|
|
|
|
|
{
|
|
|
|
|
if (g_display_label_conf[Num].RectVet[Cnt].size())
|
|
|
|
|
{
|
|
|
|
|
g_display_label_conf[Num].RectVet[Cnt].pop_back();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (event->key() == Qt::Key_Return && event->isAutoRepeat() == false)
|
|
|
|
|
else if (event->key() == Qt::Key_Return && event->isAutoRepeat() == false)//画框回车保存参数
|
|
|
|
|
{
|
|
|
|
|
std::fstream cfg_file;
|
|
|
|
|
char buf[256];
|
|
|
|
@ -1537,7 +1593,13 @@ void Cigarette::admin_timeout()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Cigarette::handleTimeout()
|
|
|
|
|
//心跳检测
|
|
|
|
|
void Cigarette::heartbeat()
|
|
|
|
|
{
|
|
|
|
|
int ret = m_PLCDevice->write_bit_2_plc(g_modbus_conf.heart, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Cigarette::handleTimeout()//获取时间,读取PLC产量、剔除数;检测相机状态;读取PLC报警信息
|
|
|
|
|
{
|
|
|
|
|
QDateTime ts_start = QDateTime::currentDateTime();
|
|
|
|
|
QTime time = QTime::currentTime();
|
|
|
|
@ -2044,8 +2106,8 @@ void Cigarette::on_pushButton_clear_released()//换班
|
|
|
|
|
g_op_time = OP_TIME;
|
|
|
|
|
|
|
|
|
|
ui.pushButton_clear->setEnabled(false);
|
|
|
|
|
m_delay->setSingleShot(true);
|
|
|
|
|
m_delay->start(5000);
|
|
|
|
|
m_delay->setSingleShot(true);//执行一次
|
|
|
|
|
m_delay->start(5000);//5秒
|
|
|
|
|
Sleep(500);
|
|
|
|
|
for (int i = 0; i < NumberOfSupportedCameras; i++)
|
|
|
|
|
{
|
|
|
|
@ -2087,7 +2149,11 @@ void Cigarette::on_pushButton_clear_released()//换班
|
|
|
|
|
QString Cigarette::read_pswd()
|
|
|
|
|
{
|
|
|
|
|
std::fstream cfg_file;
|
|
|
|
|
#ifdef __DEBUGPATH
|
|
|
|
|
cfg_file.open("pswd.txt");
|
|
|
|
|
#else
|
|
|
|
|
cfg_file.open("D:/Release/pswd.txt");
|
|
|
|
|
#endif
|
|
|
|
|
if (!cfg_file.is_open())
|
|
|
|
|
{
|
|
|
|
|
std::cout << "Error: Open config file pswd.txt" << std::endl;
|
|
|
|
@ -2119,7 +2185,11 @@ QString Cigarette::read_pswd()
|
|
|
|
|
QString Cigarette::read_op_pswd()
|
|
|
|
|
{
|
|
|
|
|
std::fstream cfg_file;
|
|
|
|
|
#ifdef __DEBUGPATH
|
|
|
|
|
cfg_file.open("pswd_op.txt");
|
|
|
|
|
#else
|
|
|
|
|
cfg_file.open("D:/Release/pswd_op.txt");
|
|
|
|
|
#endif
|
|
|
|
|
if (!cfg_file.is_open())
|
|
|
|
|
{
|
|
|
|
|
std::cout << "Error: Open config file pswd_op.txt" << std::endl;
|
|
|
|
@ -2150,15 +2220,15 @@ QString Cigarette::read_op_pswd()
|
|
|
|
|
bool Cigarette::read_conf(ConfPath& conf_path) {
|
|
|
|
|
std::fstream conf_file;
|
|
|
|
|
conf_file.open(CONFPATH);
|
|
|
|
|
if (!conf_file.is_open()) {
|
|
|
|
|
if (!conf_file.is_open()) {//判断能否打开文件
|
|
|
|
|
std::cout << "Error: Open conf path file " << CONFPATH << std::endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
while (!conf_file.eof()) {
|
|
|
|
|
while (!conf_file.eof()) {//从头读到尾,完成后conf_file.eof()==TRUE
|
|
|
|
|
char tmp[256] = "";
|
|
|
|
|
conf_file.getline(tmp, 256);
|
|
|
|
|
std::string line(tmp);
|
|
|
|
|
if (line.length() > 0) {
|
|
|
|
|
if (line.length() > 0) {//按行读取
|
|
|
|
|
size_t pos = line.find('=');
|
|
|
|
|
std::string tmp_key = line.substr(0, pos);
|
|
|
|
|
if (tmp_key == "CONF_PATH") {
|
|
|
|
@ -2566,6 +2636,22 @@ bool Cigarette::read_sys_config(SysConf& conf, QString conf_path)
|
|
|
|
|
{
|
|
|
|
|
conf.TcpPort = atoi(line.substr(pos + 1).c_str());
|
|
|
|
|
}
|
|
|
|
|
else if (tmp_key == "FtpIP")
|
|
|
|
|
{
|
|
|
|
|
conf.FtpIP = line.substr(pos + 1);
|
|
|
|
|
}
|
|
|
|
|
else if (tmp_key == "FtpPort")
|
|
|
|
|
{
|
|
|
|
|
conf.FtpPort = atoi(line.substr(pos + 1).c_str());
|
|
|
|
|
}
|
|
|
|
|
else if (tmp_key == "FtpUserName")
|
|
|
|
|
{
|
|
|
|
|
conf.FtpUserName= line.substr(pos + 1);
|
|
|
|
|
}
|
|
|
|
|
else if (tmp_key == "FtpUserPwd")
|
|
|
|
|
{
|
|
|
|
|
conf.FtpUserPwd = line.substr(pos + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2627,6 +2713,10 @@ bool Cigarette::read_modbus_config(ModbusConf& conf)
|
|
|
|
|
{
|
|
|
|
|
conf.alarm = atoi(line.substr(pos + 1).c_str());
|
|
|
|
|
}
|
|
|
|
|
else if (tmp_key == "HEART")
|
|
|
|
|
{
|
|
|
|
|
conf.heart = atoi(line.substr(pos + 1).c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cfg_file.close();
|
|
|
|
@ -2821,7 +2911,7 @@ void Cigarette::init_plc_value()
|
|
|
|
|
void Cigarette::CreatWorkThread(int classid, int Num, Cigarette* classptr)
|
|
|
|
|
{
|
|
|
|
|
#ifdef SYNC_CAMERA
|
|
|
|
|
sync_work_thread.init(g_image_sync_queue, g_result_queue[0]);
|
|
|
|
|
sync_work_thread.init(g_image_sync_queue, g_result_queue, 0); // 默认使用第一个相机的数据
|
|
|
|
|
connect(&sync_work_thread, SIGNAL(notify(int, int, cv::Mat)), classptr, SLOT(OnNotifyHub(int, int, cv::Mat)));
|
|
|
|
|
connect(&sync_work_thread, SIGNAL(display_timecost(int, int)), classptr, SLOT(OnDisplayTimeCostHub(int, int)));
|
|
|
|
|
connect(&sync_work_thread, SIGNAL(display_check_total(int, long)), classptr, SLOT(OnDisplayCheckNumberHub(int, long)));
|
|
|
|
@ -3127,11 +3217,11 @@ bool Cigarette::ControlCamOpenOrClose(int Num, bool OpenOrClose)
|
|
|
|
|
else if (SingleCamInfo[Num].CamClass == HIKClassID)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "open for hik";
|
|
|
|
|
int nRet = MV_OK;
|
|
|
|
|
int nRet = MV_OK;//海康内部定义MV_OK = 0x0000000;
|
|
|
|
|
void* camhandle;
|
|
|
|
|
nRet = MV_CC_CreateHandle(&camhandle, HIKCamera::stDeviceList.pDeviceInfo[SingleCamInfo[Num].unfiltered_num]);
|
|
|
|
|
HIKCamHandle[Num] = camhandle;
|
|
|
|
|
nRet = MV_CC_OpenDevice(camhandle);
|
|
|
|
|
nRet = MV_CC_OpenDevice(camhandle);//打开相机成功返回MV_OK
|
|
|
|
|
if (nRet)
|
|
|
|
|
{
|
|
|
|
|
MV_CC_CloseDevice(camhandle);
|
|
|
|
@ -3143,6 +3233,7 @@ bool Cigarette::ControlCamOpenOrClose(int Num, bool OpenOrClose)
|
|
|
|
|
}
|
|
|
|
|
if (HIKCamera::stDeviceList.pDeviceInfo[SingleCamInfo[Num].unfiltered_num]->nTLayerType == MV_GIGE_DEVICE)
|
|
|
|
|
{
|
|
|
|
|
//配置网口相机
|
|
|
|
|
int nPacketSize = MV_CC_GetOptimalPacketSize(camhandle);
|
|
|
|
|
if (nPacketSize > 0)
|
|
|
|
|
{
|
|
|
|
@ -3236,7 +3327,7 @@ bool Cigarette::ControlCamOpenOrClose(int Num, bool OpenOrClose)
|
|
|
|
|
if (!g_debug_mode)
|
|
|
|
|
connect(pHIKCaptureThread[Num], SIGNAL(updateStatistics(const QString&, int)), this, SLOT(updateStatisticsHub(const QString&, int)));
|
|
|
|
|
pThread[Num]->start();
|
|
|
|
|
if (pThread[Num]->isRunning())
|
|
|
|
|
if (pThread[Num]->isRunning())//线程开始工作后打印消息
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "hik pThread OK";
|
|
|
|
|
SingleCamInfo[Num].IsOpen = true;
|
|
|
|
@ -3250,6 +3341,7 @@ bool Cigarette::ControlCamOpenOrClose(int Num, bool OpenOrClose)
|
|
|
|
|
if (SingleCamInfo[Num].CamClass == BalluffClassID)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "close for balluff";
|
|
|
|
|
//取消函数连接
|
|
|
|
|
disconnect(pThread[Num], SIGNAL(started()), pCaptureThread[Num], SLOT(process()));
|
|
|
|
|
//disconnect(pCaptureThread[Num], SIGNAL(error(QString)), this, SLOT(errorString(QString)));
|
|
|
|
|
disconnect(pCaptureThread[Num], SIGNAL(finished()), pThread[Num], SLOT(quit()));
|
|
|
|
@ -3347,7 +3439,7 @@ void Cigarette::EnumerateCameras(SingleCamInfoStruct* TempSingleCamInfoStruct, b
|
|
|
|
|
Pylon::CInstantCameraArray cameras(filtered);
|
|
|
|
|
Pylon::CTlFactory& tlFactory = Pylon::CTlFactory::GetInstance();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < min(filtered, NumberOfSupportedCameras); i++)
|
|
|
|
|
for (int i = 0; i < min(filtered, NumberOfIdentityCameras); i++)
|
|
|
|
|
{
|
|
|
|
|
SingleCamInfoStruct CamInfo;
|
|
|
|
|
//cameras[i].Attach(tlFactory.CreateDevice(BaslerCamera::devices[i]));
|
|
|
|
@ -3378,7 +3470,7 @@ void Cigarette::EnumerateCameras(SingleCamInfoStruct* TempSingleCamInfoStruct, b
|
|
|
|
|
int hik_cnt = 0;
|
|
|
|
|
int unfiltered = 0;
|
|
|
|
|
unfiltered = HIKCamera::Enumerate();
|
|
|
|
|
for (int i = 0; i < min(unfiltered, NumberOfSupportedCameras); i++)
|
|
|
|
|
for (int i = 0; i < min(unfiltered, NumberOfIdentityCameras); i++)
|
|
|
|
|
{
|
|
|
|
|
MV_CC_DEVICE_INFO* pDeviceInfo = HIKCamera::stDeviceList.pDeviceInfo[i];
|
|
|
|
|
std::string manufacture;
|
|
|
|
@ -3441,7 +3533,7 @@ void Cigarette::EnumerateCameras(SingleCamInfoStruct* TempSingleCamInfoStruct, b
|
|
|
|
|
|
|
|
|
|
int balluff_cnt = 0;
|
|
|
|
|
unfiltered = BalluffCamera::Enumerate();
|
|
|
|
|
for (int i = 0; i < min(unfiltered, NumberOfSupportedCameras); i++)
|
|
|
|
|
for (int i = 0; i < min(unfiltered, NumberOfIdentityCameras); i++)
|
|
|
|
|
{
|
|
|
|
|
Device* pDev = BalluffCamera::devMgr[i];
|
|
|
|
|
if (!pDev->isInUse()) {
|
|
|
|
@ -3542,7 +3634,7 @@ void Cigarette::EnableDebugMode()
|
|
|
|
|
}
|
|
|
|
|
g_debug_mode = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//非调试模式
|
|
|
|
|
void Cigarette::DisableDebugMode()
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < NumberOfSupportedCameras; i++)
|
|
|
|
@ -3600,7 +3692,7 @@ void Cigarette::CleanThreadStart()
|
|
|
|
|
QThread* handleThread = new QThread();
|
|
|
|
|
CleanWorkThread* cleanWorkThread = new CleanWorkThread();
|
|
|
|
|
|
|
|
|
|
cleanWorkThread->moveToThread(handleThread);
|
|
|
|
|
cleanWorkThread->moveToThread(handleThread);//依附到handleThread线程
|
|
|
|
|
|
|
|
|
|
connect(handleThread, &QThread::started, cleanWorkThread, &CleanWorkThread::startWork);
|
|
|
|
|
connect(cleanWorkThread, &CleanWorkThread::workStart, cleanWorkThread, &CleanWorkThread::setSel);
|
|
|
|
@ -3629,39 +3721,70 @@ void Cigarette::record_output_statistic(qint64 quantity, int Kick[NumberOfSuppor
|
|
|
|
|
QString file_name, file_path;
|
|
|
|
|
for (int i = 0; i < NumberOfSupportedCameras; i++)
|
|
|
|
|
{
|
|
|
|
|
if (SingleCamInfo[i].IsOpen && quantity > 0) {
|
|
|
|
|
if (SingleCamInfo[i].IsOpen) //&& quantity > 0
|
|
|
|
|
{
|
|
|
|
|
std::fstream cfg_file;
|
|
|
|
|
file_name = QString(STATISTIC_FILE).arg(i);
|
|
|
|
|
file_path = g_conf_path.config_path + "/" + file_name;
|
|
|
|
|
|
|
|
|
|
char buf[256];
|
|
|
|
|
memset(buf, 0, 256);
|
|
|
|
|
sprintf(buf, "%s", file_path.toLocal8Bit().constData());
|
|
|
|
|
|
|
|
|
|
cfg_file.open(buf, std::ios::app);
|
|
|
|
|
if (cfg_file.good())
|
|
|
|
|
{
|
|
|
|
|
if (last_shift == 2 || last_shift == 256) {
|
|
|
|
|
memset(buf, 0, 256);
|
|
|
|
|
sprintf(buf, "\n\n**************************************************************************************\n");
|
|
|
|
|
cfg_file.write(buf, strlen(buf));
|
|
|
|
|
//QDate date = QDate::currentDate();
|
|
|
|
|
QDateTime date = QDateTime::currentDateTime();
|
|
|
|
|
memset(buf, 0, 256);
|
|
|
|
|
sprintf(buf, "%s:\n", date.toString("yyyy-MM-dd_HH-mm-ss").toStdString().c_str());
|
|
|
|
|
cfg_file.write(buf, strlen(buf));
|
|
|
|
|
}
|
|
|
|
|
memset(buf, 0, 256);
|
|
|
|
|
double ng_rate;
|
|
|
|
|
if (ng[i] > 0)
|
|
|
|
|
ng_rate = double(ng[i]) / production_number[i];
|
|
|
|
|
else
|
|
|
|
|
ng_rate = 0;
|
|
|
|
|
QDateTime date = QDateTime::currentDateTime();
|
|
|
|
|
string nowtime = date.toString("yyyy-MM-dd_HH:mm:ss").toStdString().c_str();
|
|
|
|
|
double ng_rate;
|
|
|
|
|
if (ng[i] > 0)
|
|
|
|
|
{
|
|
|
|
|
ng_rate = double(ng[i]) / production_number[i];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ng_rate = 0;
|
|
|
|
|
}
|
|
|
|
|
if (quantity > 0)
|
|
|
|
|
{
|
|
|
|
|
sprintf(buf, "%c 总产量:%010I64d 剔除率:%02.5f%% 合格率:%02.5f%% NG率:%02.5f%%\n", (shift == 0) ? 'A' : ((shift == 1) ? 'B' : 'C'), quantity, ((double)Kick[i] / quantity) * 100, (1.0 - ng_rate) * 100, ng_rate * 100);
|
|
|
|
|
cfg_file.write(buf, strlen(buf));
|
|
|
|
|
memset(buf, 0, 256);
|
|
|
|
|
}
|
|
|
|
|
cfg_file.close();
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sprintf(buf, "%c 总产量:%010I64d 剔除率:%02.5f%% 合格率:%02.5f%% NG率:%02.5f%%\n", (shift == 0) ? 'A' : ((shift == 1) ? 'B' : 'C'), quantity, 0.00, 0.00, 0.00);
|
|
|
|
|
}
|
|
|
|
|
std::ifstream file(file_path.toStdString());
|
|
|
|
|
std::ifstream file_(file_path.toStdString());
|
|
|
|
|
std::vector<std::string> lines; //用于存储文件的所有行
|
|
|
|
|
if (file_.good())
|
|
|
|
|
{
|
|
|
|
|
file_.close();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
std::ofstream outFile(file_path.toStdString());
|
|
|
|
|
std::string fristNews = "**************************************************************************************\n" + nowtime + "\n" + buf;
|
|
|
|
|
outFile << fristNews << endl;
|
|
|
|
|
outFile.close();
|
|
|
|
|
}
|
|
|
|
|
if (file.is_open())
|
|
|
|
|
{
|
|
|
|
|
std::string line;
|
|
|
|
|
while (std::getline(file, line))
|
|
|
|
|
{
|
|
|
|
|
lines.push_back(line);
|
|
|
|
|
}
|
|
|
|
|
file.close();
|
|
|
|
|
// 在第一行添加数据
|
|
|
|
|
std::string newData = "**************************************************************************************\n"+nowtime +"\n" + buf;
|
|
|
|
|
if (!lines.empty())
|
|
|
|
|
{
|
|
|
|
|
lines.insert(lines.begin(), newData); // 在vector的开始位置插入新数据
|
|
|
|
|
}
|
|
|
|
|
// 将修改后的数据写回文件
|
|
|
|
|
std::ofstream outFile(file_path.toStdString());
|
|
|
|
|
if (outFile.is_open())
|
|
|
|
|
{
|
|
|
|
|
for (const auto& l : lines)
|
|
|
|
|
{
|
|
|
|
|
outFile << l << std::endl;
|
|
|
|
|
}
|
|
|
|
|
outFile.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
last_shift = shift;
|
|
|
|
|