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.

822 lines
23 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 "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<CProduct*>::iterator it;
RETURN_CHK_NOPRT(sindex >= LocationInput && sindex <= LocationNg3, ERR_INPUT_PARAM);
vector<CProduct*>& 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<string, CProduct*>(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;
}