1052 lines
30 KiB
C++
1052 lines
30 KiB
C++
/*******************************************************************************
|
|
* *
|
|
* 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 détecte les déclenchements au fur
|
|
et à mesure qu'un train chemine sur la ZT1
|
|
|
|
*/
|
|
|
|
/* ************************************************************************** */
|
|
/* Revision:
|
|
### YYYMMDD JFM
|
|
Verision d'origine.
|
|
|
|
### YYYYMMDD Description du besoin ou du bug
|
|
Description du changement.
|
|
*/
|
|
|
|
/* ************************************************************************** */
|
|
|
|
#include "GlobalDefine.h"
|
|
#include "ZT1AnalysisThread.h"
|
|
#include "PCIIOMgr.h"
|
|
#include "AbstractLazerProbe.h"
|
|
#include <QElapsedTimer>
|
|
#include "ZTconfigmgr.h"
|
|
#include <QDebug>
|
|
|
|
|
|
CZT1AnalysisThread::CZT1AnalysisThread()
|
|
{
|
|
mLastInputs = 0;
|
|
mLastPGIntValue = mLastPGExtValue = mLastSDFValue = 0;
|
|
mZT1TrainState = ZT1_WAIT_FOR_S1_STATE;
|
|
|
|
mPGIntHandle = 0;
|
|
mPGExtHandle = 0;
|
|
mPCIInputsHandle = 0;
|
|
mSDFAnalogInterface = 0;
|
|
mExitLoop = false;
|
|
mZT1Analyzing = false;
|
|
mPGCalibration = false;
|
|
|
|
}
|
|
|
|
unsigned int CZT1AnalysisThread::Init(CPCIIOMgr *PCIIOHandle,GenericInputMasks_t *InputMasks, CAbstractLazerProbe* PGExtHandle,CAbstractLazerProbe* PGIntHandle,QElapsedTimer *RefTimer,CAnalogInputModule *AnalogInterface)
|
|
{
|
|
mPCIInputsHandle = PCIIOHandle;
|
|
mInputMasksPtr = InputMasks;
|
|
mPGIntHandle = PGIntHandle;
|
|
mPGExtHandle = PGExtHandle;
|
|
mReferenceTimer = RefTimer;
|
|
mSDFAnalogInterface = AnalogInterface;
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
void CZT1AnalysisThread::SetPGTreshold(qint32 PGTreshold)
|
|
{
|
|
mMutex.lock();
|
|
mPGTreshold = PGTreshold;
|
|
mMutex.unlock();
|
|
}
|
|
|
|
bool CZT1AnalysisThread::SetPGCalibration(bool CalibON)
|
|
{
|
|
mMutex.lock();
|
|
if(mZT1Analyzing)
|
|
{
|
|
mMutex.unlock();
|
|
return false;
|
|
}
|
|
mPGCalibration = CalibON;
|
|
mMutex.unlock();
|
|
|
|
return true;
|
|
}
|
|
|
|
void CZT1AnalysisThread::AnalyzeZT1Train()
|
|
{
|
|
|
|
// qDebug("ZT1 Thread started!");
|
|
mExitLoop = false;
|
|
mZT1Analyzing = true;
|
|
mPEQDetectionLatch = false;
|
|
|
|
|
|
mZT1TrainState = ZT1_PRE_DETECTION_STATE;
|
|
unsigned int PCIInputs = 0;
|
|
bool Run = true;
|
|
QElapsedTimer TrainSpeedTimer1,TrainSpeedTimer2,AcquisitionTimer;
|
|
|
|
AcquisitionTimer.start();
|
|
|
|
//inputs
|
|
unsigned int S1 = 0, S2 = 0, Pint = 0, Pext = 0, FN = 0;
|
|
qint32 PGint,PGExt;
|
|
int SDFAnalog = 0;
|
|
|
|
|
|
//Train analysis variables
|
|
float TrainSpeed = 0;
|
|
unsigned int Bogie = 0;
|
|
unsigned int Rank = 0;
|
|
unsigned int CountS1 = 0;
|
|
unsigned int CountS2 = 0;
|
|
unsigned int CountFN = 0;
|
|
unsigned int TrainType = TRAIN_TYPE_UNKNOWN;
|
|
mMutex.lock();
|
|
qint32 PGValueTreshold = mPGTreshold;
|
|
bool PGCalibration = mPGCalibration;
|
|
mMutex.unlock();
|
|
|
|
mLastInputs = 0;
|
|
mLastSDFValue = 0;
|
|
|
|
|
|
bool FNDetected = false;
|
|
bool PPIDetected = false;
|
|
bool PPEDetected = false;
|
|
bool PGActive = false;
|
|
|
|
bool LazerProbesTransitOnly = false;
|
|
|
|
qint32 PGIOffset,PGEOffset;
|
|
qint32 Quadra;
|
|
qint32 PGICalibValue = 0, PGECalibValue = 0;
|
|
|
|
PGValueTreshold *= PGValueTreshold; //use square value...
|
|
PGIOffset = mPGIntHandle->GetLastData();
|
|
PGEOffset = mPGExtHandle->GetLastData();
|
|
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mIntPGOffset = PGIOffset;
|
|
emit NewZT1Flag(ZT1_INT_PG_OFFSET_FLAG_ID,Flag);
|
|
|
|
Flag = new CZT1FlagsData(); //the state machine deletes the pointer, we must create a new one.
|
|
Flag->mExtPGOffset = PGEOffset;
|
|
emit NewZT1Flag(ZT1_EXT_PG_OFFSET_FLAG_ID,Flag);
|
|
|
|
Flag = new CZT1FlagsData(); //the state machine deletes the pointer, we must create a new one.
|
|
Flag->mPGTresholdValue = PGValueTreshold;
|
|
emit NewZT1Flag(ZT1_PG_TRESHOLD_VALUE_FLAG_ID,Flag);
|
|
|
|
while(Run == true)
|
|
{
|
|
{
|
|
AcquisitionTimer.start();
|
|
|
|
PCIInputs = mPCIInputsHandle->GetInputs();
|
|
|
|
PGint = mPGIntHandle->GetLastData();
|
|
PGExt = mPGExtHandle->GetLastData();
|
|
if(mSDFAnalogInterface != 0)
|
|
mSDFAnalogInterface->GetAnalogInput(0,&SDFAnalog);
|
|
|
|
if(PCIInputs != mLastInputs)
|
|
{
|
|
LazerProbesTransitOnly = false;
|
|
}
|
|
else
|
|
{
|
|
LazerProbesTransitOnly = true;
|
|
}
|
|
|
|
if(PCIInputs != mLastInputs ||
|
|
PGint != mLastPGIntValue ||
|
|
PGExt != mLastPGExtValue ||
|
|
SDFAnalog != mLastSDFValue )
|
|
{
|
|
//Extract useful flags
|
|
|
|
S1 = ((PCIInputs & mInputMasksPtr->InputZT1S1Mask) != 0);
|
|
S2 = ((PCIInputs & mInputMasksPtr->InputZT1S2Mask) != 0);
|
|
Pint = ((PCIInputs & mInputMasksPtr->InputZT1PIMask) == 0); //PP are active low
|
|
Pext = ((PCIInputs & mInputMasksPtr->InputZT1PEMask) == 0);
|
|
FN = ((PCIInputs & mInputMasksPtr->InputZT1FNMask) == 0); //FN is active low
|
|
|
|
switch(mZT1TrainState)
|
|
{
|
|
case ZT1_PRE_DETECTION_STATE: //Get in this state only once at the beginning.
|
|
{
|
|
//Pre-detection : Check if SDF is not active.
|
|
if(FN == 1 || Pint == 1 || Pext == 1)
|
|
{
|
|
RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
if(FN == 1)
|
|
{
|
|
emit AddLogString(QString("Panne équipement ZT1: Pré détection Frotteur négatif = 1"));
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mPEQ1Type = PEQ1_FN_PREDETECTION_TYPE;
|
|
emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag);
|
|
}
|
|
if(Pint == 1)
|
|
{
|
|
emit AddLogString(QString("Panne équipement ZT1: Pré détection Pneu porteur intérieur = 1"));
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mPEQ1Type = PEQ1_PINT_PREDETECTION_TYPE;
|
|
emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag);
|
|
}
|
|
if(Pext == 1)
|
|
{
|
|
emit AddLogString(QString("Panne équipement ZT1: Pré détection Pneu porteur extérieur = 1"));
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mPEQ1Type = PEQ1_PEXT_PREDETECTION_TYPE;
|
|
emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag);
|
|
}
|
|
}
|
|
if(S1 == 1 || S2 == 1)
|
|
{
|
|
RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
if(S1 == 1)
|
|
{
|
|
emit AddLogString(QString("Panne équipement ZT1: Pré détection S1 = 1"));
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mPEQ1Type = PEQ1_MAG_SENSOR_S1_PREDETECTION_TYPE;
|
|
emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag);
|
|
}
|
|
if(S2 == 1)
|
|
{
|
|
emit AddLogString(QString("Panne équipement ZT1: Pré détection S2 = 1"));
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mPEQ1Type = PEQ1_MAG_SENSOR_S2_PREDETECTION_TYPE;
|
|
emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag);
|
|
}
|
|
}
|
|
if(mPGIntHandle->IsProbeAlive() == false)
|
|
{
|
|
RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
emit AddLogString(QString("Panne équipement ZT1: Pré détection Sonde lazer intérieure défectueuse"));
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mPEQ1Type = PEQ1_LAZER_SENSOR_INT_PREDETECTION_TYPE;
|
|
emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag);
|
|
}
|
|
if(mPGExtHandle->IsProbeAlive() == false)
|
|
{
|
|
RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
emit AddLogString(QString("Panne équipement ZT1: Pré détection Sonde lazer extérieure défectueuse"));
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mPEQ1Type = PEQ1_LAZER_SENSOR_EXT_PREDETECTION_TYPE;
|
|
emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag);
|
|
}
|
|
|
|
mZT1TrainState = ZT1_WAIT_FOR_S1_STATE;
|
|
break;
|
|
}
|
|
case ZT1_WAIT_FOR_S1_STATE: //1
|
|
{
|
|
FNDetected = false;
|
|
PPEDetected = false;
|
|
PPIDetected = false;
|
|
PGActive = false;
|
|
|
|
if(FN == 1)// The SDF should not detect any FN at this step (no bogie on the ZT).
|
|
{
|
|
if(mPEQDetectionLatch == false)
|
|
{
|
|
// emit AddLogString(QString("Panne équipement ZT1: SDF <collé> à 1"));
|
|
CZT1FlagsData *Flag = new CZT1FlagsData();
|
|
Flag->mPEQ1Type = PEQ1_FN_STUCK_LOW_TYPE;
|
|
emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag);
|
|
}
|
|
RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
|
|
if(S1 == 0 && S2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 1 && S2 == 0)
|
|
{
|
|
Bogie++;
|
|
Rank++;
|
|
CountS1++;
|
|
if(PGCalibration)
|
|
{
|
|
PGICalibValue = PGIOffset;
|
|
PGECalibValue = PGEOffset;
|
|
}
|
|
|
|
TrainSpeedTimer1.start();
|
|
mZT1TrainState = ZT1_S1_ACTIVE_STATE;
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_S1_ACTIVE_STATE: //2
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
if(PGCalibration)
|
|
{
|
|
|
|
qint32 Value = PGint - PGIOffset;
|
|
if(Value < PGICalibValue)
|
|
PGICalibValue = Value;
|
|
|
|
Value = PGExt - PGEOffset;
|
|
if(Value < PGECalibValue)
|
|
PGECalibValue = Value;
|
|
}
|
|
else if(PGActive == false)
|
|
{
|
|
//Compute and verify if the PG is detected.
|
|
Quadra = ((PGint - PGIOffset) * (PGExt - PGEOffset));
|
|
|
|
if(Quadra > PGValueTreshold)
|
|
{
|
|
//The PG has been detected, stop sampling...
|
|
PGActive = true;
|
|
}
|
|
}
|
|
|
|
if(S1 == 1 && S2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 0 && S2 == 0)
|
|
{
|
|
if(PGCalibration)
|
|
{
|
|
CZTPGCalibrationData *Data = new CZTPGCalibrationData();
|
|
Data->mTimestamp = mReferenceTimer->nsecsElapsed();
|
|
Data->mPGExtValue = PGECalibValue;
|
|
Data->mPGIntValue = PGICalibValue;
|
|
|
|
emit NewPGCalibrationData(Data);
|
|
PGICalibValue = PGIOffset;
|
|
PGECalibValue = PGEOffset;
|
|
}
|
|
else if(PGActive == false) //The PG has not been detected...
|
|
{
|
|
RegisterDetection(DETECTION_PG_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
PGActive = false;
|
|
|
|
|
|
if(TrainType == TRAIN_TYPE_UNKNOWN) //First bogie, the train type is unknown
|
|
{
|
|
mZT1TrainState = ZT1_S1_TRANSIT_STATE; //goto state 3 to determine train type...
|
|
}
|
|
else if(TrainType == TRAIN_TYPE_MR63_MR73)
|
|
{
|
|
mZT1TrainState = ZT1_S1_TANSIT_MR_STATE; //goto state 3_MR
|
|
}
|
|
else if(TrainType == TRAIN_TYPE_MPM10)
|
|
{
|
|
mZT1TrainState = ZT1_S1_TRANSIT_MPM_STATE; //goto state3_MPM
|
|
}
|
|
else
|
|
CEngLog::instance()->AddLogString("LOGIC ERROR IN ZT1AnalysysThread.CPP - ZT1_ACTIVE_STATE: invalid train type",1);
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_S1_TRANSIT_STATE: //3
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
|
|
if(S1 == 0 && S2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 1 && S2 == 0)
|
|
{
|
|
CountS1++;
|
|
TrainType = TRAIN_TYPE_MR63_MR73;
|
|
TrainSpeed = (MR_BOGIE_LENGTH / TrainSpeedTimer1.elapsed()) * 1000; // m/s
|
|
TrainSpeed *= 2.23694; // Mph
|
|
mZT1TrainState = ZT1_MR_S1_SECOND_PULSE_STATE; //goto state 4
|
|
}
|
|
else if(S1 == 0 && S2 == 1)
|
|
{
|
|
CountS2++;
|
|
TrainType = TRAIN_TYPE_MPM10;
|
|
TrainSpeedTimer2.start();
|
|
Rank++;
|
|
PPEDetected = false;
|
|
PPIDetected = false;
|
|
mZT1TrainState = ZT1_MPM10_S2_ACTIVE_STATE; //goto state 8
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_S1_TANSIT_MR_STATE: //3_MR
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
|
|
if(S1 == 0 && S2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 1 && S2 == 0)
|
|
{
|
|
CountS1++;
|
|
TrainSpeed = (MR_BOGIE_LENGTH / TrainSpeedTimer1.elapsed()) * 1000; // m/s
|
|
TrainSpeed *= 2.23694; // Mph
|
|
mZT1TrainState = ZT1_MR_S1_SECOND_PULSE_STATE; //goto state 4
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_S1_TRANSIT_MPM_STATE: //3_MPM
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
|
|
if(S1 == 0 && S2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 0 && S2 == 1)
|
|
{
|
|
CountS2++;
|
|
TrainSpeedTimer2.start();
|
|
Rank++;
|
|
PPEDetected = false;
|
|
PPIDetected = false;
|
|
mZT1TrainState = ZT1_MPM10_S2_ACTIVE_STATE; //goto state 8
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_MR_S1_SECOND_PULSE_STATE: //4
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
|
|
if(S2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S2 == 1)
|
|
{
|
|
CountS2++;
|
|
TrainSpeedTimer2.start();
|
|
Rank++;
|
|
PPEDetected = false;
|
|
PPIDetected = false;
|
|
mZT1TrainState = ZT1_MR_S2_ACTIVE_STATE;
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_MR_S2_ACTIVE_STATE: //5
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
|
|
if(S2 == 1)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 0 && S2 == 0)
|
|
{
|
|
mZT1TrainState = ZT1_MR_S2_TRANSIT_STATE;
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_MR_S2_TRANSIT_STATE: //6
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
|
|
if(S1 == 0 && S2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 0 && S2 == 1)
|
|
{
|
|
CountS2++;
|
|
|
|
TrainSpeed = (MR_BOGIE_LENGTH / TrainSpeedTimer2.elapsed()) * 1000; // m/s
|
|
TrainSpeed *= 2.23694; // Mph
|
|
mZT1TrainState = ZT1_MR_S2_SECOND_PULSE_STATE;
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_MR_S2_SECOND_PULSE_STATE: //7
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
if(PGCalibration)
|
|
{
|
|
|
|
qint32 Value = PGint - PGIOffset;
|
|
if(Value < PGICalibValue)
|
|
PGICalibValue = Value;
|
|
|
|
Value = PGExt - PGEOffset;
|
|
if(Value < PGECalibValue)
|
|
PGECalibValue = Value;
|
|
}
|
|
else if(PGActive == false)
|
|
{
|
|
//Compute and verify if the PG is detected.
|
|
Quadra = ((PGint - PGIOffset) * (PGExt - PGEOffset));
|
|
if(Quadra > PGValueTreshold)
|
|
{
|
|
//The PG has been detected, stop sampling...
|
|
PGActive = true;
|
|
}
|
|
}
|
|
|
|
if(S1 == 0 && S2 == 1)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 0 && S2 == 0)
|
|
{
|
|
if(PGCalibration)
|
|
{
|
|
CZTPGCalibrationData *Data = new CZTPGCalibrationData();
|
|
Data->mTimestamp = mReferenceTimer->nsecsElapsed();
|
|
Data->mPGExtValue = PGECalibValue;
|
|
Data->mPGIntValue = PGICalibValue;
|
|
|
|
emit NewPGCalibrationData(Data);
|
|
PGICalibValue = PGIOffset;
|
|
PGECalibValue = PGEOffset;
|
|
|
|
}
|
|
else if(PGActive == false) //The PG has not been detected...
|
|
{
|
|
RegisterDetection(DETECTION_PG_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
PGActive = false;
|
|
|
|
if(FNDetected == false)
|
|
{
|
|
RegisterDetection(DETECTION_FN_DETECTION,Bogie,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
else
|
|
{
|
|
CountFN++;
|
|
}
|
|
|
|
mZT1TrainState = ZT1_WAIT_FOR_S1_STATE; //bogie is passed entirely, go back to state ZT1_WAIT_FOR_S1_STATE (state 1)
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_MPM10_S2_ACTIVE_STATE: //8
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
|
|
if(S1 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 1)
|
|
{
|
|
CountS1++;
|
|
TrainSpeed = (MPM_BOGIE_LENGTH / TrainSpeedTimer1.elapsed()) * 1000; // m/s
|
|
TrainSpeed *= 2.23694; // Mph
|
|
mZT1TrainState = ZT1_MPM10_S1_SECOND_PULSE_STATE;
|
|
// qDebug("Goto state 9");
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_MPM10_S1_SECOND_PULSE_STATE: //9
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
|
|
if(S1 == 1)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 0 && S2 == 0)
|
|
{
|
|
mZT1TrainState = ZT1_MPM10_S1_S2_TRAINSIT_STATE;
|
|
}
|
|
else //S1 = 0 & S2 = 1
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_MPM10_S1_S2_TRAINSIT_STATE://10
|
|
{
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
|
|
}
|
|
|
|
|
|
if(S1 == 0 && S2 == 0)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 0 && S2 == 1)
|
|
{
|
|
CountS2++;
|
|
|
|
TrainSpeed = (MPM_BOGIE_LENGTH / TrainSpeedTimer2.elapsed()) * 1000; // m/s
|
|
TrainSpeed *= 2.23694; // Mph
|
|
mZT1TrainState = ZT1_MPM10_S2_SECOND_PULSE_STATE;
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_MPM10_S2_SECOND_PULSE_STATE: //11
|
|
{
|
|
|
|
if(Pint == 1 && PPIDetected == false)
|
|
{
|
|
PPIDetected = true;
|
|
RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(Pext == 1 && PPEDetected == false)
|
|
{
|
|
PPEDetected = true;
|
|
RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
if(FN == 1)
|
|
{
|
|
FNDetected = true;
|
|
}
|
|
|
|
if(PGCalibration)
|
|
{
|
|
|
|
qint32 Value = PGint - PGIOffset;
|
|
if(Value < PGICalibValue)
|
|
PGICalibValue = Value;
|
|
|
|
Value = PGExt - PGEOffset;
|
|
if(Value < PGECalibValue)
|
|
PGECalibValue = Value;
|
|
}
|
|
else if(PGActive == false)
|
|
{
|
|
//Compute and verify if the PG is detected.
|
|
Quadra = ((PGint - PGIOffset) * (PGExt - PGEOffset));
|
|
if(Quadra > PGValueTreshold)
|
|
{
|
|
//The PG has been detected, stop sampling...
|
|
PGActive = true;
|
|
}
|
|
}
|
|
|
|
if(S1 == 0 && S2 == 1)
|
|
{
|
|
break;
|
|
}
|
|
else if(S1 == 0 && S2 == 0)
|
|
{
|
|
if(PGCalibration)
|
|
{
|
|
CZTPGCalibrationData *Data = new CZTPGCalibrationData();
|
|
Data->mTimestamp = mReferenceTimer->nsecsElapsed();
|
|
Data->mPGExtValue = PGECalibValue;
|
|
Data->mPGIntValue = PGICalibValue;
|
|
|
|
emit NewPGCalibrationData(Data);
|
|
PGICalibValue = PGIOffset;
|
|
PGECalibValue = PGEOffset;
|
|
|
|
}
|
|
else if(PGActive == false) //The PG has not been detected...
|
|
{
|
|
RegisterDetection(DETECTION_PG_DETECTION,Rank,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
PGActive = false;
|
|
|
|
if(FNDetected == false)
|
|
{
|
|
RegisterDetection(DETECTION_FN_DETECTION,Bogie,mReferenceTimer->nsecsElapsed());
|
|
}
|
|
else
|
|
{
|
|
CountFN++;
|
|
}
|
|
|
|
mZT1TrainState = ZT1_WAIT_FOR_S1_STATE; //bogie is passed entirely, go back to state ZT1_WAIT_FOR_S1_STATE (state 1)
|
|
}
|
|
else
|
|
{
|
|
RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed());
|
|
mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case ZT1_POST_ANALYSIS_MODE_STATE:
|
|
{
|
|
//In this mode, there is no "Real Time" analysis. Data is stored and will be treated after
|
|
//the train has passed.
|
|
Bogie = 0;
|
|
CountFN = 0;
|
|
Rank = 0;
|
|
TrainSpeed = 0;
|
|
TrainType = TRAIN_TYPE_UNKNOWN;
|
|
CountS1 = 0;
|
|
CountS2 = 0;
|
|
|
|
break;
|
|
}
|
|
|
|
} //switch(mZT1TrainState)
|
|
|
|
mLastInputs = PCIInputs;
|
|
mLastPGIntValue = PGint;
|
|
mLastPGExtValue = PGExt;
|
|
mLastSDFValue = SDFAnalog;
|
|
|
|
CZT1ThreadData *Data = new CZT1ThreadData();
|
|
Data->mTimeStamp = mReferenceTimer->nsecsElapsed();
|
|
Data->mS1 = S1;
|
|
Data->mS2 = S2;
|
|
Data->mFN = FN;
|
|
Data->mPExt = Pext;
|
|
Data->mPInt = Pint;
|
|
Data->mPG = (PGActive == true);
|
|
Data->mPGIntValue = PGint;
|
|
Data->mPGExtValue = PGExt;
|
|
|
|
Data->mBogie = Bogie;
|
|
Data->mFNCount = CountFN;
|
|
Data->mRank = Rank;
|
|
Data->mTrainSpeed = TrainSpeed;
|
|
Data->mTrainType = TrainType;
|
|
Data->mS1Count = CountS1;
|
|
Data->mS2Count = CountS2;
|
|
|
|
emit ZT1DataUpdate(Data,LazerProbesTransitOnly,SDFAnalog);
|
|
|
|
}//if(PCIInputs != mLastInputs)
|
|
|
|
|
|
mMutex.lock();
|
|
if(mExitLoop == true)
|
|
Run = false;
|
|
mMutex.unlock();
|
|
|
|
}//if loop timeout expired
|
|
|
|
}//while
|
|
|
|
mZT1Analyzing = false;
|
|
|
|
}
|
|
|
|
void CZT1AnalysisThread::TerminateAnalysis()
|
|
{
|
|
mMutex.lock();
|
|
mExitLoop = true;
|
|
mMutex.unlock();
|
|
}
|
|
|
|
bool CZT1AnalysisThread::UpdateDetectionConfig(CZTDetectionFunctionConfig *NewConfig)
|
|
{
|
|
//do not update in the middle of a train analysis.
|
|
bool Go;
|
|
mMutex.lock();
|
|
Go = mZT1Analyzing;
|
|
mMutex.unlock();
|
|
|
|
if(Go == true)
|
|
return false;
|
|
|
|
//No need for a Mutex here since the thread is
|
|
//not analyzing.
|
|
mDetectionConfig = *NewConfig;
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
void CZT1AnalysisThread::RegisterDetection(unsigned int DetectionID, unsigned int Rank,qint64 TimeStamp)
|
|
{
|
|
if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive == false)
|
|
return;
|
|
|
|
//Register an error only if the analysis is active
|
|
switch(DetectionID)
|
|
{
|
|
case DETECTION_MAGNETIC_SENSOR_COUNT:
|
|
{
|
|
if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive == false)
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case DETECTION_PEQ1_DETECTION:
|
|
{
|
|
if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive == false)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//If PEQ1 was already registered, ignore this occurence.
|
|
if(mPEQDetectionLatch == true)
|
|
{
|
|
return;
|
|
}
|
|
mPEQDetectionLatch = true;
|
|
}
|
|
break;
|
|
}
|
|
case DETECTION_FN_DETECTION:
|
|
{
|
|
if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive == false)
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case DETECTION_PG_DETECTION:
|
|
{
|
|
if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive == false)
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case DETECTION_PPI_DETECTION:
|
|
{
|
|
if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive == false)
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case DETECTION_PPE_DETECTION:
|
|
{
|
|
if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive == false)
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
CZTDetectionData *DetectData = new CZTDetectionData;
|
|
DetectData->mTimeStamp = TimeStamp;
|
|
DetectData->mRank = Rank;
|
|
DetectData->mDetectionID = DetectionID;
|
|
|
|
emit DetectionTriggered(DetectData);
|
|
|
|
|
|
}
|
|
|