// 秒寻科技 // 计算各基站幅度 // 2023-03-12 #include "../../includes/includes.h" // 导出全局变量定义 extern flt32 gg_afOneFrameLocationData[PUB_SLOT_FRAME_LEN]; // 计算频点幅度主控函数,负责输出基站幅度镜像数据队列和基站最强幅度数据队列 // pstLocationDataList:定位数据队列 // pstBtsAmplMirrorDataList:基站幅度镜像数据队列(返回参数) // pstAmplDataList:基站最强幅度数据队列(返回参数) void bts_ampl_main(PUB_LOCATION_DATA_T *pstLocationDataList, BTS_AMPL_MIRROR_DATA_T *pstBtsAmplMirrorDataList, BTS_MAX_AMPL_DATA_T *pstBtsMaxAmplDataList) { PUB_LOCATION_DATA_T *pstLocationData = NULL; // 一帧定位数据 BTS_AMPL_MIRROR_DATA_T *pstBtsAmplMirrorData = NULL; // 一帧镜像数据 BTS_MAX_AMPL_DATA_T *pstBtsMaxAmplData = NULL; // 基站最强幅度数据 uint32 dwFrameNo = 0; // 当前帧号 uint8 byRemainder = 0; // 取模余数 uint8 bySlotIndex = 0; // 时隙索引 uint32 dwStartIndex = 0; flt32 *pfOneDataHead = NULL; flt32 *pfMultiDataHead = NULL; flt32 *pfDataHead = NULL; uint32 dwTmpIndex = 0; flt32 fMaxValue = 0; uint16 wMaxValueIndex = 0; flt32 fSnr = 0; //// 遍历基站,镜像数据(包括一秒数据和多秒数据) for (uint8 i = 0; i < PUB_SYS_CARRIER_NUM; i++) { pstLocationData = &pstLocationDataList[i]; // 基站定位数据 pstBtsAmplMirrorData = &pstBtsAmplMirrorDataList[i]; // 基站信号幅度镜像数据 // 计算前一帧的帧号(帧号从1开始,第2帧时镜像第1帧) dwFrameNo = pstLocationData->dwFrameNo - 1; if (dwFrameNo > 0) { // 1秒缓存队列重置 byRemainder = dwFrameNo % PUB_SYS_SLOT_NUM; if (byRemainder == 1) { memset(pstBtsAmplMirrorData->afOneSecondData, 0, sizeof(flt32) * PUB_SIGNAL_SAMPLE_RATIO); } // 多秒缓存队列重置 byRemainder = dwFrameNo % BTS_AMPL_MIRROR_FRAMES; if (byRemainder == 1) { memset(pstBtsAmplMirrorData->afMultiSecondData, 0, sizeof(flt32) * PUB_SIGNAL_SAMPLE_RATIO); pstBtsAmplMirrorData->byAmplValidTimes = 0; } // 获取当前帧的前一帧数据 util_looplist_get_flt32(pstLocationData->afData, PUB_LCT_DATA_LIST_LEN, pstLocationData->dwFourthLocationIndex, gg_afOneFrameLocationData, PUB_SLOT_FRAME_LEN, &dwTmpIndex); pfDataHead = gg_afOneFrameLocationData; // 镜像数据 bySlotIndex = (pstLocationData->dwFrameNo - 2) % PUB_SYS_SLOT_NUM; // 该帧所在时隙索引 dwStartIndex = bySlotIndex * PUB_SLOT_FRAME_LEN; // 开始索引 pfOneDataHead = &pstBtsAmplMirrorData->afOneSecondData[dwStartIndex]; pfMultiDataHead = &pstBtsAmplMirrorData->afMultiSecondData[dwStartIndex]; for (uint16 j = 0; j < PUB_SLOT_FRAME_LEN; j++) { *pfOneDataHead = *pfDataHead; *pfMultiDataHead += *pfDataHead / BTS_AMPL_MIRROR_SECONDS; pfDataHead++; pfOneDataHead++; pfMultiDataHead++; } // 检查当前一秒频点的有效性 if ((bySlotIndex % PUB_SYS_SLOT_NUM) == 3) { // 检查当前一秒频点的有效性 bts_ampl_check_freq_valid(pstLocationData, pstBtsAmplMirrorData); } // 计算4秒镜像数据的最大值和最大值索引 byRemainder = dwFrameNo % BTS_AMPL_MIRROR_FRAMES; if (byRemainder == 0) { wMaxValueIndex = util_looplist_find_max_value_index_flt32(pstBtsAmplMirrorData->afMultiSecondData, PUB_SIGNAL_SAMPLE_RATIO); fMaxValue = pstBtsAmplMirrorData->afMultiSecondData[wMaxValueIndex]; // 保存最前幅度数据 pstBtsMaxAmplData = &pstBtsMaxAmplDataList[i]; pstBtsMaxAmplData->byFreqIndex = i; pstBtsMaxAmplData->fMaxValue = fMaxValue; pstBtsMaxAmplData->wMaxValueIndex = wMaxValueIndex; // 判断基站是否有效 pstLocationData->byBtsValidFlag = 0; if (pstBtsAmplMirrorData->byAmplValidTimes > 1) // 两次有效 { pstLocationData->byBtsValidFlag = 1; } } } } // 当前帧需要对基站幅度进行排序 byRemainder = dwFrameNo % BTS_AMPL_MIRROR_FRAMES; if (byRemainder == 0) { // 对基站幅度进行排序,最强排在前面 bts_ampl_sort_max_ampl_list(pstBtsMaxAmplDataList); } return; } // 检查当前一秒频点的有效性 // pstLocationData:定位数据 // pstBtsAmplMirrorData:镜像数据 void bts_ampl_check_freq_valid(PUB_LOCATION_DATA_T *pstLocationData, BTS_AMPL_MIRROR_DATA_T *pstBtsAmplMirrorData) { uint16 wStartIndex = 0; uint16 wMeanStartIndex = 0; // 计算均值 flt32 fTmpValue = 0; // 临时变量 flt32 *pfOneSecondData = NULL; flt32 fMaxValue = FLT_MIN; // FLT_MAX在系统库中有定义,最小值 uint16 wMaxValueIndex = 0; int16 wIndexOffset = 0; flt32 fMinValue = FLT_MAX; // FLT_MAX在系统库中有定义,最大值 uint16 wMinValueIndex = 0; flt32 fMeanValue = 0; // 均值 flt32 afDataNoiseList[1500] = {0}; // 计算噪声的队列 flt32 fMiddleValue = 0; // 中位数 flt32 fFrameNoise = 0; // 帧内噪声 flt32 fSnr = 0; flt32 fAheadAmpl = pstLocationData->fCurrentMaxAmpl; // 前一次幅度 ////1、计算1秒帧内最大值和最大值索引 pfOneSecondData = pstBtsAmplMirrorData->afOneSecondData; wMaxValueIndex = util_looplist_find_max_value_index_flt32(pfOneSecondData, PUB_SIGNAL_SAMPLE_RATIO); fMaxValue = pfOneSecondData[wMaxValueIndex]; pstBtsAmplMirrorData->fOneSecondMaxValue = fMaxValue; pstBtsAmplMirrorData->wOneSecondMaxValueIndex = wMaxValueIndex; ////2、在最大值索引左侧5000点内找一个最小值 // 计算开始索引 wIndexOffset = wMaxValueIndex - PUB_SYNC_INDEX_OFFSET_NUM; if (wIndexOffset >= 0) { wStartIndex = wIndexOffset; } else { wStartIndex = PUB_SIGNAL_SAMPLE_RATIO + wIndexOffset; } // 查找一个最小值,并镜像当前值 for (uint16 j = 0; j < PUB_SYNC_INDEX_OFFSET_NUM; j++) { if (wStartIndex >= PUB_SIGNAL_SAMPLE_RATIO) { wStartIndex = 0; } fTmpValue = pstBtsAmplMirrorData->afOneSecondData[wStartIndex]; if (fTmpValue < fMinValue) { fMinValue = fTmpValue; wMinValueIndex = wStartIndex; } wStartIndex++; } fMinValue *= 5; // 最小值放大5倍 ////3、 计算最小值左侧1000点右侧500点的均值 // 计算开始索引 wIndexOffset = wMinValueIndex - 1000; if (wIndexOffset >= 0) { wStartIndex = wIndexOffset; } else { wStartIndex = PUB_SIGNAL_SAMPLE_RATIO + wIndexOffset; } // 计算均值 fFrameNoise = 0; for (int16 k = 0; k < 1500; k++) { if (wStartIndex >= PUB_SIGNAL_SAMPLE_RATIO) { wStartIndex = 0; } // 计算均值 fTmpValue = pstBtsAmplMirrorData->afOneSecondData[wStartIndex]; fMeanValue += fTmpValue / 1500; wStartIndex++; // 保存当前值 afDataNoiseList[k] = fTmpValue; } //// 计算中位数 util_sort_flt32_asc(afDataNoiseList, 1500); fMiddleValue = afDataNoiseList[900]; // 6/10 //// 4、计算帧内噪声 fFrameNoise = fMeanValue > fMinValue ? fMeanValue : fMinValue; fFrameNoise = fFrameNoise > fMiddleValue ? fFrameNoise : fMiddleValue; fSnr = fMaxValue / fFrameNoise; ////5、检查频点有效性 // 上一秒信号有效,则判断大值索引差值来检验当前信号是否有效 if (pstLocationData->byCurrentAmplValidFlag) { if (fMaxValue > BTS_AMPL_BTS_AMPL_VALID_THRESHOLD && fMaxValue > (0.10 * fAheadAmpl) && fSnr > BTS_AMPL_BTS_SNR_VALID_THRESHOLD) { pstLocationData->byCurrentAmplValidFlag = 1; pstBtsAmplMirrorData->byAmplValidTimes++; } else { pstLocationData->byCurrentAmplValidFlag = 0; } } // 上一秒信号无效,则通过判断当前信号大值来检验当前信号是否有效 else { // 通过幅度判断基站是否有效,信号幅度绝对值大于500 if (fMaxValue > BTS_AMPL_BTS_AMPL_VALID_THRESHOLD && fSnr > BTS_AMPL_BTS_SNR_VALID_THRESHOLD) { pstLocationData->byCurrentAmplValidFlag = 1; pstBtsAmplMirrorData->byAmplValidTimes++; } else { pstLocationData->byCurrentAmplValidFlag = 0; } } // 更新上一次最大值和最大值索引 pstLocationData->fCurrentMaxAmpl = fMaxValue; return; } // 对最强频点队列按照幅度大小倒排序 // pstBtsMaxAmplDataList:最强幅度队列 void bts_ampl_sort_max_ampl_list(BTS_MAX_AMPL_DATA_T *pstBtsMaxAmplDataList) { BTS_MAX_AMPL_DATA_T stTmp = {0}; // 按照信幅度倒排序,信噪比最大的站为主站 for (uint8 i = 0; i < PUB_SYS_CARRIER_NUM; i++) { for (uint8 j = (i + 1); j < PUB_SYS_CARRIER_NUM; j++) { if (pstBtsMaxAmplDataList[i].fMaxValue < pstBtsMaxAmplDataList[j].fMaxValue) { stTmp = pstBtsMaxAmplDataList[i]; pstBtsMaxAmplDataList[i] = pstBtsMaxAmplDataList[j]; // 数据交换 pstBtsMaxAmplDataList[j] = stTmp; } } } return; }