TI中文支持网
TI专业的中文技术问题搜集分享网站

IWR1642运行driver vital signals demo没有数据波形

运行vital_signal_gui后没有数据波形,cmd的运行结果如下所示

请问是什么原因,如何解决?

Chris Meng:

你好,

你能提供一下你修改的部分代码么?

user6319700:

回复 Chris Meng:

修改过的函数代码如下,将未初始化的变量初始化
void MmwDemo_interFrameProcessing(MmwDemo_DSS_DataPathObj *obj)
{
//Vital Signs Demo Processing Chain

gFrameCount++; // Increment the Global Frame Count
static uint16_t frameCountLocal = 0; // Local circular count
uint16_t loopIndexBuffer = 0; // Index that loops over the buffers

/* Obtain GUI-related Flags sent through the CLI */
VitalSignsDemo_GuiMonSel *pGuiMonSel;
pGuiMonSel = (VitalSignsDemo_GuiMonSel *) &(obj->cliCfg->vitalSigns_GuiMonSel);

/* Variables for Impulse Noise Removal */
static float dataCurr = 0;
static float dataPrev2 = 0;
static float dataPrev1 = 0;

/* Variables for Clutter Removal */
float maxValClutter = 0;
uint16_t guiFlag_ClutterRemoval = pGuiMonSel->guiFlag_ClutterRemoval;
uint16_t rangeBinMaxClutter = 0;

/* Variables for Phase Unwrapping */
static float phasePrevFrame = 0; // Phase value of Previous frame (For phase unwrapping)
static float diffPhaseCorrectionCum = 0; // Phase correction *** (For phase unwrapping)
static float phaseUsedComputationPrev = 0; // Phase values used for the Previous frame
float phaseUsedComputation = 0; // Unwrapped Phase value used for computation

/* Variables for Detecting Motion Corrupted Segments */
uint16_t guiFlag_MotionDetection = obj->cliCfg->motionDetectionParamsCfg.enabled; // GUI Flag. Set from the configuration File
uint16_t guiFlag_GainControl = obj->cliCfg->motionDetectionParamsCfg.gainControl; // GUI Flag. Set from the configuration File
uint16_t indexMotionDetection = 0; // Temporary Index
float sumEnergy = 0; // Energy in the data-segment checked for presence of large-scale motion

/* Vital Signs Waveform */
float outputFilterBreathOut = 0; // Breathing waveform after the IIR-Filter
float outputFilterHeartOut = 0; // Cardiac waveform after the IIR-Filter

/* Variables for FFT-based Spectral Estimation */
uint16_t pPeakSortOutIndex[MAX_NUM_PEAKS_SPECTRUM] = {0}; // Sorted Peaks in the Spectrum
uint16_t numPeaks_BreathSpectrum = 0; // Number of Peaks in the Breathing Spectrum
uint16_t numPeaks_heartSpectrum = 0; // Number of Peaks in the Cardiac Spectrum
uint16_t maxIndexHeartBeatSpect = 0, maxIndexBreathSpect = 0; // Indices corresponding to the max peak in the Breathing and Cardiac Spectrum
uint16_t maxIndexHeartBeatSpect_4Hz = 0; // Indices corresponding to the max peak from [1.6 – 4.0] Hz
float breathingRateEst_FFT = 0, heartRateEst_FFT = 0; // Vital Signs Estimate based on the FFT
float heartRateEst_FFT_4Hz = 0; // Vital Signs Estimate based on the FFT

/* Confidence Metric associated with the estimates */
float confidenceMetricBreath[MAX_NUM_PEAKS_SPECTRUM] = {0}; // Confidence Metric associated with each Breathing Spectrum Peak
float confidenceMetricHeart[MAX_NUM_PEAKS_SPECTRUM] = {0}; // Confidence Metric associated with each Cardiac Spectrum Peak
float confidenceMetricBreathOut = 0, confidenceMetricHeartOut = 0; // Confidence Metric associated with the estimates
float confidenceMetricHeartOut_4Hz = 0; // Confidence Metric for the 1st Heart beat Harmonic
float confidenceMetricHeartOut_xCorr = 0; // Confidence Metric for the Autocorrelation
float confidenceMetricBreathOut_xCorr = 0; // Confidence Metric for the Autocorrelation based breathing-rate estimate
float peakValueBreathSpect = 0;

/* Variables for peak-counting */
uint16_t pPeakLocsHeart[MAX_PEAKS_ALLOWED_WFM] = {0}; // Peak locations (indices) of the Cardiac Waveform
uint16_t pPeakLocsBreath[MAX_PEAKS_ALLOWED_WFM] = {0}; // Peak locations (indices) of the Breathing Waveform
uint16_t pPeakLocsValid[MAX_PEAKS_ALLOWED_WFM] = {0}; // Peak locations after only retaining the valid peaks
uint16_t numPeaksBreath = 0, numPeaksHeart = 0; // Number of peaks in the time-domain filtered waveform
float breathingRateEst_peakCount = 0, heartRateEst_peakCount = 0; // Vital Signs Estimate based on peak-Interval
float heartRateEst_peakCount_filtered = 0; // Heart-rate peak-interval based estimate after filtering

/* Exponential smoothing filter */
static float breathWfmOutUpdated = 0;
static float heartWfmOutUpdated = 0; // Updated values after exponential smoothing
float breathWfmOutPrev = 0, heartWfmOutPrev = 0; // Exponential smoothing values at time instance (t-1)
float sumEnergyBreathWfm = 0, sumEnergyHeartWfm = 0; // These values are used to make a decision if the energy in the waveform is sufficient for it to be classfied as a valid waveform

/* Variables for Auto-Correlation */
float heartRateEst_xCorr = 0; // Heart-rate estimate from the Autocorrelation Method
float breathRateEst_xCorr = 0; // Breathing-rate estimate from the Autocorrelation Method

/* For FIR Filtering */
static float pDataIn[FIR_FILTER_SIZE] = {0};

/* Variables for Extracting the Range-FFT output */
uint16_t rangeBinIndex = 0; // Range-bin Index
float rangeBinPhase = 0; // Phase of the Range-bin selected for processing
static uint16_t rangeBinIndexPhase = 0; // Index of the Range Bin for which the phase is computed
uint16_t rangeBinMax = 0; // Index of the Strongest Range-Bin

uint16_t indexTemp = 0, indexNumPeaks = 0; // Temporary Indices
int16_t temp_real = 0, temp_imag = 0; // Temporary variables storing the Real and Imaginary part of a range-bin in the Range-FFT Output
float absVal = 0; // Absolute value based on the Real and Imaginary values
float maxVal = 0; // Maximum Value of the Range-Bin in the current range-profile

if (pGuiMonSel->guiFlag_Reset == 1) // Refresh Pushbutton on the GUI Pressed
{
gFrameCount = 1;
pGuiMonSel->guiFlag_Reset = 0;
breathWfmOutUpdated = 0;
heartWfmOutUpdated = 0;
}

if (RANGE_BIN_TRACKING)
{
frameCountLocal = gFrameCount % RESET_LOCAL_COUNT_VAL;
}
else
{
frameCountLocal = gFrameCount;
}

rangeBinMax = 0;
maxVal = 0;
rangeBinMaxClutter = 0;
maxValClutter = 0;

// tempPtr points towards the RX-Channel to process
cmplx16ReIm_t *tempPtr = obj->fftOut1D + (obj->rxAntennaProcess – 1)*obj->numRangeBins;
// tempPtr points towards rangeBinStartIndex
tempPtr += (obj->rangeBinStartIndex) ;

for (rangeBinIndex = obj->rangeBinStartIndex; rangeBinIndex <= obj->rangeBinEndIndex; rangeBinIndex++)
{
// Points towards the real part of the current range-bin i.e. rangeBinIndex
temp_real = (int16_t) tempPtr->real;
obj->pRangeProfileCplx[rangeBinIndex – obj->rangeBinStartIndex].real = temp_real;

// Points towards the imaginary part of the current range-bin i.e. rangeBinIndex
temp_imag = (int16_t) tempPtr->imag;
obj->pRangeProfileCplx[rangeBinIndex – obj->rangeBinStartIndex].imag = temp_imag;

// Move the pointer towards the next range-bin
tempPtr ++;

if (guiFlag_ClutterRemoval == 1)
{
// Clutter Removed Range Profile
float tempReal_Curr,tempImag_Curr;
float alphaClutter = 0.01;
float currVal;

tempReal_Curr = (float) temp_real;
tempImag_Curr = (float) temp_imag;
uint16_t currRangeIndex;
currRangeIndex = rangeBinIndex – obj->rangeBinStartIndex;

obj->pTempReal_Prev[currRangeIndex] = alphaClutter*tempReal_Curr + (1-alphaClutter)*obj->pTempReal_Prev[currRangeIndex];
obj->pTempImag_Prev[currRangeIndex] = alphaClutter*tempImag_Curr + (1-alphaClutter)*obj->pTempImag_Prev[currRangeIndex];

currVal = sqrt((tempReal_Curr – obj->pTempReal_Prev[currRangeIndex])*(tempReal_Curr – obj->pTempReal_Prev[currRangeIndex]) + (tempImag_Curr – obj->pTempImag_Prev[currRangeIndex])*(tempImag_Curr – obj->pTempImag_Prev[currRangeIndex]));
obj->pRangeProfileClutterRemoved[rangeBinIndex – obj->rangeBinStartIndex] = currVal;

// Based on the Max value Range-bin
if (currVal > maxValClutter)
{
maxValClutter = currVal;
rangeBinMaxClutter = rangeBinIndex;
}
}
else
{
// Magnitude of the current range-bin
absVal = (float) temp_real * (float) temp_real + (float) temp_imag * (float) temp_imag;
// Maximum value range-bin of the current range-profile
if (absVal > maxVal)
{
maxVal = absVal;
rangeBinMax = rangeBinIndex;
}
}
// If the Refresh button in the GUI is pressed
if (frameCountLocal == 1)
{
if (guiFlag_ClutterRemoval == 1)
{
rangeBinIndexPhase = rangeBinMaxClutter;
}
else
{
rangeBinIndexPhase = rangeBinMax;
}
}
if (rangeBinIndex == (rangeBinIndexPhase))
{
rangeBinPhase = atan2(temp_imag, temp_real);
}
} // For Loop ends

// Phase-Unwrapping
obj->unwrapPhasePeak = unwrap(rangeBinPhase, phasePrevFrame, &diffPhaseCorrectionCum);
phasePrevFrame = rangeBinPhase;

#ifdef TEST_TONE // Generates a Test-Tone

float testTone_ampBreath_mm = 1.0;
float testTone_freqBreath_Hz = 0.45;
float testTone_ampHeart_mm = 0.01;
float testTone_freqHeart_Hz = 1.8;

obj->unwrapPhasePeak = (4 * PI_/WAVELENGTH_MM) *(
(testTone_ampBreath_mm * sin(2*PI_*testTone_freqBreath_Hz* gFrameCount/obj->samplingFreq_Hz))+
(testTone_ampHeart_mm * sin(2*PI_*testTone_freqHeart_Hz*gFrameCount/obj->samplingFreq_Hz))
);
// +0.5*(testTone_ampBreath_mm *sin(2*PI_*(2*testTone_freqBreath_Hz)* gFrameCount/obj->samplingFreq_Hz)); // Harmonic signal
#endif

// Computes the phase differences between successive phase samples
if(FLAG_COMPUTE_PHASE_DIFFERENCE)
{
phaseUsedComputation = obj->unwrapPhasePeak – phaseUsedComputationPrev;
phaseUsedComputationPrev = obj->unwrapPhasePeak;
}
else
{
phaseUsedComputation = obj->unwrapPhasePeak;
}

// Removes impulse like noise from the waveforms
if (FLAG_REMOVE_IMPULSE_NOISE)
{
dataPrev2 = dataPrev1;
dataPrev1 = dataCurr;
dataCurr = phaseUsedComputation;
phaseUsedComputation = filter_RemoveImpulseNoise(dataPrev2, dataPrev1, dataCurr, obj->noiseImpulse_Thresh);
}

// IIR Filtering
outputFilterBreathOut = filter_IIR_BiquadCascade(phaseUsedComputation, obj->pFilterCoefsBreath, obj->pScaleValsBreath, obj->pDelayBreath, IIR_FILTER_BREATH_NUM_STAGES);
outputFilterHeartOut = filter_IIR_BiquadCascade(phaseUsedComputation, obj->pFilterCoefsHeart_4Hz, obj->pScaleValsHeart_4Hz, obj->pDelayHeart, IIR_FILTER_HEART_NUM_STAGES);

// Copies the "Breathing Waveform" in a circular Buffer
for (loopIndexBuffer = 1; loopIndexBuffer < obj->circularBufferSizeBreath; loopIndexBuffer++)
{
obj->pVitalSigns_Breath_CircularBuffer[loopIndexBuffer – 1] = obj->pVitalSigns_Breath_CircularBuffer[loopIndexBuffer];
}
obj->pVitalSigns_Breath_CircularBuffer[obj->circularBufferSizeBreath – 1] = outputFilterBreathOut;

// Detection of Motion corrupted Segments
if (guiFlag_MotionDetection == 1)
{
// Update the Motion Removal Circular Buffer
for (loopIndexBuffer = 1; loopIndexBuffer < obj->motionDetection_BlockSize; loopIndexBuffer++)
{
obj->pMotionCircularBuffer[loopIndexBuffer – 1] = obj->pMotionCircularBuffer[loopIndexBuffer] ;
}
obj->pMotionCircularBuffer[obj->motionDetection_BlockSize-1] = outputFilterHeartOut;
indexMotionDetection = gFrameCount % obj->motionDetection_BlockSize;

// Only perform these steps for every obj->motionDetection_BlockSize sample
if (indexMotionDetection == 0)
{
// Check if the current segment is "Noisy"
sumEnergy = 0;
for (loopIndexBuffer = 0; loopIndexBuffer < obj->motionDetection_BlockSize; loopIndexBuffer++)
{
sumEnergy += (obj->pMotionCircularBuffer[loopIndexBuffer]*obj->pMotionCircularBuffer[loopIndexBuffer]);
}

if (sumEnergy > obj->motionDetection_Thresh)
{
obj->motionDetected = 1; // Temporary variable to send to the GUI
}
else
{
obj->motionDetected = 0; // Temporary variable to send to the GUI
}

// If NO motion detected in the current segment
if ( obj->motionDetected == 0)
{
uint16_t tempEndIndex;
// Shift the current contents of the circular Buffer
for (loopIndexBuffer = obj->motionDetection_BlockSize; loopIndexBuffer < obj->circularBufferSizeHeart; loopIndexBuffer++)
{
obj->pVitalSigns_Heart_CircularBuffer[loopIndexBuffer – obj->motionDetection_BlockSize] = obj->pVitalSigns_Heart_CircularBuffer[loopIndexBuffer] ;
}
// Copy the current data segment to the end of the Circular Buffer
for (loopIndexBuffer = 0; loopIndexBuffer < obj->motionDetection_BlockSize; loopIndexBuffer++)
{
tempEndIndex = obj->circularBufferSizeHeart – obj->motionDetection_BlockSize;
obj->pVitalSigns_Heart_CircularBuffer[ tempEndIndex + loopIndexBuffer] = obj->pMotionCircularBuffer[loopIndexBuffer] ;
}
}
}
}
// If Motion DETECTED then don't UPDATE or SHIFT the values in the buffer
else // Regular processing
{
// Copies the "Cardiac Waveform" in a circular Buffer
for (loopIndexBuffer = 1; loopIndexBuffer < obj->circularBufferSizeHeart; loopIndexBuffer++)
{
obj->pVitalSigns_Heart_CircularBuffer[loopIndexBuffer – 1] = obj->pVitalSigns_Heart_CircularBuffer[loopIndexBuffer];
}
obj->pVitalSigns_Heart_CircularBuffer[obj->circularBufferSizeHeart – 1] = outputFilterHeartOut;
}

/* Spectral Estimation based on the Inter-Peaks Distance */
numPeaksHeart = find_Peaks(obj->pVitalSigns_Heart_CircularBuffer, float_type, pPeakLocsHeart,obj->pPeakValues, 0, obj->circularBufferSizeHeart – 1);
if (numPeaksHeart != 0)
{
numPeaksHeart = filterPeaksWfm(pPeakLocsHeart, pPeakLocsValid, numPeaksHeart, obj->peakDistanceHeart_Min, obj->peakDistanceHeart_Max);
}
heartRateEst_peakCount = CONVERT_HZ_BPM * ((numPeaksHeart * obj->samplingFreq_Hz) / obj->circularBufferSizeHeart);

for (loopIndexBuffer = 1; loopIndexBuffer < FIR_FILTER_SIZE; loopIndexBuffer++)
{
pDataIn[loopIndexBuffer – 1] = pDataIn[loopIndexBuffer];
}
pDataIn[FIR_FILTER_SIZE – 1] = heartRateEst_peakCount;
heartRateEst_peakCount_filtered = filter_FIR(pDataIn, obj->pFilterCoefs, FIR_FILTER_SIZE);

numPeaksBreath = find_Peaks(obj->pVitalSigns_Breath_CircularBuffer, int32_type, pPeakLocsBreath, obj->pPeakValues, 0, obj->circularBufferSizeBreath – 1);
if (numPeaksBreath != 0)
{
numPeaksBreath = filterPeaksWfm(pPeakLocsBreath, pPeakLocsValid, numPeaksBreath, obj->peakDistanceBreath_Min, obj->peakDistanceBreath_Max);
}

breathingRateEst_peakCount = CONVERT_HZ_BPM * ((numPeaksBreath * obj->samplingFreq_Hz) / obj->circularBufferSizeHeart);
heartRateEst_peakCount = CONVERT_HZ_BPM * ((numPeaksHeart * obj->samplingFreq_Hz) / obj->circularBufferSizeBreath);

// Input to the FFT needs to be complex
memset((uint8_t *)obj->pVitalSignsBuffer_Cplx, 0, obj->breathingWfm_Spectrum_FftSize * sizeof(cmplx32ReIm_t));
for (loopIndexBuffer = 0; loopIndexBuffer < obj->circularBufferSizeBreath; loopIndexBuffer++)
{
obj->pVitalSignsBuffer_Cplx[loopIndexBuffer].real = (int32_t) obj->scale_breathingWfm*obj->pVitalSigns_Breath_CircularBuffer[loopIndexBuffer];
obj->pVitalSignsBuffer_Cplx[loopIndexBuffer].imag=0;
}

// Input is overwritten by the DSP_fft32x32 function
DSP_fft32x32(
(int32_t *)obj->pVitalSignsSpectrumTwiddle32x32,
obj->breathingWfm_Spectrum_FftSize,
(int32_t *) obj->pVitalSignsBuffer_Cplx,
(int32_t *) obj->pVitalSigns_SpectrumCplx);

MmwDemo_magnitudeSquared(
obj->pVitalSigns_SpectrumCplx,
obj->pVitalSigns_Breath_AbsSpectrum,
obj->breathingWfm_Spectrum_FftSize);

memset((uint8_t *)obj->pVitalSignsBuffer_Cplx, 0, obj->heartWfm_Spectrum_FftSize * sizeof(cmplx32ReIm_t));

// Pre-Processing Steps for the Cardiac Waveform
// Perform Automatic Gain Control if enabled from the GUI
if (guiFlag_GainControl == 1)
{
computeAGC ( obj->pVitalSigns_Heart_CircularBuffer, obj->circularBufferSizeHeart, obj->motionDetection_BlockSize, obj->motionDetection_Thresh);
}

if (guiFlag_MotionDetection == 1)
{
outputFilterHeartOut = obj->pMotionCircularBuffer[obj->motionDetection_BlockSize-1];
}
else
{
outputFilterHeartOut = obj->pVitalSigns_Heart_CircularBuffer[obj->circularBufferSizeHeart-1];
}

// Perform Autocorrelation on the Waveform
if (PERFORM_XCORR)
{
float temp;
// Perform Autocorrelation on the Cardiac-Waveform
uint16_t xCorr_numPeaks;
uint16_t maxIndex_lag;
computeAutoCorrelation ( obj->pVitalSigns_Heart_CircularBuffer, obj->circularBufferSizeHeart , obj->pXcorr, obj->xCorr_minLag, obj->xCorr_maxLag);
xCorr_numPeaks = find_Peaks(obj->pXcorr, float_type, obj->pPeakIndex, obj->pPeakValues, obj->xCorr_minLag, obj->xCorr_maxLag);
maxIndex_lag = computeMaxIndex((float*) obj->pXcorr, obj->xCorr_minLag, obj->xCorr_maxLag);
temp = (float) (1.0)/(maxIndex_lag/obj->samplingFreq_Hz);
heartRateEst_xCorr = (float) CONVERT_HZ_BPM *temp;

if (xCorr_numPeaks == 0 )
{
confidenceMetricHeartOut_xCorr = 0;
}
else
{
confidenceMetricHeartOut_xCorr = obj->pXcorr[maxIndex_lag];
}

// Auto-correlation on the Breathing Waveform
computeAutoCorrelation ( obj->pVitalSigns_Breath_CircularBuffer, obj->circularBufferSizeBreath,
obj->pXcorr, obj->xCorr_Breath_minLag, obj->xCorr_Breath_maxLag);
xCorr_numPeaks = find_Peaks(obj->pXcorr, float_type, obj->pPeakIndex, obj->pPeakValues, obj->xCorr_Breath_minLag, obj->xCorr_Breath_maxLag);
maxIndex_lag = computeMaxIndex((float*) obj->pXcorr, obj->xCorr_Breath_minLag, obj->xCorr_Breath_maxLag);
temp = (float) (1.0)/(maxIndex_lag/obj->samplingFreq_Hz);
breathRateEst_xCorr = (float) CONVERT_HZ_BPM *temp;

if (xCorr_numPeaks == 0 )
{
confidenceMetricBreathOut_xCorr = 0;
}
else
{
confidenceMetricBreathOut_xCorr = obj->pXcorr[maxIndex_lag];
}
}

// Apply Window on the Cardiac Waveform prior to FFT-based spectral estimation
// and copies the Pre-processed data to pCircularBufferHeart
if (FLAG_APPLY_WINDOW)
{
uint16_t index_win;
uint16_t index_WinEnd;

float tempFloat;
index_WinEnd = obj->circularBufferSizeHeart – 1;
for (index_win = 0; index_win < DOPPLER_WINDOW_SIZE; index_win++)
{
tempFloat = obj->pDopplerWindow[index_win];
obj->pVitalSignsBuffer_Cplx[index_win].real = (int32_t) obj->scale_heartWfm * tempFloat * obj->pVitalSigns_Heart_CircularBuffer[index_win];
obj->pVitalSignsBuffer_Cplx[index_WinEnd].real = (int32_t) obj->scale_heartWfm * tempFloat * obj->pVitalSigns_Heart_CircularBuffer[index_WinEnd];
obj->pVitalSignsBuffer_Cplx[index_win].imag = 0;
obj->pVitalSignsBuffer_Cplx[index_WinEnd].imag = 0;
index_WinEnd –;
}
for (loopIndexBuffer = DOPPLER_WINDOW_SIZE; loopIndexBuffer < obj->circularBufferSizeHeart – DOPPLER_WINDOW_SIZE ; loopIndexBuffer++)
{
obj->pVitalSignsBuffer_Cplx[loopIndexBuffer].real = (int32_t) (obj->scale_heartWfm)*obj->pVitalSigns_Heart_CircularBuffer[loopIndexBuffer];
obj->pVitalSignsBuffer_Cplx[loopIndexBuffer].imag = 0;
}
}
else
{
for (loopIndexBuffer = 0; loopIndexBuffer < obj->circularBufferSizeHeart; loopIndexBuffer++)
{
obj->pVitalSignsBuffer_Cplx[loopIndexBuffer].real = (int32_t) (obj->scale_heartWfm)*obj->pVitalSigns_Heart_CircularBuffer[loopIndexBuffer];
obj->pVitalSignsBuffer_Cplx[loopIndexBuffer].imag=0;
}
}

// FFT of the Cardiac Waveform
DSP_fft32x32(
(int32_t *)obj->pVitalSignsSpectrumTwiddle32x32,
obj->heartWfm_Spectrum_FftSize,
(int32_t *) obj->pVitalSignsBuffer_Cplx,
(int32_t *) obj->pVitalSigns_SpectrumCplx);

MmwDemo_magnitudeSquared(
obj->pVitalSigns_SpectrumCplx,
obj->pVitalSigns_Heart_AbsSpectrum,
obj->heartWfm_Spectrum_FftSize);

// Pick the Peaks in the Breathing Spectrum
numPeaks_BreathSpectrum = find_Peaks(obj->pVitalSigns_Breath_AbsSpectrum, float_type, obj->pPeakIndex, obj->pPeakValues,
obj->breath_startFreq_Index, obj->breath_endFreq_Index);
indexNumPeaks = (numPeaks_BreathSpectrum < MAX_NUM_PEAKS_SPECTRUM) ? numPeaks_BreathSpectrum : MAX_NUM_PEAKS_SPECTRUM;

if (indexNumPeaks != 0)
{
heapsort_index(obj->pPeakValues, numPeaks_BreathSpectrum, obj->pPeakIndexSorted);
for(indexTemp = 0; indexTemp < indexNumPeaks; indexTemp++ )
{
pPeakSortOutIndex[indexTemp] = obj->pPeakIndex [obj->pPeakIndexSorted[numPeaks_BreathSpectrum-indexTemp-1] ];
confidenceMetricBreath[indexTemp] = computeConfidenceMetric(obj->pVitalSigns_Breath_AbsSpectrum,
obj->confMetric_spectrumBreath_IndexStart,
obj->confMetric_spectrumBreath_IndexEnd,
pPeakSortOutIndex[indexTemp],
obj->confMetric_numIndexAroundPeak_breath);
}
maxIndexBreathSpect = pPeakSortOutIndex[0]; // The maximum peak
confidenceMetricBreathOut = confidenceMetricBreath[0];
}
else
{
maxIndexBreathSpect = computeMaxIndex((float*) obj->pVitalSigns_Breath_AbsSpectrum, obj->breath_startFreq_Index, obj->breath_endFreq_Index);
confidenceMetricBreathOut = computeConfidenceMetric(obj->pVitalSigns_Breath_AbsSpectrum,
0,
PHASE_FFT_SIZE/4,
maxIndexBreathSpect,
obj->confMetric_numIndexAroundPeak_breath);
}
peakValueBreathSpect = obj->pVitalSigns_Breath_AbsSpectrum[maxIndexBreathSpect]/(10*obj->scale_breathingWfm);

// Pick the Peaks in the Heart Spectrum [1.6 – 4.0 Hz]
numPeaks_heartSpectrum = find_Peaks(obj->pVitalSigns_Heart_AbsSpectrum, uint32_type, obj->pPeakIndex, obj->pPeakValues,
obj->heart_startFreq_Index_1p6Hz, obj->heart_endFreq_Index_4Hz);
indexNumPeaks = (numPeaks_heartSpectrum < MAX_NUM_PEAKS_SPECTRUM) ? numPeaks_heartSpectrum : MAX_NUM_PEAKS_SPECTRUM;
if (indexNumPeaks != 0)
{
heapsort_index(obj->pPeakValues, numPeaks_heartSpectrum, obj->pPeakIndexSorted);
for(indexTemp = 0; indexTemp < indexNumPeaks; indexTemp++ )
{
pPeakSortOutIndex[indexTemp] = obj->pPeakIndex [obj->pPeakIndexSorted[numPeaks_heartSpectrum-indexTemp-1] ];
}
maxIndexHeartBeatSpect_4Hz = pPeakSortOutIndex[0]; // The maximum peak
confidenceMetricHeartOut_4Hz = computeConfidenceMetric(obj->pVitalSigns_Heart_AbsSpectrum,
obj->confMetric_spectrumHeart_IndexStart_1p6Hz,
obj->confMetric_spectrumHeart_IndexStart_4Hz,
maxIndexHeartBeatSpect_4Hz,
obj->confMetric_numIndexAroundPeak_heart);
}
else
{
maxIndexHeartBeatSpect_4Hz = computeMaxIndex((float*) obj->pVitalSigns_Heart_AbsSpectrum, obj->heart_startFreq_Index_1p6Hz, obj->heart_endFreq_Index_4Hz);
confidenceMetricHeartOut_4Hz = computeConfidenceMetric(obj->pVitalSigns_Heart_AbsSpectrum,
0,
PHASE_FFT_SIZE/4,
maxIndexHeartBeatSpect_4Hz,
obj->confMetric_numIndexAroundPeak_heart);
}
heartRateEst_FFT_4Hz = (float) CONVERT_HZ_BPM * maxIndexHeartBeatSpect_4Hz * (obj->freqIncrement_Hz);

// If a peak is within [1.6 2.0] Hz then check if a harmonic is present is the cardiac spectrum region [0.8 – 2.0] Hz
if (heartRateEst_FFT_4Hz < MAX_HEART_RATE_BPM)
{
for (indexTemp =1; indexTemp<numPeaks_heartSpectrum;indexTemp++)

if(abs(heartRateEst_FFT_4Hz – CONVERT_HZ_BPM *(obj->freqIncrement_Hz)*pPeakSortOutIndex[indexTemp]) < HEART_HAMRONIC_THRESH_BPM)
{
heartRateEst_FFT_4Hz = CONVERT_HZ_BPM *(obj->freqIncrement_Hz)*pPeakSortOutIndex[indexTemp];
break;
}
}

// Pick the Peaks in the Cardiac Spectrum
numPeaks_heartSpectrum = find_Peaks(obj->pVitalSigns_Heart_AbsSpectrum, float_type, obj->pPeakIndex, obj->pPeakValues, obj->heart_startFreq_Index, obj->heart_endFreq_Index);
indexNumPeaks = (numPeaks_heartSpectrum < MAX_NUM_PEAKS_SPECTRUM) ? numPeaks_heartSpectrum : MAX_NUM_PEAKS_SPECTRUM;

if (indexNumPeaks != 0)
{
heapsort_index(obj->pPeakValues, numPeaks_heartSpectrum, obj->pPeakIndexSorted);
for(indexTemp = 0; indexTemp < indexNumPeaks; indexTemp++ )
{
pPeakSortOutIndex[indexTemp] = obj->pPeakIndex [obj->pPeakIndexSorted[numPeaks_heartSpectrum-indexTemp-1] ];
confidenceMetricHeart[indexTemp] = computeConfidenceMetric(obj->pVitalSigns_Heart_AbsSpectrum,
obj->confMetric_spectrumHeart_IndexStart,
obj->confMetric_spectrumHeart_IndexEnd,
pPeakSortOutIndex[indexTemp],
obj->confMetric_numIndexAroundPeak_heart);
}
maxIndexHeartBeatSpect = pPeakSortOutIndex[0]; // The maximum peak
confidenceMetricHeartOut = confidenceMetricHeart[0];
}
else
{
maxIndexHeartBeatSpect = computeMaxIndex((float*) obj->pVitalSigns_Heart_AbsSpectrum, obj->heart_startFreq_Index, obj->heart_endFreq_Index);
confidenceMetricHeartOut = computeConfidenceMetric(obj->pVitalSigns_Heart_AbsSpectrum,
0,
PHASE_FFT_SIZE/4,
maxIndexHeartBeatSpect,
obj->confMetric_numIndexAroundPeak_heart);
}

// Remove the First Breathing Harmonic (if present in the cardiac Spectrum)
if(FLAG_HARMONIC_CANCELLATION)
{
float diffIndex = abs(maxIndexHeartBeatSpect – BREATHING_HARMONIC_NUM*maxIndexBreathSpect);
if ( diffIndex*(obj->freqIncrement_Hz)*CONVERT_HZ_BPM < BREATHING_HAMRONIC_THRESH_BPM ) // Only cancel the 2nd Breathing Harmonic
{
maxIndexHeartBeatSpect = pPeakSortOutIndex[1]; // Pick the 2nd Largest peak in the cardiac-spectrum
confidenceMetricHeartOut = confidenceMetricHeart[1];
}
}

heartRateEst_FFT = (float) CONVERT_HZ_BPM * maxIndexHeartBeatSpect * (obj->freqIncrement_Hz);
breathingRateEst_FFT = (float) CONVERT_HZ_BPM * maxIndexBreathSpect * (obj->freqIncrement_Hz);

#ifdef HARMONICS_ENERGY
float heartRateEst_HarmonicEnergy;
float breathRateEst_HarmonicEnergy;
uint16_t maxIndexHeartBeatSpect_temp;
uint16_t maxIndexBreathSpect_temp;

memset((void *)obj->pDataOutTemp, 0, obj->heartWfm_Spectrum_FftSize*sizeof(float));
computeEnergyHarmonics (obj->pVitalSigns_Heart_AbsSpectrum,
obj->pDataOutTemp,
obj->confMetric_spectrumHeart_IndexStart,
obj->confMetric_spectrumHeart_IndexEnd,
obj->confMetric_numIndexAroundPeak_heart);
maxIndexHeartBeatSpect_temp = computeMaxIndex(obj->pDataOutTemp,
obj->confMetric_spectrumHeart_IndexStart,
obj->confMetric_spectrumHeart_IndexEnd);
heartRateEst_HarmonicEnergy = (float) CONVERT_HZ_BPM * maxIndexHeartBeatSpect_temp * (obj->freqIncrement_Hz);

memset((void *)obj->pDataOutTemp, 0, obj->heartWfm_Spectrum_FftSize*sizeof(float));
computeEnergyHarmonics (obj->pVitalSigns_Breath_AbsSpectrum,
obj->pDataOutTemp,
obj->confMetric_spectrumBreath_IndexStart,
obj->confMetric_spectrumBreath_IndexEnd,
obj->confMetric_numIndexAroundPeak_breath);
maxIndexBreathSpect_temp = computeMaxIndex(obj->pDataOutTemp,
obj->confMetric_spectrumBreath_IndexStart,
obj->confMetric_spectrumBreath_IndexEnd);
breathRateEst_HarmonicEnergy = (float) CONVERT_HZ_BPM * maxIndexBreathSpect_temp * (obj->freqIncrement_Hz);

#endif

// Median Value for Heart Rate and Breathing Rate based on 'MEDIAN_WINDOW_LENGTH' previous estimates
if(FLAG_MEDIAN_FILTER)
{
for (loopIndexBuffer = 1; loopIndexBuffer < MEDIAN_WINDOW_LENGTH; loopIndexBuffer++)
{
obj->pBufferHeartRate[loopIndexBuffer – 1] = obj->pBufferHeartRate[loopIndexBuffer];
obj->pBufferBreathingRate[loopIndexBuffer – 1] = obj->pBufferBreathingRate[loopIndexBuffer];
obj->pBufferHeartRate_4Hz[loopIndexBuffer – 1] = obj->pBufferHeartRate_4Hz[loopIndexBuffer];
}
obj->pBufferHeartRate[MEDIAN_WINDOW_LENGTH – 1] = heartRateEst_FFT;
obj->pBufferBreathingRate[MEDIAN_WINDOW_LENGTH – 1] = breathingRateEst_FFT;
obj->pBufferHeartRate_4Hz[MEDIAN_WINDOW_LENGTH – 1] = heartRateEst_FFT_4Hz;

heapsort_index(obj->pBufferHeartRate, MEDIAN_WINDOW_LENGTH, obj->pPeakSortTempIndex);
heartRateEst_FFT = obj->pBufferHeartRate[ obj->pPeakSortTempIndex[MEDIAN_WINDOW_LENGTH/2+1]];

heapsort_index(obj->pBufferHeartRate_4Hz, MEDIAN_WINDOW_LENGTH, obj->pPeakSortTempIndex);
heartRateEst_FFT_4Hz = obj->pBufferHeartRate_4Hz[ obj->pPeakSortTempIndex[MEDIAN_WINDOW_LENGTH/2+1]];

heapsort_index(obj->pBufferBreathingRate, MEDIAN_WINDOW_LENGTH, obj->pPeakSortTempIndex);
breathingRateEst_FFT = obj->pBufferBreathingRate[ obj->pPeakSortTempIndex[MEDIAN_WINDOW_LENGTH/2+1]];
}

// Exponential Smoothing
breathWfmOutPrev = breathWfmOutUpdated;
breathWfmOutUpdated = (obj->alpha_breathing)*(outputFilterBreathOut*outputFilterBreathOut) + (1 – (obj->alpha_breathing))*breathWfmOutPrev; // Exponential Smoothing
sumEnergyBreathWfm = breathWfmOutUpdated*10000;

heartWfmOutPrev = heartWfmOutUpdated;
heartWfmOutUpdated = (obj->alpha_heart)*(outputFilterHeartOut*outputFilterHeartOut) + (1 – (obj->alpha_heart))*heartWfmOutPrev; // Exponential Smoothing
sumEnergyHeartWfm = heartWfmOutUpdated*10000;

// Output Values
obj->VitalSigns_Output.unwrapPhasePeak_mm = obj->unwrapPhasePeak;
obj->VitalSigns_Output.outputFilterBreathOut = outputFilterBreathOut;
obj->VitalSigns_Output.outputFilterHeartOut = outputFilterHeartOut;
obj->VitalSigns_Output.rangeBinIndexPhase = rangeBinIndexPhase; //frameCountLocal;
obj->VitalSigns_Output.maxVal = maxVal;
obj->VitalSigns_Output.sumEnergyHeartWfm = sumEnergyHeartWfm;
obj->VitalSigns_Output.sumEnergyBreathWfm = sumEnergyBreathWfm*peakValueBreathSpect;

obj->VitalSigns_Output.confidenceMetricBreathOut = confidenceMetricBreathOut;
obj->VitalSigns_Output.confidenceMetricHeartOut = confidenceMetricHeartOut; // Confidence Metric associated with the estimates
obj->VitalSigns_Output.confidenceMetricHeartOut_4Hz = confidenceMetricHeartOut_4Hz;
obj->VitalSigns_Output.confidenceMetricHeartOut_xCorr = confidenceMetricHeartOut_xCorr;

obj->VitalSigns_Output.breathingRateEst_FFT = breathingRateEst_FFT;
obj->VitalSigns_Output.breathingRateEst_peakCount = breathingRateEst_peakCount;
obj->VitalSigns_Output.heartRateEst_peakCount_filtered = heartRateEst_peakCount_filtered;
obj->VitalSigns_Output.heartRateEst_xCorr = heartRateEst_xCorr;
obj->VitalSigns_Output.heartRateEst_FFT_4Hz = heartRateEst_FFT_4Hz;
obj->VitalSigns_Output.heartRateEst_FFT = heartRateEst_FFT;

obj->VitalSigns_Output.processingCyclesOut = obj->timingInfo.interFrameProcCycles/DSP_CLOCK_MHZ;
obj->VitalSigns_Output.rangeBinStartIndex = obj->rangeBinStartIndex;
obj->VitalSigns_Output.rangeBinEndIndex = obj->rangeBinEndIndex;
obj->VitalSigns_Output.motionDetectedFlag = obj->motionDetected;
obj->VitalSigns_Output.breathingRateEst_xCorr = breathRateEst_xCorr; //breathRateEst_HarmonicEnergy;
obj->VitalSigns_Output.confidenceMetricBreathOut_xCorr = confidenceMetricBreathOut_xCorr; //breathRateEst_HarmonicEnergy;
obj->VitalSigns_Output.breathingRateEst_harmonicEnergy = breathRateEst_HarmonicEnergy; //heartRateEst_HarmonicEnergy;
obj->VitalSigns_Output.heartRateEst_harmonicEnergy = heartRateEst_HarmonicEnergy;

}

Chris Meng:

回复 user6319700:

你好,

我刚才在一块IWR1642BOOST上尝试了vital sign的demo,做的修改就是你贴的代码部分,可以正常工作。

还请你再确认一下你的编译环境/SDK/lab代码/路径等是否正确。

Chris Meng:

回复 Chris Meng:

你好,

如果你使用的是CCS下载可执行文件,请确保你烧写的ccs_debug.bin是mmwave sdk 2.0.0.4版本里的。

user6319700:

回复 Chris Meng:

将修改过的vita signal demo例程 重新用官方例程覆盖跑一遍,数据波形正常了

赞(0)
未经允许不得转载:TI中文支持网 » IWR1642运行driver vital signals demo没有数据波形
分享到: 更多 (0)