/******************************************************************************* * * * Société de Transports de Montréal. * * 2012 - 2013 * * * * Projet Zones Tests * * * * * * * *******************************************************************************/ /* Description: Cette classe est un thread qui roule en parallèle au programme. Elle est responsable de l'analyse en temps réel du passage d'un train. Elle fait la lecture des entrées sur la carte PCI et analyse les déclenchements au fur et à mesure qu'un train chemine sur la ZT2 */ /* ************************************************************************** */ /* Revision: ### YYYMMDD JFM Verision d'origine. ### YYYYMMDD Description du besoin ou du bug Description du changement. */ /* ************************************************************************** */ #include "GlobalDefine.h" #include "ZT2AnalysisThread.h" #include "PCIIOMgr.h" #include "AbstractLazerProbe.h" #include #include "ZTconfigmgr.h" //const char * ErrorString[25] = {"Erreur de comptage S1-S2", // "Déclenchement frotteur négatif", // "Déclenchement pneu de guidage intérieur", // "Déclenchement pneu de guidage extérieur", // "Déclenchement pneu porteur intérieur", // "Déclenchement pneu porteur extérieur", // "Pré-détection frotteur négatif"}; CZT2AnalysisThread::CZT2AnalysisThread() { mLastInputs = 0; mZT2TrainState = ZT2_PRE_DETECTION_STATE; mPCIInputsHandle = 0; mExitLoop = false; mZT2Analyzing = false; } unsigned int CZT2AnalysisThread::Init(CPCIIOMgr *PCIIOHandle,GenericInputMasks_t *InputMasks,QElapsedTimer *RefTimer) { mPCIInputsHandle = PCIIOHandle; mInputMasksPtr = InputMasks; mReferenceTimer = RefTimer; return RET_OK; } void CZT2AnalysisThread::AnalyzeZT2Train() { qDebug("ZT2 Thread started!"); mExitLoop = false; mZT2Analyzing = true; mPEQDetectionLatch = false; mZT2TrainState = ZT2_PRE_DETECTION_STATE; unsigned int PCIInputs = 0; mLastInputs = 0; bool Run = true; QElapsedTimer AcquisitionTimer; AcquisitionTimer.start(); //inputs unsigned int S1 = 0, Pint = 0, Pext = 0; //Train analysis variables unsigned int Bogie = 0; unsigned int Rank = 0; unsigned int CountS1 = 0; bool PPIDetected = false; bool PPEDetected = false; while(Run == true) { PCIInputs = mPCIInputsHandle->GetInputs(); if(PCIInputs != mLastInputs) { //Extract useful flags S1 = ((PCIInputs & mInputMasksPtr->InputZT2S1Mask) != 0); Pint = ((PCIInputs & mInputMasksPtr->InputZT2PIMask) == 0); Pext = ((PCIInputs & mInputMasksPtr->InputZT2PEMask) == 0); if(mZT2TrainState == ZT2_PRE_DETECTION_STATE) { if(S1 != 0 || Pint != 0 || Pext != 0) { RegisterDetection(DETECTION_PEQ2_DETECTION,0,mReferenceTimer->nsecsElapsed()); if(S1 != 0) { emit AddLogString(QString("Panne équipement ZT2: Pré détection S1 = 1")); } if(Pint != 0) { emit AddLogString(QString("Panne équipement ZT2: Pré détection Pneu porteur intérieur = 1")); } if(Pext != 0) { emit AddLogString(QString("Panne équipement ZT2: Pré détection Pneu porteur extérieur = 1")); } } mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; } switch(mZT2TrainState) { case ZT2_PRE_DETECTION_STATE: { CEngLog::instance()->AddLogString("ZT2AnalysisThread::Logic error, in ZT2 Pre detection state and should not..."); mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; break; } case ZT2_WAIT_FOR_S1_STATE: { if(Pint != 0) { if(PPIDetected == false) { PPIDetected = true; RegisterDetection(DETECTION_ZT2_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); } } if(Pext != 0) { if(PPEDetected == false) { PPEDetected = true; RegisterDetection(DETECTION_ZT2_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); } } if(S1 == 1) { Rank++; CountS1++; if(Rank %2 == 1) Bogie++; PPIDetected = false; PPEDetected = false; mZT2TrainState = ZT2_S1_ACTIVE_STATE; } break; } case ZT2_S1_ACTIVE_STATE: { if(Pint != 0) { if(PPIDetected == false) { PPIDetected = true; RegisterDetection(DETECTION_ZT2_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); } } if(Pext != 0) { if(PPEDetected == false) { PPEDetected = true; RegisterDetection(DETECTION_ZT2_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); } } if(S1 == 0) { mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; } break; } }//switch(mZT2TrainState) mLastInputs = PCIInputs; CZT2ThreadData *Data = new CZT2ThreadData(); Data->mTimeStamp = mReferenceTimer->nsecsElapsed(); // Data->mDateTime = QDateTime::currentDateTime(); Data->mS1 = S1; Data->mPPExt = Pext; Data->mPPInt = Pint; Data->mBogie = Bogie; Data->mRank = Rank; Data->mS1Count = CountS1; emit ZT2DataUpdate(Data); }//if(PCIInputs != mLastInputs) mMutex.lock(); if(mExitLoop == true) Run = false; mMutex.unlock(); }//while mZT2Analyzing = false; } void CZT2AnalysisThread::TerminateAnalysis() { mMutex.lock(); mExitLoop = true; mMutex.unlock(); } bool CZT2AnalysisThread::UpdateDetectionConfig(CZTDetectionFunctionConfig *NewConfig) { //do not update in the middle of a train analysis. bool Go; mMutex.lock(); Go = mZT2Analyzing; mMutex.unlock(); if(Go == true) return false; //No need for a Mutex here since the thread is //not analyzing. mDetectionConfig = *NewConfig; return true; } void CZT2AnalysisThread::RegisterDetection(unsigned int DetectionID, unsigned int Rank,qint64 TimeStamp) { if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive == false) return; switch(DetectionID) { case DETECTION_PEQ2_DETECTION: { if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive == false) { return; } break; } case DETECTION_ZT2_MAGNETIC_SENSOR_COUNT: { if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive == false) { return; } else { if(mPEQDetectionLatch == true) { return; } mPEQDetectionLatch = true; } break; } case DETECTION_ZT2_PPI_DETECTION: { if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive == false) { return; } break; } case DETECTION_ZT2_PPE_DETECTION: { if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive == false) { return; } break; } } CZTDetectionData *DetectData = new CZTDetectionData; DetectData->mTimeStamp = TimeStamp; DetectData->mRank = Rank; DetectData->mDetectionID = DetectionID; emit DetectionTriggered(DetectData); // qDebug("%s -> Rang %d",CZTData::GetErrorString(DetectionID),Rank); }