You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2222 lines
60 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}