#include "manage.h" #include "log.h" #include "skt.h" #include "var.h" #include "ops.h" #include "test.h" #include "config.h" #include "matrix.h" #include "user.h" #include "sysapi.h" //默认参数 #define CONFIG "C001" //料号 #define LOT "P001" //产品批次/料号 #define MACHINE "MS001" //设备ID #define SITEL "rs" //厂商 #define PRONA "pr10010" //项目代码 #define BINA "BinA" //BinA #define SUBLOT "SP001" //子产品批次/料号 CManage* CManage::m_pInstance = NULL; CManage::CManage(void) { char buff[MAX_NAME_LEN] = {0}; m_pv = NULL; m_pt = NULL; m_pclear = NULL; m_pFour = NULL; m_pntake = NULL; m_pnput = NULL; m_pUph = NULL; m_pAllUph = NULL; m_pOutput = NULL; m_pLot = NULL; m_pEnda = NULL; m_pPause = NULL; m_pBin = NULL; m_pCastoff = NULL; _logct = 0; m_prePut = 0; memset(&m_cfg, 0, sizeof(m_cfg)); //test m_brun = false; m_tstRun = false; m_bupdatevar = false; m_pconn = new CTest(); m_hThread = INVALID_HANDLE; for(int i = 0; i < TESTCNT; i++) { m_ptest[i] = new CTest(); sprintf(buff, "%d", 76001 + i); m_psimTest[i] = new CSimTest(i + 1, buff); } m_pVisionTest = new CVision(); for (int i = 0; i < EVSize; i++) { m_pVision[i] = new CVision(); } m_vacm_cnt = VACMCNT; m_vacm_lst = new CProduct*[m_vacm_cnt]; memset(m_lst_index, 0, sizeof(m_lst_index)); memset(m_pvar_vacm, 0, sizeof(m_pvar_vacm)); memset(m_pvar_test, 0, sizeof(m_pvar_test)); memset(m_vacm_lst, 0, sizeof(CProduct*) *m_vacm_cnt); m_hSection = sys_InitializeCriticalSection(); } CManage::~CManage(void) { Deinit(); delete m_pconn; delete []m_vacm_lst; delete m_pVisionTest; for (int i = 0; i < EVSize; i++) {//释放视觉组 delete m_pVision[i]; } for(int i = 0; i < TESTCNT; i++) { delete m_ptest[i]; delete m_psimTest[i]; } sys_DeleteCriticalSection(m_hSection); } CManage* CManage::Get_Instance() { try { if (NULL == m_pInstance) { m_pInstance = new CManage; } } catch (...) { } return m_pInstance; } void CManage::ReleaseInstance() { FREE_ANY(m_pInstance); } cstr CManage::GetVersion() {//4\5位版本号转化为字符串 int iver = VERSION; char buff[16] = { 0 }; static char cver[16] = { 0 }; RETURN_CHK_NOPRT(0 == cver[0], cver); if (iver > 10000) { sprintf(buff, "beta%d", iver % 10); iver %= 10000; } else if (iver <= 0) { iver = 1001; } sprintf(cver, "%d_%d_%d_%d", iver / 1000, (iver / 100) % 10, (iver / 10) % 10, iver % 10 ); if (buff[0]) { strcat(cver, " "); strcat(cver, buff); } return cver; } int CManage::Init() { /*CreateVar("total1", "治具1测试总数", 0); CreateVar("OK1", "治具1测试OK数", 0); CreateVar("total2", "治具2测试总数", 0); CreateVar("OK2", "治具2测试OK数", 0); CreateVar("total3", "治具3测试总数", 0); CreateVar("OK3", "治具3测试OK数", 0); CreateVar("total4", "治具4测试总数", 0); CreateVar("OK4", "治具4测试OK数", 0); CreateVar("total5", "治具5测试总数", 0); CreateVar("OK5", "治具5测试OK数", 0); CreateVar("total6", "治具6测试总数", 0); CreateVar("OK6", "治具6测试OK数", 0);*/ CreateVar("totalall", "测试总数", 1); CreateVar("OKall", "测试总OK数", 1); CreateVar("lot", "换料盘自动计数"); getVar("dualtest", "分组测试标识"); m_pv = getVar("v", "当前吸嘴编号", false); m_pt = getVar("t", "当前治具/料仓编号", false); m_pFour = getVar("pic", "一次拍几张图片"); m_pclear = getVar("clear", "清料信号"); m_pntake = getVar("ntake", "需要取多少颗料"); m_pnput = getVar("nput", "需要放多少颗料到OK仓"); m_pUph = getVar("uph", "最近5分钟uph"); m_pAllUph = getVar("uphs", "机台平均uph"); m_pOutput = getVar("output", "最近工作产量"); m_pEnda = getVar("enda", "A组结束序号"); m_pPause = getVar("ops_pause", "ops系统信号"); m_pBin = getVar("tlevel", "产品分bin信息"); m_pCastoff = getVar("castoff", "临时取料索引"); m_pCastoff->seti(0); ReadConfig(); StartRun(); return 0; } int CManage::Deinit() { StopRun(); while (m_tstRun); //等待退出 for (int i = 0; i < TESTCNT; i++) {//先停线程 m_psimTest[i]->Deinit(); } sys_EnterCriticalSection(m_hSection); for (int i = 0; i < EVSize; i++) {//释放视觉组 m_pVision[i]->Deinit(); } m_pVisionTest->Deinit(); for(int i = 0; i < TESTCNT; i++) { m_ptest[i]->Close(); } m_pconn->Close(); Release(); sys_LeaveCriticalSection(m_hSection); return 0; } int CManage::EventTracker(const char* keyword, int errcode, const char*errmsg, const char*msg) { int ret = 0; SYS_TIME tm; cstr pszuser = NULL; char files[KEY_LEN] = { 0 }; const char* title = "VERSION,SITEID,PROJECTID,MACHINEID,DATE,TIME," "LOT NAME,LOGIN MODE,KEYWORD,ERROR CODE,ERROR MESSAGE,MESSAGE\n"; sys_GetLocalTime(&tm); if (IsMakeDir()) {//按日期生成文件夹 sprintf(files, "Break_Event_Summary_Unit\\%04d%02d%02d\\EventTracker_%04d%02d%02d.csv", tm.wYear, tm.wMonth, tm.wDay, tm.wYear, tm.wMonth, tm.wDay); } else { sprintf(files, "Break_Event_Summary_Unit\\EventTracker_%04d%02d%02d.csv", tm.wYear, tm.wMonth, tm.wDay); } sys_EnterCriticalSection(m_hSection); if (!files_read(files)) { files_writes(files, title); } pszuser = get_cur_user(); ret = files_write(files, "%s,%s,%s,%s,%02d/%02d/%04d,%02d:%02d:%02d,%s,%s,%s,%d,%s,%s\n", GetVersion(), m_cfg.sitel, m_cfg.project, m_cfg.machine, tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond, m_cfg.lot, pszuser ? pszuser : "OP", keyword, errcode, errmsg, msg); sys_LeaveCriticalSection(m_hSection); if (ret) REPORT("写入日志%s 失败", files); return 0; } int CManage::UnitTracker(const char* sn, const char* ate, const char* lot, int result, const char* RetryUsage) { int ret = 0; SYS_TIME tm; cstr pszuser = NULL; char files[KEY_LEN] = { 0 }; const char* title = "SiteID,ProjectID,MachineID,Date,Time,LotName," "LoginMode,Serial Number,Socker ID,Test Result,Trial,Socket Usage\n"; sys_GetLocalTime(&tm); if (IsMakeDir()) {//按日期生成文件夹 sprintf(files, "Break_Event_Summary_Unit\\%04d%02d%02d\\UnitTracker_%04d%02d%02d.csv", tm.wYear, tm.wMonth, tm.wDay, tm.wYear, tm.wMonth, tm.wDay); } else { sprintf(files, "Break_Event_Summary_Unit\\UnitTracker_%04d%02d%02d.csv", tm.wYear, tm.wMonth, tm.wDay); } /*sprintf(files, "log\\%04d%02d%02d_%s_%s_%s_UnitTracker.csv", tm.wYear, tm.wMonth, tm.wDay, pCfg->sitel, pCfg->project, MachineID);*/ //2021-09-24 修改 sys_EnterCriticalSection(m_hSection); if (!files_read(files)) { files_writes(files, title); } pszuser = get_cur_user(); ret = files_write(files, "%s,%s,%s,%02d/%02d/%04d,%02d:%02d:%02d," "%s,%s,%s,%s,%s,%s,%d%d%d%d%d%d\n", /*core_version(), */m_cfg.sitel, m_cfg.project, m_cfg.machine, tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond, lot, pszuser ? pszuser : "OP", sn, ate, (result == 1) ? "PASS" : "FAIL", RetryUsage, m_ptest[0]->_data.benable, m_ptest[1]->_data.benable, m_ptest[2]->_data.benable, m_ptest[3]->_data.benable, m_ptest[4]->_data.benable, m_ptest[5]->_data.benable); sys_LeaveCriticalSection(m_hSection); if (ret) REPORT("写入日志%s 失败", files); return ret; } ulong CManage::GetLastCT(ulong curct) {//获取最后一次CT ulong ct = _logct > 0 ? curct - _logct : 0; _logct = curct; return ct; } int CManage::SummaryLog(const char* title, const char* content) { int ret = 0; SYS_TIME tm; char files[KEY_LEN] = { 0 }; cstr pszuser = NULL; //按日期生成文件夹 sys_GetLocalTime(&tm); if (IsMakeDir()) {//按日期生成文件夹 sprintf(files, "Break_Event_Summary_Unit\\%04d%02d%02d\\Summary_%04d%02d%02d.csv", tm.wYear, tm.wMonth, tm.wDay, tm.wYear, tm.wMonth, tm.wDay); } else { sprintf(files, "Break_Event_Summary_Unit\\Summary_%04d%02d%02d.csv", tm.wYear, tm.wMonth, tm.wDay); } sys_EnterCriticalSection(m_hSection); if (title && *title && !files_read(files)) { files_writes(files, title); } ret = files_writes(files, content); pszuser = get_cur_user(); if (pszuser != NULL && (!strcmp(pszuser, "AUDIT") || !strcmp(pszuser, "Audit"))) { sprintf(files, "Break_Event_Summary_Unit\\AuditCheck.csv"); files_writes(files, content); } //ret = files_close(files); sys_LeaveCriticalSection(m_hSection); if (ret) REPORT("写入日志%s 失败", files); return ret; } int CManage::BreakdownLog(const char* psztype, const char* pszmsg) { int ret = 0; SYS_TIME tm; char files[KEY_LEN] = { 0 }; static const char* psztitle = "Machine,Tester Category,Tester_Sequence_Item Detail,TimeStamp,Time(ms)\n"; RETURN_CHK_NOPRT(NodeLog(), 0); RETURN_CHK_NOPRT(psztype && pszmsg, ERR_INPUT_PARAM); sys_GetLocalTime(&tm); if (IsMakeDir()) {//按日期生成文件夹 sprintf(files, "Break_Event_Summary_Unit\\%04d%02d%02d\\Breakdown_%04d%02d%02d.csv", tm.wYear, tm.wMonth, tm.wDay, tm.wYear, tm.wMonth, tm.wDay); } else { sprintf(files, "Break_Event_Summary_Unit\\Breakdown_%04d%02d%02d.csv", tm.wYear, tm.wMonth, tm.wDay); } sys_EnterCriticalSection(m_hSection); if (!files_read(files)) { files_writes(files, psztitle); } ret = files_write(files, "%s,%s,%s,%02d/%02d/%04d %02d:%02d:%02d.%03d,%d\n", m_cfg.machine, psztype, pszmsg, tm.wMonth, tm.wDay, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds, GetLastCT(sys_GetTickCount())); sys_LeaveCriticalSection(m_hSection); if (ret) REPORT("写入日志%s 失败", files); return ret; } cstr CManage::GetTestModel() { cstr pszuser = get_cur_user(); if (!pszuser) pszuser = "OP"; return GetTestMode(pszuser); } int CManage::SetConfig(CoreConfig* pcfg) { RETURN_CHK_NOPRT(pcfg->uphFrequency >= 0 && pcfg->uphFrequency <= 5, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(pcfg->iSimYield >= 0 && pcfg->iSimYield <= 100, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(pcfg->iSimCT >= 5 && pcfg->iSimCT <= 100, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(pcfg->idualindex >= MINAEND && pcfg->idualindex <= TESTCNT, ERR_INPUT_PARAM); if (strcmp(pcfg->lot, m_cfg.lot)) { strcpy(m_cfg.lot, pcfg->lot); modify_cfg(CFG_KEY, "lot", m_cfg.lot); } if (strcmp(pcfg->Config, m_cfg.Config)) { strcpy(m_cfg.Config, pcfg->Config); modify_cfg(CFG_KEY, "Config", m_cfg.Config); } if (strcmp(pcfg->ConfigD, m_cfg.ConfigD)) { strcpy(m_cfg.ConfigD, pcfg->ConfigD); modify_cfg(CFG_KEY, "ConfigD", m_cfg.ConfigD); } if (strcmp(pcfg->project, m_cfg.project)) { strcpy(m_cfg.project, pcfg->project); modify_cfg(CFG_KEY, "project", m_cfg.project); } if (strcmp(pcfg->sublotname, m_cfg.sublotname)) { strcpy(m_cfg.sublotname, pcfg->sublotname); modify_cfg(CFG_KEY, "sublotname", m_cfg.sublotname); } if (pcfg->bFourPic != m_cfg.bFourPic) {//和工作盘一起放 m_cfg.bFourPic = pcfg->bFourPic; m_pFour->seti(m_cfg.bFourPic ? 4 : 1); modify_cfg_int(CFG_KEY, "bFourPic", m_cfg.bFourPic); } if (pcfg->bSavePos != m_cfg.bSavePos) {//是否缓存位置 m_cfg.bSavePos = pcfg->bSavePos; modify_cfg_int(CFG_KEY, "bSavePos", m_cfg.bSavePos); } //系统配置 if (strcmp(pcfg->sitel, m_cfg.sitel)) { strcpy(m_cfg.sitel, pcfg->sitel); modify_sys_cfg(CFG_KEY, "sitel", m_cfg.sitel); } if (strcmp(pcfg->BinA, m_cfg.BinA)) {//BinA strcpy(m_cfg.BinA, pcfg->BinA); modify_sys_cfg(CFG_KEY, "BinA", m_cfg.BinA); } if (strcmp(pcfg->serverip, m_cfg.serverip) && chk_ipaddress(pcfg->serverip)) {//测试服务器IP strcpy(m_cfg.serverip, pcfg->serverip); modify_sys_cfg(CFG_KEY, "serverip", m_cfg.serverip); } if (strcmp(pcfg->visionip, m_cfg.visionip) && chk_ipaddress(pcfg->visionip)) {//视觉服务器IP strcpy(m_cfg.visionip, pcfg->visionip); modify_sys_cfg(CFG_KEY, "visionip", m_cfg.visionip); for (int i = 0; i < EVSize; i++) { m_pVision[i]->Deinit(); m_pVision[i]->Init(m_cfg.visionip, VPORT + i); } m_pVisionTest->Deinit(); m_pVisionTest->Init(m_cfg.visionip, VPORTEST); } if (strcmp(pcfg->machine, m_cfg.machine)) { strcpy(m_cfg.machine, pcfg->machine); //modify_cfg(CFG_KEY, "machine", m_cfg.machine); modify_sys_cfg(CFG_KEY, "machine", m_cfg.machine); } if (pcfg->testType != m_cfg.testType) { m_cfg.testType = pcfg->testType; modify_sys_cfg_int(CFG_KEY, "testType", m_cfg.testType); } if (pcfg->bNodeLog != m_cfg.bNodeLog) { m_cfg.bNodeLog = pcfg->bNodeLog; modify_sys_cfg_int(CFG_KEY, "bNodeLog", m_cfg.bNodeLog); } if (pcfg->bUpMes != m_cfg.bUpMes) { m_cfg.bUpMes = pcfg->bUpMes; modify_sys_cfg_int(CFG_KEY, "bUpMes", m_cfg.bUpMes); } if (pcfg->bUpMTcp != m_cfg.bUpMTcp) { m_cfg.bUpMTcp = pcfg->bUpMTcp; modify_sys_cfg_int(CFG_KEY, "bUpMTcp", m_cfg.bUpMTcp); } if (pcfg->bUpNoise != m_cfg.bUpNoise) { m_cfg.bUpNoise = pcfg->bUpNoise; modify_sys_cfg_int(CFG_KEY, "bUpNoise", m_cfg.bUpNoise); } if (pcfg->bSingleTestFilter != m_cfg.bSingleTestFilter) { m_cfg.bSingleTestFilter = pcfg->bSingleTestFilter; modify_sys_cfg_int(CFG_KEY, "bSingleTestFilter", m_cfg.bSingleTestFilter); } if (pcfg->bDirDate != m_cfg.bDirDate) { m_cfg.bDirDate = pcfg->bDirDate; modify_sys_cfg_int(CFG_KEY, "bDirDate", m_cfg.bDirDate); } if (pcfg->b2nd != m_cfg.b2nd) { m_cfg.b2nd = pcfg->b2nd; modify_sys_cfg_int(CFG_KEY, "b2nd", m_cfg.b2nd); } if (pcfg->bTestlog != m_cfg.bTestlog) { m_cfg.bTestlog = pcfg->bTestlog; modify_sys_cfg_int(CFG_KEY, "bTestlog", m_cfg.bTestlog); } if (pcfg->bVisionlog != m_cfg.bVisionlog) { m_cfg.bVisionlog = pcfg->bVisionlog; modify_sys_cfg_int(CFG_KEY, "bVisionlog", m_cfg.bVisionlog); } if (pcfg->uphFrequency != m_cfg.uphFrequency) { m_cfg.uphFrequency = pcfg->uphFrequency; modify_sys_cfg_int(CFG_KEY, "uphFrequency", m_cfg.uphFrequency); } if (pcfg->idualindex != m_cfg.idualindex) {//分组序号 m_cfg.idualindex = pcfg->idualindex; SetVarInit("dualtest", m_cfg.idualindex); } if (pcfg->bPassTestB != m_cfg.bPassTestB) {//是否测试pass才进入B组测试 m_cfg.bPassTestB = pcfg->bPassTestB; modify_sys_cfg_int(CFG_KEY, "bPassTestB", m_cfg.bPassTestB); } if (pcfg->bBindB != m_cfg.bBindB) {//B组是否为绑定模式 TC1->TCB1 TC2->TCB2 m_cfg.bBindB = pcfg->bBindB; modify_sys_cfg_int(CFG_KEY, "bBindB", m_cfg.bBindB); } if (pcfg->iSimYield != m_cfg.iSimYield) {//模拟良率 m_cfg.iSimYield = pcfg->iSimYield; modify_sys_cfg_int(CFG_KEY, "iSimYield", m_cfg.iSimYield); } if (pcfg->iSimCT != m_cfg.iSimCT) {//模拟机台CT m_cfg.iSimCT = pcfg->iSimCT; modify_sys_cfg_int(CFG_KEY, "iSimCT", m_cfg.iSimCT); } if (pcfg->bSimTest1 != m_cfg.bSimTest1) { m_cfg.bSimTest1 = pcfg->bSimTest1; modify_sys_cfg_int(CFG_KEY, "bSimTest1", m_cfg.bSimTest1); m_cfg.bSimTest1 ? m_psimTest[0]->Init() : m_psimTest[0]->Deinit(); } if (pcfg->bSimTest2 != m_cfg.bSimTest2) { m_cfg.bSimTest2 = pcfg->bSimTest2; modify_sys_cfg_int(CFG_KEY, "bSimTest2", m_cfg.bSimTest2); m_cfg.bSimTest2 ? m_psimTest[1]->Init() : m_psimTest[1]->Deinit(); } if (pcfg->bSimTest3 != m_cfg.bSimTest3) { m_cfg.bSimTest3 = pcfg->bSimTest3; modify_sys_cfg_int(CFG_KEY, "bSimTest3", m_cfg.bSimTest3); m_cfg.bSimTest3 ? m_psimTest[2]->Init() : m_psimTest[2]->Deinit(); } if (pcfg->bSimTest4 != m_cfg.bSimTest4) { m_cfg.bSimTest4 = pcfg->bSimTest4; modify_sys_cfg_int(CFG_KEY, "bSimTest4", m_cfg.bSimTest4); m_cfg.bSimTest4 ? m_psimTest[3]->Init() : m_psimTest[3]->Deinit(); } if (pcfg->bSimTest5 != m_cfg.bSimTest5) { m_cfg.bSimTest5 = pcfg->bSimTest5; modify_sys_cfg_int(CFG_KEY, "bSimTest5", m_cfg.bSimTest5); m_cfg.bSimTest5 ? m_psimTest[4]->Init() : m_psimTest[4]->Deinit(); } if (pcfg->bSimTest6 != m_cfg.bSimTest6) { m_cfg.bSimTest6 = pcfg->bSimTest6; modify_sys_cfg_int(CFG_KEY, "bSimTest6", m_cfg.bSimTest6); m_cfg.bSimTest6 ? m_psimTest[5]->Init() : m_psimTest[5]->Deinit(); } return 0; } void CManage::MakeInput() {//生成进料盘 TMatrixInfo mat; sys_EnterCriticalSection(m_hSection); get_matrix_info(LocationInput, &mat); if (IsFourpic()) mat.size *= 4; //1拍4 for (int i = 0; i < mat.size; i++) { MakeProduct(LocationInput, i); } sys_LeaveCriticalSection(m_hSection); } void CManage::Resize(vector& vec, int nsize) {//确保缓冲区够大 for (int i = (int)vec.size(); i < nsize; i++) { vec.push_back(NULL); } } void CManage::MakeProduct(int sindex, int index) {//判断料盘某个位置是否有料?无料则创建一个 vector& vec = m_vecStock[sindex - LocationInput]; Resize(vec, index + 1); if (!vec[index]) vec[index] = new CProduct(sindex); } void CManage::ReleaseProduct(int sindex, int index) {//判断料盘某个位置是否有料?有料则释放 vector& vec = m_vecStock[sindex - LocationInput]; ZERO_CHK(index < (int)vec.size()); ZERO_CHK(vec[index]); FreeProduct(vec[index]); vec[index] = NULL; } CProduct* CManage::GetFromInput() {//从进料仓获取物料 int index = 0; TMatrixInfo mat; TMatrixNode node; CProduct* p = NULL; vector& vec = m_vecStock[LocationInput - LocationInput]; index = m_pCastoff->geti(); if (index > 0) {//传入index m_pCastoff->seti(0); get_matrix_info(LocationInput, &mat); get_matrix_cur_node(LocationInput, &node); if (IsFourpic()) {//4次拍照 index依次传入1234 对应位置位左上、右上、左下、右下 index = (node.col - 1) * 2 + (node.row - 1) * 2 * mat.col * 2 + ((index - 1) / 2) * mat.col * 2 + (index - 1) % 2 + 1; } else index = node.index; //不是1拍4则直接获取当前料盘索引 } else index = GetPosxy(LocationInput); //从上次取料位置获取 if (index > 0 && index <= (int)vec.size() && vec[index - 1]) {//索引有效,且有值 p = vec[index - 1]; vec[index - 1] = NULL; p->Clear(); //return p; } else p = new CProduct(); p->data.takeIndex = index; return p; } void CManage::PutToStock(int sindex, CProduct* p) {//放入料仓 -- sindex != LocationInput int index = 0; TMatrixNode node; vector& vec = m_vecStock[sindex - LocationInput]; m_pOutput->seti(m_pOutput->geti() + 1); //计数+1 p->data.pos = (EMapPos)sindex; index = GetPosxy(sindex); if (0 == index) {//无效值 get_matrix_cur_node(sindex, &node); index = node.index; } if (0 == index) index = 1; //为什么会运行这一步? Resize(vec, index); //确保vec[index-1]可以访问 FreeProduct(vec[index - 1]); //若有,则释放 vec[index - 1] = p; p->data.index = index; //赋值索引 } int CManage::SetPosxy(int sindex) {//posget sindex 获取拍照数据 变量res=0标识获取成功,拍照补偿写入(sn,x,y)。否则标识要拍照获取数据 TPosxy* p = NULL; RETURN_CHK_NOPRT(sindex >= LocationInput && sindex <= LocationNg3, ERR_INPUT_PARAM); list& lst = m_lst_pos[sindex - LocationInput]; sys_EnterCriticalSection(m_hSection); if (!lst.empty()) {//队列有值 p = lst.front(); lst.pop_front(); if (IsSavePos()) m_lst_posTmp[sindex - LocationInput].push_back(p); } else RestorePos(sindex); //恢复 sys_LeaveCriticalSection(m_hSection); if (p) {//有位置 set_var("sn", p->sn); set_int_var("res", 0); set_double_var("x", p->x); set_double_var("y", p->y); m_lst_index[sindex - LocationInput] = p->index; if (!IsSavePos()) delete p; } else {//is null set_var("sn", ""); set_int_var("res", -1); set_double_var("x", 0); set_double_var("y", 0); } return 0; } int CManage::GetPosxy(int sindex) {//获取上一次获取位置时的索引 -- 并重置 int index = 0; RETURN_CHK_NOPRT(sindex >= LocationInput && sindex <= LocationNg3, 0); index = m_lst_index[sindex - LocationInput]; m_lst_index[sindex - LocationInput] = 0; return index; } /* int CManage::GetPosxy(int sindex) {//获取位置索引,并从队列删除 int index = 0; TPosxy* p = NULL; RETURN_CHK_NOPRT(sindex >= LocationInput && sindex <= LocationNg3, 0); list& lst = m_lst_pos[sindex - LocationInput]; sys_EnterCriticalSection(m_hSection); if (!lst.empty()) { p = lst.front(); lst.pop_front(); if (IsSavePos()) m_lst_posTmp[sindex - LocationInput].push_back(p); } sys_LeaveCriticalSection(m_hSection); RETURN_CHK_NOPRT(p, 0); index = p->index; if (!IsSavePos()) delete p; return index; } */ void CManage::RestorePos(int sindex) {//从tmp队列恢复到主队列 TPosxy* p = NULL; list& lst = m_lst_pos[sindex - LocationInput]; list& lstT = m_lst_posTmp[sindex - LocationInput]; //sys_EnterCriticalSection(m_hSection); while (!lstT.empty()) { lst.push_back(lstT.front()); lstT.pop_front(); } //sys_LeaveCriticalSection(m_hSection); } int CManage::PosMap(int sindex) {//posmap sindex 通过3点数据计算矩阵 int col = 0; int row = 0; TMatrixInfo mat; TPosxy* p = NULL; TPosxy* p1 = NULL; TPosxy* p2 = NULL; TPosxy* p3 = NULL; double offsetc = 0; double offsetr = 0; RETURN_CHK_NOPRT(sindex >= LocationInput && sindex <= LocationNg3, ERR_INPUT_PARAM); list& lst = m_lst_pos[sindex - LocationInput]; sys_EnterCriticalSection(m_hSection); if (lst.size() != 3) {//必须是3组数据 sys_LeaveCriticalSection(m_hSection); return ERR_INPUT_PARAM; } p1 = lst.front(); lst.pop_front(); p2 = lst.front(); lst.pop_front(); p3 = lst.front(); lst.pop_front(); ReleasePosxy(sindex); //释放队列 get_matrix_info(sindex, &mat); if (IsFourpic() && LocationInput == sindex) {//一次拍4个 mat.row *= 2; mat.col *= 2; mat.size *= 4; } for (int i = 0; i < mat.size; i++) {//生成阵列 //memset(p, 0, sizeof(TPosxy)); p = new TPosxy; p->index = i + 1; col = i % mat.col; row = i / mat.col; //计算x轴 offsetc = mat.col > 1 ? (p2->x - p1->x) / (mat.col - 1) : 0.0f; offsetr = mat.row > 1 ? (p3->x - p1->x) / (mat.row - 1) : 0.0f; p->x = p1->x + offsetc * col + offsetr * row; //计算y轴 offsetc = mat.col > 1 ? (p2->y - p1->y) / (mat.col - 1) : 0.0f; offsetr = mat.row > 1 ? (p3->y - p1->y) / (mat.row - 1) : 0.0f; p->y = p1->y + offsetc * col + offsetr * row; lst.push_back(p); } delete p1; delete p2; delete p3; sys_LeaveCriticalSection(m_hSection); return 0; } int CManage::ReleasePosxy(int sindex) { RETURN_CHK_NOPRT(sindex >= LocationInput && sindex <= LocationNg3, ERR_INPUT_PARAM); list& lst = m_lst_pos[sindex - LocationInput]; list& lstT = m_lst_posTmp[sindex - LocationInput]; sys_EnterCriticalSection(m_hSection); while (!lst.empty()) {//释放主队列 FREE_ANY(lst.front()); lst.pop_front(); } while (!lstT.empty()) {//释放缓冲区 FREE_ANY(lstT.front()); lstT.pop_front(); } m_lst_index[sindex - LocationInput] = 0; //置0 if (LocationInput == sindex && m_pCastoff) m_pCastoff->seti(0); //变量标识清零 sys_LeaveCriticalSection(m_hSection); return 0; } void CManage::Release() {//释放内存 vector::iterator it; for (int i = 0; i < STOCKCNT; i++) {//释放数据 ReleasePosxy(i + LocationInput); for (it = m_vecStock[i].begin(); it != m_vecStock[i].end(); it++) {//释放 FreeProduct(*it); } m_vecStock[i].clear(); } for(auto it = m_hash_lst.begin(); it != m_hash_lst.end(); it++) {//释放map表里面剩余的数据,一般到这都是空列表了 delete it->second; } m_hash_lst.clear(); } void CManage::ReadConfig() { const char* ptmp = NULL; ptmp = get_cfg(CFG_KEY, "Config"); comm_strncpy(m_cfg.Config, ptmp ? ptmp : CONFIG, MAX_NAME_LEN); ptmp = get_cfg(CFG_KEY, "ConfigD"); comm_strncpy(m_cfg.ConfigD, ptmp ? ptmp : CONFIG, MAX_NAME_LEN); ptmp = get_cfg(CFG_KEY, "lot"); comm_strncpy(m_cfg.lot, ptmp ? ptmp : LOT, MAX_NAME_LEN); ptmp = get_cfg(CFG_KEY, "project"); comm_strncpy(m_cfg.project, ptmp ? ptmp : PRONA, MAX_NAME_LEN); ptmp = get_cfg(CFG_KEY, "sublotname"); comm_strncpy(m_cfg.sublotname, ptmp ? ptmp : SUBLOT, MAX_NAME_LEN); ptmp = get_cfg(CFG_KEY, "bFourPic"); m_cfg.bFourPic = ptmp ? atoi(ptmp) : 1; //默认1拍4 m_pFour->seti(m_cfg.bFourPic ? 4 : 1); ptmp = get_cfg(CFG_KEY, "bSavePos"); m_cfg.bSavePos = ptmp ? atoi(ptmp) : 1; //默认缓存位置 //以下项使用系统配置,不跟随产品变化 ptmp = get_sys_cfg(CFG_KEY, "sitel"); comm_strncpy(m_cfg.sitel, ptmp ? ptmp : SITEL, MAX_NAME_LEN); ptmp = get_sys_cfg(CFG_KEY, "BinA"); comm_strncpy(m_cfg.BinA, ptmp ? ptmp : BINA, MAX_NAME_LEN); ptmp = get_sys_cfg(CFG_KEY, "serverip"); strcpy(m_cfg.serverip, chk_ipaddress(ptmp) ? ptmp : ANY_IP); ptmp = get_sys_cfg(CFG_KEY, "visionip"); strcpy(m_cfg.visionip, chk_ipaddress(ptmp) ? ptmp : "127.0.0.1"); ptmp = get_sys_cfg(CFG_KEY, "machine"); comm_strncpy(m_cfg.machine, ptmp ? ptmp : MACHINE, MAX_NAME_LEN); m_cfg.uphFrequency = get_sys_cfg_int(CFG_KEY, "uphFrequency"); if (m_cfg.uphFrequency < 0 || m_cfg.uphFrequency > 5) m_cfg.uphFrequency = 0; m_cfg.testType = get_sys_cfg_int(CFG_KEY, "testType"); m_cfg.bNodeLog = get_sys_cfg_int(CFG_KEY, "bNodeLog"); m_cfg.bUpMes = get_sys_cfg_int(CFG_KEY, "bUpMes"); m_cfg.bUpMTcp = get_sys_cfg_int(CFG_KEY, "bUpMTcp"); m_cfg.bUpNoise = get_sys_cfg_int(CFG_KEY, "bUpNoise"); m_cfg.bSingleTestFilter = get_sys_cfg_int(CFG_KEY, "bSingleTestFilter"); m_cfg.b2nd = get_sys_cfg_int(CFG_KEY, "b2nd"); m_cfg.bTestlog = get_sys_cfg_int(CFG_KEY, "bTestlog"); m_cfg.bVisionlog = get_sys_cfg_int(CFG_KEY, "bVisionlog"); m_cfg.idualindex = get_int_var("dualtest"); m_cfg.bPassTestB = get_sys_cfg_int(CFG_KEY, "bPassTestB"); m_cfg.bBindB = get_sys_cfg_int(CFG_KEY, "bBindB"); if (m_cfg.idualindex < MINAEND || m_cfg.idualindex > TESTCNT) {//不合法 -- 默认A(1-4) B(5-6) m_cfg.idualindex = TESTCNT; //默认不分组 SetVarInit("dualtest", m_cfg.idualindex); } ptmp = get_sys_cfg(CFG_KEY, "bDirDate"); m_cfg.bDirDate = ptmp ? atoi(ptmp) : 1; //默认要生成日期文件夹 ptmp = get_sys_cfg(CFG_KEY, "iSimYield"); m_cfg.iSimYield = ptmp ? atoi(ptmp) : 100; if (m_cfg.iSimYield < 0 || m_cfg.iSimYield > 100) {//不合法 -- 默认100 m_cfg.iSimYield = 100; modify_sys_cfg_int(CFG_KEY, "iSimYield", m_cfg.iSimYield); } ptmp = get_sys_cfg(CFG_KEY, "iSimCT"); m_cfg.iSimCT = ptmp ? atoi(ptmp) : 30; if (m_cfg.iSimCT < 5 || m_cfg.iSimCT > 100) {//不合法 -- 默认30 m_cfg.iSimCT = 30; modify_sys_cfg_int(CFG_KEY, "iSimCT", m_cfg.iSimCT); } m_cfg.bSimTest1 = get_sys_cfg_int(CFG_KEY, "bSimTest1"); m_cfg.bSimTest2 = get_sys_cfg_int(CFG_KEY, "bSimTest2"); m_cfg.bSimTest3 = get_sys_cfg_int(CFG_KEY, "bSimTest3"); m_cfg.bSimTest4 = get_sys_cfg_int(CFG_KEY, "bSimTest4"); m_cfg.bSimTest5 = get_sys_cfg_int(CFG_KEY, "bSimTest5"); m_cfg.bSimTest6 = get_sys_cfg_int(CFG_KEY, "bSimTest6"); if (m_cfg.bSimTest1) m_psimTest[0]->Init(); if (m_cfg.bSimTest2) m_psimTest[1]->Init(); if (m_cfg.bSimTest3) m_psimTest[2]->Init(); if (m_cfg.bSimTest4) m_psimTest[3]->Init(); if (m_cfg.bSimTest5) m_psimTest[4]->Init(); if (m_cfg.bSimTest6) m_psimTest[5]->Init(); for (int i = 0; i < EVSize; i++) { m_pVision[i]->Init(m_cfg.visionip, VPORT + i); } m_pVisionTest->Init(m_cfg.visionip, VPORTEST); } int CManage::CreateVar(const char* pszname, const char* pszdesc, int keep) { TVar v; int tid = 0; tid = get_var_id(pszname); RETURN_CHK_NOPRT(tid <= 0, tid); memset(&v, 0, sizeof(v)); strcpy(v.val, "0"); strcpy(v.desc, pszdesc); strcpy(v.name, pszname); v.bkeep = keep; return create_var(&v) ? 0 : v.id; } void CManage::SetVarInit(const char* pszname, int ival) { TVar v; int tid = 0; ipvar* p = NULL; tid = get_var_id(pszname); if (tid <= 0) {//create memset(&v, 0, sizeof(v)); strcpy(v.desc, pszname); strcpy(v.name, pszname); sprintf(v.val, "%d", ival); create_var(&v); } else {//set get_var_info(tid, &v); sprintf(v.val, "%d", ival); update_var(&v); p = get_ipvar(v.id); if (p) p->seti(ival); } } ipvar* CManage::getVar(const char* pszname, const char* pszdesc, bool block) { int tid = 0; ipvar* p = NULL; tid = CreateVar(pszname, pszdesc, 0); p = get_ipvar(tid); RETURN_CHK_NOPRT(p, 0); if (block) p->lock(); //锁定 return p; } ipvar* CManage::getVar(const char* pszname, const char* pszdesc, const char* pszval) { TVar v; ipvar* p = get_ipvars(pszname); if (!p) {//no exist memset(&v, 0, sizeof(v)); strcpy(v.val, pszval); strcpy(v.desc, pszdesc); strcpy(v.name, pszname); create_var(&v); p = get_ipvars(pszname); } if (p) p->lock(); //锁定 return p; } CProduct* CManage::FindProduct(const char* sn) { CProduct* p = NULL; hash_map::iterator it; sys_EnterCriticalSection(m_hSection); it = m_hash_lst.find(sn); if (it != m_hash_lst.end()) { p = it->second; } sys_LeaveCriticalSection(m_hSection); return p; } void CManage::FreeProduct(CProduct* p) { hash_map::iterator it; ZERO_CHK(p); sys_EnterCriticalSection(m_hSection); it = m_hash_lst.find(p->data.sn); if (it != m_hash_lst.end()) { m_hash_lst.erase(it); } sys_LeaveCriticalSection(m_hSection); LOG_INF1("relsease product:%s", p->data.sn); delete p; } int CManage::GreaterThenProduct(const void* a, const void* b) { int ret = 0; const TProduct* info1 = (const TProduct*)a; const TProduct* info2 = (const TProduct*)b; ret = info1->pos - info2->pos; RETURN_CHK_NOPRT(!ret, ret); return strcmp(info1->start, info2->start); } int CManage::GetProductByPos(EMapPos pos, int index, TProduct* pdata/* = 0*/) { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = GetProductByPosB(pos, index, pdata); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::GetProductList(EMapPos pos, TProduct* pdata/* = 0*/, int nsize/* = 0*/) { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = GetProductListB(pos, pdata, nsize); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::GetProductByPosB(EMapPos pos, int index, TProduct* pdata/* = 0*/) { CProduct* p = NULL; switch (pos) { case LocationVacm: RETURN_CHK_NOPRT(index > 0 && index <= m_vacm_cnt, ERR_INPUT_PARAM); p = m_vacm_lst[index-1]; break; case LocationTest: RETURN_CHK_NOPRT(index > 0 && index <= TESTCNT, ERR_INPUT_PARAM); p = m_ptest[index - 1]->getProduct(); break; default: RETURN_CHK_NOPRT(index > 0 && index <= (int)m_vecStock[pos - LocationInput].size(), ERR_INPUT_PARAM); p = m_vecStock[pos - LocationInput][index - 1]; break; } RETURN_CHK_NOPRT(p, ERR_INPUT_PARAM); if (pdata) memcpy(pdata, &p->data, sizeof(TProduct)); return 0; } int CManage::GetProductListB(EMapPos pos, TProduct* pdata/* = 0*/, int nsize/* = 0*/) { int ncnt = 0; switch (pos) { case LocationVacm: for(int i = 0; i < m_vacm_cnt; i++) {//遍历吸嘴 if (!m_vacm_lst[i]) continue; if (pdata) { if (ncnt >= nsize) return ncnt; memcpy(pdata++, &m_vacm_lst[i]->data, sizeof(TProduct)); } ncnt++; } break; case LocationTest: for(int i = 0; i < TESTCNT; i++) {//遍历治具产品 if (!m_ptest[i]->getProduct()) continue; if (pdata) { if (ncnt >= nsize) return ncnt; memcpy(pdata++, &m_ptest[i]->getProduct()->data, sizeof(TProduct)); } ncnt++; } break; default: vector& lst = m_vecStock[pos - LocationInput]; for(int i = 0; i < (int)lst.size(); i++) {//遍历其它料仓 if (!lst[i]) continue; if (pdata) { if (ncnt >= nsize) return ncnt; memcpy(pdata++, &lst[i]->data, sizeof(TProduct)); } ncnt++; } break; } return ncnt; } int CManage::GetProduct(const char* sn, TProduct* pdata) { int ret = ERR_INVALID_ID; hash_map::iterator it; RETURN_CHK_NOPRT(sn && *sn && pdata, ERR_INPUT_PARAM); sys_EnterCriticalSection(m_hSection); it = m_hash_lst.find(sn); if (it != m_hash_lst.end()) { ret = 0; memcpy(pdata, &it->second->data, sizeof(TProduct)); } sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::GetAllProduct(TProduct* pdata/* = 0*/, int nsize/* = 0*/) { int index = 0; int ncount = 0; hash_map::iterator it; sys_EnterCriticalSection(m_hSection); ncount = (int)m_hash_lst.size(); if (pdata) {//需要获取 if (ncount > nsize) ncount = nsize; for(it = m_hash_lst.begin(); it != m_hash_lst.end(); it++) { if (index >= ncount) break; memcpy(&pdata[index++], &it->second->data, sizeof(TProduct)); } qsort(pdata, ncount, sizeof(TProduct), CManage::GreaterThenProduct); } sys_LeaveCriticalSection(m_hSection); return ncount; } int CManage::GetMachine(int index, TestMachine* pdata) { RETURN_CHK_NOPRT(pdata && index > 0 && index <= TESTCNT, ERR_INPUT_PARAM); memcpy(pdata, &m_ptest[index-1]->_data, sizeof(TestMachine)); //strcpy(pdata->sn, m_ptest[index-1]->_p ? _p) return 0; } int CManage::TestEnable(int index, int benable) { RETURN_CHK_NOPRT(index > 0 && index <= TESTCNT, ERR_INPUT_PARAM); m_ptest[index-1]->_data.benable = benable; return 0; } int CManage::TestDebug(int index, const char* sn) { int ret = 0; ret = TakeFromInput(sn, 1); //默认从1号吸嘴 RETURN_CHK_NOPRT(!ret, ret); return MovetoTest(1, index); } int CManage::TestHome(int testIndex) { RETURN_CHK_NOPRT(testIndex > 0 && testIndex <= TESTCNT, ERR_INPUT_PARAM); return m_ptest[testIndex - 1]->Home(); } int CManage::TestReset(int testIndex) { RETURN_CHK_NOPRT(testIndex > 0 && testIndex <= TESTCNT, ERR_INPUT_PARAM); return m_ptest[testIndex - 1]->Reset(); } int CManage::TestClear(int testIndex) { RETURN_CHK_NOPRT(testIndex > 0 && testIndex <= TESTCNT, ERR_INPUT_PARAM); m_ptest[testIndex - 1]->resetCounter(); return 0; } int CManage::TestPause(int testIndex, int bpause) { RETURN_CHK_NOPRT(testIndex > 0 && testIndex <= TESTCNT, ERR_INPUT_PARAM); return m_ptest[testIndex - 1]->Pause(bpause); } int CManage::GripEnable(int testIndex, int benable) { RETURN_CHK_NOPRT(testIndex > 0 && testIndex <= TESTCNT, ERR_INPUT_PARAM); return m_ptest[testIndex - 1]->EnableGrip(benable); } int CManage::M1B() { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = M1(); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::M2B() { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = M2(); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::VacmResetB() { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = VacmReset(); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::StockResetB(int sindex) { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = StockReset(sindex); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::VacmTakeB() { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = VacmTake(); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::TestPutB() { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = TestPut(); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::TestTakeB() { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = TestTake(); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::StockPutB() { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = StockPut(); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::WhereToGoB() { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = WhereToGo(); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::CreateProductB(const char* sn, int vacmIndex) { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = TakeFromInput(sn, vacmIndex); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::MovetoVacmB(int testIndex, int vacmIndex) { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = MovetoVacm(testIndex, vacmIndex); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::MovetoStockB(int vacmIndex, int sindex) { int ret = 0; sys_EnterCriticalSection(m_hSection); ret = MovetoStock(vacmIndex, sindex); sys_LeaveCriticalSection(m_hSection); return ret; } int CManage::StartRun() {//任务开始 RETURN_CHK_NOPRT(!m_brun, 0); m_brun = true; m_hThread = sys_CreateThread(ThreadFun, this); return 0; } int CManage::StopRun() {//关闭任务 RETURN_CHK_NOPRT(m_brun, 0); m_brun = false; sys_WaitForSingleObject(m_hThread); sys_CloseHandle(m_hThread); return 0; } int CManage::GetTestIndex(const char* ate) {//通过编码查找测试机台序号 for(int i = 0; i < TESTCNT; i++) { if (0 == strcmp(m_ptest[i]->_data.ate, ate)) { return i + 1; } } return 0; } int WINAPI CManage::ThreadFun(void* param) { CManage* p = (CManage*)param; return p->Process(); } int CManage::Process() { //ulong ct1, ct2; while(m_brun) {//循环 CalcUph(); //计算uph //ct1 = sys_GetTickCount(); AcceptNew(); //等待新连接 //ct2 = sys_GetTickCount(); //if (ct2 > ct1) REPORT("AcceptNew ct: %dms", ct2 - ct1); ProcessMsg(); //消息处理 //ct1 = sys_GetTickCount() - ct2; //if ((ct1 > 0 && ct1 < 50) || ct1 > 110) REPORT("ProcessMsg ct: %dms", ct1); //UploadReport(); //ct2 = sys_GetTickCount(); //if (ct2 > ct1) REPORT("UploadReport ct: %dms", ct2 - ct1); UpdateVarProduct(); } return 0; } #define TMIN 1 //间隔多少分钟检测一次 static const int tmin[] = { 1, 2, 5, 6, 10, 20 }; void CManage::CalcUph() {//计算uph ulong wkc = 0; ulong total = 0; ulong cur = sys_GetTickCount(); ulong imin = tmin[m_cfg.uphFrequency]; static ulong lct = cur; //计时 static ulong alltm = 0; //总时间 static ulong lastotal = 0; //最后产量记录 ZERO_CHK(cur >= lct + imin * 60000); lct = cur; alltm += imin; //总时间 total = m_pOutput->geti(); wkc = total - lastotal; //此次产量多高? lastotal = total; m_pUph->seti(wkc * 60 / imin); m_pAllUph->seti(total * 60 / alltm); } void CManage::UploadReport() {//把日志传给UI char* pmsg = NULL; sys_EnterCriticalSection(m_hSection); if (!m_lsgMsg.empty()) {//非空 pmsg = m_lsgMsg.front(); m_lsgMsg.pop_front(); } sys_LeaveCriticalSection(m_hSection); if (pmsg) {//send send_messages(MSG_ASCII, pmsg); delete pmsg; } } void CManage::AcceptNew() {//等待连接 if (m_pconn->IsNormal()) {//已连接且已注册 *m_ptest[m_pconn->getIndex()-1] = *m_pconn; //赋值到对应位置 } ZERO_CHK(!m_pconn->IsConn()); if (!m_pconn->IsOpen()) {//打开 m_pconn->Open(m_cfg.serverip); } m_pconn->Connect(); //触发连接 } bool CManage::ChkAteValid(int index, const char* pszate) {//检测治具编码是否重复 for (int i = 0; i < TESTCNT; i++) { if (i + 1 == index) continue; if (!m_ptest[i]->IsNormal()) continue; if (!stricmp(pszate, m_ptest[i]->_data.ate)) return false; } return true; } static const char* psztgr[] = { "M1", "M2", "M3", "M4", "M5", "M6" }; int CManage::SendTestGR(int tindex, const char* s) { TOpsCfg cfg; char buff[1024] = { 0 }; RETURN_CHK_NOPRT(tindex > 0 && tindex <= TESTCNT, ERR_INPUT_PARAM); ops_get_cfg(&cfg); if (cfg.offVision) {//禁用视觉 return PostReplyGR(tindex, "0,1"); //return m_ptest[tindex - 1]->SendGR("0,1"); } if (s && *s) {//有附加参数 sprintf(buff, "%s,%s", psztgr[tindex - 1], s); s = buff; } else s = psztgr[tindex - 1]; return m_pVisionTest->Send(s); } int CManage::PostReplyGR(int tindex, const char* s) { TGRMsg* pmsg = NULL; RETURN_CHK_NOPRT(s && *s, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(tindex > 0 && tindex <= TESTCNT, ERR_INPUT_PARAM); pmsg = new TGRMsg; pmsg->tindex = tindex; pmsg->s = new char[strlen(s) + 1]; comm_strcpy(pmsg->s, s); sys_EnterCriticalSection(m_hSection); m_tstMsg.push_back(pmsg); if (!m_tstRun) {//启动线程 m_tstRun = true; pool_thread(PoolGR, this); } sys_LeaveCriticalSection(m_hSection); return 0; } void CManage::ProcessSendGR() {//线程池执行 int ret = 0; TGRMsg* pmsg = NULL; while (1) { sys_EnterCriticalSection(m_hSection); if (m_tstMsg.empty()) {//null m_tstRun = false; sys_LeaveCriticalSection(m_hSection); break; } pmsg = m_tstMsg.front(); m_tstMsg.pop_front(); sys_LeaveCriticalSection(m_hSection); ret = m_ptest[pmsg->tindex - 1]->SendGR(pmsg->s); //发送 if (ret) { LOG_ERR("test(%d) send:%s ERROR.", pmsg->tindex, pmsg->s); } delete pmsg->s; delete pmsg; } } int WINAPI CManage::PoolGR(void* lparam) { ((CManage*)lparam)->ProcessSendGR(); return 0; } void CManage::RecvTestMsg() { char* pcmd = NULL; char* ptmp = NULL; char* pnext = NULL; char msg[1024] = { 0 }; m_pVisionTest->RecvMsg(msg, 1024); ZERO_CHK(msg[0]); pnext = msg; while (1) {//可能有多条消息 ptmp = sys_strtok(NULL, ";", &pnext); if (0 == ptmp || 0 == *ptmp) break; pcmd = sys_strtok(NULL, ",", &ptmp); for (int i = 0; i < TESTCNT; i++) { if (!stricmp(pcmd, psztgr[i])) {//find tindex //m_ptest[i]->SendGR(ptmp); ins->PostReplyGR(i + 1, ptmp); break; } } } } void CManage::ProcessMsg() {//消息处理 int ret = 0; int index = 0; vector s; vector si; if (m_pconn->IsConn()) {//处理其它事务,例如注册 m_pconn->Process(); if (m_pconn->IsConn()) {//process有可能断开连接 si.push_back(0); //序号0 s.push_back(m_pconn->getSocket()); } } //视觉检测 index++; if (!m_pVisionTest->IsConn()) m_pVisionTest->Connect(); if (m_pVisionTest->IsConn()) { si.push_back(1); //序号1 s.push_back(m_pVisionTest->getSocket()); } index++; for (int i = 0; i < EVSize; i++) { if (!m_pVision[i]->IsConn()) m_pVision[i]->Connect(); if (m_pVision[i]->IsConn()) { si.push_back(i + index); //前面有2个固定位 s.push_back(m_pVision[i]->getSocket()); } } index += EVSize; for(int i = 0; i < TESTCNT; i++) {//遍历处理 if (m_ptest[i]->IsConn()) {//process处理 m_ptest[i]->Process(); if (m_ptest[i]->IsConn()) {//process有可能断开连接 si.push_back(i + index); s.push_back(m_ptest[i]->getSocket()); } } } if (s.size() == 0) {//没有连接对象 sys_Sleep(50); return; } ret = sys_Select(&s[0], (int)s.size(), 100); ZERO_CHK(ret >= 0); ret = si[ret]; //获取序号 if (0 == ret) {//等待连接测试治具 m_pconn->RecvMsg(); return; } if (1 == ret) {//侧相机 RecvTestMsg(); return; } if (ret < index) {//其它视觉对象 m_pVision[ret-2]->RecvMsg(); return; } //测试治具通信 //ulong ct1 = sys_GetTickCount(); m_ptest[ret - index]->RecvMsg(); //ulong ct2 = sys_GetTickCount(); //if (ct2 > ct1) REPORT("test(%d) msg ct: %dms", ret - index, ct2 - ct1); } static const char* _pszcmddesc = "业务模块自定义消息格式.\n" "\n发送消息格式:\n\n\n" "M1 通知取料仓拍照,并返回拍照结果\n\n" "M2 通知搬运模组拍照,并返回拍照结果\n\n" "M3 通知OK仓拍照,并返回拍照结果\n\n" "M4 通知NG仓拍照,并返回拍照结果\n\n" "M5 通知NG取一拍一模式拍照,并返回拍照结果\n\n" "M6 通知NG放一拍一模式拍照,并返回拍照结果\n\n" "M7 通知治具取料模式拍照,并返回拍照结果\n\n" "M8 通知治具放料模式拍照,并返回拍照结果\n\n" "MT tindex [sn] 模拟治具发送侧相机处理请求\n\n" "vacmreset 通知释放吸嘴产品数据\n\n" "makeinput 模拟生成进料盘数据\n\n" "posreset sindex 通知释放拍照数据 sindex料仓编号[1-5]\n\n" "posget sindex 获取拍照取料位置数据写入变量 res=0标识获取成功,否则标识要拍照获取数据.取料信息写入(sn,x,y)\n\n" "posset sindex index sn x y 将拍照数据暂存起来,sindex料仓编号[1-5] index数据编号[1-4] sn二维码 x,y基于相机的坐标值\n\n" "posmap sindex 拍照3次(左上、右上、左下)后,此指令可计算矩阵,生成料盘位置数据.\n\n" "clear tindex 清空治具统计参数 tindex治具编号[1-6]\n\n" "home tindex 通知治具回原 tindex治具编号[1-6]\n\n" "reset tindex 通知治具复位 tindex治具编号[1-6]\n\n" "pause tindex flag 通知治具暂停 tindex治具编号[1-6] flag 1暂停 0暂停取消\n\n" "grip tindex 1/0 通知治具控制夹爪 tindex治具编号[1-6] 1夹紧 0松开\n\n" "status tindex a 设置治具状态更新到某个变量 tindex治具编号[1-6] a变量名\n\n" "sim tindex bsim 打开/关闭模拟治具 tindex治具编号[1-6] bsim 1打开模拟 0关闭模拟\n\n" "stockreset sindex 通知释放料盘产品数据 sindex料仓编号[1-5]\n\n" "where 通知设置当前是给治具换料还是放料到料仓,设置到变量't'中,0标识放料到料仓,[1-6]标识给治具换料\n\n" "vacmtake 通知设置需要取料的吸嘴编号为0时无效,设置到变量'v'中\n\n" "testput 通知设置需要进入治具的吸嘴编号->'v',治具编号->'t',为0时无效\n\n" "testake 通知设置需要从治具取料的吸嘴编号->'v',治具编号->'t',为0时无效\n\n" "stockput 通知设置需要放回料仓的吸嘴编号->'v',料仓编号[2-5]->'t',为0时无效\n\n" "create sn vindex 从进料仓到吸嘴,并创建产品资料 vindex吸嘴编号\n\n" "vacm_to_test vindex tindex 变更产品位置,从吸嘴到测试治具并开始测试 vindex吸嘴编号 tindex治具编号\n\n" "test_to_vacm tindex vindex 变更产品位置,从测试治具到吸嘴 tindex治具编号 vindex吸嘴编号\n\n" "vacm_to_stock vindex sindex 变更产品位置,从吸嘴到料仓 vindex吸嘴编号 sindex料仓编号[2-5]\n\n" "\n接收消息(\"msg\"格式):\n\n\n" "waitOk tindex 等待测试治具就绪,当状态就绪时,返回0,否则返回超时\n\n" "WaitM1 接收进料仓拍照处理结果,消息返回格式:res,sn,x,y res=0标识成功\n\n" "WaitM2 sindex sindex料仓编号[1-5] 等待搬运模组拍照处理结果,自动刷新产品标识到数组中,消息返回格式:res 0标识成功\n\n" "WaitM3 接收OK仓拍照结果,消息返回格式:res,x,y res=0标识成功\n\n" "WaitM4 接收NG仓拍照结果,消息返回格式:res,x,y res=0标识成功\n\n" "WaitM5 接收NG取一拍一拍照结果,消息返回格式:res,x,y res=0标识成功\n\n" "WaitM6 接收NG放一拍一拍照结果,消息返回格式:res,x,y res=0标识成功\n\n" "WaitM7 接收治具取料拍照结果,消息返回格式:res,x,y res=0标识成功\n\n" "WaitM8 接收治具放料拍照结果,消息返回格式:res,x,y res=0标识成功\n\n" "uploadnoreset 给治具上料的顺序复位,从第一个治具开始上料\n\n" ; int CManage::GetCommandDesc(char* pszcmddesc) { int len = (int)strlen(_pszcmddesc); if (!pszcmddesc) return len; comm_strcpy(pszcmddesc, _pszcmddesc); return len; } int CManage::SendCustomCmd(const char* msg, char* res) { int tmp = 0; char* pcmd = NULL; char* ptmp = NULL; char buff[MAX_BUF_LEN] = {0}; RETURN_CHK_NOPRT(msg && *msg, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(strlen(msg) < MAX_BUF_LEN, ERR_INPUT_PARAM); strcpy(buff, msg); ptmp = sys_strtok(buff, " ", &pcmd); if (!strcmp("test", ptmp)) {//测试接口 return Test(pcmd); } if (!strcmp("sim", ptmp)) {//清空吸嘴数据 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return SimTest(atoi(ptmp), atoi(pcmd)); } if (!strcmp("M1", ptmp)) {//取料拍照 return M1(); } if (!strcmp("M2", ptmp)) {//搬运拍照 return M2(); } if (!strcmp("M3", ptmp)) {//OK拍照 return M3(); } if (!strcmp("M4", ptmp)) {//NG拍照 return M4(); } if (!strcmp("M5", ptmp)) {//NG取一拍一 return M5(); } if (!strcmp("M6", ptmp)) {//NG放一拍一 return M6(); } if (!strcmp("M7", ptmp)) {//治具取 return M7(); } if (!strcmp("M8", ptmp)) {//治具放 return M8(); } if (!strcmp("MT", ptmp)) {//治具侧相机 RETURN_CHK_NOPRT(pcmd, ERR_INPUT_PARAM); trim_char(pcmd); ptmp = sys_strtok(NULL, " ", &pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); return SendTestGR(atoi(ptmp), pcmd); } if (!strcmp("vacmreset", ptmp)) {//清空吸嘴数据 return VacmResetB(); } if (!strcmp("makeinput", ptmp)) {//模拟进料盘数据 MakeInput(); return 0; } if (!strcmp("stockreset", ptmp)) {//清空料盘数据 if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return StockResetB(atoi(pcmd)); } if (!strcmp("posreset", ptmp)) {//清空拍照数据 if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return ReleasePosxy(atoi(pcmd)); } if (!strcmp("posget", ptmp)) {//获取拍照数据 if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return SetPosxy(atoi(pcmd));; } if (!strcmp("posmap", ptmp)) {//通过3点数据计算矩阵 if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return PosMap(atoi(pcmd));; } if (!strcmp("posset", ptmp)) {//保存拍照数据 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); return SetPosxy(atoi(ptmp), pcmd); } if (!strcmp("where", ptmp)) {//去哪? return WhereToGoB(); } if (!strcmp("vacmtake", ptmp)) {//设置取料吸嘴编号 return VacmTakeB(); } if (!strcmp("testput", ptmp)) {//设置放治具测试编号 return TestPutB(); } if (!strcmp("testake", ptmp)) {//设置取治具测试编号 return TestTakeB(); } if (!strcmp("stockput", ptmp)) {//设置放料仓 return StockPutB(); } if (!stricmp("home", ptmp)) {//控制回原 if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return TestHome(atoi(pcmd)); } if (!stricmp("reset", ptmp)) {//控制复位 if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return TestReset(atoi(pcmd)); } if (!stricmp("clear", ptmp)) {//控制重置统计 if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return TestClear(atoi(pcmd)); } if (!stricmp("grip", ptmp)) {//控制夹爪 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return GripEnable(atoi(ptmp), atoi(pcmd)); } if (!stricmp("pause", ptmp)) {//控制治具暂停 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return TestPause(atoi(ptmp), atoi(pcmd)); } if (!strcmp("create", ptmp)) {//进料仓到吸嘴 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return CreateProductB(ptmp, atoi(pcmd)); } if (!strcmp("vacm_to_test", ptmp)) {//吸嘴到测试治具 WriteLog("manager.txt", "%s", "vacm_to_test-->start"); ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return MovetoTest(atoi(ptmp), atoi(pcmd)); } if (!strcmp("test_to_vacm", ptmp)) {//测试治具到吸嘴 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return MovetoVacmB(atoi(ptmp), atoi(pcmd)); } if (!strcmp("vacm_to_stock", ptmp)) {//吸嘴到料仓 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return MovetoStockB(atoi(ptmp), atoi(pcmd)); } if (!strcmp("status", ptmp)) {//设置治具状态到变量 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp) && pcmd, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(get_var_id(pcmd) > 0, ERR_INPUT_PARAM); tmp = atoi(ptmp); RETURN_CHK_NOPRT(tmp > 0 && tmp <= TESTCNT, ERR_INPUT_PARAM); return m_ptest[tmp-1]->SetVarStatus(pcmd); } if (!strcmp("test_debug", ptmp)) {//吸嘴到测试治具 ptmp = sys_strtok(NULL, " ", &pcmd); if (ptmp) trim_char(ptmp); if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp) && pcmd, ERR_INPUT_PARAM); return TestDebug(atoi(ptmp), pcmd); } if (!strcmp("uploadnoreset", ptmp)) { m_prePut = 0; return 0; } return ERR_INPUT_PARAM; } int CManage::RecvCustomCmd(const char* msg, char* res, int timeout/* = 0*/) { char* pcmd = NULL; char* ptmp = NULL; char buff[MAX_BUF_LEN] = {0}; RETURN_CHK_NOPRT(res && msg && *msg, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(strlen(msg) < MAX_BUF_LEN, ERR_INPUT_PARAM); if (!strcmp("WaitM1", msg)) {//等待拍照结果 return m_pVision[EVInput]->WaitResult(res, timeout); } if (!strcmp("WaitM3", msg)) {//等待拍照结果 return m_pVision[EVOkTray]->WaitResult(res, timeout); } if (!strcmp("WaitM4", msg)) {//等待拍照结果 return m_pVision[EVNGTray]->WaitResult(res, timeout); } if (!strcmp("WaitM5", msg)) {//NG取一拍一拍照结果 return m_pVision[EVNGTakeOne]->WaitResult(res, timeout); } if (!strcmp("WaitM6", msg)) {//NG放一拍一拍照结果 return m_pVision[EVNGPutOne]->WaitResult(res, timeout); } if (!strcmp("WaitM7", msg)) {//治具取料拍照结果 return m_pVision[EVTestTake]->WaitResult(res, timeout); } if (!strcmp("WaitM8", msg)) {//治具放料拍照结果 return m_pVision[EVTestPut]->WaitResult(res, timeout); } strcpy(buff, msg); ptmp = sys_strtok(buff, " ", &pcmd); //waitOk tindex 等待测试治具就绪,当状态就绪时,返回0,否则返回超时 if (!strcmp("waitOk", ptmp)) {//等待测试治具ok if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return WaitTestIdle(atoi(pcmd), timeout); } if (!strcmp("WaitM2", ptmp)) {//等待拍照结果 if (pcmd) trim_char(pcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pcmd), ERR_INPUT_PARAM); return WaitM2Result(atoi(pcmd), res, timeout); } return ERR_INPUT_PARAM; } void CManage::Report(const char *pszFormat, ...) { va_list args; int nWrite = 0; char* pmsg = NULL; char buff[1024] = { 0 }; ZERO_CHK(pszFormat); va_start(args, pszFormat); nWrite = vsprintf(buff, pszFormat, args); va_end(args); ZERO_CHK(nWrite > 0 && nWrite < MAX_BUF_LEN); pmsg = new char[nWrite + 1]; comm_strcpy(pmsg, buff); sys_EnterCriticalSection(m_hSection); m_lsgMsg.push_back(pmsg); sys_LeaveCriticalSection(m_hSection); } int WINAPI ThreadPostWarn(void* param) { char* pmsg = (char*)param; send_messages(MSG_WARN, pmsg); delete pmsg; return 0; } void CManage::PostWarn(const char *pszFormat, ...) { va_list args; int nWrite = 0; char* pmsg = NULL; char buff[1024] = { 0 }; ZERO_CHK(pszFormat); va_start(args, pszFormat); nWrite = vsprintf(buff, pszFormat, args); va_end(args); ZERO_CHK(nWrite > 0 && nWrite < MAX_BUF_LEN); pmsg = new char[nWrite + 1]; comm_strcpy(pmsg, buff); pool_thread(ThreadPostWarn, pmsg); } void CManage::WriteLog(const char* filename, const char* pszFormat, ...) { if (this->testLog()) { sys_EnterCriticalSection(m_hSection); time_t now = time(0); tm *ltm = localtime(&now); int year = ltm->tm_year + 1900; int month = ltm->tm_mon + 1; int day = ltm->tm_mday; int hour = ltm->tm_hour; int min = ltm->tm_min; int sec = ltm->tm_sec; char sztime[64] = { 0 }; sprintf(sztime, "%d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec); char date[64] = { 0 }; char filedir[256] = { 0 }; char filepath[256] = { 0 }; char pszcontent[2048] = { 0 }; sprintf(date, "%d%02d%02d", year, month, day); sprintf(filedir, "d:\\log\\updown\\%s", date); if (is_file_exist(filedir) == 0) { create_path(filedir); } sprintf(filepath, "%s\\%s", filedir, filename); std::ofstream ofs; ofs.open(filepath, std::ios::app); va_list vl; va_start(vl, pszFormat); vsnprintf(pszcontent, 2048, pszFormat, vl); va_end(vl); ofs << sztime << " >>> " << pszcontent << std::endl; ofs.close(); sys_LeaveCriticalSection(m_hSection); } } int CManage::get_cam_status() { int status = 0; for (int i = 0; i < EVSize; i++) { status |= (m_pVision[i]->IsConn() << i); } status |= (m_pVisionTest->IsConn() << EVSize); return status; } int CManage::get_test_status() { int status = 0; for (int i = 0; i < TESTCNT; i++) { status |= (m_ptest[i]->IsConn() << i); } return status; } int CManage::registercallbackmsg(CommunicationMsgCallback communicationmsgCallback) { if (communicationmsgCallback != NULL) { m_communicationmsgCallback = communicationmsgCallback; return 0; } return -1; }