#include "manage.h" #include "var.h" #include "ops.h" #include "log.h" #include "test.h" #include "user.h" #include "config.h" #include "matrix.h" #include "control.h" using std::pair; //CManage类 void makelenstr(char* psz, int len) { int nlen = strlen(psz); if (nlen < len) { mem_backward(psz, nlen, len - nlen); for (int i = 0; i < len - nlen; i++) { psz[i] = '0'; } } } void CManage::UpdateVarProduct() { ZERO_CHK(m_bupdatevar); CProduct* p = NULL; char buff[256] = { 0 }; for (int i = 0; i < m_vacm_cnt; i++) { p = m_vacm_lst[i]; if (p) { makelenstr(p->data.sn, 4); sprintf(buff, "0 %s %d %d %d time:%s status:%d count:%d", p->data.sn, p->_t1, p->_t2, p->_t3, p->data.start, p->data.status, p->data.count); } else sprintf(buff, "%d", 0); if (strcmp(buff, m_pvar_vacm[i]->getcs())) { m_pvar_vacm[i]->sets(buff); } } for (int i = 0; i < TESTCNT; i++) { p = m_ptest[i]->_p; if (p) { makelenstr(p->data.sn, 4); sprintf(buff, "%d %s %d %d %d time:%s status:%d count:%d", m_ptest[i]->_data.status, p->data.sn, p->_t1, p->_t2, p->_t3, p->data.start, p->data.status, p->data.count); } else sprintf(buff, "%d", m_ptest[i]->_data.status); if (strcmp(buff, m_pvar_test[i]->getcs())) { m_pvar_test[i]->sets(buff); } } } int CManage::Test(const char* pszcmd) { char name[32] = { 0 }; char desc[32] = { 0 }; for (int i = 0; i < m_vacm_cnt; i++) { sprintf(name, "vacm%d_p", i + 1); sprintf(desc, "吸嘴%d产品数据", i + 1); m_pvar_vacm[i] = getVar(name, desc); } for (int i = 0; i < TESTCNT; i++) { sprintf(name, "test%d_p", i + 1); sprintf(desc, "治具%d产品数据", i + 1); m_pvar_test[i] = getVar(name, desc); } m_bupdatevar = true; /*CoreConfig cfg; GetConfig(&cfg); cfg.bBindB = 1; cfg.idualindex = 3; cfg.bPassTestB = 1; SetConfig(&cfg);*/ return 0; } int CManage::GetVacmCount() {//获取吸嘴现在有多少颗物料 int count = 0; for(int i = 0; i < m_vacm_cnt; i++) { if (m_vacm_lst[i]) count++; } return count; } void CManage::MakeDate(char* pszdate) { SYS_TIME tm; sys_GetLocalTime(&tm); sprintf(pszdate, "%04d/%02d/%02d %02d:%02d:%02d", tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond); } int CManage::M1() {//M1 通知进料仓拍照,并返回拍照结果 return m_pVision[EVInput]->Process(); } int CManage::M3() {//M1 通知OK仓拍照,并返回拍照结果 return m_pVision[EVOkTray]->Process(); } int CManage::M4() {//M4 通知NG仓拍照,并返回拍照结果 return m_pVision[EVNGTray]->Process(); } int CManage::M2() {//M2 通知2号相机拍照,并返回拍照结果 return m_pVision[EVHamal]->Process(); } int CManage::M5() {//NG取一拍一 return m_pVision[EVNGTakeOne]->Process(); } int CManage::M6() {//NG放一拍一 return m_pVision[EVNGPutOne]->Process(); } int CManage::M7() {//治具取 return m_pVision[EVTestTake]->Process(); } int CManage::M8() {//治具放 return m_pVision[EVTestPut]->Process(); } int CManage::VacmReset() {//vacmreset 通知释放吸嘴产品数据 _logct = 0; for(int i = 0; i < m_vacm_cnt; i++) { m_vacm_lst[i] = NULL; } return 0; } int CManage::SimTest(int tindex, int benable) { CoreConfig cfg; memcpy(&cfg, &m_cfg, sizeof(cfg)); switch(tindex) { case 1: cfg.bSimTest1 = benable; break; case 2: cfg.bSimTest2 = benable; break; case 3: cfg.bSimTest3 = benable; break; case 4: cfg.bSimTest4 = benable; break; case 5: cfg.bSimTest5 = benable; break; case 6: cfg.bSimTest6 = benable; break; default: return -1; } return SetConfig(&cfg); } int CManage::StockReset(int sindex) {//stockreset sindex 通知释放料盘产品数据 sindex料仓编号[1-5] vector::iterator it; RETURN_CHK_NOPRT(sindex >= LocationInput && sindex <= LocationNg3, ERR_INPUT_PARAM); vector& vec = m_vecStock[sindex - LocationInput]; for (it = vec.begin(); it != vec.end(); it++) { if (*it) {//有值则释放 FreeProduct(*it); *it = NULL; } } //不清空内存 pvec->clear(); return 0; } int CManage::VacmTake() {//vacmtake 通知设置需要取料的吸嘴编号为0时无效,设置到变量'v'中 int count = GetVacmCount(); if (count >= m_vacm_cnt - 1 || m_pclear->geti()) {//已满或者有清料信号 m_pv->seti(0); m_pt->seti(0); return 0; } for(int i = 0; i < m_vacm_cnt; i++) { if (!m_vacm_lst[i]) { count = i + 1; break; } } m_pt->seti(1); m_pv->seti(count); LOG_INF1("input set v = %d", count); return 0; } int CManage::FindTest(CProduct* p, bool bchkp, int aend) {//查找可以放的治具 for (int i = 0; i < aend; i++) {//测试治具 if (bchkp && m_ptest[i]->_p) continue; //检测有料 if (!m_ptest[i]->Enabled()) continue; //未启用 if (!m_ptest[i]->IsReady()) continue; //不在就绪状态 if (m_ptest[i]->IsNextNoTest()) {//用于缓存 -- 直接可以 REPORT("set notest t = %d.", i + 1); //set_int_var("test", 1); //ops_analog_signal(IOS_PAUSE, 1); //测试,暂停一下 return i + 1; } if (IsAAB() && !p->CanTestAAB(m_ptest[i]->_data.ate)) {//AAB模式不可以放 continue; } if (IsABC() && !p->CanTestABC(m_ptest[i]->_data.ate)) {//ABC模式不可以放 continue; } return i + 1; //ok直接返回 } return 0; } void CManage::GetPutByTest(int &v, int t, bool bchkp) {//testput 通知设置需要进入治具的吸嘴编号->'v',治具编号->'t',为0时无效 int aend = m_pEnda->geti(); const char* ate = m_ptest[t-1]->_data.ate; for(int i = 0; i < m_vacm_cnt; i++) {//吸嘴编号 if (!m_vacm_lst[i]) continue; if (bchkp && m_ptest[t - 1]->_p) continue; if (m_ptest[t - 1]->IsNextNoTest()) {//用于缓存 -- 直接可以 v = i + 1; REPORT("set notest v = %d t = %d.", v, t); //set_int_var("test", 1); //ops_analog_signal(IOS_PAUSE, 1); //测试,暂停一下 break; } if (m_vacm_lst[i]->lastIndex() > aend) continue; //已经进B组测试 if (!m_vacm_lst[i]->NeedTest(getBinA())) continue; //不需要测试 if (IsAAB() && !m_vacm_lst[i]->CanTestAAB(ate)) {//AAB模式不可以放 continue; } if (IsABC() && !m_vacm_lst[i]->CanTestABC(ate)) {//ABC模式不可以放 continue; } v = i + 1; break; } } void CManage::GetTestPut(int &v, int &t, bool bchkp) {//testput 通知设置需要进入治具的吸嘴编号->'v',治具编号->'t',为0时无效 v = 0; if (t > 0 && t <= TESTCNT && m_ptest[t-1]->Enabled() && m_ptest[t-1]->IsReady()) {//治具编号有效 return GetPutByTest(v, t, bchkp); } for(int i = 0; i < m_vacm_cnt; i++) {//吸嘴编号 if (!m_vacm_lst[i]) continue; if (!m_vacm_lst[i]->NeedTest(getBinA())) continue; //不需要测试 t = FindTest(m_vacm_lst[i], bchkp); if (0 == t) continue; //未找到 v = i + 1; break; } } int CManage::TestPut() {//testput 通知设置需要进入治具的吸嘴编号->'v',治具编号->'t',为0时无效 int v = 0; int t = m_pt->geti(); //优先选择当前治具 int aend = m_pEnda->geti(); //GetTestPut(v, t, true); GetTestPutDual(v, t, aend, true); //这里要判定有没有产品在治具 m_pv->seti(v && t ? v : 0); m_pt->seti(v && t ? t : 0); LOG_INF1("testput get v = %d t = %d", v, t); return 0; } void CManage::GetTestTake(int &v, int &t) {//testake 通知设置需要从治具取料的吸嘴编号->'v',治具编号->'t',为0时无效 v = 0; //先获取空闲的吸嘴 for(int i = 0; i < m_vacm_cnt; i++) {//吸嘴编号 if (m_vacm_lst[i]) continue; //已有料 v = i + 1; break; } ZERO_CHK(v > 0); if (t > 0 && t <= TESTCNT && m_ptest[t-1]->Enabled() && //启用 m_ptest[t-1]->IsReady()) //就绪 {//当前传入的治具编号有效,直接返回 if (!m_ptest[t - 1]->_p) {//如果是无料,则此次取料作废,不取直接放 v = 0; //这里不可以把t变0,会影响后面的放料 } return; } t = 0; //重置 for(int i = 0; i < TESTCNT; i++) {//测试治具 if (!m_ptest[i]->_p) continue; //没料 if (!m_ptest[i]->Enabled()) continue; //未启用 if (!m_ptest[i]->IsReady()) continue; //未就绪 t = i + 1; break; } } int CManage::TestTake() {//testake 通知设置需要从治具取料的吸嘴编号->'v',治具编号->'t',为0时无效 int v = 0; int t = m_pt->geti(); //优先选择当前治具 GetTestTake(v, t); m_pt->seti(t); m_pv->seti(v && t ? v : 0); LOG_INF1("testake get v = %d t = %d", v, t); return 0; } int CManage::StockPut() {//stockput 通知设置需要放回料仓的吸嘴编号->'v',料仓编号[2-5]->'t',为0时无效 int v = 0; int t = 0; int tmax = 0; int vmax = 0; for(int i = 0; i < m_vacm_cnt; i++) {//查找最大值 if (!m_vacm_lst[i]) continue; //无料 if (m_vacm_lst[i]->lastIndex() <= m_pEnda->geti() //未进B组 && m_vacm_lst[i]->NeedTest(getBinA())) continue; //且A组需要测试 v = i + 1; t = m_vacm_lst[i]->IsOk() ? 2/*m_vacm_lst[i]->tCount() + 1*/ : 5; //3次NG为料仓5 if (t > tmax) {//找到更大值 -- 每个料仓一次性放完 tmax = t; vmax = v; } } m_pv->seti(vmax); m_pt->seti(tmax); if (vmax > 0) m_pBin->sets(m_vacm_lst[vmax - 1]->data.level); //设置bin信息到变量 LOG_INF1("stockput set v = %d t = %d", vmax, tmax); return 0; } void CManage::GetNotestPut(int &v, int &t) {//4个吸嘴都需要测试,但是又找不到治具可以测试,这个时候卡死 //for (int i = 0; i < m_vacm_cnt; i++) //{ // if (m_vacm_lst[i]) // {//有物料的吸嘴就行 // v = i + 1; // break; // } //} v = 1; //理论上应该是这样 for (int i = 0; i < TESTCNT; i++) {//测试治具 if (m_ptest[i]->_p) continue; //有料 if (!m_ptest[i]->Enabled()) continue; //未启用 if (!m_ptest[i]->IsReady()) continue; //未就绪 m_ptest[i]->setNextNoTest(); //设置为不测试 t = i + 1; break; } } #define PUTCT 6000 //补料时间 每颗6s int CManage::WhereToGo() {//where 通知设置当前是给治具换料还是放料到料仓,设置到变量't'中,0标识放料到料仓,[1-6]标识给治具换料 int i = 0; int v = 0; int t = 0; int v1 = 0; int t1 = 0; ulong cur = 0; ulong minct = TESTCT; //最小时间 ulong takect = 0; //补料需要时间 ulong tm = 0; //测试结束剩余时间 int ntest = 0; //有多少个可以放到治具的料 int nput = 0; //有多少个可以放到OK料仓的料 int nstock = 0; //有多少个可以放到料仓的料 //int curt = m_pt->geti(); //当前治具序号 int curt = m_prePut; //当前治具序号 int aend = m_pEnda->geti(); int bclear = m_pclear->geti(); //清料信号 for(i = 0; i < m_vacm_cnt; i++) { if (!m_vacm_lst[i]) {//空的吸嘴先记录一下 if (0 == v) v = i + 1; continue; } if (NeedTestDual(m_vacm_lst[i])) {//次数小于3次并且测试NG ntest++; } else {//必须放到料仓 nstock++; if (1 == m_vacm_lst[i]->tCount()) nput++; //OK仓 } } m_pnput->seti(nput); m_pntake->seti(m_vacm_cnt - ntest - 1); //if ((0 == ntest && !bclear) || (ntest + nstock == m_vacm_cnt)) if ((0 == ntest && !bclear) || (nstock >= m_vacm_cnt - 1) || (nstock > 0 && ntest + nstock >= m_vacm_cnt)) {//吸嘴上没有料,则必须放料 -- 大于2颗料要放仓库,则先放仓库 m_pt->seti(0); LOG_INF1("where set t = 0"); return 0; } //计算当前放料到治具需要等多久? //计算当前取满3颗料需要多久? cur = sys_GetTickCount(); takect = PUTCT * nstock; //补料耗时预估 if (curt <= 0 || curt > TESTCNT) curt = TESTCNT; i = curt - 1; //当前索引 do {//从当前t下一个开始遍历,到下一次到t结束 i = (i + 1) % TESTCNT; //循环控制 if (!m_ptest[i]->Enabled()) continue; //未启用 if (m_ptest[i]->IsReady()) {//就绪状态直接放 t1 = i + 1; //GetTestPut(v, t); //获取可以放的治具和吸嘴 //REPORT("test(%d) idle", t1); GetTestPutDual(v1, t1, aend, ntest == m_vacm_cnt ? true : false); //获取可以放的治具和吸嘴 if (v1 > 0 && t1 > 0) {//ok 可以换料 m_pv->seti(v); //吸嘴设置为取料吸嘴 m_pt->seti(t1); LOG_INF1("where set v = %d t = %d", v, t1); return 0; } if (bclear) {//若没有可放的,但是有清料信号,判断是否可以取 GetTestTake(v1, t1); if (v1 > 0 && t1 > 0) {//ok 可以换料 m_pv->seti(v1); m_pt->seti(t1); LOG_INF1("where set v = %d t = %d", v1, t1); return 0; } } } else if ((i < aend || bclear) && m_ptest[i]->IsRunning()) {//还需要多久可以测试完成(预估) -- A组才预估,B组必须空闲(清料时要等待) tm = m_ptest[i]->startCT() + m_ptest[i]->lastCT(); if (tm > cur) tm -= cur; //剩余时间 else tm = 0; //即将结束 //REPORT("test(%d) lastct:%d start:%d remain time:%d", i + 1, m_ptest[i]->lastCT(), m_ptest[i]->startCT(), tm); if (tm < minct) {//获取最快结束测试的治具序号 minct = tm; t = i + 1; } } } while (i != curt - 1); if (TESTCT == minct && bclear) {//清料状态下,所有治具都已空 t = -1; //结束标识 m_prePut = 0; REPORT("clear material finished."); } else if (minct > takect && nstock > 0) {//取料比较快,并且还可以补料 t = 0; } else if (ntest == m_vacm_cnt) {//4个吸嘴都需要测试,但是又找不到治具可以测试,这个时候卡死 GetNotestPut(v, t); //m_pPause->seti(1); //暂停 REPORT("4 vacm must test."); //send_message(MSG_NORMAL, "4 vacm must test."); } m_pv->seti(v); m_pt->seti(t); LOG_INF1("where set v = %d t = %d", v, t); return 0; } int CManage::TakeFromInput(const char* sn, int vacmIndex) {//从进料盘取料 int index = 0; CProduct* p = NULL; RETURN_CHK_NOPRT(sn && *sn, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(strlen(sn) < MAX_NAME_LEN, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(vacmIndex > 0 && vacmIndex <= m_vacm_cnt, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(!m_vacm_lst[vacmIndex - 1], ERR_EXIST_PRODUCT); sys_EnterCriticalSection(m_hSection); p = GetFromInput(); strcpy(p->data.sn, sn); MakeDate(p->data.start); p->data.index = vacmIndex; p->data.pos = LocationVacm; m_vacm_lst[vacmIndex - 1] = p; LOG_INF1("create product:%s", p->data.sn); if (m_hash_lst.find(sn) == m_hash_lst.end()) {//没有则插入 m_hash_lst.insert(pair(sn, p)); } sys_LeaveCriticalSection(m_hSection); return 0; } int CManage::MovetoTest(int vacmIndex, int testIndex) {//物料搬运 int ret = 0; CProduct* p = NULL; CTest* ptest = NULL; RETURN_CHK_NOPRT(vacmIndex > 0 && vacmIndex <= m_vacm_cnt, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(testIndex > 0 && testIndex <= TESTCNT, ERR_INPUT_PARAM); p = m_vacm_lst[vacmIndex - 1]; ptest = m_ptest[testIndex - 1]; RETURN_CHK_NOPRT(p, ERR_NO_PRODUCT); RETURN_CHK_NOPRT(!ptest->_p, ERR_EXIST_PRODUCT); RETURN_CHK_NOPRT(ptest->IsReady(), ERR_NOREADY); ret = m_ptest[testIndex - 1]->StartTest(p, m_cfg.machine, m_cfg.Config, m_cfg.ConfigD, m_cfg.sitel, m_cfg.project, m_cfg.bUpMes, m_cfg.bUpMTcp, 0,m_cfg.sublotname,m_cfg.bUpNoise); RETURN_CHK_NOPRT(!ret, ret); m_prePut = testIndex; //保存上一次放料 m_vacm_lst[vacmIndex - 1] = NULL; //清空吸嘴 return 0; } int CManage::MovetoVacm(int testIndex, int vacmIndex) {//物料搬运 CProduct* p = NULL; RETURN_CHK_NOPRT(vacmIndex > 0 && vacmIndex <= m_vacm_cnt, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(testIndex > 0 && testIndex <= TESTCNT, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(!m_vacm_lst[vacmIndex - 1], ERR_EXIST_PRODUCT); RETURN_CHK_NOPRT(m_ptest[testIndex-1]->IsReady(), ERR_NOREADY); p = m_ptest[testIndex-1]->_p; RETURN_CHK_NOPRT(p, ERR_NO_PRODUCT); p->data.index = vacmIndex; p->data.pos = LocationVacm; m_ptest[testIndex-1]->_p = NULL; m_vacm_lst[vacmIndex-1] = p; return 0; } int CManage::MovetoStock(int vacmIndex, int sindex) {//物料搬运-料仓 CProduct* p = NULL; RETURN_CHK_NOPRT(vacmIndex > 0 && vacmIndex <= m_vacm_cnt, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(sindex >= LocationOk && sindex <= LocationNg3, ERR_INPUT_PARAM); p = m_vacm_lst[vacmIndex-1]; RETURN_CHK_NOPRT(p, ERR_NO_PRODUCT); MakeDate(p->data.end); PutToStock(sindex, p); m_vacm_lst[vacmIndex-1] = NULL; return 0; } int CManage::WaitTestIdle(int testIndex, int timeout) {//等待测试治具就绪 uint ct = sys_GetTickCount(); RETURN_CHK_NOPRT(testIndex > 0 && testIndex <= TESTCNT, ERR_INPUT_PARAM); RETURN_CHK_NOPRT(m_ptest[testIndex-1]->Enabled(), ERR_NOREADY); while (1) { if (m_ptest[testIndex-1]->IsReady()) {//就绪 return 0; } if (sys_GetTickCount() > ct + timeout) {//超时 return ERR_TIMEOUT; } sys_Sleep(5); //这里需要设置延时,否则占用CPU严重 } return ERR_TIMEOUT; } int CManage::WaitM2Result(int sindex, char* szres, int timeout) {//WaitM2 sindex sindex料仓编号[1-5] 等待2号相机处理结果,自动刷新产品标识到数组中,消息返回格式:res 0标识成功 TOpsCfg cfg; int res = 0; int bret = 0; int index = 0; int start = 0; TMatrixInfo mat; char* ptmp = NULL; char* pnext = NULL; char buff[1024] = {0}; RETURN_CHK_NOPRT(sindex >= LocationInput && sindex <= LocationNg3, ERR_INPUT_PARAM); ops_get_cfg(&cfg); if (cfg.offVision) {//屏蔽视觉 sprintf(szres, "0"); StockReset(sindex); set_matrix_cur_node(sindex, 0); #if 0 if (LocationInput == sindex) {//模拟一下进料仓数据 get_matrix_info(sindex, &mat); if (IsFourpic()) mat.size *= 4; for (int i = 0; i < mat.size; i++) { res = (i < 10 || (i < 26 && i >= 16)) ? 0 : 1; if (res) MakeProduct(sindex, index); else ReleaseProduct(sindex, index); if (0 == start && LocationInput == sindex && res) {//进料盘,等下设置料盘当前节点 start = index + 1; } else if (0 == start && LocationInput != sindex && !res) {//出料盘 start = index + 1; } index++; } if (start > 0 && IsFourpic() && (LocationInput == sindex)) {//计算缩小后的料盘索引 int r = (start - 1) / (mat.col * 2) / 2; //new row int c = (start - 1) % (mat.col * 2) / 2; //new col start = r * mat.col + c + 1; } set_matrix_cur_node(sindex, start > 0 ? start - 1 : mat.size); } #else if (LocationInput == sindex) MakeInput(); #endif return 0; //返回成功 } res = m_pVision[EVHamal]->WaitResult(buff, timeout); RETURN_CHK_NOPRT(!res, res); //处理结果 ptmp = sys_strtok(buff, ",", &pnext); if (!ptmp || 0 == *ptmp) return 0; res = atoi(ptmp); if (0 != res) {//拍照失败 sprintf(szres, "%d", res); //res==0才有后面的结果,否则直接返回接收结果成功 return 0; //指令返回成功 } while(ptmp = sys_strtok(NULL, ",", &pnext)) { if (EMSTR_INT != get_str_type(ptmp)) {//格式错误 REPORT("M2 reply format error"); return ERR_INPUT_PARAM; } res = atoi(ptmp); //标识有无物料 if (res) {//有物料 MakeProduct(sindex, index); if (LocationInput != sindex) bret = 1; //其它仓判定有物料 } else {//缺物料 ReleaseProduct(sindex, index); if (LocationInput == sindex) bret = 1; //进料仓判定缺物料 } if (0 == start && LocationInput == sindex && res) {//进料盘,等下设置料盘当前节点 start = index + 1; } else if (0 == start && LocationInput != sindex && !res) {//出料盘 start = index + 1; } index++; } get_matrix_info(sindex, &mat); if (start > 0 && IsFourpic() && (LocationInput == sindex)) {//计算缩小后的料盘索引 int r = (start - 1) / (mat.col * 2) / 2; //new row int c = (start - 1) % (mat.col * 2) / 2; //new col start = r * mat.col + c + 1; } sprintf(szres, "%d", bret); //返回0正常,返回1标识缺产品或者有产品 set_matrix_cur_node(sindex, start > 0 ? start - 1 : mat.size); //设置为结束,表明要换盘 return 0; } int CManage::SetPosxy(int sindex, char* pszcmd) {//pszcmd index sn offsetx offsety int index = 0; TMatrixInfo mat; TMatrixNode node; TPosxy* p = NULL; char* sn = NULL; char* ptmp = NULL; RETURN_CHK_NOPRT(pszcmd && sindex >= LocationInput && sindex <= LocationNg3, ERR_INPUT_PARAM); //index trim_char(pszcmd); ptmp = sys_strtok(NULL, " ", &pszcmd); RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(ptmp), ERR_INPUT_PARAM); index = atoi(ptmp); RETURN_CHK_NOPRT(index > 0 && index <= 4, ERR_INPUT_PARAM); get_matrix_info(sindex, &mat); get_matrix_cur_node(sindex, &node); if (IsFourpic() && LocationInput == sindex) {//4次拍照 index依次传入1234 对应位置位左上、右上、左下、右下 node.index = (node.col - 1) * 2 + (node.row - 1) * 2 * mat.col * 2 + ((index - 1) / 2) * mat.col * 2 + (index - 1) % 2 + 1; } //sn trim_char(pszcmd); sn = sys_strtok(NULL, " ", &pszcmd); RETURN_CHK_NOPRT(pszcmd && sn && *sn && strlen(sn) < MAX_NAME_LEN, ERR_INPUT_PARAM); //x y trim_char(pszcmd); ptmp = sys_strtok(NULL, " ", &pszcmd); if (pszcmd) trim_char(pszcmd); RETURN_CHK_NOPRT(get_str_type(ptmp) && get_str_type(pszcmd), ERR_INPUT_PARAM); p = new TPosxy; p->x = atof(ptmp); p->y = atof(pszcmd); p->index = node.index; comm_strcpy(p->sn, sn); sys_EnterCriticalSection(m_hSection); m_lst_pos[sindex - LocationInput].push_back(p); sys_LeaveCriticalSection(m_hSection); return 0; }