#include "StdAfx.h" #include "PathScheduler_Quad_Active_Sorting.h" #include #include "MotionInfo_Axis.h" inline bool ComparePosAscend(SPathData& a, SPathData& b) { return (a.nPosX < b.nPosX); } inline bool ComparePosDescend(SPathData& a, SPathData& b) { return (a.nPosX > b.nPosX); } inline bool ComparePosX(SPathData& a, SPathData& b) { return (a.nPosX < b.nPosX); } inline bool ComparePosY(SPathData& a, SPathData& b) { return (a.nPosY < b.nPosY); } inline int GetDiffCountX(const VectorPathData& vecPathData, int nCenterPos) { int nLeft = 0; int nRight = 0; for (constVectorPathDataIt it=vecPathData.begin(); it!=vecPathData.end(); it++) { if (it->nPosX < nCenterPos) { nLeft++; } else { nRight++; } } return abs(nLeft-nRight); } inline int GetDiffCountY(const VectorPathData& vecPathData, int nCenterPos) { int nTop = 0; int nBottom = 0; for (constVectorPathDataIt it=vecPathData.begin(); it!=vecPathData.end(); it++) { if (it->nPosY < nCenterPos) { nTop++; } else { nBottom++; } } return abs(nTop-nBottom); } inline int GetCollisionPosX(const VectorPathData& vecPathData, int nGlassSizeX, int nCollisionDist) { VectorPathData vecSortData = vecPathData; // sort std::sort(vecSortData.begin(), vecSortData.end(), ComparePosX); int nSize = (int)vecSortData.size(); int nCenterPosX = vecSortData[nSize/2].nPosX; int nCollisionDistX = nCollisionDist; // À§Ä¡°¡ ³Ê¹« À۰ųª Ŭ¶§? if ( nCenterPosX<(nCollisionDistX*2) || nCenterPosX>=(nGlassSizeX-(nCollisionDistX*2)) ) { int nLeftPos = (nCollisionDistX*2); int nRightPos = nGlassSizeX-(nCollisionDistX*2); // Á¿ìÀÇ Å©±â Â÷À̰¡ ÀÛÀº À§Ä¡·Î ÇÒ´çÇÏÀÚ! nCenterPosX = (GetDiffCountX(vecPathData, nLeftPos) < GetDiffCountX(vecPathData, nRightPos)) ? nLeftPos: nRightPos; } return nCenterPosX; } inline int GetCollisionPosY(const VectorPathData& vecPathData, int nGlassSizeY, int nCollisionDist) { VectorPathData vecSortData = vecPathData; // sort std::sort(vecSortData.begin(), vecSortData.end(), ComparePosY); int nSize = (int)vecSortData.size(); int nCenterPosY = vecSortData[nSize/2].nPosY; int nCollisionDistY = nCollisionDist; // À§Ä¡°¡ ³Ê¹« À۰ųª Ŭ¶§? if ( nCenterPosY<(nCollisionDistY*2) || nCenterPosY>=(nGlassSizeY-(nCollisionDistY*2)) ) { int nTopPos = (nCollisionDistY*2); int nBottomPos = nGlassSizeY-(nCollisionDistY*2); // Á¿ìÀÇ Å©±â Â÷À̰¡ ÀÛÀº À§Ä¡·Î ÇÒ´çÇÏÀÚ! nCenterPosY = (GetDiffCountY(vecPathData, nTopPos) < GetDiffCountY(vecPathData, nBottomPos)) ? nTopPos: nBottomPos; } return nCenterPosY; } CPathScheduler_Quad_Active_Sorting::CPathScheduler_Quad_Active_Sorting(void) { } CPathScheduler_Quad_Active_Sorting::~CPathScheduler_Quad_Active_Sorting(void) { } int CPathScheduler_Quad_Active_Sorting::PathScheduling( const VectorPathData& vecPathData, const VectorPathData& vecStartPath ) { m_vecRangeRect.clear(); m_vecScanRangeData.clear(); m_vecPathSchedulerResult.clear(); int nGantryCount = 2; int nRangeCount = CalculateRangeRect( nGantryCount, m_PathSchedulerParam.GetModuleCount(), m_PathSchedulerParam.GetGlassSizeX(), m_PathSchedulerParam.GetGlassSizeY(), m_PathSchedulerParam.GetCollisionDistX(), m_PathSchedulerParam.GetCollisionDistY(), m_PathSchedulerParam.GetOriginDir(), m_PathSchedulerParam.GetBaseModuleDir(), vecPathData, m_vecScanRangeData); if (nRangeCount<1) return 0; FILE *fp = NULL; CString strFilename = _T(""); strFilename.Format(_T("c:\\temp\\range_info.csv")); _tfopen_s(&fp, strFilename, _T("w")); if (fp) { _ftprintf_s(fp, _T("[ModuleIdx], [ScanIdx], [Left], [Right], [Top], [Bottom], [ScanDir], [StartX], [EndX], [ColliX], [ColliY]\n")); } m_vecRangeRect.clear(); int nTotalCount = 0; SPathData sStartPath; // ¸ðµâº° ½ºÄµ ½ÃÀÛÀ§Ä¡ ÀúÀå. for (int nModuleIdx=0; nModuleIdxnLeft, pRangeData->nTop, pRangeData->nRight, pRangeData->nBottom); rect.NormalizeRect(); m_vecRangeRect.push_back(rect); if (fp) { _ftprintf_s(fp, _T("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n"), pRangeData->nModuleIdx, pRangeData->nScanIdx, pRangeData->nLeft, pRangeData->nRight, pRangeData->nTop, pRangeData->nBottom, pRangeData->nScanDir, pRangeData->nScanStartX, pRangeData->nScanEndX, pRangeData->nColliPosX, pRangeData->nColliPosY); } // ½ÃÀÛÀ§Ä¡´Â ÇöÀç¸ðµâÀÇ À§Ä¡ÀÌ´Ù. sStartPath = vecStartPath[nModuleIdx]; // ¿µ¿ªº° ½ºÄÉÁ층 ¼öÇà. CPathSchedulerResult schedulerResult(nModuleIdx, 0); // °æ·Î °è»ê int nCount = CalculatePath(nModuleIdx, 0, sStartPath, vecPathData, *pRangeData, schedulerResult); nTotalCount += nCount; // ¸ðµâÀÇ Ãæµ¹À§Ä¡ ÀúÀå schedulerResult.SetCollisionPositionX(pRangeData->nColliPosX); schedulerResult.SetCollisionPositionY(pRangeData->nColliPosY); // °á°ú ÀúÀå. m_vecPathSchedulerResult.push_back(schedulerResult); } if (fp) fclose(fp); return int(m_vecPathSchedulerResult.size()); } int CPathScheduler_Quad_Active_Sorting::CalculatePath(int nModuleIdx, int nScanIdx, const SPathData& startPath, const VectorPathData& vecTotalPathData, const SRangeData& rtRange, CPathSchedulerResult& scheduleResult ) { scheduleResult.Reset(); CRect rtTemp(rtRange.nLeft, rtRange.nTop, rtRange.nRight, rtRange.nBottom); // get path data VectorPathData vecPathData; for (constVectorPathDataIt it=vecTotalPathData.begin(); it!=vecTotalPathData.end(); it++) { if ( rtTemp.PtInRect( CPoint(it->nPosX,it->nPosY )) ) { vecPathData.push_back(*it); } } // sort for scan direction if (rtRange.nScanDir==0) { std::sort(vecPathData.begin(), vecPathData.end(), ComparePosAscend); } else { std::sort(vecPathData.begin(), vecPathData.end(), ComparePosDescend); } // set result count scheduleResult.SetScheduleResultCount((int)vecPathData.size()); FILE *fp = NULL; CString strFilename = _T(""); strFilename.Format(_T("c:\\temp\\%d_%d.csv"), nModuleIdx, nScanIdx); _tfopen_s(&fp, strFilename, _T("w")); if (fp) { _ftprintf_s(fp, _T("[Left], [Right], [Top], [Bottom], [ScanStart], [ScanEnd], [ScanDir]\n")); _ftprintf_s(fp, _T("%d, %d, %d, %d, %d, %d, %d\n"), rtRange.nLeft, rtRange.nRight, rtRange.nTop, rtRange.nBottom, rtRange.nScanStartX, rtRange.nScanEndX, rtRange.nScanDir); _ftprintf_s(fp, _T("[Index], [PosX], [PosY]\n")); } // calculate path SSchedulerResult sStartPos; sStartPos.dPositionX = double(startPath.nPosX / 1000.0); sStartPos.dPositionY = double(startPath.nPosY / 1000.0); for (int nIdx=0; nIdx<(int)vecPathData.size(); nIdx++) { SSchedulerResult sResult; sResult.nTotalIndex = vecPathData[nIdx].nIndex; sResult.dPositionX = double(vecPathData[nIdx].nPosX) / 1000.0; sResult.dPositionY = double(vecPathData[nIdx].nPosY) / 1000.0; sResult.dAutoFocusTime = m_PathSchedulerParam.GetAutoFocusTime(); sResult.dImageGrabTime = m_PathSchedulerParam.GetImageGrabTime(); sResult.dMotionDelayTime = m_PathSchedulerParam.GetMotionDelayTime(); memcpy(sResult.pDataType, vecPathData[nIdx].pDataType, sizeof(int)*PATH_DATA_TYPE_COUNT); // exist start pos if (!CalculateDistanceSpeedTime(sResult, sStartPos)) { continue; } // save cur_pos to start_pos sStartPos = sResult; if (fp) _ftprintf_s(fp, _T("%d, %d, %d\n"), nIdx, vecPathData[nIdx].nPosX, vecPathData[nIdx].nPosY); scheduleResult.SetScheduleResult(nIdx, sResult); } if (fp) fclose(fp); return scheduleResult.GetPathSchedulerResultCount(); } int CPathScheduler_Quad_Active_Sorting::CalculateRangeRect(int nGantryCount, int nModuleCount, int nGlassSizeX, int nGlassSizeY, int nDistX, int nDistY, int nOriginDir, int nBaseDir, const VectorPathData& vecPathData, VectorRangeData& vecRangeData) { // get x pos int nResultPosX = GetCollisionPosX(vecPathData, m_PathSchedulerParam.GetGlassSizeX(), m_PathSchedulerParam.GetCollisionDistX()); // get left or right VectorPathData vecLeft, vecRight; for (constVectorPathDataIt it=vecPathData.begin(); it!=vecPathData.end(); it++) { if (it->nPosX > nResultPosX) { vecRight.push_back(*it); } else { vecLeft.push_back(*it); } } // get y pos int nResultLeftY = GetCollisionPosY(vecLeft, m_PathSchedulerParam.GetGlassSizeY(), 0); // get y pos int nResultRightY = GetCollisionPosY(vecRight, m_PathSchedulerParam.GetGlassSizeY(), 0); SRangeData range; range.nScanIdx = 0; range.nScanDir = 0; // left top range.nTop = 0; range.nBottom = nResultLeftY; range.nLeft = 0; range.nRight = nResultPosX; range.nModuleIdx = 0; range.nScanStartX = range.nLeft; // ½ºÄµ ½ÃÀÛÀ§Ä¡ range.nScanEndX = range.nRight; // ½ºÄµ Á¾·áÀ§Ä¡ range.nColliPosX = range.nRight - m_PathSchedulerParam.GetCollisionDistX(); range.nColliPosY = range.nBottom - m_PathSchedulerParam.GetCollisionDistY(); vecRangeData.push_back(range); // left bottom range.nTop = nResultLeftY; range.nBottom = m_PathSchedulerParam.GetGlassSizeY(); range.nLeft = 0; range.nRight = nResultPosX; range.nModuleIdx = 1; range.nScanStartX = range.nLeft; // ½ºÄµ ½ÃÀÛÀ§Ä¡ range.nScanEndX = range.nRight; // ½ºÄµ Á¾·áÀ§Ä¡ range.nColliPosX = range.nRight - m_PathSchedulerParam.GetCollisionDistX(); range.nColliPosY = range.nTop + m_PathSchedulerParam.GetCollisionDistY(); vecRangeData.push_back(range); // right top range.nTop = 0; range.nBottom = nResultRightY; range.nLeft = nResultPosX; range.nRight = m_PathSchedulerParam.GetGlassSizeX(); range.nModuleIdx = 2; range.nScanStartX = range.nLeft; // ½ºÄµ ½ÃÀÛÀ§Ä¡ range.nScanEndX = range.nRight; // ½ºÄµ Á¾·áÀ§Ä¡ range.nColliPosX = range.nLeft + m_PathSchedulerParam.GetCollisionDistX(); range.nColliPosY = range.nBottom - m_PathSchedulerParam.GetCollisionDistY(); vecRangeData.push_back(range); // right bottom range.nTop = nResultRightY; range.nBottom = m_PathSchedulerParam.GetGlassSizeY(); range.nLeft = nResultPosX; range.nRight = m_PathSchedulerParam.GetGlassSizeX(); range.nModuleIdx = 3; range.nScanStartX = range.nLeft; // ½ºÄµ ½ÃÀÛÀ§Ä¡ range.nScanEndX = range.nRight; // ½ºÄµ Á¾·áÀ§Ä¡ range.nColliPosX = range.nLeft + m_PathSchedulerParam.GetCollisionDistX(); range.nColliPosY = range.nTop + m_PathSchedulerParam.GetCollisionDistY(); vecRangeData.push_back(range); // set info int nGlassDivX = nGlassSizeX / nGantryCount; int nGantryModuleCount = nModuleCount / nGantryCount; int nGlassDivModuleY = nGlassSizeY / nGantryModuleCount; int nGlassDivScanY = nGlassDivModuleY; int nScanCount = 1; int nScanIdx = 0; VectorRangeData vecResult; for (int nModuleIdx=0; nModuleIdxnModuleIdx==nModuleIdx && it->nScanIdx==nScanIdx) { return &(*it); } } return NULL; } const SRangeData* CPathScheduler_Quad_Active_Sorting::GetScanRangeData( int nModuleIdx, int nScanIdx ) const { for (constVectorRangeDataIt it=m_vecScanRangeData.begin(); it!=m_vecScanRangeData.end(); it++) { if (it->nModuleIdx==nModuleIdx && it->nScanIdx==nScanIdx) { return &(*it); } } return NULL; } int CPathScheduler_Quad_Active_Sorting::GetDirectionX(int nDir1, int nDir2) { //SchedulerDir_LeftTop=0, SchedulerDir_RightTop, SchedulerDir_LeftBottom, SchedulerDir_RightBottom // Dir1 == Left if (nDir1==SchedulerDir_LeftTop || nDir1==SchedulerDir_LeftBottom) { if (nDir2==SchedulerDir_LeftTop || nDir2==SchedulerDir_LeftBottom) { return 1; } else { return -1; } } // Dir1 == Right if (nDir2==SchedulerDir_RightTop || nDir2==SchedulerDir_RightBottom) { return 1; } return -1; } int CPathScheduler_Quad_Active_Sorting::GetDirectionY(int nDir1, int nDir2) { //SchedulerDir_LeftTop=0, SchedulerDir_RightTop, SchedulerDir_LeftBottom, SchedulerDir_RightBottom // Dir1 == Top if (nDir1==SchedulerDir_LeftTop || nDir1==SchedulerDir_RightTop) { if (nDir2==SchedulerDir_LeftTop || nDir2==SchedulerDir_RightTop) { return 1; } else { return -1; } } // Dir1 == Bottom if (nDir2==SchedulerDir_LeftBottom || nDir2==SchedulerDir_RightBottom) { return 1; } return -1; } int CPathScheduler_Quad_Active_Sorting::IsChangeModuleIndex(int nDir1, int nDir2) { return (nDir1!=nDir2); } int CPathScheduler_Quad_Active_Sorting::IsChangeScanIndex(int nDir1, int nDir2) { if (GetDirectionY(nDir1, nDir2)==-1) return 1; return 0; } int CPathScheduler_Quad_Active_Sorting::IsChangeScanDir(int nDir1, int nDir2) { if (GetDirectionX(nDir1, nDir2)==-1) return 1; return 0; } int CPathScheduler_Quad_Active_Sorting::GetChangeModuleIndex(int nModuleIndex, int nOriginDir, int nBaseDir, int nGantryModuleCount, int nTotalModuleCount) { int nTmpValue = nModuleIndex; if (GetDirectionX(nOriginDir, nBaseDir)==-1) // x ¿ª¹æÇâ { if (nTmpValuenGantryModuleCount && nModuleIdx