From ad734ac4fe086391b42874b422e94612a8e80d56 Mon Sep 17 00:00:00 2001 From: bestlqiang Date: Thu, 24 Dec 2020 18:10:17 +0800 Subject: [PATCH] 1224 --- LaiPuLaser/CommonFlowMgr.cpp | 91 +--- LaiPuLaser/DlgTest.cpp | 15 + LaiPuLaser/DlgTest.h | 1 + LaiPuLaser/LaiPuLaser.rc | Bin 132224 -> 133222 bytes LaiPuLaser/LaipuVbDllMgr.cpp | 18 +- LaiPuLaser/Laser.cpp | 19 + LaiPuLaser/Laser.h | 4 +- LaiPuLaser/MarkArea.cpp | 79 +-- LaiPuLaser/MarkArea.h | 2 + LaiPuLaser/MarkAreaMgr.cpp | 19 +- LaiPuLaser/MarkAreaMgr.h | 1 + LaiPuLaser/MarkCtrl.cpp | 4 +- LaiPuLaser/MarkData.txt | 6 - LaiPuLaser/MarkData_Server.txt | 10 + LaiPuLaser/ModuleMgr.cpp | 2 +- LaiPuLaser/ObjComponent.h | 12 +- LaiPuLaser/ObjComponentMgr.cpp | 77 ++- LaiPuLaser/Product.cpp | 164 +++++-- LaiPuLaser/Product.h | 30 +- LaiPuLaser/Product0.cpp | 543 +++++++++++++++++++++ LaiPuLaser/Product0.h | 97 ++++ LaiPuLaser/ProductMgr.cpp | 2 +- LaiPuLaser/ProductMgr.h | 4 +- LaiPuLaser/Program_SZ_XL.cpp | 120 ++++- LaiPuLaser/Program_SZ_XL.h | 9 +- LaiPuLaser/Program_SZ_XL_TrackWorkFlow.cpp | 18 +- LaiPuLaser/ServerMgr.cpp | 100 +++- LaiPuLaser/ServerMgr.h | 11 + LaiPuLaser/WorkCmdInvoker.cpp | 2 +- LaiPuLaser/WorkCmdMarkArea.cpp | 4 +- LaiPuLaser/hlp/LaiPuLaser.chm | Bin 11730 -> 11726 bytes LaiPuLaser/resource.h | Bin 64574 -> 64850 bytes 32 files changed, 1245 insertions(+), 219 deletions(-) delete mode 100644 LaiPuLaser/MarkData.txt create mode 100644 LaiPuLaser/MarkData_Server.txt create mode 100644 LaiPuLaser/Product0.cpp create mode 100644 LaiPuLaser/Product0.h diff --git a/LaiPuLaser/CommonFlowMgr.cpp b/LaiPuLaser/CommonFlowMgr.cpp index ec95162..60cc5e6 100644 --- a/LaiPuLaser/CommonFlowMgr.cpp +++ b/LaiPuLaser/CommonFlowMgr.cpp @@ -1010,6 +1010,7 @@ bool CCommonFlowMgr::NormalMarkByPciCard(bool bSel,int times,int CyclicTimes) //创建一个临时的area CMarkArea MarkArea(Dbxy(0,0),DbSize(100,100)); //收集加工数据 + MarkArea.CollectOrgWorkData(bSel, Product); MarkArea.CollectWorkData(bSel,Product); if(MarkArea.HasWorkData()) @@ -1079,80 +1080,7 @@ bool CCommonFlowMgr::MultipleAreaMark(CProduct &Product,bool bSel) gMarkAreaMgr->CollectWorkData(bSel,Product); if(!gMarkAreaMgr->HasWorkData()) return false; - //是否需要自动回原点 - //bool bAutoFindOrigin = (m_FindOriginTimes>0 && m_CurWorktimes>=m_FindOriginTimes && Product.IsbLastOne()); - - //重置所有obj 的marked 状态 - // gObjComponentMgr->ResetAllMarkedState(); - - /* CWorkCmdInvoker Invoker; - CWorkCmdContainer &CmdContainer = CWorkCmdContainer::GetInstance();//指令集 - CmdContainer.Clear();*/ - - /* //开始之前的工作 - { - CWorkCmd *pCmd = new CWorkCmdWorkStart(); - CmdContainer.AddCmd(pCmd); - } - - SetLightStateCmd(CmdContainer,true);//警示灯 - //加工时亮绿灯----------------------------------------- - if(m_bSetLightState) - { - CWorkCmd *pCmd = new CWorkCmdPciPortSwitch(PCI_PORT_LIGHT_G,true); - CmdContainer.AddCmd(pCmd); - } - if(m_bVacuum)//打开真空吸附 - { - CWorkCmd *pCmd = new CWorkCmdPciPortSwitch(PCI_PORT_VACUUM_OUT1,true); - CmdContainer.AddCmd(pCmd); - } - //等待运动结束 - { - CWorkCmdWaitMotorStop *pCmd = new CWorkCmdWaitMotorStop(); - if(gMotionCard_PCI1245->GetCurGpIdx() == 0) - pCmd->SetbWaitMotorX(); - else - pCmd->SetbWaitMotorX2(); - pCmd->SetbWaitMotorY(); - pCmd->SetbCheckActCoord();//检测实际光栅尺的坐标 - CmdContainer.AddCmd(pCmd); - } - //切换为工作速度 - { - CWorkCmdSetMotorSpeed *pCmd = new CWorkCmdSetMotorSpeed(); - if(gMotionCard_PCI1245->GetCurGpIdx() == 0) - pCmd->SetbSetMotorX(); - else - pCmd->SetbSetMotorX2(); - - pCmd->SetbSetMotorY(); - pCmd->SetSpeedType(_SpeedType_Work); - CmdContainer.AddCmd(pCmd); - } - - - / * if(m_bVacuum)//关闭真空吸附 - { - CWorkCmd *pCmd = new CWorkCmdPciPortSwitch(PCI_PORT_VACUUM_OUT1,false); - CmdContainer.AddCmd(pCmd); - }* / - //结束之后的工作 - { - CWorkCmd *pCmd = new CWorkCmdWorkEnd(); - CmdContainer.AddCmd(pCmd); - } - - //执行指令----------------------------------------------------- - Invoker.ExcuteAllCmd(); - - if(Invoker.IsCancel()) - return false; - if(!bSel)//记录工作次数 - { - gProductMgr->WorkTimesInc(); - }*/ - + gProductMgr->WorkTimesInc(); return true;//全部加工一次才返回true } @@ -1504,8 +1432,15 @@ bool CCommonFlowMgr::AutoMeasureVisionData() ofstream file; file.open(FilePath); //输出范围和间隔 - file<iSW%1i{8h)9^^Aj%{~Y2dFI`2URF6e2Iqp?-p`O#@@Ff9#T(ICQk&~;W zowVTm@|k3TENv$h-;41-x6VjN*G zVuKKnyfq=1Rf(>r+(Ds-y{*h`CJy>=1ZtD92k=c^=wihl$+l9(ICRj| z3~&V=Dab}V^!F6pq@9n!kgK#4SFW;H(a(BaEFn8MUGGjR!*H0d$jq}zyEupgKW$sE z^^1_aJqISh?U*b!B2eE97<19if1;I&^go{iU+R3S*wqxL;0wR2DhLmX?_pauKWSpn>Wk= delta 731 zcmX|;Ur19?9LMhuQ^%5R&f9fe^*ZNrI{)42TuD7d^x#V&QPP8imPrf|xyTR|2^q^m zH1{1l7Cvb7C?YJpPsLEPmx>q?J@gPEK9%gLx2UsoR}a7Q`ToAYFNgEv96z-^d~Dk` zoQOG7Sa;R3!S^KNldB&~E(bSK$W{6=SZQ#svmm2Q_^Mvw$f4q>Y7&F;5>Dh45@!~n zC`k->+<2oHoHF{VW1JekRTug+@}7Cb&MxrsKvfO+YupHH8nWsT*Q>Z$YxVh>A+A@E zs8eCDo8o+q9nHnFbDU|E`4o)SkKuFuJTEuKz0<;b(qKnL!$?t2amIOhvE>^VUbeA< z9e*ST`Wpv|Mj@o&hCe3w-9INdea`CbO;)c5+<4V=SIqRltl&XlvPd^Zo1qGDFwc?F7lBv!63`pXn>)JuPNZ zo7Bw{l?l4V`c*o`FV@+ISsG?rf5>L;KB9v%XGrShx${zlpS@BKTOOuPHgS)9Y<+}$ zrhS?0#Ma75G0T!P=49#DG-T#BsL#s=_DN=4yA-oj_P@Hm_s{!UR7+w{Gxe4fLbQ9^ K+9-(g7j> diff --git a/LaiPuLaser/LaipuVbDllMgr.cpp b/LaiPuLaser/LaipuVbDllMgr.cpp index cc801fc..c0b1f73 100644 --- a/LaiPuLaser/LaipuVbDllMgr.cpp +++ b/LaiPuLaser/LaipuVbDllMgr.cpp @@ -139,8 +139,21 @@ void CLaipuVbDllMgr::Marking_DA(double V,short XY) #if 1 void CLaipuVbDllMgr::CallMarkingData(vector> &vec) { - - + /*ofstream file; + string name = "MarkData.txt"; + if (gProgram_SZ_XL->IsbSelMarkMode()) + { + name = "MarkData-Sel.txt"; + } + file.open(name); + for ( auto itr:vec) + { + for (auto data:itr) + { + file << data.x << "," << data.y< &vec) return ret; } + //封装SAFEARRAY 的创建过程(需要在调用后释放资源) SAFEARRAY * CLaipuVbDllMgr::CreatSafeArray(vector> &vec) { diff --git a/LaiPuLaser/Laser.cpp b/LaiPuLaser/Laser.cpp index 1c1a372..9941543 100644 --- a/LaiPuLaser/Laser.cpp +++ b/LaiPuLaser/Laser.cpp @@ -52,6 +52,25 @@ CMFCPropertyGridProperty *CLaser::CreatGridProperty() pGroup->AddSubItem(p1); gDevicePropertieMgr.Insert(p1, pPropertie); } + + { + //添加属性变量映射 + Name = _T("m_CutSpeedIncrement");//变量名字 + CPropertie *pPropertie = new CPropertie; + pPropertie->SetpVal((void*)&m_CutSpeedIncrement); + pPropertie->SetType(_PROP_TYPE_INT); + pPropertie->SetpModule(this); + pPropertie->SetPath(Path); + pPropertie->SetName(Name); + pPropertie->WriteRead(true);//读取保存的属性 + //添加属性显示 + PropertyName = _T("切速增量"); + Description = _T("激光切割时,相对主机的速度增量."); + CMFCPropertyGridProperty* p1 = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_CutSpeedIncrement, Description); + pGroup->AddSubItem(p1); + gDevicePropertieMgr.Insert(p1, pPropertie); + } + { //添加属性变量映射 Name = _T("m_LaserCoord_x");//变量名字 diff --git a/LaiPuLaser/Laser.h b/LaiPuLaser/Laser.h index 826b7ba..ce02c29 100644 --- a/LaiPuLaser/Laser.h +++ b/LaiPuLaser/Laser.h @@ -24,9 +24,11 @@ public: void AddAdjustFocalCmd(); void OnOpen(); void OnClose(); + int m_CutSpeedIncrement = 0;//切割速度增量 + private: Dbxy m_LaserCoord;//激光垂直点在平台的坐标(PLATFORM_COORD) - int m_OpenDelay;//开关后延时 ms + int m_OpenDelay;//开关后延时 ms //激光焦距管理,Z 轴有电机的情况使用 double m_BaseThickness;//用来调试焦距的基准产品厚度mm diff --git a/LaiPuLaser/MarkArea.cpp b/LaiPuLaser/MarkArea.cpp index d87c92a..d749125 100644 --- a/LaiPuLaser/MarkArea.cpp +++ b/LaiPuLaser/MarkArea.cpp @@ -225,6 +225,31 @@ bool CMarkArea::CheckbNeedMark() } #endif //搜集在area 范围内的obj 数据(Product 是当前要加工的工件,主要用来偏移旋转数据) +void CMarkArea::CollectOrgWorkData(bool bNeedSel, CProduct &Product) +{ + + vector> &WorkDataVec = m_WorkData.GetDataVec(); + vector> &SpecialWorkDataVec = m_SpecialWorkData.GetDataVec(); + m_WorkData.Clear(); + m_SpecialWorkData.Clear();//特殊刀对象 + //先搜集元件对象数据----------------------------------- + CollectComponentObj(WorkDataVec, bNeedSel); + //收集特殊对象增加的数据 + gCommonFlowMgr->SetbCollectSpecialObj(true); + CollectComponentObj(SpecialWorkDataVec, bNeedSel); + gCommonFlowMgr->SetbCollectSpecialObj(false); + + //如果没有收集到原件的数据才搜集layer 中obj 的数据 + if (WorkDataVec.empty() && !gObjComponentMgr->HasObj()) + { + //先找到在area 内的obj + CObjContainer ObjContainer; + CollectLayerObj(ObjContainer); + //提取obj 的数据点(理论值) 这些数据是相对于layer 中心的坐标 + ObjContainer.GetObjPtData(WorkDataVec, bNeedSel); + } +} + void CMarkArea::CollectWorkData(bool bNeedSel,CProduct &Product) { gLogMgr->WriteDebugLog("func : CMarkArea---->CollectWorkData"); @@ -233,40 +258,22 @@ void CMarkArea::CollectWorkData(bool bNeedSel,CProduct &Product) //不要移动area 的中心 m_RealBasePt = m_BasePt; - + auto AreaCenter = m_RealBasePt; //将相对于layer 中心的数据转换为area 实际中心的数据 //数据的偏移调整(每个area 的单独调整量+ 整体性的调整量) - Dbxy Offset; - { + Dbxy Offset = gCommonFlowMgr->GetAdjustOffsetAll(); + + /*{ Dbxy AllOffset2; AllOffset2 = gCommonFlowMgr->GetAdjustOffsetAll(); Offset.x = AllOffset2.x;//-m_RealBasePt.x; Offset.y = AllOffset2.y;// -m_RealBasePt.y; - } - - if(bNeedSel) - { - m_WorkData.Clear(); - m_SpecialWorkData.Clear();//特殊刀对象 - vector> &WorkDataVec = m_WorkData.GetDataVec(); - vector> &SpecialWorkDataVec = m_SpecialWorkData.GetDataVec(); - //先搜集元件对象数据----------------------------------- - CollectComponentObj(WorkDataVec,bNeedSel); - //收集特殊对象增加的数据 - gCommonFlowMgr->SetbCollectSpecialObj(true); - CollectComponentObj(SpecialWorkDataVec,bNeedSel); - gCommonFlowMgr->SetbCollectSpecialObj(false); - - //如果没有收集到原件的数据才搜集layer 中obj 的数据 - if(WorkDataVec.empty() && !gObjComponentMgr->HasObj()) - { - //先找到在area 内的obj - CObjContainer ObjContainer; - CollectLayerObj(ObjContainer); - //提取obj 的数据点(理论值) 这些数据是相对于layer 中心的坐标 - ObjContainer.GetObjPtData(WorkDataVec,bNeedSel); - } - + }*/ + + if(1) + { + vector> &WorkDataVec = m_WorkData.GetDataVec(); + vector> &SpecialWorkDataVec = m_SpecialWorkData.GetDataVec(); bool HasData = false;//判断有没有数据 { vector>::iterator iter = WorkDataVec.begin(); @@ -282,13 +289,13 @@ void CMarkArea::CollectWorkData(bool bNeedSel,CProduct &Product) } if(!HasData) { - WorkDataVec.clear(); - SpecialWorkDataVec.clear(); + //WorkDataVec.clear(); + //SpecialWorkDataVec.clear(); return; } - Product.TheoryDataToRealData(WorkDataVec, m_BasePt,Offset); - Product.TheoryDataToRealData(SpecialWorkDataVec, m_BasePt,Offset); + Product.TheoryDataToRealData(WorkDataVec, AreaCenter,Offset); + Product.TheoryDataToRealData(SpecialWorkDataVec, AreaCenter,Offset); return; //根据抓取两个mark 来计算拉伸数据 @@ -298,16 +305,16 @@ void CMarkArea::CollectWorkData(bool bNeedSel,CProduct &Product) Product.StretchDataToRealSize(SpecialWorkDataVec); } //根据旋转偏移计算数据的实际值(相对于layer 中心) - Product.TheoryDataToRealData(WorkDataVec,Offset); - Product.TheoryDataToRealData(SpecialWorkDataVec,Offset); + Product.TheoryDataToRealData0(WorkDataVec, AreaCenter,Offset); + Product.TheoryDataToRealData0(SpecialWorkDataVec, AreaCenter,Offset); } else//全部加工时使用之前准备好的数据 { //检查是否需要加工 - if(CheckbNeedMark()) + /* if(CheckbNeedMark()) { Product.TheoryDataToRealData(m_SrcWorkData.GetDataVec(),m_DecWorkData.GetDataVec(),Offset); - } + }*/ } } bool CMarkArea::DrawObjComponentVec(vector> &vec,CDC* pDC,bool bSel) diff --git a/LaiPuLaser/MarkArea.h b/LaiPuLaser/MarkArea.h index 1eb8f7d..cb55bcc 100644 --- a/LaiPuLaser/MarkArea.h +++ b/LaiPuLaser/MarkArea.h @@ -24,6 +24,8 @@ public: void SetBasePt(Dbxy pt); DbSize GetSize(){return m_Size;}; + void CollectOrgWorkData(bool bNeedSel, CProduct & Product); + void CollectWorkData(bool bNeedSel,CProduct &Product); bool HasWorkData(); bool HasSpecialWorkData(); diff --git a/LaiPuLaser/MarkAreaMgr.cpp b/LaiPuLaser/MarkAreaMgr.cpp index f921d72..e36077d 100644 --- a/LaiPuLaser/MarkAreaMgr.cpp +++ b/LaiPuLaser/MarkAreaMgr.cpp @@ -329,18 +329,33 @@ void CMarkAreaMgr::MoveAllAreaToTargetPt(Dbxy TargetPt) #endif #if 1 + +void CMarkAreaMgr::CollectOrgWorkData(bool bNeedSel, CProduct &Product) +{ + gLogMgr->WriteDebugLog("func : CMarkAreaMgr---->CollectWorkData"); + //重置元件的收集状态 + gObjComponentMgr->ResetObjCollectState(false); + vector::iterator iter = m_AreaVec.begin(); + vector::iterator iter_end = m_AreaVec.end(); + for (;iter != iter_end;iter++) + { + (*iter).CollectOrgWorkData(bNeedSel, Product); + } +} //收集加工数据入口 void CMarkAreaMgr::CollectWorkData(bool bNeedSel,CProduct &Product) { + //Product.CalAffinePars(); gLogMgr->WriteDebugLog("func : CMarkAreaMgr---->CollectWorkData"); //重置元件的收集状态 gObjComponentMgr->ResetObjCollectState(false); vector::iterator iter = m_AreaVec.begin(); vector::iterator iter_end = m_AreaVec.end(); + for(;iter!=iter_end;iter++) - { - (*iter).CollectWorkData(bNeedSel,Product); + { + (*iter).CollectWorkData(bNeedSel, Product); } } diff --git a/LaiPuLaser/MarkAreaMgr.h b/LaiPuLaser/MarkAreaMgr.h index 6bbdb5b..9acca5f 100644 --- a/LaiPuLaser/MarkAreaMgr.h +++ b/LaiPuLaser/MarkAreaMgr.h @@ -35,6 +35,7 @@ public: void MoveAllArea(double Val,DIRECTION dir); void SelAreaByPt(Dbxy pt); void SetAllMarkSize(); + void CollectOrgWorkData(bool bNeedSel, CProduct & Product); void CollectWorkData(bool bNeedSel,CProduct &Product); void SelFristArea(); void SetbDrawIdx(bool b){m_bDrawIdx = b;}; diff --git a/LaiPuLaser/MarkCtrl.cpp b/LaiPuLaser/MarkCtrl.cpp index df60934..b729724 100644 --- a/LaiPuLaser/MarkCtrl.cpp +++ b/LaiPuLaser/MarkCtrl.cpp @@ -88,7 +88,7 @@ void CMarkCtrl::StartMarkPci(vector> &DateVec,vector> LaipuVbDll.CallMarkingEnd(fileno,fileAll,MarkM,m_sel,head,NULL);//结束 #endif // NoPCI_MarkData2Txt } - +#include "Laser.h" //设置标刻参数 void CMarkCtrl::SetMarkParam(CLaipuVbDllMgr &LaipuVbDll) @@ -97,7 +97,7 @@ void CMarkCtrl::SetMarkParam(CLaipuVbDllMgr &LaipuVbDll) CMarkPar &MarkPar = gMarkParMgr->GetCurPen(); //振镜参数-------------------------------------------------------------- //float ms = MarkPar.ms;//标刻速度mm/s - float ms = (float)gCommonFlowMgr->GetCutSpeed(); + float ms = (float)(gCommonFlowMgr->GetCutSpeed()+gLaser->m_CutSpeedIncrement); float mms = MarkPar.mms;//空移速度mm/s long tcf = MarkPar.tcf;//关激光前延时us long tch = MarkPar.tch;//关激光后延时us diff --git a/LaiPuLaser/MarkData.txt b/LaiPuLaser/MarkData.txt deleted file mode 100644 index 8d01d27..0000000 --- a/LaiPuLaser/MarkData.txt +++ /dev/null @@ -1,6 +0,0 @@ -MarkData: X=32.332754;Y=17.384913 -MarkData: X=25.515365;Y=17.075846 -MarkData: X=32.218140;Y=19.913061 -MarkData: X=25.400751;Y=19.603994 -MarkData: X=31.913434;Y=26.634239 -MarkData: X=25.096045;Y=26.325171 diff --git a/LaiPuLaser/MarkData_Server.txt b/LaiPuLaser/MarkData_Server.txt new file mode 100644 index 0000000..b3ffdc7 --- /dev/null +++ b/LaiPuLaser/MarkData_Server.txt @@ -0,0 +1,10 @@ +TD: 87.873390,-5.896572 +RD: 30.300570,20.521548 +TD: 87.873390,-5.896572 +RD: 30.300570,20.521548 +TD: 87.646767,-5.699993 +RD: 30.073516,20.717701 +TD: 87.646767,-3.299999 +RD: 30.068488,23.117649 +TD: 87.857735,-3.086712 +RD: 30.279026,23.331325 diff --git a/LaiPuLaser/ModuleMgr.cpp b/LaiPuLaser/ModuleMgr.cpp index 4b96ca9..85e3b46 100644 --- a/LaiPuLaser/ModuleMgr.cpp +++ b/LaiPuLaser/ModuleMgr.cpp @@ -194,4 +194,4 @@ void CModuleMgr::OnExitApp() //延时等待线程结束,避免报错 Sleep(2000); } -#endif \ No newline at end of file +#endif diff --git a/LaiPuLaser/ObjComponent.h b/LaiPuLaser/ObjComponent.h index e06b70a..cb82f1f 100644 --- a/LaiPuLaser/ObjComponent.h +++ b/LaiPuLaser/ObjComponent.h @@ -2,7 +2,7 @@ #include "GlobalDefine.h" #include "SmartPtr.h" #include "ObjBase.h" - +#include //元件对象 class CObjComponent { @@ -55,6 +55,8 @@ public: void SetbHide(bool b){m_bHide = b;}; void SetbMark1Obj(bool b){m_bMark1Obj = b;}; bool IsbMark1Obj(){return m_bMark1Obj;}; + void SetbMark2Obj(bool b) { m_bMark2Obj = b; }; + bool IsbMark2Obj() { return m_bMark2Obj; }; void SetSelObjPenNum(); bool IsbSpecialObj(); void SetObjOffset(Dbxy Offset){m_ObjOffset = Offset;}; @@ -67,12 +69,14 @@ private: bool m_bBase;//是否为基准元件 bool m_bSel;//是否被选中 bool m_bCircle;//是否为圆形 - bool m_bCollected;//数据是否已经被收集过了,避免重复收集 + //atomic_bool m_bCollected;//数据是否已经被收集过了,避免重复收集 + bool m_bCollected;//数据是否已经被收集过了,避免重复收集 bool m_bMarked;//是否被加工过了 bool m_bCollecteData;//是否需要收集加工数据(false 的时候不收集obj 的数据) bool m_bMarkObj;//是否为标记的obj (用于CCD 定位) - bool m_bMark1Obj;//第一个mark - bool m_bMark3Obj;//是否为mark3 + bool m_bMark1Obj=false;//是否为mark1 + bool m_bMark2Obj=false;//是否为mark2 + bool m_bMark3Obj=false;//是否为mark3 bool m_bHide;//是否隐藏 Dbxy m_BasePt;//元件的基准点(中心点) diff --git a/LaiPuLaser/ObjComponentMgr.cpp b/LaiPuLaser/ObjComponentMgr.cpp index 51709e7..9146079 100644 --- a/LaiPuLaser/ObjComponentMgr.cpp +++ b/LaiPuLaser/ObjComponentMgr.cpp @@ -379,15 +379,17 @@ void CObjComponentMgr::Draw(CDC* pDC) { if(m_ComponentVec[i].IsbMark1Obj()) str = "Mark1"; - else + if (m_ComponentVec[i].IsbMark2Obj()) str = "Mark2"; + if (m_ComponentVec[i].IsbMark3Obj()) + str = "Mark3"; gDraw->DrawTxt(pDC,str,m_ComponentVec[i].GetBasePt()); } - else if(m_ComponentVec[i].IsbMark3Obj()) + /* else if(m_ComponentVec[i].IsbMark3Obj()) { str = "Mark3"; gDraw->DrawTxt(pDC,str,m_ComponentVec[i].GetBasePt()); - } + }*/ m_ComponentVec[i].Draw(pDC); } Dbxy Offset; @@ -635,7 +637,7 @@ void CObjComponentMgr::SetMarkObj() bool CObjComponentMgr::GetTwoMarkPt(Dbxy &MarkPt1,Dbxy &MarkPt2) { int MarkCnt = GetMarkObjCnt(); - if(MarkCnt != 2) + if(MarkCnt != 3) { return false; } @@ -651,9 +653,8 @@ bool CObjComponentMgr::GetTwoMarkPt(Dbxy &MarkPt1,Dbxy &MarkPt2) if((*iter).IsbMark1Obj()) { MarkPt1 = pt; - bMark1 = false; } - else + if ((*iter).IsbMark2Obj()) { MarkPt2 = pt; } @@ -1023,9 +1024,65 @@ void CObjComponentMgr::AnalyseMarkPt() { bool flg = false; int size = MarkVec.size(); - if(size>=2) + if (size == 3) + { + flg = true; + MarkVec[0]->SetbMark1Obj(true); + MarkVec[1]->SetbMark2Obj(true); + MarkVec[2]->SetbMark3Obj(true); + + MarkVec[0]->SetbMarkObj(true); + MarkVec[1]->SetbMarkObj(true); + MarkVec[2]->SetbMarkObj(true); + } + /* if(size>=3) { - double MaxX,MinX; + + sort(MarkVec.begin(), MarkVec.end(), [](CObjComponent * & a, CObjComponent* & b) {return (a->GetBasePt().y) < (b->GetBasePt().y); }); + + vector MaxYVec;//Y值最大的容器 + vector MinYVec;//Y值最小的容器 + + double MaxY = (*MarkVec.rbegin())->GetBasePt().y; + double MinY = (*MarkVec.begin())->GetBasePt().y; + + for (auto it:MarkVec) + { + double tempY = (it->GetBasePt()).y; + if (IsTwoDbEqual(tempY,MaxY)) + { + MaxYVec.push_back(it); + } + if (IsTwoDbEqual(tempY, MinY)) + { + MinYVec.push_back(it); + } + } + + sort(MaxYVec.begin(), MaxYVec.end(), [](CObjComponent * & a, CObjComponent* & b) {return (a->GetBasePt().x) < (b->GetBasePt().x); }); + sort(MinYVec.begin(), MinYVec.end(), [](CObjComponent * & a, CObjComponent* & b) {return (a->GetBasePt().x) < (b->GetBasePt().x); }); + + if (MaxYVec.size() > 1) + { + (*MaxYVec.begin())->SetbMark1Obj(true); + (*MaxYVec.rbegin())->SetbMark2Obj(true); + (*MinYVec.begin())->SetbMark3Obj(true); + (*MaxYVec.begin())->SetbMarkObj(true); + (*MaxYVec.rbegin())->SetbMarkObj(true); + (*MinYVec.begin())->SetbMarkObj(true); + } + else + { + (*MinYVec.begin())->SetbMark1Obj(true); + (*MinYVec.rbegin())->SetbMark2Obj(true); + (*MaxYVec.begin())->SetbMark3Obj(true); + (*MinYVec.begin())->SetbMarkObj(true); + (*MinYVec.rbegin())->SetbMarkObj(true); + (*MaxYVec.begin())->SetbMarkObj(true); + } + flg = true; + + / *double MaxX,MinX; double Mark1Idx = 0; double Mark2Idx = 0; double Mark3Idx = -1; @@ -1085,8 +1142,8 @@ void CObjComponentMgr::AnalyseMarkPt() MarkVec[Mark3Idx]->SetbMark3Obj(true);//标记为mark3 MarkVec[Mark3Idx]->NotCollect();//不要收集加工数据 MarkVec[Mark3Idx]->SetbMark1Obj(false); - } - } + }* / + }*/ if(!flg) { CMsgBox MsgBox; diff --git a/LaiPuLaser/Product.cpp b/LaiPuLaser/Product.cpp index b458b47..d48d3b5 100644 --- a/LaiPuLaser/Product.cpp +++ b/LaiPuLaser/Product.cpp @@ -8,7 +8,7 @@ #include "CommonFlowMgr.h" #include "DrawSimpleShape.h" - + //IMPLEMENT_SERIAL(CProduct,CObject,1) CProduct::CProduct(void) { m_bUsed = true;//是否使用 @@ -101,7 +101,6 @@ bool CProduct::IsSetRealMarkPt2() //定位数据是否准备好了 bool CProduct::IsMarkReady() { - return true; Dbxy MarkPt1; Dbxy MarkPt2; if(gObjComponentMgr->GetTwoMarkPt(MarkPt1,MarkPt2))//有定位点 @@ -113,7 +112,7 @@ bool CProduct::IsMarkReady() return gCommonFlowMgr->IsNoMarkCanWork(); } } -//设置实际定位点坐标(CCD 的抓取结果) +//设置实际定位点坐标(CCD 的抓取结果)抓完最后一个点时,计算数据旋转、平移、拉伸参数,用于后续计算 void CProduct::SetRealMarkPt(Dbxy pt) { if(IsSetRealMarkPt1() && IsSetRealMarkPt2()) @@ -160,35 +159,68 @@ void CProduct::SetRealMarkPt(Dbxy pt) CalTheoryToRealPar(); } } - +#include"CameraHawkvis.h" #include using namespace cv; void CProduct::CalAffinePars() { + //微调角度的仿射系数 + { + Point2f PRThroryCoords[3];//旋转前理论值 + Point2f ARRealCoords[3];//旋转后实际值 + PRThroryCoords[0] = Point2f(0, -1000); + PRThroryCoords[1] = Point2f(1000, 0); + PRThroryCoords[2] = Point2f(0, 1000); + auto angle = gProductMgr->GetAdjustAngle(); + angle = _360ToAngle(angle); + auto SinAngle = sin(angle); + auto CosAngle = cos(angle); + ARRealCoords[0] = Point2f(1000*SinAngle, -1000*CosAngle); + ARRealCoords[1] = Point2f(1000*CosAngle, 1000*SinAngle); + ARRealCoords[2] = Point2f(-1000*SinAngle, 1000*CosAngle); + + Mat warp_mat(2, 3, CV_32FC1); + //得放射变换参数矩阵 + warp_mat = getAffineTransform(PRThroryCoords, ARRealCoords); + warp_mat.convertTo(warp_mat, CV_32FC1);//不转化时,默认CV_64FC1 后续计算会错误 + + //取出6个变换参数 + m_rp00 = warp_mat.at(0, 0); + m_rp01 = warp_mat.at(0, 1); + m_p02 = warp_mat.at(0, 2); + + m_rp10 = warp_mat.at(1, 0); + m_rp11 = warp_mat.at(1, 1); + m_rp12 = warp_mat.at(1, 2); + } + +/* + CString logstr; + Dbxy T2oft = Dbxy(0, 0); - o_TheoryMarkPt1 = m_TheoryMarkPt1 - m_BasePt; + o_TheoryMarkPt1 = m_TheoryMarkPt1 - m_BasePt-T2oft; logstr.Format("TheoryMarkPt1 Coord(%f,%f)", o_TheoryMarkPt1.x, o_TheoryMarkPt1.y); gLogMgr->WriteDebugLog(logstr); - o_TheoryMarkPt2 = m_TheoryMarkPt2 - m_BasePt; + o_TheoryMarkPt2 = m_TheoryMarkPt2 - m_BasePt-T2oft; logstr.Format("TheoryMarkPt2 Coord(%f,%f)", o_TheoryMarkPt2.x, o_TheoryMarkPt2.y); gLogMgr->WriteDebugLog(logstr); - o_TheoryMarkPt3 = m_TheoryMarkPt3 - m_BasePt; + o_TheoryMarkPt3 = m_TheoryMarkPt3 - m_BasePt-T2oft; logstr.Format("TheoryMarkPt3 Coord(%f,%f)", o_TheoryMarkPt3.x, o_TheoryMarkPt3.y); gLogMgr->WriteDebugLog(logstr); - o_RealMarkPt1 = m_RealMarkPt1 - m_BasePt; + o_RealMarkPt1 = m_RealMarkPt1 - m_BasePt-T2oft; logstr.Format("RealMarkPt1 Coord(%f,%f)", o_RealMarkPt1.x, o_RealMarkPt1.y); gLogMgr->WriteDebugLog(logstr); - o_RealMarkPt2 = m_RealMarkPt2 - m_BasePt; + o_RealMarkPt2 = m_RealMarkPt2 - m_BasePt-T2oft; logstr.Format("RealMarkPt2 Coord(%f,%f)", o_RealMarkPt2.x, o_RealMarkPt2.y); gLogMgr->WriteDebugLog(logstr); - o_RealMarkPt3 = m_RealMarkPt3 - m_BasePt; + o_RealMarkPt3 = m_RealMarkPt3 - m_BasePt-T2oft; logstr.Format("RealMarkPt3 Coord(%f,%f)", o_RealMarkPt3.x, o_RealMarkPt3.y); gLogMgr->WriteDebugLog(logstr); @@ -208,15 +240,16 @@ void CProduct::CalAffinePars() { gTrackWorkFlow1.RadAlamOnOff(true);//报警提示 ResetRealMarkPt(); - CString LogStr("Mark 间距误差超出范围,定位可能误判!"); + CString LogStr("Mark 间距误差超出范围,定位可能误判!\r\n"); + logstr = LogStr + logstr; AfxMessageBox(logstr); gTrackWorkFlow1.RadAlamOnOff(false);//报警提示 CExceptionMsg Msg; Msg.SetMsg(CString("")); throw Msg;//抛出异常 - /* CExceptionMsg Msg; + / * CExceptionMsg Msg; Msg.SetMsg(LogStr); - throw Msg;*/ + throw Msg;* / } Point2f ThroryCoords[3]; @@ -245,6 +278,7 @@ void CProduct::CalAffinePars() m_p11 = warp_mat.at(1, 1); m_p12 = warp_mat.at(1, 2); +*/ } //计算真实数据的偏移和旋转值 @@ -292,7 +326,6 @@ void CProduct::CalTheoryToRealPar() gLogMgr->WriteDebugLog(LogStr); if(DisDiff > abs(gProductMgr->GetMaxMarkDisDiff())) { - gTrackWorkFlow1.RadAlamOnOff(true);//报警提示 ResetRealMarkPt(); CString LogStr("Mark 间距误差超出范围,定位可能误判!"); @@ -348,34 +381,94 @@ void CProduct::TheoryDataToRealData(vector &vec,Dbxy &Offset) vector::iterator iter_end = vec.end(); for(;iter!=iter_end;iter++) { - (*iter) = TheoryPtToRealPt((*iter)); - (*iter).x += Offset.x; - (*iter).y += Offset.y; + auto & it = (*iter); + it = TheoryPtToRealPt(it); + it = it + Offset; + //(*iter).x += Offset.x; + //(*iter).y += Offset.y; } } +void CProduct::TheoryDataToRealData0(vector>& vec, Dbxy & AreaCenter, Dbxy CutAdjust) +{ + gLogMgr->WriteDebugLog("CProduct::TheoryDataToRealData"); + vector>::iterator iter = vec.begin(); + vector>::iterator iter_end = vec.end(); + for (;iter != iter_end;iter++) + { + TheoryDataToRealData0(*iter, AreaCenter, CutAdjust); + } +} + +void CProduct::TheoryDataToRealData0(vector& vec, Dbxy & AreaCenter, Dbxy CutAdjust) +{ + vector::iterator iter = vec.begin(); + vector::iterator iter_end = vec.end(); + for (;iter != iter_end;iter++) + { + auto & it = (*iter); + it = TheoryPtToRealPt(it); + it = it - AreaCenter; + + //振镜缩放 + Dbxy Scale = gProgram_SZ_XL->GetJig2Scale(); + if (gServer->m_RcvCurTrackIndex == 1) + { + Scale = gProgram_SZ_XL->GetJig4Scale(); + } + it.x *= Scale.x; + it.y *= Scale.y; + + it = it + CutAdjust; + + } +} + //理论数据转换为实际数据 -void CProduct::TheoryDataToRealData(vector &vec, Dbxy &BaseOffset, Dbxy CutAdjust) +void CProduct::TheoryDataToRealData(vector &vec, Dbxy &AreaCenter, Dbxy CutAdjust) { vector::iterator iter = vec.begin(); vector::iterator iter_end = vec.end(); + + //原图中心 + //gObjComponentMgr->CalAllObjCenterPt(); + //Dbxy DataCenter = gObjComponentMgr->GetAllObjCenterPt(); + for (;iter != iter_end;iter++) { - //(*iter) = TheoryPtToRealPt((*iter)); - //(*iter) = (*iter) - m_BasePt; + //(*iter) = (*iter) - DataCenter; //移动至以(0,0)(全数据中心点)为原点 + auto x = (*iter).x; auto y = (*iter).y; - double retx = m_p00*x + m_p01*y + m_p02+ CutAdjust.x; - double rety = m_p10*x + m_p11*y + m_p12+ CutAdjust.y; - (*iter).x = retx; - (*iter).y = rety; - auto temp = BaseOffset - m_BasePt; + //根据仿射变换参数计算整图 + double retx = m_p00*x + m_p01*y + m_p02; + double rety = m_p10*x + m_p11*y + m_p12; + + //强制的微调旋转量 + //double retx2 = m_rp00*retx + m_rp01*rety + m_rp02; + //double rety2 = m_rp10*retx + m_rp11*rety + m_rp12; + (*iter).x = retx; + (*iter).y= rety; + //移动至以区域中心为原点 + auto temp = AreaCenter;//-DataCenter; (*iter) = (*iter) - temp; - - /*(*iter).x += CutAdjust.x; - (*iter).y += CutAdjust.y;*/ + + //振镜缩放 + Dbxy Scale = gProgram_SZ_XL->GetJig2Scale(); + if (gServer->m_RcvCurTrackIndex == 1) + { + Scale = gProgram_SZ_XL->GetJig4Scale(); + } + (*iter).x *= Scale.x; + (*iter).y *= Scale.y; + + //偏移调整 + (*iter).x += CutAdjust.x; + (*iter).y +=CutAdjust.y; + + } } void CProduct::ResetAffinePars() @@ -467,6 +560,9 @@ void CProduct::StretchDataToRealSize(vector> &vec) } } } + +/* + //理论数据转换为实际数据(SrcVec 和DecVec 的大小必须一致) void CProduct::TheoryDataToRealData(vector> &SrcVec,vector> &DecVec,Dbxy &Offset) { @@ -500,9 +596,17 @@ void CProduct::TheoryDataToRealData(vector &SrcVec,vector &DecVec,Db DecVec[k].y += Offset.y; } } +*/ + + //(TheoryPt 先旋转,再相对偏移) Dbxy CProduct::TheoryPtToRealPt(Dbxy TheoryPt) { + /*Dbxy ret; + ret.x = TheoryPt.x*m_p00 + TheoryPt.y*m_p01 + m_p02; + ret.y = TheoryPt.x*m_p10 + TheoryPt.y*m_p11 + m_p12; + return ret;*/ + double RotateAng = m_RotateAng; Dbxy pt; //先旋转---------------------------------- @@ -530,14 +634,14 @@ void CProduct::TheoryDataToRealData(vector> &vec,Dbxy &Offset) //理论数据转换为实际数据 -void CProduct::TheoryDataToRealData(vector> &vec, Dbxy &BaseOffset, Dbxy CutAdjust) +void CProduct::TheoryDataToRealData(vector> &vec, Dbxy &AreaCenter, Dbxy CutAdjust) { gLogMgr->WriteDebugLog("CProduct::TheoryDataToRealData"); vector>::iterator iter = vec.begin(); vector>::iterator iter_end = vec.end(); for (;iter != iter_end;iter++) { - TheoryDataToRealData(*iter, BaseOffset,CutAdjust); + TheoryDataToRealData(*iter, AreaCenter,CutAdjust); } } #endif diff --git a/LaiPuLaser/Product.h b/LaiPuLaser/Product.h index 5c803a5..b2aab11 100644 --- a/LaiPuLaser/Product.h +++ b/LaiPuLaser/Product.h @@ -4,9 +4,10 @@ //工件产品 -class CProduct +class CProduct//:public CObject { friend class CProductMgr; + // DECLARE_SERIAL(CProduct) public: CProduct(void); ~CProduct(void); @@ -27,17 +28,23 @@ public: void SetbHasMarkPt3(bool b){m_bHasMarkPt3 = b;}; void SetTheoryMark3Pt(Dbxy pt){m_TheoryMarkPt3 = pt;}; void SetRealMark3Pt(Dbxy pt){m_RealMarkPt3 = pt;}; - Dbxy TheoryPtToRealPt(Dbxy TheoryMarkPt); + Dbxy TheoryPtToRealPt(Dbxy TheoryMarkPt); void StretchDataToRealSize(vector> &vec); void TheoryDataToRealData(vector> &vec, Dbxy &Offset); void TheoryDataToRealData(vector &vec, Dbxy &Offset); - void TheoryDataToRealData(vector& vec, Dbxy & BaseOffset, Dbxy CutAdjust); + + void TheoryDataToRealData0(vector& vec, Dbxy & AreaCenter, Dbxy CutAdjust);//旧算法更改后 + void TheoryDataToRealData0(vector>& vec, Dbxy & AreaCenter, Dbxy CutAdjust);//旧算法更改后 + + + void TheoryDataToRealData(vector& vec, Dbxy & AreaCenter, Dbxy CutAdjust); + void TheoryDataToRealData(vector>& vec, Dbxy & AreaCenter, Dbxy CutAdjust); void ResetAffinePars();//重置仿射变换参数 - void TheoryDataToRealData(vector>& vec, Dbxy & BaseOffset, Dbxy CutAdjust); - void TheoryDataToRealData(vector> &SrcVec,vector> &DecVec,Dbxy &Offset); - void TheoryDataToRealData(vector &SrcVec,vector &DecVec,Dbxy &Offset); + /*void TheoryDataToRealData(vector> &SrcVec, vector> &DecVec, Dbxy &Offset); + void TheoryDataToRealData(vector &SrcVec, vector &DecVec, Dbxy &Offset);*/ + bool IsSetRealMarkPt1(); bool IsSetRealMarkPt2(); void UseDefualtOffset(); @@ -46,8 +53,8 @@ public: void SetbLastOne(bool b){m_bLastOne = b;}; void SetbNewAddProduct(bool bNew) { m_bNewAddProduct = bNew; };//设置是否是改造新增的产品 bool IsbNewAddProduct() { return m_bNewAddProduct; };//查询是否是改造新增的产品 -private: void CalAffinePars(); +private: void CalTheoryToRealPar(); Dbxy CalRealProductScale(); void StretchPt(Dbxy &Pt,SObjOperatePar &Par); @@ -85,6 +92,14 @@ public: float m_p10=0; float m_p11=1; float m_p12=0; + //强制(微调)旋转角度的仿射参数(应对平台不垂直)------------------------------------ + float m_rp00 = 1; + float m_rp01 = 0; + float m_rp02 = 0; + + float m_rp10 = 0; + float m_rp11 = 1; + float m_rp12 = 0; public: //实际偏移旋转结果--------------------------------- Dbxy m_Offset;//理论数据映射为平台坐标的偏移 @@ -93,5 +108,6 @@ public: SObjOperatePar m_StretchParX;//X 方向拉伸参数 SObjOperatePar m_StretchParY;//Y 方向拉伸参数 + //virtual void Serialize(CArchive& ar); }; diff --git a/LaiPuLaser/Product0.cpp b/LaiPuLaser/Product0.cpp new file mode 100644 index 0000000..f917214 --- /dev/null +++ b/LaiPuLaser/Product0.cpp @@ -0,0 +1,543 @@ +#include "StdAfx.h" +#include "Product.h" +#include "GlobalFunction.h" +#include "LogMgr.h" +#include "ObjComponentMgr.h" +#include "ExceptionMsg.h" +#include "ProductMgr.h" +#include "CommonFlowMgr.h" +#include "DrawSimpleShape.h" + + +CProduct::CProduct(void) +{ + m_bUsed = true;//是否使用 + m_MaxRotateAng = 0.3;//最大旋转角度 + m_RotateAng = 0; + m_bLastOne = true;//是否为最后一个 + m_bHasMarkPt3 = false;//是否有mark3 +} +CProduct::~CProduct(void) +{ +} +void CProduct::Draw(CDC* pDC) +{ + CPen Pen; + Pen.CreatePen(PS_INSIDEFRAME,0.5,RGB_GREEN1); + DbRect Rect(m_BasePt,3); + DrawCrossX(pDC,Pen,Rect); +} +#if 1 +//设置定位点理论坐标 +void CProduct::SetTheoryMarkPt(Dbxy pt1,Dbxy pt2) +{ + if(pt1.x &LabVec) +{ + LabVec.push_back(CLab(LAB_NULL,m_BasePt.x)); + LabVec.push_back(CLab(LAB_NULL,m_BasePt.y)); + LabVec.push_back(CLab(LAB_NULL,m_bUsed)); + LabVec.push_back(CLab(LAB_NULL,m_TheoryMarkPt1.x)); + LabVec.push_back(CLab(LAB_NULL,m_TheoryMarkPt1.y)); + LabVec.push_back(CLab(LAB_NULL,m_TheoryMarkPt2.x)); + LabVec.push_back(CLab(LAB_NULL,m_TheoryMarkPt2.y)); +} +void CProduct::ReadWorkFile(CLabVecRang &LabVecRang) +{ + int idx = LabVecRang.GetStart(); + m_BasePt.x = LabVecRang.GetDouble(idx++); + m_BasePt.y = LabVecRang.GetDouble(idx++); + m_bUsed = LabVecRang.GetBool(idx++); + m_TheoryMarkPt1.x = LabVecRang.GetDouble(idx++); + m_TheoryMarkPt1.y = LabVecRang.GetDouble(idx++); + m_TheoryMarkPt2.x = LabVecRang.GetDouble(idx++); + m_TheoryMarkPt2.y = LabVecRang.GetDouble(idx++); +} +#endif +#if 1 +//重设实际定位点 +void CProduct::ResetRealMarkPt() +{ + m_RealMarkPt1.x = 0; + m_RealMarkPt1.y = 0; + m_RealMarkPt2.x = 0; + m_RealMarkPt2.y = 0; + //m_RealMarkPt3.x = 0; + //m_RealMarkPt3.y = 0; + //偏移和旋转都要重设 + m_Offset.x = 0;//理论数据映射为平台坐标的偏移X + m_Offset.y = 0;//理论数据映射为平台坐标的偏移Y + m_RotateAng = 0;//理论数据映射为平台坐标的旋转角度 +} +bool CProduct::IsSetRealMarkPt1() +{ + return (!IsDbxyZero(m_RealMarkPt1)); +} +bool CProduct::IsSetRealMarkPt2() +{ + return (!IsDbxyZero(m_RealMarkPt2)); +} +//定位数据是否准备好了 +bool CProduct::IsMarkReady() +{ + return true; + Dbxy MarkPt1; + Dbxy MarkPt2; + if(gObjComponentMgr->GetTwoMarkPt(MarkPt1,MarkPt2))//有定位点 + { + return IsSetRealMarkPt1() && IsSetRealMarkPt2(); + } + else//无定位点 + { + return gCommonFlowMgr->IsNoMarkCanWork(); + } +} +//设置实际定位点坐标(CCD 的抓取结果) +void CProduct::SetRealMarkPt(Dbxy pt) +{ + if(IsSetRealMarkPt1() && IsSetRealMarkPt2()) + { + //重设实际定位点 + ResetRealMarkPt(); + } + //如果没有设置定位点1的情况先设置定位点1 + if(!IsSetRealMarkPt1()) + { + gLogMgr->WriteDebugLog("SetRealMarkPt1"); + m_RealMarkPt1 = pt; + } + //设置了定位点1,没设置定位点2 时设置定位点2 + else if(!IsSetRealMarkPt2()) + { + gLogMgr->WriteDebugLog("SetRealMarkPt2"); + m_RealMarkPt2 = pt; + double RotatoAdjustX = gCommonFlowMgr->GetRotatoAdjust();//mark点手动调整量 + m_RealMarkPt2.x += RotatoAdjustX; + } + + //需要同时设置了理论数据和真实数据的定位点坐标才能计算 + if(!IsSetRealMarkPt1() || !IsSetRealMarkPt2()) + return; + + CalAffinePars(); + return; + + //计算偏移旋转 + CalTheoryToRealPar(); + + //根据抓取两个mark 来计算拉伸数据 + if(gCommonFlowMgr->IsbStretchDataToRealSize()) + { + //计算拉伸实际尺寸拉伸参数 + CalRealStretchPar(); + //把理论定位点坐标拉伸 + StretchPt(m_TheoryMarkPt1,m_StretchParX); + StretchPt(m_TheoryMarkPt1,m_StretchParY); + StretchPt(m_TheoryMarkPt2,m_StretchParX); + StretchPt(m_TheoryMarkPt2,m_StretchParY); + //重新计算旋转和偏移 + CalTheoryToRealPar(); + } +} + +#include +using namespace cv; + +void CProduct::CalAffinePars() +{ + CString logstr; + + o_TheoryMarkPt1 = m_TheoryMarkPt1 - m_BasePt; + logstr.Format("TheoryMarkPt1 Coord(%f,%f)", o_TheoryMarkPt1.x, o_TheoryMarkPt1.y); + gLogMgr->WriteDebugLog(logstr); + + o_TheoryMarkPt2 = m_TheoryMarkPt2 - m_BasePt; + logstr.Format("TheoryMarkPt2 Coord(%f,%f)", o_TheoryMarkPt2.x, o_TheoryMarkPt2.y); + gLogMgr->WriteDebugLog(logstr); + + o_TheoryMarkPt3 = m_TheoryMarkPt3 - m_BasePt; + logstr.Format("TheoryMarkPt3 Coord(%f,%f)", o_TheoryMarkPt3.x, o_TheoryMarkPt3.y); + gLogMgr->WriteDebugLog(logstr); + + o_RealMarkPt1 = m_RealMarkPt1 - m_BasePt; + logstr.Format("RealMarkPt1 Coord(%f,%f)", o_RealMarkPt1.x, o_RealMarkPt1.y); + gLogMgr->WriteDebugLog(logstr); + + o_RealMarkPt2 = m_RealMarkPt2 - m_BasePt; + logstr.Format("RealMarkPt2 Coord(%f,%f)", o_RealMarkPt2.x, o_RealMarkPt2.y); + gLogMgr->WriteDebugLog(logstr); + + o_RealMarkPt3 = m_RealMarkPt3 - m_BasePt; + logstr.Format("RealMarkPt3 Coord(%f,%f)", o_RealMarkPt3.x, o_RealMarkPt3.y); + gLogMgr->WriteDebugLog(logstr); + + double TheoryDis = CalDistance(o_TheoryMarkPt1, o_TheoryMarkPt2); + logstr.Format("[Mark1&2理论间距]: [%f]", TheoryDis); + gLogMgr->WriteDebugLog(logstr); + + double RealDis = CalDistance(o_RealMarkPt1, o_RealMarkPt2); + logstr.Format("[Mark1&2真实间距]: [%f]", RealDis); + gLogMgr->WriteDebugLog(logstr); + + double DisDiff = abs(TheoryDis - RealDis); + logstr.Format(_T("[Mark 间距误差] = [%f]"), DisDiff); + gLogMgr->WriteDebugLog(logstr); + + if (DisDiff > abs(gProductMgr->GetMaxMarkDisDiff())) + { + gTrackWorkFlow1.RadAlamOnOff(true);//报警提示 + ResetRealMarkPt(); + CString LogStr("Mark 间距误差超出范围,定位可能误判!"); + AfxMessageBox(logstr); + gTrackWorkFlow1.RadAlamOnOff(false);//报警提示 + CExceptionMsg Msg; + Msg.SetMsg(CString("")); + throw Msg;//抛出异常 + /* CExceptionMsg Msg; + Msg.SetMsg(LogStr); + throw Msg;*/ + } + + Point2f ThroryCoords[3]; + Point2f RealCoords[3]; + + Mat warp_mat(2, 3, CV_32FC1); + + ThroryCoords[1] = Point2f(o_TheoryMarkPt1.x, o_TheoryMarkPt1.y); + ThroryCoords[2] = Point2f(o_TheoryMarkPt2.x, o_TheoryMarkPt2.y); + ThroryCoords[0] = Point2f(o_TheoryMarkPt3.x, o_TheoryMarkPt3.y); + + RealCoords[1] = Point2f(o_RealMarkPt1.x, o_RealMarkPt1.y); + RealCoords[2] = Point2f(o_RealMarkPt2.x, o_RealMarkPt2.y); + RealCoords[0] = Point2f(o_RealMarkPt3.x, o_RealMarkPt3.y); + + //得放射变换参数矩阵 + warp_mat = getAffineTransform(ThroryCoords, RealCoords); + warp_mat.convertTo(warp_mat, CV_32FC1);//不转化时,默认CV_64FC1 后续计算会错误 + + //取出6个变换参数 + m_p00 = warp_mat.at(0, 0); + m_p01 = warp_mat.at(0, 1); + m_p02 = warp_mat.at(0, 2); + + m_p10 = warp_mat.at(1, 0); + m_p11 = warp_mat.at(1, 1); + m_p12 = warp_mat.at(1, 2); + + +} +//计算真实数据的偏移和旋转值 +void CProduct::CalTheoryToRealPar() +{ + gLogMgr->WriteDebugLog("func : CalTheoryToRealPar"); + + //以第一个点的来计算相对的偏移 + m_Offset.x = m_RealMarkPt1.x - m_TheoryMarkPt1.x; + m_Offset.y = m_RealMarkPt1.y - m_TheoryMarkPt1.y; + //得到偏移后的第二个点(理论值) + Dbxy OffsetPt2 = m_TheoryMarkPt2; + OffsetPt2.x += m_Offset.x; + OffsetPt2.y += m_Offset.y; + + //特殊处理(避免两个mark 在一条直线上时的角度计算错误) + if(IsTwoDbEqual(m_RealMarkPt1.x,OffsetPt2.x)) + { + OffsetPt2.x += 0.001; + } + if(IsTwoDbEqual(m_RealMarkPt1.y,OffsetPt2.y)) + { + OffsetPt2.y += 0.001; + } + //以第二个点的旋转来计算相对的角度 + m_RotateAng = CalAngle(m_RealMarkPt1,OffsetPt2,m_RealMarkPt2); + m_RotateAng *= -1; + double RotateAng = AngleTo360(m_RotateAng); + + //gLogMgr->SetbWriteDebugLog(true); + CString LogStr; + LogStr.Format(_T("[m_Offset.x] = [%f] ,[m_Offset.y] = [%f]"),m_Offset.x,m_Offset.y); + gLogMgr->WriteDebugLog(LogStr); + LogStr.Format(_T("[RotateAng] = [%f]"),m_RotateAng);//弧度角 + gLogMgr->WriteDebugLog(LogStr); + LogStr.Format(_T("[RotateAng360] = [%f]"),RotateAng); + gLogMgr->WriteDebugLog(LogStr); + //gLogMgr->SetbWriteDebugLog(false); + + //通过判断实际测量mark1 和mark2 的距离来避免抓取误差 + double TheoryDis = CalDistance(m_TheoryMarkPt1,m_TheoryMarkPt2);//理论距离 + double RealDis = CalDistance(m_RealMarkPt1,m_RealMarkPt2);//实际距离 + double DisDiff = abs(TheoryDis - RealDis); + LogStr.Format(_T("[Mark 间距误差] = [%f]"),DisDiff); + gLogMgr->WriteDebugLog(LogStr); + if(DisDiff > abs(gProductMgr->GetMaxMarkDisDiff())) + { + + gTrackWorkFlow1.RadAlamOnOff(true);//报警提示 + ResetRealMarkPt(); + CString LogStr("Mark 间距误差超出范围,定位可能误判!"); + CExceptionMsg Msg; + Msg.SetMsg(LogStr); + throw Msg; + } +} +//使用默认偏移量 +void CProduct::UseDefualtOffset() +{ + m_Offset.x = m_Offset.y = 0; + m_RotateAng = 0; +} +#endif +#if 1 +//获取旋转角度(360 度角) +double CProduct::GetRotateAng() +{ + return AngleTo360(m_RotateAng); +} +//计算拉伸实际尺寸拉伸参数 +void CProduct::CalRealStretchPar() +{ + Dbxy ProductScale = CalRealProductScale();//伸缩比例 + DbRect AllObjRect = gObjComponentMgr->GetAllObjRect2(); + SObjOperatePar &StretchParX = m_StretchParX; + SObjOperatePar &StretchParY = m_StretchParY; + //计算X 方向拉伸参数 + { + StretchParX.OpType = _OP_STRETCH; + StretchParX.BasePt = AllObjRect.GetCenterPt(); + StretchParX.OldSize = AllObjRect.Width(); + StretchParX.Diff = (ProductScale.x-1)*StretchParX.OldSize; + StretchParX.NewSize = StretchParX.OldSize + StretchParX.Diff; + StretchParX.xy = _X; + } + //计算Y 方向拉伸参数 + { + StretchParY.OpType = _OP_STRETCH; + StretchParY.BasePt = AllObjRect.GetCenterPt(); + StretchParY.OldSize = AllObjRect.Height(); + StretchParY.Diff = (ProductScale.y-1)*StretchParY.OldSize; + StretchParY.NewSize = StretchParY.OldSize + StretchParY.Diff; + StretchParY.xy = _Y; + } +} + +//理论数据转换为实际数据 +void CProduct::TheoryDataToRealData(vector &vec,Dbxy &Offset) +{ + vector::iterator iter = vec.begin(); + vector::iterator iter_end = vec.end(); + for(;iter!=iter_end;iter++) + { + (*iter) = TheoryPtToRealPt((*iter)); + (*iter).x += Offset.x; + (*iter).y += Offset.y; + } +} + +//理论数据转换为实际数据 +void CProduct::TheoryDataToRealData(vector &vec, Dbxy &BaseOffset, Dbxy CutAdjust) +{ + vector::iterator iter = vec.begin(); + vector::iterator iter_end = vec.end(); + for (;iter != iter_end;iter++) + { + //(*iter) = TheoryPtToRealPt((*iter)); + //(*iter) = (*iter) - m_BasePt; + auto x = (*iter).x; + auto y = (*iter).y; + double retx = m_p00*x + m_p01*y + m_p02+ CutAdjust.x; + double rety = m_p10*x + m_p11*y + m_p12+ CutAdjust.y; + (*iter).x = retx; + (*iter).y = rety; + + auto temp = BaseOffset;//-m_BasePt; + + (*iter) = (*iter) - temp; + + /*(*iter).x += CutAdjust.x; + (*iter).y += CutAdjust.y;*/ + } +} +void CProduct::ResetAffinePars() +{ + m_p00 = 1; + m_p01 = 0; + m_p02 = 0; + + m_p10 = 0; + m_p11 = 1; + m_p12 = 0; +} +//获取实际产品的尺寸比例 +Dbxy CProduct::CalRealProductScale() +{ + Dbxy ProductScale; + //三个mark 的情况xy 方向拉伸比例分开计算 + if(m_bHasMarkPt3)//3 + { + ProductScale.x = CalRealProductScaleExt(m_TheoryMarkPt1,m_TheoryMarkPt2,m_RealMarkPt1,m_RealMarkPt2); + if(IsTwoDbEqual(m_TheoryMarkPt1.x,m_TheoryMarkPt3.x))//mark1 和mark3 + { + ProductScale.y = CalRealProductScaleExt(m_TheoryMarkPt1,m_TheoryMarkPt3,m_RealMarkPt1,m_RealMarkPt3); + } + else + { + ProductScale.y = CalRealProductScaleExt(m_TheoryMarkPt2,m_TheoryMarkPt3,m_RealMarkPt2,m_RealMarkPt3); + } + } + else//两个mark 的情况 + { + double Scale = CalRealProductScaleExt(m_TheoryMarkPt1,m_TheoryMarkPt2,m_RealMarkPt1,m_RealMarkPt2); + ProductScale.x = ProductScale.y = Scale; + } + CString LogStr; + LogStr.Format(_T("[拉伸比例x] = [%f]"),ProductScale.x); + gLogMgr->WriteDebugLog(LogStr); + LogStr.Format(_T("[拉伸比例y] = [%f]"),ProductScale.y); + gLogMgr->WriteDebugLog(LogStr); + + return ProductScale; +} +double CProduct::CalRealProductScaleExt(Dbxy TheoryMarkPt1,Dbxy TheoryMarkPt2,Dbxy RealMarkPt1,Dbxy RealMarkPt2) +{ + double TheoryMarkDis = CalDistance(TheoryMarkPt1,TheoryMarkPt2); + double RealMarkDis = CalDistance(RealMarkPt1,RealMarkPt2); + double Diff = (RealMarkDis-TheoryMarkDis); + double ProductScale = RealMarkDis/TheoryMarkDis; + CString LogStr; + LogStr.Format(_T("[间距理论值] = [%f]"),TheoryMarkDis); + gLogMgr->WriteDebugLog(LogStr); + LogStr.Format(_T("[间距实际值] = [%f]"),RealMarkDis); + gLogMgr->WriteDebugLog(LogStr); + LogStr.Format(_T("[尺寸误差] = [%f]"),Diff); + gLogMgr->WriteDebugLog(LogStr); + return ProductScale; +} +//拉伸 +//BasePt 拉伸基准点 +//Size 拉伸前的尺寸 +//Diff 是旧尺寸和新尺寸的差 +void CProduct::StretchPt(Dbxy &Pt,SObjOperatePar &Par) +{ + if(Par.Diff == 0) + return; + if(Par.xy == _X) + { + Pt.x = Pt.x+Par.Diff*((Pt.x-Par.BasePt.x)/Par.OldSize); + } + else + { + Pt.y = Pt.y+Par.Diff*((Pt.y-Par.BasePt.y)/Par.OldSize); + } +} + +//根据抓取两个mark 来计算拉伸数据(CenterPt计算的中心点) +void CProduct::StretchDataToRealSize(vector> &vec) +{ + vector>::iterator iter = vec.begin(); + vector>::iterator iter_end = vec.end(); + for(;iter!=iter_end;iter++) + { + int size = (*iter).size(); + for(int k=0;k> &SrcVec,vector> &DecVec,Dbxy &Offset) +{ + gLogMgr->WriteDebugLog("CProduct::TheoryDataToRealData"); + int size1 = SrcVec.size(); + int size2 = DecVec.size(); + if(size1!=size2) + { + gLogMgr->WriteDebugLog("SrcVec.size() != DecVec.size()"); + return; + } + for(int k=0;k &SrcVec,vector &DecVec,Dbxy &Offset) +{ + int size1 = SrcVec.size(); + int size2 = DecVec.size(); + if(size1!=size2) + { + gLogMgr->WriteDebugLog("SrcVec.size() != DecVec.size()"); + return; + } + for(int k=0;k> &vec,Dbxy &Offset) +{ + gLogMgr->WriteDebugLog("CProduct::TheoryDataToRealData"); + vector>::iterator iter = vec.begin(); + vector>::iterator iter_end = vec.end(); + for(;iter!=iter_end;iter++) + { + TheoryDataToRealData(*iter,Offset); + } +} + + +//理论数据转换为实际数据 +void CProduct::TheoryDataToRealData(vector> &vec, Dbxy &BaseOffset, Dbxy CutAdjust) +{ + gLogMgr->WriteDebugLog("CProduct::TheoryDataToRealData"); + vector>::iterator iter = vec.begin(); + vector>::iterator iter_end = vec.end(); + for (;iter != iter_end;iter++) + { + TheoryDataToRealData(*iter, BaseOffset,CutAdjust); + } +} +#endif diff --git a/LaiPuLaser/Product0.h b/LaiPuLaser/Product0.h new file mode 100644 index 0000000..5c803a5 --- /dev/null +++ b/LaiPuLaser/Product0.h @@ -0,0 +1,97 @@ +#pragma once +#include "GlobalDefine.h" +#include "LabVecRang.h" + + +//工件产品 +class CProduct +{ + friend class CProductMgr; +public: + CProduct(void); + ~CProduct(void); + void Draw(CDC* pDC); + void WriteWorkFile(vector &LabVec); + void ReadWorkFile(CLabVecRang &LabVecRang); + void SetBasePt(Dbxy pt){m_BasePt = pt;}; + Dbxy &GetProductBasePt(){return m_BasePt;}; + Dbxy &GetOffset(){return m_Offset;}; + double GetRotateAng(); + + bool &IsUsed(){return m_bUsed;}; + void SetUsed(bool b){m_bUsed = b;}; + void GetMarkCoord(Dbxy &mark1,Dbxy &mark2); + void SetRealMarkPt(Dbxy pt); + void ResetRealMarkPt(); + void SetTheoryMarkPt(Dbxy pt1,Dbxy pt2); + void SetbHasMarkPt3(bool b){m_bHasMarkPt3 = b;}; + void SetTheoryMark3Pt(Dbxy pt){m_TheoryMarkPt3 = pt;}; + void SetRealMark3Pt(Dbxy pt){m_RealMarkPt3 = pt;}; + Dbxy TheoryPtToRealPt(Dbxy TheoryMarkPt); + void StretchDataToRealSize(vector> &vec); + + void TheoryDataToRealData(vector> &vec, Dbxy &Offset); + void TheoryDataToRealData(vector &vec, Dbxy &Offset); + void TheoryDataToRealData(vector& vec, Dbxy & BaseOffset, Dbxy CutAdjust); + void ResetAffinePars();//重置仿射变换参数 + void TheoryDataToRealData(vector>& vec, Dbxy & BaseOffset, Dbxy CutAdjust); + + void TheoryDataToRealData(vector> &SrcVec,vector> &DecVec,Dbxy &Offset); + void TheoryDataToRealData(vector &SrcVec,vector &DecVec,Dbxy &Offset); + bool IsSetRealMarkPt1(); + bool IsSetRealMarkPt2(); + void UseDefualtOffset(); + bool IsMarkReady(); + bool IsbLastOne(){return m_bLastOne;}; + void SetbLastOne(bool b){m_bLastOne = b;}; + void SetbNewAddProduct(bool bNew) { m_bNewAddProduct = bNew; };//设置是否是改造新增的产品 + bool IsbNewAddProduct() { return m_bNewAddProduct; };//查询是否是改造新增的产品 +private: + void CalAffinePars(); + void CalTheoryToRealPar(); + Dbxy CalRealProductScale(); + void StretchPt(Dbxy &Pt,SObjOperatePar &Par); + void CalRealStretchPar(); + double CalRealProductScaleExt(Dbxy TheoryMarkPt1,Dbxy TheoryMarkPt2,Dbxy RealMarkPt1,Dbxy RealMarkPt2); +private: + Dbxy m_BasePt;//工件的基准坐标点 + bool m_bUsed;//是否使用 + bool m_bLastOne;//是否为最后一个 + bool m_bHasMarkPt3;//是否有mark3 + bool m_bNewAddProduct = false;//是否是改造后新增的那块产品(201910) +public: + //用于定位的两个定位点--------------------------- + Dbxy m_TheoryMarkPt1;//理论坐标(layer 中的坐标) mm + Dbxy m_TheoryMarkPt2; + Dbxy m_TheoryMarkPt3; + //ccd 抓取的实际值------------------------------------ + Dbxy m_RealMarkPt1;//真实坐标(相对于激光中心点) mm + Dbxy m_RealMarkPt2; + Dbxy m_RealMarkPt3; +public: + Dbxy o_TheoryMarkPt1;//理论坐标(不移动时) mm + Dbxy o_TheoryMarkPt2; + Dbxy o_TheoryMarkPt3; + //ccd 抓取的实际值------------------------------------ + Dbxy o_RealMarkPt1;//真实坐标(不移动时) mm + Dbxy o_RealMarkPt2; + Dbxy o_RealMarkPt3; + + //仿射参数------------------------------------ + float m_p00=1; + float m_p01=0; + float m_p02=0; + + float m_p10=0; + float m_p11=1; + float m_p12=0; +public: + //实际偏移旋转结果--------------------------------- + Dbxy m_Offset;//理论数据映射为平台坐标的偏移 + double m_RotateAng;//理论数据映射为平台坐标的旋转角度(反正切角) + double m_MaxRotateAng;//最大旋转角度(360 度角)计算出来的旋转角度超过这个值时可能有错误,计算无效 + + SObjOperatePar m_StretchParX;//X 方向拉伸参数 + SObjOperatePar m_StretchParY;//Y 方向拉伸参数 +}; + diff --git a/LaiPuLaser/ProductMgr.cpp b/LaiPuLaser/ProductMgr.cpp index 2df2910..efbedb6 100644 --- a/LaiPuLaser/ProductMgr.cpp +++ b/LaiPuLaser/ProductMgr.cpp @@ -156,7 +156,7 @@ CMFCPropertyGridProperty *CProductMgr::CreatGridProperty() //添加属性显示 PropertyName = _T("角度微调"); - Description = _T("产品偏移角度的微调值(弧度值)"); + Description = _T("产品偏移角度的微调值(角度值)"); CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_AngleAdjust, Description); //p->AllowEdit(FALSE);//不可修改 pGroup->AddSubItem(p); diff --git a/LaiPuLaser/ProductMgr.h b/LaiPuLaser/ProductMgr.h index 20b7fee..1def887 100644 --- a/LaiPuLaser/ProductMgr.h +++ b/LaiPuLaser/ProductMgr.h @@ -41,13 +41,15 @@ public: void WorkTimesInc(); int GetCurWorkTimes(){return m_CurWorkTimes;}; int GetTotalWorkTimes(){return m_TotalWorkTimes;}; - double GetAngleAdjust(){return m_AngleAdjust;}; + //double GetAngleAdjust(){return m_AngleAdjust;}; void MoveObjToBasePt(Dbxy BasePt); void UpdateProductState(); void SetDefualtRect(DbRect r){m_DefualtRect = r;}; Dbxy GetDefualtBasePt(); void SetProductCenterPt(); double GetMaxMarkDisDiff(){return m_MaxMarkDisDiff;}; + double GetAdjustAngle() { return m_AngleAdjust; }; + private: void InsertProduct(CMFCPropertyGridProperty* p); void DrawMarkPoint(CDC* pDC,Dbxy pt,CString str); diff --git a/LaiPuLaser/Program_SZ_XL.cpp b/LaiPuLaser/Program_SZ_XL.cpp index 11080b5..45fa341 100644 --- a/LaiPuLaser/Program_SZ_XL.cpp +++ b/LaiPuLaser/Program_SZ_XL.cpp @@ -82,6 +82,92 @@ CMFCPropertyGridProperty *CProgram_SZ_XL::CreatGridProperty() PropertyName = _T("双轨设备"); CMFCPropertyGridProperty* pGroup = new CMFCPropertyGridProperty(PropertyName); //-------------------------------------------------------------------------------// + + if (gAuthorityMgr->CheckAuthority(_ADMIN)) + { + PropertyName = _T("固定缩放比例"); + CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(PropertyName); + { + //添加属性变量映射 + Name = _T("m_Jig2Scale_x");//变量名字 + CPropertie *pPropertie = new CPropertie; + pPropertie->SetpVal((void*)&m_Jig2Scale.x); + pPropertie->SetType(_PROP_TYPE_DOUBLE); + pPropertie->SetpModule(this); + pPropertie->SetPath(Path); + pPropertie->SetName(Name); + pPropertie->WriteRead(true);//读取保存的属性 + + //添加属性显示 + PropertyName = _T("治具2X"); + Description = _T("治具2X方向缩放比例"); + CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Jig2Scale.x, Description); + //p->AllowEdit(FALSE);//不可修改 + pGroup1->AddSubItem(p); + PropertieMgr.Insert(p, pPropertie); + } + { + //添加属性变量映射 + Name = _T("m_Jig2Scale_y");//变量名字 + CPropertie *pPropertie = new CPropertie; + pPropertie->SetpVal((void*)&m_Jig2Scale.y); + pPropertie->SetType(_PROP_TYPE_DOUBLE); + pPropertie->SetpModule(this); + pPropertie->SetPath(Path); + pPropertie->SetName(Name); + pPropertie->WriteRead(true);//读取保存的属性 + + //添加属性显示 + PropertyName = _T("治具2Y"); + Description = _T("治具2Y方向缩放比例"); + CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Jig2Scale.y, Description); + //p->AllowEdit(FALSE);//不可修改 + pGroup1->AddSubItem(p); + PropertieMgr.Insert(p, pPropertie); + } + { + //添加属性变量映射 + Name = _T("m_Jig4Scale_x");//变量名字 + CPropertie *pPropertie = new CPropertie; + pPropertie->SetpVal((void*)&m_Jig4Scale.x); + pPropertie->SetType(_PROP_TYPE_DOUBLE); + pPropertie->SetpModule(this); + pPropertie->SetPath(Path); + pPropertie->SetName(Name); + pPropertie->WriteRead(true);//读取保存的属性 + + //添加属性显示 + PropertyName = _T("治具4X"); + Description = _T("治具4X方向缩放比例"); + CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Jig4Scale.x, Description); + //p->AllowEdit(FALSE);//不可修改 + pGroup1->AddSubItem(p); + PropertieMgr.Insert(p, pPropertie); + } + { + //添加属性变量映射 + Name = _T("m_Jig4Scale");//变量名字 + CPropertie *pPropertie = new CPropertie; + pPropertie->SetpVal((void*)&m_Jig4Scale.y); + pPropertie->SetType(_PROP_TYPE_DOUBLE); + pPropertie->SetpModule(this); + pPropertie->SetPath(Path); + pPropertie->SetName(Name); + pPropertie->WriteRead(true);//读取保存的属性 + + //添加属性显示 + PropertyName = _T("治具4Y"); + Description = _T("治具4Y方向缩放比例"); + CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Jig4Scale.y, Description); + //p->AllowEdit(FALSE);//不可修改 + pGroup1->AddSubItem(p); + PropertieMgr.Insert(p, pPropertie); + } + pGroup->AddSubItem(pGroup1); + } + + + if(gAuthorityMgr->CheckAuthority(_FACTORY)) { PropertyName = _T("基础设置"); @@ -632,15 +718,17 @@ CMFCPropertyGridProperty *CProgram_SZ_XL::CreatGridProperty() } pGroup->AddSubItem(pGroup1); }*/ + + if(gAuthorityMgr->CheckAuthority(_ADMIN)) { PropertyName = _T("加工偏移"); CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(PropertyName); { //添加属性变量映射 - Name = _T("m_Track1MarkOffset_x");//变量名字 + Name = _T("m_Jig2MarkOffset_x");//变量名字 CPropertie *pPropertie = new CPropertie; - pPropertie->SetpVal((void*)&m_Track1MarkOffset.x); + pPropertie->SetpVal((void*)&m_Jig2MarkOffset.x); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); @@ -650,16 +738,16 @@ CMFCPropertyGridProperty *CProgram_SZ_XL::CreatGridProperty() //添加属性显示 PropertyName = _T("治具2振镜偏移X"); Description = _T("轨道1上治具2的切割偏移X"); - CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Track1MarkOffset.x, Description); + CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Jig2MarkOffset.x, Description); //p->AllowEdit(FALSE);//不可修改 pGroup1->AddSubItem(p); PropertieMgr.Insert(p, pPropertie); } { //添加属性变量映射 - Name = _T("m_Track1MarkOffset_y");//变量名字 + Name = _T("m_Jig2MarkOffset_y");//变量名字 CPropertie *pPropertie = new CPropertie; - pPropertie->SetpVal((void*)&m_Track1MarkOffset.y); + pPropertie->SetpVal((void*)&m_Jig2MarkOffset.y); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); @@ -669,16 +757,16 @@ CMFCPropertyGridProperty *CProgram_SZ_XL::CreatGridProperty() //添加属性显示 PropertyName = _T("治具2振镜偏移Y"); Description = _T("轨道1上治具2的切割偏移Y"); - CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Track1MarkOffset.y, Description); + CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Jig2MarkOffset.y, Description); //p->AllowEdit(FALSE);//不可修改 pGroup1->AddSubItem(p); PropertieMgr.Insert(p, pPropertie); } { //添加属性变量映射 - Name = _T("m_Track2MarkOffset_x");//变量名字 + Name = _T("m_Jig4MarkOffset_x");//变量名字 CPropertie *pPropertie = new CPropertie; - pPropertie->SetpVal((void*)&m_Track2MarkOffset.x); + pPropertie->SetpVal((void*)&m_Jig4MarkOffset.x); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); @@ -688,16 +776,16 @@ CMFCPropertyGridProperty *CProgram_SZ_XL::CreatGridProperty() //添加属性显示 PropertyName = _T("治具4振镜偏移X"); Description = _T("轨道2上治具4的切割偏移X"); - CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Track2MarkOffset.x, Description); + CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Jig4MarkOffset.x, Description); //p->AllowEdit(FALSE);//不可修改 pGroup1->AddSubItem(p); PropertieMgr.Insert(p, pPropertie); } { //添加属性变量映射 - Name = _T("m_Track2MarkOffset_y");//变量名字 + Name = _T("m_Jig4MarkOffset_y");//变量名字 CPropertie *pPropertie = new CPropertie; - pPropertie->SetpVal((void*)&m_Track2MarkOffset.y); + pPropertie->SetpVal((void*)&m_Jig4MarkOffset.y); pPropertie->SetType(_PROP_TYPE_DOUBLE); pPropertie->SetpModule(this); pPropertie->SetPath(Path); @@ -707,7 +795,7 @@ CMFCPropertyGridProperty *CProgram_SZ_XL::CreatGridProperty() //添加属性显示 PropertyName = _T("治具4振镜偏移Y"); Description = _T("轨道2上治具4的切割偏移Y"); - CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Track2MarkOffset.y, Description); + CMFCPropertyGridProperty* p = new CMFCPropertyGridProperty(PropertyName, (_variant_t)m_Jig4MarkOffset.y, Description); //p->AllowEdit(FALSE);//不可修改 pGroup1->AddSubItem(p); PropertieMgr.Insert(p, pPropertie); @@ -878,9 +966,13 @@ Dbxy CProgram_SZ_XL::GetTrackMarkOffset(ETrackType TrackType) else MarkOffset = m_Track2MarkOffset;*/ if (gServer->m_RcvCurTrackIndex == 0) - MarkOffset = m_Track1MarkOffset; + { + MarkOffset = m_Jig2MarkOffset; + } else - MarkOffset = m_Track2MarkOffset; + { + MarkOffset = m_Jig4MarkOffset; + } return MarkOffset; } //打开,夹紧载盘/真空 diff --git a/LaiPuLaser/Program_SZ_XL.h b/LaiPuLaser/Program_SZ_XL.h index fb0f302..6aa35d5 100644 --- a/LaiPuLaser/Program_SZ_XL.h +++ b/LaiPuLaser/Program_SZ_XL.h @@ -62,6 +62,8 @@ private: public: int m_ServerPort=2404;//监听的端口号 CString m_NetPath="W";//网盘的盘符 + Dbxy GetJig2Scale() { return m_Jig2Scale; }; + Dbxy GetJig4Scale() { return m_Jig4Scale; }; private: int m_TrackComPort1;//轨道1 串口号 int m_TrackComPort2;//轨道2 串口号 @@ -94,8 +96,11 @@ private: Dbxy m_Track2Offset;//轨道2相对轨道1 的偏移量 - Dbxy m_Track1MarkOffset;//轨道1的整体加工偏移 - Dbxy m_Track2MarkOffset;//轨道2的整体加工偏移 + Dbxy m_Jig2MarkOffset;//治具2的加工偏移 + Dbxy m_Jig4MarkOffset;//治具4的加工偏移 + + Dbxy m_Jig2Scale=Dbxy(1,1);//治具2的加工缩放 + Dbxy m_Jig4Scale=Dbxy(1,1);//治具4的加工缩放 double m_Track1DangerCoordStart;//轨道1 的危险范围start double m_Track1DangerCoordEnd;//轨道1 的危险范围end diff --git a/LaiPuLaser/Program_SZ_XL_TrackWorkFlow.cpp b/LaiPuLaser/Program_SZ_XL_TrackWorkFlow.cpp index 9883848..d729fa0 100644 --- a/LaiPuLaser/Program_SZ_XL_TrackWorkFlow.cpp +++ b/LaiPuLaser/Program_SZ_XL_TrackWorkFlow.cpp @@ -814,13 +814,17 @@ void CTrackWorkFlow::MarkProcess() SetCurTrackWorkStep(_ETrack_Step_Marking); //XY 组切换 MarkProcessExt(); + CString str = "READY"; + gServer->BroadCast(str); + gLogMgr->WriteDebugLog(str); + //设置当前的工作步骤 SetCurTrackWorkStep(_ETrack_Step_Marking); //数据移动回默认的位置 - //gProgramCutMgr->MoveObjData(Dbxy(0, 0)); - //gMarkAreaMgr->MoveAllAreaToTargetPt(Dbxy(0, 0)); + /* gProgramCutMgr->MoveObjData(Dbxy(0, 0)); + gMarkAreaMgr->MoveAllAreaToTargetPt(Dbxy(0, 0));*/ - + //gCurLockTrackType = _ETrackType_NULL;//解锁 //VacSorbOnOff(false);//真空放开 @@ -836,11 +840,12 @@ bool CTrackWorkFlow::MarkProcessExt() Dbxy MarkOffset = gProgram_SZ_XL->GetTrackMarkOffset(m_TrackType); gCommonFlowMgr->SetAdjustOffsetAll(MarkOffset); //记录当前正在切割的轨道 - //gProgram_SZ_XL->SetCurMarkingTrack(m_TrackType); + gProgram_SZ_XL->SetCurMarkingTrack(m_TrackType); CProduct &Product = gServer->m_RcvProduct; -/* + +/* Dbxy BasePt = Product.GetProductBasePt(); //=======移动obj============== gProgramCutMgr->MoveObjData(BasePt); @@ -848,8 +853,7 @@ bool CTrackWorkFlow::MarkProcessExt() //计算所有obj 的中心点 gObjComponentMgr->CalAllObjCenterPt(); Dbxy AllObjCenterPt = gObjComponentMgr->GetAllObjCenterPt(); - gMarkAreaMgr->MoveAllAreaToTargetPt(AllObjCenterPt); -*/ + gMarkAreaMgr->MoveAllAreaToTargetPt(AllObjCenterPt);*/ bool Ret; //启动切割 diff --git a/LaiPuLaser/ServerMgr.cpp b/LaiPuLaser/ServerMgr.cpp index 6487f43..6e2cdb6 100644 --- a/LaiPuLaser/ServerMgr.cpp +++ b/LaiPuLaser/ServerMgr.cpp @@ -163,13 +163,12 @@ void CServerMgr::OnReceive(int nErrorCode) } - if (RcvStr.Find(ACTION_TANSPRODUCTINFO) != -1) //先告知数据类型,再传数据. + if (RcvStr.Find(ACTION_TANSPRODUCTINFO) != -1) //传数据. { - CString str = "EXECMD_OK;"; + /* CString str = "EXECMD_OK;"; Send(str, str.GetLength()); - - Receive(&gServer->m_RcvProduct, sizeof(CProduct)); + Receive(&gServer->m_RcvProduct, sizeof(CProduct));*/ gLogMgr->WriteDebugLog(ACTION_TANSPRODUCTINFO + "OK"); if (RcvStr.Find(TRACK_1) != -1) @@ -180,21 +179,68 @@ void CServerMgr::OnReceive(int nErrorCode) { gServer->m_RcvCurTrackIndex = 1; } + + + int spos = 0; + int epos = 0; + CString temp; + vector dvec; + for (int i = 0;i != 6;i++) + { + if ( (spos = RcvStr.Find("[",spos+1))<1|| (epos = RcvStr.Find("]",epos+1))<1) + { + AfxMessageBox("接收数据错误!"); + return; + } + temp = RcvStr.Mid(spos+1, epos - spos-1); + dvec.push_back(atof(temp)); + } + gServer->m_RcvProduct.m_p00 = dvec[0]; + gServer->m_RcvProduct.m_p01 = dvec[1]; + gServer->m_RcvProduct.m_p02 = dvec[2]; + gServer->m_RcvProduct.m_p10 = dvec[3]; + gServer->m_RcvProduct.m_p11 = dvec[4]; + gServer->m_RcvProduct.m_p12 = dvec[5]; + + gTrackWorkFlow1.SetCurTrackWorkStep(_ETrack_Step_Catch_mark_End); } + if (RcvStr.Find(ACTION_COLLECT) != -1) //收集数据. + { + gMarkAreaMgr->CollectOrgWorkData(gProgram_SZ_XL->IsbSelMarkMode(), gServer->m_RcvProduct); + gLogMgr->WriteDebugLog(ACTION_COLLECT + "OK"); + } + if (RcvStr.Find(ACTION_STARTWORK) != -1) //启动加工 - { + { int sPos = RcvStr.ReverseFind(';'); int ePos = RcvStr.GetLength(); CString Index = RcvStr.Mid(sPos + 1, ePos - sPos - 1); - m_RcvAreaIndex = atoi(Index); + m_RcvAreaIndex = atoi(Index); + /* StartMarkArea(); + }*/ gCommonFlowMgr->MarkAreaByIdx(m_RcvAreaIndex);//根据加工区域索引加工 - gLogMgr->WriteDebugLog("MarkArea " + Index + " Finished!"); - CString str = "AREA_FINISHED;"; - Send(str, str.GetLength()); - gLogMgr->WriteDebugLog("Send: " + str); - Sleep(50); + gLogMgr->WriteDebugLog("MarkArea " + Index + " Finished!"); + CString str = "AREA_FINISHED;"; + Send(str, str.GetLength()); + gLogMgr->WriteDebugLog("Send: " + str); + Sleep(50); + } + + if (RcvStr.Find(ACTION_PAUSEWORK) != -1) //暂停加工 + { + PauseMark(); + } + + if (RcvStr.Find(ACTION_RESUMEWORK) != -1) //恢复加工 + { + ResumeMark(); + } + + if (RcvStr.Find(ACTION_EXITWORK) != -1) //退出加工 + { + ExitMark(); } if (RcvStr.Find(ACTION_SETSPECAILOBJ) != -1) //设置特殊对象 @@ -354,3 +400,35 @@ void CServerMgr::DeleteClientObject(CServerMgr * pConn) } } +void CServerMgr::StartMarkArea() +{ + if (m_workThread.joinable()) + { + return; + } + m_workThread=thread(&CCommonFlowMgr::MarkAreaByIdx, gCommonFlowMgr,m_RcvAreaIndex);//根据加工区域索引加工) + //gCommonFlowMgr->gCommonFlowMgr->MarkAreaByIdx(m_RcvAreaIndex);//根据加工区域索引加工(m_RcvAreaIndex);//根据加工区域索引加工 + m_workThread.join(); + gLogMgr->WriteDebugLog("MarkArea " +(CString) (to_string(m_RcvAreaIndex).c_str()) + " Finished!"); + CString str = "AREA_FINISHED;"; + Send(str, str.GetLength()); + gLogMgr->WriteDebugLog("Send: " + str); + Sleep(50); +} + +void CServerMgr::PauseMark() +{ + + SuspendThread(m_workThread.native_handle()); +} + +void CServerMgr::ResumeMark() +{ + ResumeThread(m_workThread.native_handle()); +} + +void CServerMgr::ExitMark() +{ + TerminateThread(m_workThread.native_handle(),0); +} + diff --git a/LaiPuLaser/ServerMgr.h b/LaiPuLaser/ServerMgr.h index a28d6df..6a1c999 100644 --- a/LaiPuLaser/ServerMgr.h +++ b/LaiPuLaser/ServerMgr.h @@ -2,7 +2,11 @@ #define ACTION_OPENFILE (CString)"OPEN_FILE;"//打开文件 #define ACTION_TANSPRODUCTINFO (CString)"TRANS_PRODUCT;" //传Product +#define ACTION_COLLECT (CString)"COLLECT_DATA;" //收集数据 #define ACTION_STARTWORK (CString)"START_WORK;" //标刻指定区域 +#define ACTION_PAUSEWORK (CString)"PAUSE_WORK;" //标刻指定区域 +#define ACTION_RESUMEWORK (CString)"RESUME_WORK;" //标刻指定区域 +#define ACTION_EXITWORK (CString)"EXIT_WORK;" //标刻指定区域 //#define ACTION_TRANSFILE (CString)"TRANS_FILE;"//传文件 #define ACTION_SETSPECAILOBJ (CString)"SET_SPECAILOBJ;"//设置特殊对象 #define ACTION_BMARKSELOBJMODE (CString)"MARK_SELOBJMODE;"//设置选择加工模式 @@ -66,6 +70,7 @@ CNetData ::~CNetData () #include "DlgSW_XL_Flow.h" #include "Product.h" #include +#include using namespace std; class CServerMgr : public CSocket { @@ -89,6 +94,12 @@ private: static void DeleteClientObject(CServerMgr* pConn); CurRcvDataType m_CurRcvDataType = DataType_String;//当前要接收的数据类型 CDlgSW_XL_Flow * m_Dlg; + + thread m_workThread; + void StartMarkArea(); + void PauseMark(); + void ResumeMark(); + void ExitMark(); }; extern CServerMgr * gServer; \ No newline at end of file diff --git a/LaiPuLaser/WorkCmdInvoker.cpp b/LaiPuLaser/WorkCmdInvoker.cpp index 670cb84..4460a3c 100644 --- a/LaiPuLaser/WorkCmdInvoker.cpp +++ b/LaiPuLaser/WorkCmdInvoker.cpp @@ -147,7 +147,7 @@ void CWorkCmdInvoker::ExcuteAllCmd(bool bNewThread) gProgressMgr.SetWorkProgress(&dlg.GetProgress()); #endif } - CWinThread* pThread = AfxBeginThread(ExcuteAllCmdThread,this); + CWinThread* pThread = AfxBeginThread(ExcuteAllCmdThread,this, THREAD_PRIORITY_HIGHEST); if(CmdCnt>1)//只有一条指令时不要显示进度 { #ifdef __PROGRESS_DLG__ diff --git a/LaiPuLaser/WorkCmdMarkArea.cpp b/LaiPuLaser/WorkCmdMarkArea.cpp index 7cf6b68..38d2cda 100644 --- a/LaiPuLaser/WorkCmdMarkArea.cpp +++ b/LaiPuLaser/WorkCmdMarkArea.cpp @@ -54,11 +54,11 @@ bool CWorkCmdMarkArea::Excute() { //重置所有area 的选择状态 gMarkAreaMgr->ResetAllAreaSelState(); - m_MarkArea.SetSelState(true);//选择当前加工的area + //m_MarkArea.SetSelState(true);//选择当前加工的area //设置markarea 内的obj 为已加工状态 // gObjComponentMgr->SetMarkedStateRect(m_MarkArea.GetRect(), m_bSelMark); - gObjComponentMgr->SetMarkedStateRect(m_MarkArea.GetRect(),true); + // gObjComponentMgr->SetMarkedStateRect(m_MarkArea.GetRect(),true); //可能会引起报错? //m_pView->MoveViewCenter(); //m_pView->RefreshView(); diff --git a/LaiPuLaser/hlp/LaiPuLaser.chm b/LaiPuLaser/hlp/LaiPuLaser.chm index d28b7f6e20d45fcb1378dee47be1db8909b6483d..6b8f41b11f8302a630ada6f6a363b00a9a8e7d06 100644 GIT binary patch delta 3081 zcmbW3=Q|q;8^&YL*yA9SmL?Ju$DU218jcb~+EVLKwYRDoQA+JyyJ|F5t3_;5rKr_d zwPz93jMkoS&-I@7A9z3f?)!PJ=enLx_lJAff@Hy?hcVTq0RR9tzoGg~DGKp9nFm8f zs&e{HMJ*_ms!bzCaHH0wqBfBwz`6K4oq&KhI32rgJ(2U4wKv z{&~Ro8$fb0H$jx^j2+jHhx3*`&puSb(zg}G?LSo-7x--195)LgLiM2-3`!3J;f5pj z6p zEE;vSX^V=ZojM0hm4rj6&C^_2cJZeg%G?fyQS z)Fan7nb*I1(;e=f3u0+iP)%%XFhyqNnSW?Kq3DjdnGgpXEoU(A$V#jq?qAU%PVF6p zc2cf~r}M0M<1jZ`O9I}EEd5-Pm=g?#x&SSduH4Bo)HWr@2waoZdxi?kkq_h3-5XxggeBOhvW;t* z2P&*j%zw6GXaOZZX6Og`KI#7|m&`B@Dtgf7vA!XglWwJaK@n@J933e@>;E!dYsnMV^qnx44G}{r?+<}P(A>i0_6!vzMpcSKA zP%ZL)oQJQu7U2|VBI#%XA7sAi%D((JT!%|s`JH%@UVbW5Ezm^2JAF`E>;d9VL?JVV zS6o#=RY!FV%7I0bTgc~-2>rz9bRGqqrCDM#O9QYeuw5vZEBaFUVVZ7ra1xoSR-v!# zC5m&!SN8i$izwU}uY1HVvYXYWYu#jm&*$4ig^TvsnV!JDr+1H!J4RjgT%ARGbY9j@ z-O!7JNQ;-klIC=TLh-<8HU@F~Lf$dA-`ALK_oOUF0ab5%l>iBMaa2}RwygaIQf~{t!ct4t`r1WnjOZ7mm?+(%X}y5Ahhz85u68EiyTz zR~5??g&${&BDz&je{r%IWKe4fMwu4X|F}+D9)zfuE$UDs2geeWO&nQ%y;)*4Sj*Pw z`05&?;bE@{Zi!Zz{`)~z79Lk)Aopp|;A`7A$?mxM2wuBCz346sD{U4^_*gZ}!kCQc zY-mdwbWh;p)_Xk$Jk{c}N((w1CSZDgzZ65`eXg>!=doDX_FIlQp<6_grVbI)jxG+hvg(hRg&jd& z6ueLCScgFt*g7ro3A!8T-BB`0ERo+r{@akBo|g@HlwVzsz{fabdB*M}!bvc+?;b*> zP&kKEC=T*mD2LQ^Fa-B|_-0ss!y@SmolIs4wag#OfAh0?!&$DEzSH(&#z8kt@v|F( z2VQ2BBNpOvN`C%_g0jVGGe!Y9#~|lZmDeK8R6P_@TuTK$CAFe%~BY&la)o#lkX<2=H59==zApjS1_|Apfv@k96|q^R~2yG?F^^ z+gSe^M`rn{t&L&PQ^Dx7eiX{kFr_5eiJ4{IwEW^rzVz&|W(F1`5|3KBR?nS&JcyWtO4 z=*MOX?A>HnzJg*rXmWx*A&nJBB&~uSw}@X33_COEkm*I%AjFU9^rHoOx<+YQ+|Fqs zS#`OQ#iM#o!}z*gx*3-J-XAGf1g{6*SuSfTC(h44^2O8Wi>!+OxG=t)8@hE$t-ZJO z!MftPBb7L0^D%KcXPzO0 ziM2P|NS<66o9g%tzr_?t|7vk+M#VaM2%Jq!aS>?}Y|q`#BNX=Th$wZpF_e89CcdYxcQuAx^p{I z=7ie-^9I|#xpnYG%q@7>-2Vi&S*F<#t8gl4vsaT9MB25wvwGQj!2y1(dB>r+l;gvScy8MWiCMmwo=$o&DtH#+j5Og5T+>n3SnL{i@X}s*f|#HjbO$ z{LtAv?bK&?^F{$I=fXOBd9yF*r>_3-Sge@eaA$Lz$l`l7A8#+;fkMTLaqK`i$)&`Y z${H($Bz1BdDdUdL7DGTY2TCQyOC9tIYBM delta 3076 zcmbW3`8U*!9>>Q%*_W9{V`)4oLu8Gt*;6!jvV|_+lYNOKOP1Sn&$;&xxSw-guOHv%^W$s8Zp;pH+rnI*0R#d${ekWepI#?Orb8^~ z#%ew1>F9+eGjB485Pa#?>FBLw2wJ@7IWoJra~T?C&u2RD$TRP}iIzm)&&=lW;>dd* z!uiht_z$4;bUp%t_m~T4dQ%paC9`|K?+#)HOTO>F)a)|jtyJ66nuElflt+|HNF<1g zVDk}2N1}>ajwCUQ1H32*#G@r&3esdzn8NID19S7lk1ZfI+?@S6(PO#}?qZ(ze=8E^ zTC|dRO=BKR$!~pP*z^$4{$T$qc=CY}LdJBlg^lOps&@S6Txa0)pKr=}=wC7wH&q>F z>(?PzSE5+r!9*WzM)2v2RZTAN-$2)sMT-~OrmFU{AE(NM_W0_nhiovXwkoo-{{Bsc zDlIIY55=xY)54fu1U5@HjRz=1E-Y~@hNIft*Ss&CD0S_jmc0UX@FAZ~TC<8%aK2|Y29#RokXb0`Q_VZTVZ>d>q^;ZZ)wmO5P0JFuSm^0Cu(GM22;%^nqH{-De03r z4WlQ5KH0pyzGLKuR@g`(R0Rw1HM|M!%-z@NYQN_6)%91Q$sR_G!-scz?e3&7*pBUc z|L@=2!0DI;0vbwuG~LZb=*( zZGPu@+=S5OAO1F|82t^+`TT8|&A7xPpSySf-tbkCVlVA>>B_BSI1nXlIOQOIVI$5Y z)wFS^%=95=gJN1otwAzvP1RzOo08J0$V}Y{OYd&yBExM5-0;~tjmZptDOt)<(@wUW zH#Df2?zLNUg7-sOhwx~YAwjJ$mSMq+`_uj<>+=O(_u-%%5v9>>ShFb~>z+yw&KWR^ z%N5XB7eYs1k2I5N*~H-yw5P9_WsXV?1tp9V$mQ6A@m!qqjIzMTsm6GYTc6=p;P?aE zI10ZHn9%xl|5d5`C_KsxS~~Oc!_z2X(H_6}+wqwuVj^BzrMzhZ_$+P7Xj|4MXugDQ zP+5>ckcVY_+eW z5jjLCALb%NKI9u{i`+0Wr00a^m}?N@uMnzMwHa?jOb{1Kl2nu;J!*H&XlzEM`RqL_ zzPf50u8EiY6VyMq+8g8nUiEphy`x6M|C%uR&^ad#9g>e>axo5c0*TieQQgk-s4+z` z8#g%}iBG%#>@;z#8<>SqMP(GlbYW&0U{f?N%3?3+txSxbl|c8Vm)X;vHkant2<3El zWGgli1!Zeey9_CmAmJ?eax9){R}^npY`x5>K&n+}6k;T>svdii*_QDFtl7CS5xlAw zWUQTM%-$B1P?!3s;WNQ0(KvWCJRvlt?uGuRE0YeU)M}S)toJfj_pl)fOqO_#0y@&c}9KtXo69wMSAp!>;e_kUwpzdb3CFrkT}kp z&7V4g1d0n>Q7ZW7K3PBO*kjyiq-gEzu*JShLWLhj*orWEIFbO$pPit%de^ z^9F@%;Jjno&6m`yZHkU9s|iGEJ|s~xA!$`Cmz!zM1*tj}s(030plww;rYd>9v(`vr zO5$f8A%|IftBU93ycE`cnaQt~?dr64Lg*0?WaEr%LdEPkv-{5Chg7grtMXU}u^7J{ zcJFDe@_n0HjDfZTfDB#sQ~4UbaPY44s;jmmV8Zy3y4QMcaerXw?QZ)`j(rVexLBa{ z9H-lFh3!ov{D}tgiH3aSSrC%SvMAljDtMqx7uiV9R%`O?BBZllQf40PM&*myP6yc1 zw!v=Omtx+XWA{1G5x-g6{Z0-t&qDt@AkGCq#-+N4^eA0kpnwD4oz*?d>QPa)9!hl0 z3Tn+2H%t1SD{Ed~nNRDx%j4b&SM^JjP5O3#HczuD?r$zg8G>k8eXVnSjU*fm5O9AD z(YqI+6Z0&Ko@aVi#*!-ILmb{vYyh6cKGb`H>EMEi5 z3mo@;2x4itb0}x-+BYCAz|K3=>@@NMKWlTx-Hx>#gJ1Ezr20L&j)?zyT>uhXQ2e+v zTA7F}kP6sp!v`pKW0s@Gh=(KXLfGJfo!RF)-+g;`?O31sW9Q!UA1@~X^vfH|Q?2Ci znx28m9jiR`d-!{iPPqn(o;A#M8IkKR_p?Hf+DPP>^1w=*h6e9WKv*{bwQcCUlqJd1MuL8@Jv%*T|0 z-K_Oc4la^$=EYoDbW(85TU>nED5d(w#rpN-jHwy@OFth>j$wd#rCqM~Z0%U-BL21O zFgLQUp%`BoJEdp8NwvMcBv64*#8@!AVM-aT9&>Ab?x7DhSlud}%r##2Yd#`u(8=*< zz@GbH(uG+=tAc5Zj{Y^#ccJoI0Q+rh*=xD895(w6|6Rrcj*538X^~^7vE9X2Y)H~lSNJu# zu~Hte>SNrlkPTk>JbkdJ-I1q-`+qMdu{ao@Io saQ853X>oHi{(s&v27&1RB=3Jq90>wtR!N=XFJ${Cg#X;%|MCCyZ?*o&RR910 diff --git a/LaiPuLaser/resource.h b/LaiPuLaser/resource.h index 8e888fc0bf2798b0581c352ffca0bc40da9fc9f0..2fbbf5e1276c00fc775b541720ea7f821b584fea 100644 GIT binary patch delta 80 zcmdn@gZa`g<_#j#CksULOwO1lHd%>LZ1aa{DH@X-c5qCduvcJmLXN^_gZ&>Ep#pr9 iweplE?O>a{?10>6g@aElC!0u$O+N5TWV7CH0Y(6)RwHEq delta 41 zcmV+^0M`G~`UAfB1F#gAvv8L{D3h>y3bPi#!U2=eA_lWM!rnQP!UGnwF8m|`r}q-t