|
|
#pragma once
|
|
|
#ifndef _INCLUDE_COREWORK_MANAGE_H
|
|
|
#define _INCLUDE_COREWORK_MANAGE_H
|
|
|
#include "sysapi.h"
|
|
|
#include <list>
|
|
|
#include <hash_map>
|
|
|
#include <string>
|
|
|
#include <vector>
|
|
|
#include "corework.h"
|
|
|
#include "simtest.h"
|
|
|
#include "vision.h"
|
|
|
#include "ipvar.h"
|
|
|
|
|
|
using std::list;
|
|
|
using std::vector;
|
|
|
using std::string;
|
|
|
using std::hash_map;
|
|
|
|
|
|
#define VACMCNT 4 //吸嘴数量
|
|
|
#define TESTCNT 6 //治具数量
|
|
|
#define MINAEND 3 //最小A组分界值
|
|
|
#define STOCKCNT 5 //料仓数量
|
|
|
|
|
|
#define VERSION 2135 //版本号
|
|
|
|
|
|
#define CFG_KEY "work"
|
|
|
|
|
|
#define ins CManage::Get_Instance()
|
|
|
|
|
|
//#define REPORT(msg, ...) ins->Report(msg, __VA_ARGS__)
|
|
|
#define REPORT(msg, ...) post_message(MSG_ASCII, msg, __VA_ARGS__)
|
|
|
|
|
|
#define SPLIT "#" //分隔符
|
|
|
#define REG "Register" //客户端往服务器注册
|
|
|
#define STATUS "Status" //查询客户端状态
|
|
|
#define START "StartTest" //通知治具启动测试
|
|
|
#define RES "Result" //查询测试结果信息
|
|
|
#define ERR "ErrorCode" //查询报警代码+描述
|
|
|
#define GRIP "Grip" //通知治具打开夹爪
|
|
|
#define PAUSE "Pause" //通知治具暂停
|
|
|
#define GR "GR" //视觉处理请求
|
|
|
#define HOME "Home" //通知治具回原
|
|
|
#define RESET "Reset" //通知治具重置
|
|
|
#define RIO "ReadIO" //读取IO
|
|
|
#define WIO "WriteIO" //写入IO
|
|
|
#define VLOG "Vlog" //上传日志
|
|
|
#define HOMECT 60000 //测试治具回原时间
|
|
|
#define TAKECT 5000 //取放单颗料预估时间
|
|
|
#define VPORT 6051 //视觉服务器起始端口
|
|
|
#define VPORTEST 6081 //测试侧相机服务端口
|
|
|
|
|
|
cstr GetTestMode(cstr p);
|
|
|
|
|
|
enum VisionSence
|
|
|
{//视觉客户端类型
|
|
|
EVInput = 0, //M1 取料盘拍照
|
|
|
EVHamal, //M2 搬运相机拍照
|
|
|
EVOkTray, //M3 ok仓拍照
|
|
|
EVNGTray, //M4 NG仓拍照
|
|
|
EVNGTakeOne, //M5 NG取一拍一
|
|
|
EVNGPutOne, //M6 NG放一拍一
|
|
|
EVTestTake, //M7 标定块场景
|
|
|
EVTestPut, //M8 治具放
|
|
|
|
|
|
EVSize, //客户端总数量
|
|
|
};
|
|
|
|
|
|
struct MachineInfo
|
|
|
{//治具结构
|
|
|
TestMachine data; //治具数据
|
|
|
int index; //治具索引
|
|
|
uint start; //开始测试时间
|
|
|
int lastct; //最后一次CT
|
|
|
uint qstatus; //查询状态时间
|
|
|
};
|
|
|
|
|
|
struct TPosxy
|
|
|
{//取料放料拍照
|
|
|
char sn[MAX_NAME_LEN];
|
|
|
double x;
|
|
|
double y;
|
|
|
int index;
|
|
|
|
|
|
TPosxy() { memset(this, 0, sizeof(TPosxy)); }
|
|
|
};
|
|
|
|
|
|
struct TGRMsg
|
|
|
{//转发给治具的消息
|
|
|
int tindex;
|
|
|
char* s;
|
|
|
};
|
|
|
|
|
|
class CProduct
|
|
|
{
|
|
|
public:
|
|
|
CProduct(int sindex = LocationInput);
|
|
|
|
|
|
int _t1; //第一次治具序号
|
|
|
int _t2; //第二次
|
|
|
int _t3;
|
|
|
TProduct data;
|
|
|
|
|
|
void Clear();
|
|
|
|
|
|
//测试次数
|
|
|
int tCount() { return data.count; }
|
|
|
|
|
|
//是否测试ok
|
|
|
bool IsOk() { return 1 == data.status; }
|
|
|
|
|
|
//是否需要继续测试
|
|
|
bool NeedTest(cstr s = 0) { return data.count < 3 && 0 == data.status && !IsSameBin(s); }
|
|
|
|
|
|
//是否Bin信息相同
|
|
|
bool IsSameBin(cstr s) { return s && 0 == strcmp(s, data.level); }
|
|
|
|
|
|
//获取重测模式标识字符串 -- 发送开始指令时
|
|
|
cstr getRetryModelS();
|
|
|
|
|
|
//获取重测模式标识字符串 -- 获取结果时
|
|
|
cstr getRetryModelE();
|
|
|
|
|
|
char* Ate(); //当前测试治具编码指针
|
|
|
|
|
|
void SetIndex(int t); //设置当前测试治具序号
|
|
|
|
|
|
int lastIndex();
|
|
|
|
|
|
const char* LastAte();
|
|
|
bool CanTestAAB(const char* ate);
|
|
|
bool CanTestABC(const char* ate);
|
|
|
};
|
|
|
|
|
|
class CTest;
|
|
|
class CManage
|
|
|
{
|
|
|
public:
|
|
|
static CManage* Get_Instance();
|
|
|
static void ReleaseInstance();
|
|
|
|
|
|
CManage(void);
|
|
|
~CManage(void);
|
|
|
|
|
|
int Init();
|
|
|
int Deinit();
|
|
|
|
|
|
int IsRun() { return m_brun ? 1 : 0; } //治具通信任务是否在运行
|
|
|
//治具通信
|
|
|
int StartRun();
|
|
|
int StopRun();
|
|
|
|
|
|
cstr GetTestModel();
|
|
|
|
|
|
int SetConfig(CoreConfig* pcfg);
|
|
|
const CoreConfig* getCfg() const { return &m_cfg; }
|
|
|
void GetConfig(CoreConfig* pcfg) { memcpy(pcfg, &m_cfg, sizeof(m_cfg)); }
|
|
|
|
|
|
int SummaryLog(const char* title, const char* content);
|
|
|
int BreakdownLog(const char* psztype, const char* pszmsg);
|
|
|
int UnitTracker(const char* sn, const char* ate, const char* lot, int result, const char* RetryUsage);
|
|
|
int EventTracker(const char* keyword, int errcode, const char*errmsg, const char*msg);
|
|
|
|
|
|
int GetProduct(const char* sn, TProduct* pdata);
|
|
|
int GetAllProduct(TProduct* pdata/* = 0*/, int nsize/* = 0*/);
|
|
|
int GetProductByPos(EMapPos pos, int index, TProduct* pdata/* = 0*/);
|
|
|
int GetProductList(EMapPos pos, TProduct* pdata/* = 0*/, int nsize/* = 0*/);
|
|
|
|
|
|
int GetMachine(int index, TestMachine* pdata);
|
|
|
int TestEnable(int index, int benable);
|
|
|
int TestDebug(int index, const char* sn);
|
|
|
int TestHome(int testIndex);
|
|
|
int TestReset(int testIndex);
|
|
|
int TestClear(int testIndex);
|
|
|
|
|
|
int SendCustomCmd(const char* msg, char* res = NULL);
|
|
|
int RecvCustomCmd(const char* msg, char* res, int timeout/* = 0*/);
|
|
|
int GetCommandDesc(char* pszcmddesc);
|
|
|
|
|
|
cstr GetVersion();
|
|
|
|
|
|
cstr getBinA() { return m_cfg.BinA; } //获取BinA设置
|
|
|
cstr getLot() { return m_cfg.lot; } //获取批次号
|
|
|
cstr getMachine() { return m_cfg.machine; }
|
|
|
bool NodeLog() { return 0 != m_cfg.bNodeLog; }
|
|
|
bool IsMakeDir() { return 0 != m_cfg.bDirDate; }
|
|
|
bool IsFourpic() { return 0 != m_cfg.bFourPic; }
|
|
|
bool IsSavePos() { return 0 != m_cfg.bSavePos; }
|
|
|
bool testLog() { return 0 != m_cfg.bTestlog; }
|
|
|
bool visionLog() { return 0 != m_cfg.bVisionlog; }
|
|
|
bool IsBindTest() { return 0 != m_cfg.bBindB; } //B组是否为绑定模式 TC1->TCB1 TC2->TCB2
|
|
|
bool IsPassToB() { return 0 != m_cfg.bPassTestB; } //是否测试pass才进入B组测试
|
|
|
|
|
|
uint getFail() { return 100 - m_cfg.iSimYield; } //失败率
|
|
|
uint getSimCT() { return m_cfg.iSimCT; } //模拟测试机台CT
|
|
|
|
|
|
//治具注册时,检测治具编码是否ok
|
|
|
bool ChkAteValid(int index, const char* pszate);
|
|
|
|
|
|
//发送给视觉处理指令
|
|
|
int SendTestGR(int tindex, const char* s = 0);
|
|
|
int PostReplyGR(int tindex, const char* s);
|
|
|
|
|
|
//上报日志
|
|
|
void Report(const char *pszFormat, ...);
|
|
|
void PostWarn(const char *pszFormat, ...);
|
|
|
|
|
|
int regist_callback(callback fun);
|
|
|
|
|
|
callback get_callback()
|
|
|
{
|
|
|
return m_callback;
|
|
|
}
|
|
|
protected:
|
|
|
|
|
|
void Release();
|
|
|
void ReadConfig();
|
|
|
void RestorePos(int sindex);
|
|
|
|
|
|
//模拟生成全盘数据
|
|
|
void MakeInput();
|
|
|
|
|
|
//确保缓冲区够大
|
|
|
void Resize(vector<CProduct*>& vec, int nsize);
|
|
|
|
|
|
//判断料盘某个位置是否有料?无料则创建一个
|
|
|
void MakeProduct(int sindex, int index);
|
|
|
|
|
|
//判断料盘某个位置是否有料?有料则释放
|
|
|
void ReleaseProduct(int sindex, int index);
|
|
|
|
|
|
//拍照数据
|
|
|
int GetPosxy(int sindex); //获取拍照位置索引,并从队列删除
|
|
|
int SetPosxy(int sindex); //设置拍照数据到变量
|
|
|
int PosMap(int sindex); //通过3点数据计算矩阵
|
|
|
int ReleasePosxy(int sindex); //释放拍照数据
|
|
|
int SetPosxy(int sindex, char* pszcmd);
|
|
|
|
|
|
void MakeDate(char* pszdate);
|
|
|
|
|
|
//创建变量,返回ID
|
|
|
int CreateVar(const char* pszname, const char* pszdesc, int keep = 0);
|
|
|
void SetVarInit(const char* pszname, int ival);
|
|
|
|
|
|
//创建变量并锁定
|
|
|
ipvar* getVar(const char* pszname, const char* pszdesc, bool block = true);
|
|
|
ipvar* getVar(const char* pszname, const char* pszdesc, const char* pszval);
|
|
|
|
|
|
int GetTestIndex(const char* ate); //通过编码查找测试机台序号
|
|
|
|
|
|
//产品
|
|
|
CProduct* GetFromInput(); //从进料仓获取物料
|
|
|
CProduct* FindProduct(const char* sn);
|
|
|
|
|
|
void FreeProduct(CProduct* p); //释放产品
|
|
|
void PutToStock(int sindex, CProduct* p); //放入料仓
|
|
|
|
|
|
//未加保护
|
|
|
int GetVacmCount(); //获取吸嘴现在有多少颗物料
|
|
|
int FindTest(CProduct* p, bool bchkp, int aend = TESTCNT); //获取空闲治具 失败返回0
|
|
|
int FindTestDual(CProduct* p, bool bchkp, int aend = TESTCNT); //获取空闲治具 失败返回0 -- 双测模式
|
|
|
|
|
|
int M1();
|
|
|
int M2();
|
|
|
int M3();
|
|
|
int M4();
|
|
|
int M5();
|
|
|
int M6();
|
|
|
int M7();
|
|
|
int M8();
|
|
|
int Test(const char* pszcmd); //测试接口
|
|
|
int SimTest(int tindex, int benable);
|
|
|
int VacmReset();
|
|
|
int StockReset(int sindex);
|
|
|
int VacmTake();
|
|
|
int TestPut();
|
|
|
int TestTake();
|
|
|
int StockPut();
|
|
|
int WhereToGo();
|
|
|
int TakeFromInput(const char* sn, int vacmIndex);
|
|
|
int MovetoTest(int vacmIndex, int testIndex);
|
|
|
int MovetoVacm(int testIndex, int vacmIndex);
|
|
|
int MovetoStock(int vacmIndex, int sindex);
|
|
|
int WaitTestIdle(int testIndex, int timeout);
|
|
|
int WaitM2Result(int sindex, char* szres, int timeout);
|
|
|
|
|
|
//双测模式接口
|
|
|
bool NeedTestDual(CProduct* p, int t = 0);
|
|
|
void GetTestPutDual(int &v, int &t, int aend, bool bchkp = false);
|
|
|
|
|
|
bool IsAAB() { return m_cfg.testType == 1; }
|
|
|
bool IsABC() { return m_cfg.testType == 2; }
|
|
|
bool IsDefault() { return m_cfg.testType == 0; }
|
|
|
|
|
|
void GetTestTake(int &v, int &t);
|
|
|
void GetNotestPut(int &v, int &t); //如果4个吸嘴满了,卡住了,需要借治具进行缓存
|
|
|
void GetPutByTest(int &v, int t, bool bchkp);
|
|
|
void GetPutByTestB(int &v, int t, bool bchkp); //按治具找产品 - B组
|
|
|
void GetTestPut(int &v, int &t, bool bchkp = false);
|
|
|
|
|
|
//加保护
|
|
|
int M1B();
|
|
|
int M2B();
|
|
|
int VacmResetB();
|
|
|
int StockResetB(int sindex);
|
|
|
int VacmTakeB();
|
|
|
int TestPutB();
|
|
|
int TestTakeB();
|
|
|
int StockPutB();
|
|
|
int WhereToGoB();
|
|
|
int TestPause(int testIndex, int bpause);
|
|
|
int GripEnable(int testIndex, int benable);
|
|
|
int CreateProductB(const char* sn, int vacmIndex);
|
|
|
int MovetoVacmB(int testIndex, int vacmIndex);
|
|
|
int MovetoStockB(int vacmIndex, int sindex);
|
|
|
|
|
|
int GetProductByPosB(EMapPos pos, int index, TProduct* pdata/* = 0*/);
|
|
|
int GetProductListB(EMapPos pos, TProduct* pdata/* = 0*/, int nsize/* = 0*/);
|
|
|
|
|
|
static int GreaterThenProduct(const void* a,const void* b);
|
|
|
|
|
|
//治具通信
|
|
|
void AcceptNew(); //等待新连接
|
|
|
void ProcessMsg(); //消息处理
|
|
|
void RecvTestMsg();
|
|
|
void CalcUph(); //计算UPH
|
|
|
void UpdateVarProduct();
|
|
|
void UploadReport();
|
|
|
|
|
|
int Process(); //线程函数
|
|
|
static int WINAPI ThreadFun(void* param);
|
|
|
|
|
|
void ProcessSendGR();
|
|
|
static int WINAPI PoolGR(void* param);
|
|
|
|
|
|
ulong _logct; //用于记录上一次日志时间
|
|
|
ulong GetLastCT(ulong curct);
|
|
|
|
|
|
private:
|
|
|
static CManage *m_pInstance;
|
|
|
|
|
|
Handle m_hSection; //临界区
|
|
|
|
|
|
CoreConfig m_cfg;
|
|
|
|
|
|
list<char*> m_lsgMsg;
|
|
|
|
|
|
bool m_tstRun; //转发线程是否在执行?
|
|
|
list<TGRMsg*> m_tstMsg; //转发给治具的消息,需要额外的线程执行
|
|
|
|
|
|
vector<CProduct*> m_vecStock[STOCKCNT]; //料盘Input OK NG1 NG2 NG3
|
|
|
CProduct** m_vacm_lst; //吸嘴产品
|
|
|
int m_vacm_cnt;
|
|
|
|
|
|
//提前拍照存储位置信息
|
|
|
list<TPosxy*> m_lst_pos[STOCKCNT];
|
|
|
list<TPosxy*> m_lst_posTmp[STOCKCNT];
|
|
|
int m_lst_index[STOCKCNT]; //缓存上一次取位置时的索引
|
|
|
|
|
|
//测试信息
|
|
|
int m_prePut; //上一次放治具编号
|
|
|
CTest* m_ptest[TESTCNT]; //治具
|
|
|
CTest* m_pconn; //新连接对象
|
|
|
|
|
|
bool m_brun; //线程运行标识
|
|
|
Handle m_hThread; //线程句柄
|
|
|
|
|
|
hash_map<string, CProduct*> m_hash_lst; //所有产品数据
|
|
|
|
|
|
//视觉连接
|
|
|
CVision* m_pVision[EVSize];
|
|
|
CVision* m_pVisionTest; //测试侧相机
|
|
|
|
|
|
//模拟
|
|
|
CSimTest* m_psimTest[TESTCNT];
|
|
|
|
|
|
//变量
|
|
|
ipvar* m_pv; //吸嘴编号
|
|
|
ipvar* m_pt; //治具/料仓编号
|
|
|
ipvar* m_pclear; //清料信号
|
|
|
ipvar* m_pFour; //是否一拍4
|
|
|
ipvar* m_pntake; //要取的料数量
|
|
|
ipvar* m_pnput; //要放OK仓的料数量
|
|
|
ipvar* m_pUph; //最近一分钟实时UPH
|
|
|
ipvar* m_pAllUph; //本次总的UPH
|
|
|
ipvar* m_pOutput; //工作产量
|
|
|
ipvar* m_pLot; //料盘换料次数
|
|
|
ipvar* m_pEnda; //A组最后序号
|
|
|
ipvar* m_pPause; //暂停信号
|
|
|
ipvar* m_pBin; //分bin信息
|
|
|
ipvar* m_pCastoff; //抛弃产品索引
|
|
|
|
|
|
//测试数据
|
|
|
bool m_bupdatevar; //是否更新产品数据到变量
|
|
|
ipvar* m_pvar_vacm[4];
|
|
|
ipvar* m_pvar_test[TESTCNT];
|
|
|
callback m_callback; //回调函数
|
|
|
};
|
|
|
|
|
|
#endif //防止重复包含
|