|
|
#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<CProduct*>& vec, int nsize)
|
|
|
{//确保缓冲区够大
|
|
|
for (int i = (int)vec.size(); i < nsize; i++)
|
|
|
{
|
|
|
vec.push_back(NULL);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CManage::MakeProduct(int sindex, int index)
|
|
|
{//判断料盘某个位置是否有料?无料则创建一个
|
|
|
vector<CProduct*>& 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<CProduct*>& 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<CProduct*>& 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<CProduct*>& 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<TPosxy*>& 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<TPosxy*>& 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<TPosxy*>& lst = m_lst_pos[sindex - LocationInput];
|
|
|
list<TPosxy*>& 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<TPosxy*>& 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<TPosxy*>& lst = m_lst_pos[sindex - LocationInput];
|
|
|
list<TPosxy*>& 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<CProduct*>::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<string, CProduct*>::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<string, CProduct*>::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<CProduct*>& 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<string, CProduct*>::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<string, CProduct*>::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<int> s;
|
|
|
vector<int> 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;
|
|
|
} |