123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866 |
- // 秒寻科技
- // 计算第一径数据队列
- // zt
- // 2023-03-25
- #include "../../includes/includes.h"
- // 导出全局变量
- extern flt32 gg_afOneFrameLocationData[PUB_SLOT_FRAME_LEN]; // 一帧临时定位数据
- extern LCT_FIRSTPATH_PARAM_T gg_stFirstPathParam; // 第一径模块参数
- extern flt32 g_afSincFilterDataList[24001]; // sinc滤波器
- extern PUB_SYS_STATUS_T gg_stSysStatus;
- extern uint32 gg_dwFrameNo;
- extern LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T gLct_astPredictionDirectionDataList[PUB_SYS_CARRIER_NUM];
- void lct_firstpath_init(LCT_FIRSTPATH_PARAM_T stFirstPathParam)
- {
- // 帧内最小值选择因子
- gg_stFirstPathParam.byMinValueFactor = stFirstPathParam.byMinValueFactor;
- // 帧内锚点因子
- gg_stFirstPathParam.byAnchorFactor = stFirstPathParam.byAnchorFactor;
- gg_stFirstPathParam.byAnchorThreshold = stFirstPathParam.byAnchorThreshold;
- // 峰间距
- gg_stFirstPathParam.byPeakPeakDistance = stFirstPathParam.byPeakPeakDistance;
- // 计算帧内噪声门限时信号因子
- gg_stFirstPathParam.byNoiseSignalFactor = stFirstPathParam.byNoiseSignalFactor;
- // 计算帧内噪声门限时噪声放大倍数
- gg_stFirstPathParam.byNoiseHightScale = stFirstPathParam.byNoiseHightScale;
- gg_stFirstPathParam.byNoiseLowScale = stFirstPathParam.byNoiseLowScale;
- // cfar因子
- gg_stFirstPathParam.byCfarLeftFactor = stFirstPathParam.byCfarLeftFactor;
- // sinc门限因子
- gg_stFirstPathParam.bySincFactor = stFirstPathParam.bySincFactor;
- // 第一径联系锚点的因子
- gg_stFirstPathParam.byFirstPathContactFactor = stFirstPathParam.byFirstPathContactFactor;
- // 第一径联系锚点的峰间距离
- gg_stFirstPathParam.wFirstPathContactDistance = stFirstPathParam.wFirstPathContactDistance;
- //// 计算跟踪径的参数
- // 跟踪窗口宽度(跟踪径索引左右两边的距离-单边距离)
- gg_stFirstPathParam.wFirstPathTrackWindowWidth = stFirstPathParam.wFirstPathTrackWindowWidth;
- // 跟踪径保护带宽
- gg_stFirstPathParam.wFirstPathTrackPeakGuardWidth = stFirstPathParam.wFirstPathTrackPeakGuardWidth;
- // 跟踪径噪声查找宽度(从保护带宽左侧向左开始算)
- gg_stFirstPathParam.wFirstPathTrackNoiseFindWidth = stFirstPathParam.wFirstPathTrackNoiseFindWidth;
- // 跟踪径增益因子
- gg_stFirstPathParam.byFirstPathTrackPeakGainFactor = stFirstPathParam.byFirstPathTrackPeakGainFactor;
- return;
- }
- // 模块主控函数:根据定位基站队列,生产第一径队列
- // pstLctBtsList:一组定位基站
- // pstLctDataList:定位数据队列
- // pstFirstPathList:第一径数据队列(返回参数)
- void lct_firstpath_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T *pstFirstPathList)
- {
- uint8 byLctBtsNum = pstLctBtsList->byBtsNum; // 有效定位基站组的基站个数
- PUB_LCT_BTS_T *pstLctBts = NULL; // 定位基站
- PUB_LOCATION_DATA_T *pstLctData = NULL; // 定位数据
- uint8 byFreqIndex = 0; // 基站频率索引
- uint16 wMaxValueIndex = 0;
- flt32 fMaxValue; // 最大值
- uint16 wAnchorIndex = 0;
- flt32 fNoise = 0;
- flt32 fPeakThreshold = 0;
- FIRST_PATH_T stFirstPath = {0};
- uint8 byCounter = 0;
- uint16 wFrameTraceIndex = 0; // 帧内跟踪索引
- LCT_FIRSTPATH_T *pstFirstPath = NULL;
- // 复位预测方向数据有效标识符
- lct_firstpath_reset_direction_valid_flag(gLct_astPredictionDirectionDataList);
- // 遍历定位基站队列,计算基站第一径
- for (uint8 i = 0; i < byLctBtsNum; i++)
- {
- pstLctBts = &pstLctBtsList->astLocationBts[i]; // 定位基站
- byFreqIndex = pstLctBts->dwFreqIndex; // 基站的频率索引
- pstLctData = &pstLctDataList[byFreqIndex]; // 基站的定位数据
- // 获取该基站一帧定位数据
- lct_firstpath_get_lct_data(pstLctData, gg_afOneFrameLocationData);
- // TODO测试
- if (PUB_DEBUG_ENABLE)
- {
- if (pstLctData->dwFrameNo > 56)
- {
- char *pfileName = "E:\\work\\ips8000\\aplm8000sdk\\output\\lctdata\\firstpath.bin";
- util_write_flt32_to_bin_file(pfileName, PUB_SLOT_FRAME_LEN, gg_afOneFrameLocationData, 1);
- uint8 byTmp = 0;
- }
- }
- // 当前一秒数据有效(byLctBtsFlag是定位基站、byBtsValidFlag定位基站有效(前4秒信号的幅度有效,并且已实现同步)、byCurrentAmplValidFlag当前幅度值有效)
- if (pstLctData->byLctBtsFlag && pstLctData->byBtsValidFlag && pstLctData->byCurrentAmplValidFlag)
- {
- // 帧内跟踪索引
- wFrameTraceIndex = pstLctData->wAheadFrameTrackPathIndex;
- // 基站第一径数据
- pstFirstPath = &pstFirstPathList->astFirstPath[byCounter]; // 返回参数
- memset(pstFirstPath, 0, sizeof(LCT_FIRSTPATH_T));
- ////将定位基站数据中的数据,复制到第一径数据结构中
- pstFirstPath->byMainFlag = (uint8)pstLctBts->dwMainBtsFlag;
- pstFirstPath->dwBuildId = pstLctBts->dwBuildId;
- pstFirstPath->dwLayerId = pstLctBts->dwLayerId;
- pstFirstPath->dwBtsId = pstLctBts->dwBtsId;
- pstFirstPath->byFreqIndex = (uint8)pstLctBts->dwFreqIndex;
- pstFirstPath->bySlot = (uint8)pstLctBts->dwSlot;
- pstFirstPath->dwLctType = pstLctBts->dwLctType;
- pstFirstPath->dwTwoBtsNum = pstLctBts->dwTwoBtsNum;
- memcpy(pstFirstPath->adwTwoBtsList, pstLctBts->adwTwoBtsList, sizeof(uint32) * pstLctBts->dwTwoBtsNum);
- pstFirstPath->dwCoordX = pstLctBts->dwCoordX;
- pstFirstPath->dwCoordY = pstLctBts->dwCoordY;
- pstFirstPath->dwCoordZ = pstLctBts->dwCoordZ;
- // 计算"计算径",并存参数
- lct_firstpath_cal_calpath(gg_afOneFrameLocationData, wFrameTraceIndex, &wMaxValueIndex, &wAnchorIndex, &fNoise, &fPeakThreshold, &stFirstPath);
- if (stFirstPath.wFirstPathIndex > 3000) // 计算径结果有效
- {
- // pstFirstPath->dwCalPathIndex = pstLctData->dwDdcIndex + pstLctData->dwSignalSlotSyncOffset + pstLctData->dwSignalSyncIndex + stFirstPath.wFirstPathIndex; // 第一径绝对索引
- // pstFirstPath->dwCalPathIndex = pstLctData->dwDdcIndex + pstLctData->dwSignalSyncIndex + stFirstPath.wFirstPathIndex; // 第一径绝对索引
- pstFirstPath->dwCalPathIndex = PUB_SLOT_FRAME_LEN + pstLctData->dwSignalSlotSyncOffset + pstLctData->dwSignalSyncIndex + stFirstPath.wFirstPathIndex; // 第一径绝对索引
- pstFirstPath->wFrameCalIndex = stFirstPath.wFirstPathIndex; // 第一径帧内索引
- pstFirstPath->fFrameCalPathValue = gg_afOneFrameLocationData[stFirstPath.wFirstPathIndex]; // 计算径值
- pstFirstPath->fCalPathIndexSnr = stFirstPath.fSnr; // 计算径信噪比
- fMaxValue = gg_afOneFrameLocationData[wMaxValueIndex];
- pstFirstPath->fMaxAmplValue = fMaxValue; // 帧内最大值
- // TODO测试
- if (PUB_DEBUG_ENABLE)
- {
- if (pstLctData->dwFrameNo > 0 && pstFirstPath->wFrameCalIndex > 0)
- {
- printf("frame no:%d, freq index:%d, sync index:%d, cal frame index:%d, cal index:%d\n", pstLctData->dwFrameNo - 1, pstFirstPath->byFreqIndex + 1, pstLctData->dwSignalSyncIndex, pstFirstPath->wFrameCalIndex, pstFirstPath->dwCalPathIndex);
- uint8 byTmp = 0;
- }
- }
- }
- else
- {
- pstFirstPath->wFrameCalIndex = 0;
- }
- // 计算"跟踪径"
- if (wFrameTraceIndex && wFrameTraceIndex < 12000)
- {
- lct_firstpath_cal_trackpath(gg_afOneFrameLocationData, wFrameTraceIndex, fNoise, fPeakThreshold, wAnchorIndex, wMaxValueIndex, &stFirstPath);
- // 跟踪成功
- if (stFirstPath.byTrackSuccessFlag && stFirstPath.wFirstPathIndex > 3000)
- {
- // pstFirstPath->dwTrackPathIndex = pstLctData->dwDdcIndex + pstLctData->dwSignalSlotSyncOffset + pstLctData->dwSignalSyncIndex + stFirstPath.wFirstPathIndex; // 第一径绝对索引
- // pstFirstPath->dwTrackPathIndex = pstLctData->dwDdcIndex + pstLctData->dwSignalSyncIndex + stFirstPath.wFirstPathIndex; // 第一径绝对索引
- pstFirstPath->dwTrackPathIndex = PUB_SLOT_FRAME_LEN + pstLctData->dwSignalSlotSyncOffset + pstLctData->dwSignalSyncIndex + stFirstPath.wFirstPathIndex; // 第一径绝对索引
- pstFirstPath->wFrameTrackIndex = stFirstPath.wFirstPathIndex; // 第一径帧内索引
- pstFirstPath->fFrameTrackPathValue = gg_afOneFrameLocationData[stFirstPath.wFirstPathIndex]; // 跟踪径值
- pstFirstPath->fTrackPathIndexSnr = stFirstPath.fSnr; // 跟踪径信噪比
- }
- // 跟踪失败,则使用计算径的数据
- else
- {
- pstFirstPath->dwTrackPathIndex = pstFirstPath->dwCalPathIndex; // 第一径绝对索引
- pstFirstPath->fFrameTrackPathValue = pstFirstPath->fFrameCalPathValue;
- pstFirstPath->wFrameTrackIndex = pstFirstPath->wFrameCalIndex;
- pstFirstPath->fTrackPathIndexSnr = pstFirstPath->fCalPathIndexSnr;
- }
- }
- else
- {
- pstFirstPath->dwTrackPathIndex = pstFirstPath->dwCalPathIndex; // 第一径绝对索引
- pstFirstPath->fFrameTrackPathValue = pstFirstPath->fFrameCalPathValue;
- pstFirstPath->wFrameTrackIndex = pstFirstPath->wFrameCalIndex;
- pstFirstPath->fTrackPathIndexSnr = pstFirstPath->fCalPathIndexSnr;
- }
- // TODO测试
- if (PUB_DEBUG_ENABLE)
- {
- if (pstLctData->dwFrameNo > 0 && pstFirstPath->wFrameTrackIndex > 0)
- {
- printf("frame no:%d, freq index:%d, sync index:%d, track frame index:%d, track index:%d\n", pstLctData->dwFrameNo - 1, pstFirstPath->byFreqIndex + 1, pstLctData->dwSignalSyncIndex, pstFirstPath->wFrameTrackIndex, pstFirstPath->dwTrackPathIndex);
- uint8 byTmp = 0;
- }
- }
- // 第一径合法
- if (pstFirstPath->wFrameCalIndex > 3000 || pstFirstPath->wFrameTrackIndex > 3000)
- {
- byCounter++;
- // 备份第一径数据,用于后续模块预测手机移动方向
- lct_firstpath_save_first_path_data(pstLctData, pstFirstPath, gLct_astPredictionDirectionDataList);
- }
- }
- }
- // 保存第一径数据队列的基站数量
- pstFirstPathList->byBtsNum = byCounter;
- // TODO预测移动方向,放到了计算模块去预测了
- // lct_firstpath_prediction_move_direction(gLct_astPredictionDirectionDataList);
- return;
- }
- // 获取一帧定位数据
- // pstLctData:定位数据队列
- // pfOutData:输出参数,一帧定位数据
- void lct_firstpath_get_lct_data(PUB_LOCATION_DATA_T *pstLctData, flt32 *pfOutData)
- {
- int32 dwStartIndex = 0;
- uint32 dwTmpIndex = 0;
- // 计算定位数据所在队列中的开始索引
- // dwStartIndex = pstLctData->dwLocationIndex + (bySolt * PUB_SLOT_FRAME_LEN);
- dwStartIndex = pstLctData->dwLocationIndex + pstLctData->dwSignalSyncIndex;
- if (dwStartIndex < 0)
- {
- dwStartIndex += PUB_LCT_DATA_LIST_LEN;
- }
- else if (dwStartIndex >= PUB_LCT_DATA_LIST_LEN)
- {
- dwStartIndex -= PUB_LCT_DATA_LIST_LEN;
- }
- // 获取一帧数据
- util_looplist_get_flt32(pstLctData->afData, PUB_LCT_DATA_LIST_LEN, dwStartIndex, pfOutData, PUB_SLOT_FRAME_LEN, &dwTmpIndex);
- return;
- }
- // 计算 "计算径"
- // pfLocationData:定位数据
- // pwMaxValueIndex:大值索引(返回参数)
- // pwAnchorIndex:锚点索引(返回参数)
- // pdwNoise:噪声(返回参数)
- // pdwPeakThreshold:选峰门限(返回参数)
- // pstFirstPath:计算径(返回参数)
- void lct_firstpath_cal_calpath(flt32 *pfLocationData, uint16 wAheadFrameFirstPath, uint16 *pwMaxValueIndex, uint16 *pwAnchorIndex, flt32 *pfNoise, flt32 *pfPeakThreshold, FIRST_PATH_T *pstFirstPath)
- {
- uint16 wMaxValueIndex = 0; // 帧内最大值索引
- uint16 wMinValueIndex = 0;
- flt32 fNoise = 0; // 帧内噪声
- flt32 fSnr = 0; // 信噪比
- flt32 fSelPeakThreshold = 0; // 帧内峰值门限
- flt32 fMiniValueFactor = (flt32)gg_stFirstPathParam.byMinValueFactor / 100;
- uint16 awPeakList[PUBLIC_LCT_PEAK_LIST_LEN]; // 峰值索引队列
- uint16 wPeakListLen = 0; // 峰值索引队列长度
- uint16 wAnchorIndex = 0; // 帧内锚点索引
- uint16 wFirstPathLen = 0; // 第一径队列长度
- uint16 awOriginalList[PUBLIC_LCT_PEAK_LIST_LEN]; // 原始峰值索引队列
- uint16 wOriginalListLen = 0; // 原始峰值索引队列长度
- uint16 wFirstPathIndex = 0; // 第一径索引
- memset(awOriginalList, 0, sizeof(uint16) * PUBLIC_LCT_PEAK_LIST_LEN);
- memset(awPeakList, 0, sizeof(uint16) * PUBLIC_LCT_PEAK_LIST_LEN);
- // 计算帧内最大值索引、噪声和信噪比
- lct_firstpath_cal_frame_max_min_value_index_noise_snr(pfLocationData, wAheadFrameFirstPath, &wMaxValueIndex, &wMinValueIndex, &fNoise, &fSnr);
- *pwMaxValueIndex = wMaxValueIndex;
- *pfNoise = fNoise;
- // 计算选峰门限
- lct_firstpath_cal_peak_threshold(fNoise, fSnr, &fSelPeakThreshold);
- if (fSelPeakThreshold < fMiniValueFactor * pfLocationData[wMaxValueIndex])
- {
- fSelPeakThreshold = fMiniValueFactor * pfLocationData[wMaxValueIndex];
- }
- *pfPeakThreshold = fSelPeakThreshold;
- // 选左侧峰
- lct_firstpath_select_left_peak(pfLocationData, fSelPeakThreshold, wMinValueIndex, wMaxValueIndex, awPeakList, &wPeakListLen);
- // 计算锚点索引
- lct_firstpath_cal_anchor_index(awPeakList, wPeakListLen, pfLocationData, fSnr, &wAnchorIndex);
- *pwAnchorIndex = wAnchorIndex;
- // 二次计算选峰门限
- fSelPeakThreshold = lct_firstpath_recal_peak_value_threshold(pfLocationData, wMaxValueIndex, wAnchorIndex, fSelPeakThreshold);
- *pfPeakThreshold = fSelPeakThreshold;
- // 二次选峰
- lct_firstpath_select_peak_by_anchor(awPeakList, wPeakListLen, wAnchorIndex, pfLocationData, fSelPeakThreshold, &wPeakListLen);
- //// 基于峰值门限计算第一径
- wFirstPathLen = 0;
- lct_firstpath_cal_first_path_by_peak_value_threshold(pfLocationData, wMaxValueIndex, fSelPeakThreshold, awPeakList, wPeakListLen, 0, &wFirstPathLen);
- wPeakListLen = wFirstPathLen; // 调整峰值队列长度
- //// 基于CFAR规则计算第一径
- wFirstPathLen = 0;
- lct_firstpath_cal_first_path_by_cfar(pfLocationData, wMaxValueIndex, awPeakList, wPeakListLen, 0, &wFirstPathLen);
- wPeakListLen = wFirstPathLen; // 调整峰值队列长度
- //// 基于SINC规则计算第一径
- wFirstPathLen = 0;
- lct_firstpath_cal_first_path_by_sinc(pfLocationData, wMaxValueIndex, fNoise, awPeakList, wPeakListLen, 0, &wFirstPathLen);
- wPeakListLen = wFirstPathLen; // 调整峰值队列长度
- // 检查锚点是否还是有效峰
- lct_firstpath_check_anchor_index(awPeakList, wPeakListLen, wAnchorIndex, wMaxValueIndex, &wAnchorIndex, &wPeakListLen);
- // 检查第一径与锚点间的关联性
- memcpy(awOriginalList, awPeakList, sizeof(uint16) * wPeakListLen);
- wOriginalListLen = wPeakListLen;
- lct_firstpath_check_first_path_contact(pfLocationData, awPeakList, wPeakListLen, awOriginalList, wOriginalListLen, wAnchorIndex, wMaxValueIndex, &wFirstPathIndex);
- // 保存输出参数
- pstFirstPath->wFirstPathIndex = wFirstPathIndex;
- pstFirstPath->fSnr = pfLocationData[wFirstPathIndex] / fNoise;
- return;
- }
- // 计算帧内最大值索引、最小值索引、噪声和信噪比
- // pdwData:定位数据
- // wAheadFrameFirstPath:上一次第一径帧内索引
- // pwMaxValueIndex:帧内最大值索引(返回参数)
- // pwMinValueIndex:帧内最小值索引(返回参数)
- // pdwNose:帧内噪声(返回参数)
- // pfSnr:帧内信噪比(返回参数)
- void lct_firstpath_cal_frame_max_min_value_index_noise_snr(flt32 *pfData, uint16 wAheadFrameFirstPath, uint16 *pwMaxValueIndex, uint16 *pwMinValueIndex, flt32 *pfNose, flt32 *pfSnr)
- {
- flt32 fMaxValue = 0;
- uint16 wMaxValueIndex = 0; // 最大值索引
- flt32 *pfDataHead = NULL;
- flt32 fTmpValue = 0;
- flt32 fMinValue = FLT_MAX; // FLT_MAX在系统库中有定义,最大值
- uint16 wMinValueIndex = 0;
- flt32 afDataNoiseList[PUB_SLOT_FRAME_LEN] = {0};
- flt32 fMiddleValue = 0;
- flt32 fNoiseHightScale = (flt32)gg_stFirstPathParam.byNoiseHightScale / 10;
- flt32 fLeftAverageValue = 0;
- flt32 fNoise = 0;
- uint16 wStartIndex = 0;
- //// 1、计算最大值索引
- if (wAheadFrameFirstPath > 1500)
- {
- wStartIndex = wAheadFrameFirstPath - 1500;
- for (uint16 k = wStartIndex; k < PUB_SLOT_FRAME_LEN; k++)
- {
- if (pfData[k] > fMaxValue)
- {
- fMaxValue = pfData[k];
- wMaxValueIndex = k;
- }
- }
- }
- else
- {
- wMaxValueIndex = util_looplist_find_max_value_index_flt32(pfData, PUB_SLOT_FRAME_LEN);
- fMaxValue = pfData[wMaxValueIndex];
- }
- ////2、在最大值左侧找一个最小值
- wStartIndex = wMaxValueIndex > 1000 ? 1000 : 0;
- pfDataHead = pfData;
- for (uint16 i = wStartIndex; i < wMaxValueIndex; i++)
- {
- fTmpValue = *pfDataHead;
- if (fTmpValue < fMinValue)
- {
- fMinValue = fTmpValue;
- wMinValueIndex = i;
- }
- pfDataHead++;
- }
- *pwMinValueIndex = wMinValueIndex;
- fMinValue *= fNoiseHightScale;
- ////3、 计算最小值左右两侧均值(左侧有可能包含泄露噪声)
- wMinValueIndex += 501;
- for (uint16 k = 0; k < wMinValueIndex; k++)
- {
- fLeftAverageValue += pfData[k] / wMinValueIndex;
- afDataNoiseList[k] = pfData[k];
- }
- ////4、 计算中位数
- util_sort_flt32_asc(afDataNoiseList, wMinValueIndex);
- fMiddleValue = afDataNoiseList[wMinValueIndex * 65 / 100];
- ////5、计算帧内噪声
- fNoise = fLeftAverageValue > fMinValue ? fLeftAverageValue : fMinValue;
- fNoise = fMiddleValue > fNoise ? fMiddleValue : fNoise;
- ////6、保存参数
- *pwMaxValueIndex = wMaxValueIndex;
- *pfNose = fNoise;
- *pfSnr = fMaxValue / fNoise;
- return;
- }
- // 计算噪声、信噪比和峰值门限
- // fNoise:噪声
- // fSnr:信噪比
- // pfPeakThreshold(返回参数)
- void lct_firstpath_cal_peak_threshold(flt32 fNoise, flt32 fSnr, flt32 *pfPeakThreshold)
- {
- uint8 byNoiseSignalFactor = gg_stFirstPathParam.byNoiseSignalFactor;
- flt32 fNoiseLowScale = (flt32)gg_stFirstPathParam.byNoiseLowScale / 10;
- flt32 fNoiseShapeSinrRatio = 1;
- flt32 fThresholdSnr = 0; // 门限snr
- flt32 fPeakThreshold = 0; // 峰值门限
- // 计算峰值门限
- if (fSnr < 10)
- {
- fThresholdSnr = fSnr > fNoiseLowScale ? fSnr : fNoiseLowScale;
- fNoiseShapeSinrRatio += (10 - fThresholdSnr) / (flt32)byNoiseSignalFactor;
- }
- fPeakThreshold = ((flt32)fNoiseLowScale / fNoiseShapeSinrRatio) * fNoise;
- *pfPeakThreshold = (uint32)fPeakThreshold; // 选峰门限
- return;
- }
- // 选最大值的左侧峰
- // pfData:定位数据
- // fPeakThreshold:选峰门限
- // wMinValueIndex:最小值索引
- // wMaxValueIndex:最大值索引
- // pwPeakList:峰列表(返回参数)
- // pwPeakListLen:峰列表长度(返回参数)
- void lct_firstpath_select_left_peak(flt32 *pfData, flt32 fPeakThreshold, uint16 wMinValueIndex, uint16 wMaxValueIndex, uint16 *pwPeakList, uint16 *pwPeakListLen)
- {
- flt32 fLeftData1 = 0;
- flt32 fLeftData2 = 0;
- flt32 fLeftData3 = 0;
- flt32 fCenterData = 0; // 峰值
- flt32 fRightData1 = 0;
- flt32 fRightData2 = 0;
- flt32 fRightData3 = 0;
- uint16 wAheadPeakIndex = 0; // 前一个峰值索引
- flt32 fAheadPeakValue = 0; // 前一个峰值值
- uint16 wPeakPeakDistance = 0; // 峰间距
- uint8 byDistanceGap = gg_stFirstPathParam.byPeakPeakDistance; // 选峰间隔
- uint16 wCounter = 0;
- uint16 wTmpIndex = 0;
- // 从最大峰向左选峰
- fAheadPeakValue = pfData[wMaxValueIndex];
- wAheadPeakIndex = wMaxValueIndex;
- for (int16 i = (wMaxValueIndex - byDistanceGap); i > wMinValueIndex; i--)
- {
- if ((i - 3) >= 0)
- {
- fLeftData3 = pfData[i - 3];
- fLeftData2 = pfData[i - 2];
- fLeftData1 = pfData[i - 1];
- fCenterData = pfData[i];
- fRightData1 = pfData[i + 1];
- fRightData2 = pfData[i + 2];
- fRightData3 = pfData[i + 3];
- wPeakPeakDistance = wAheadPeakIndex - i; // 峰间距
- if (fCenterData > fPeakThreshold && fCenterData > fLeftData1 && fCenterData > fLeftData2 && fCenterData > fLeftData3 && fCenterData > fRightData1 && fCenterData > fRightData2 && fCenterData > fRightData3 && fCenterData > 0.15 * fAheadPeakValue && wPeakPeakDistance < 1000)
- {
- fAheadPeakValue = fCenterData;
- wAheadPeakIndex = i;
- pwPeakList[wCounter] = i;
- i -= (byDistanceGap + 1); // 调整峰值索引到下一个峰开始位置
- wCounter++;
- }
- }
- }
- // 保存最大峰值索引
- pwPeakList[wCounter] = wMaxValueIndex; // 最大值是锚点索引或者前一次第一径索引
- wCounter++;
- // 对峰值索引队列重新排序(从小到大)
- for (uint16 k = 0; k < wCounter; k++)
- {
- for (uint16 m = k + 1; m < wCounter; m++)
- {
- if (pwPeakList[m] < pwPeakList[k])
- {
- wTmpIndex = pwPeakList[k];
- pwPeakList[k] = pwPeakList[m];
- pwPeakList[m] = wTmpIndex;
- }
- }
- }
- // 保存峰值列表长度
- *pwPeakListLen = wCounter;
- return;
- }
- // 选跟踪峰
- // pfData:定位数据
- // wMaxValueIndex:最大值索引
- // wTrackIndex:跟踪径索引
- // pwPeakList:峰列表(返回参数)
- // pwPeakListLen:峰列表长度(返回参数)
- void lct_firstpath_sel_track_peak(flt32 *pfData, uint16 wMaxValueIndex, uint16 wTrackIndex, uint16 *pwPeakList, uint16 *pwPeakListLen)
- {
- uint16 wStartIndex = 0;
- uint16 wStopIndex = 0;
- uint16 wGuardWidth = gg_stFirstPathParam.wFirstPathTrackPeakGuardWidth; // 跟踪峰保护带宽
- uint16 wTrackWindowWidth = gg_stFirstPathParam.wFirstPathTrackWindowWidth; // 跟踪窗口宽度
- flt32 fLeftData1 = 0;
- flt32 fLeftData2 = 0;
- flt32 fLeftData3 = 0;
- flt32 fCenterData = 0; // 峰值
- flt32 fRightData1 = 0;
- flt32 fRightData2 = 0;
- flt32 fRightData3 = 0;
- uint8 byDistance = gg_stFirstPathParam.byPeakPeakDistance;
- uint16 wCounter = 0;
- uint16 wTmpIndex = 0;
- // 计算左侧选峰结束索引
- if ((wTrackIndex - wGuardWidth - wTrackWindowWidth) > 0)
- {
- wStartIndex = wTrackIndex - wGuardWidth - wTrackWindowWidth;
- }
- else
- {
- wStartIndex = 0;
- }
- // 从跟踪索引向左选峰
- for (int16 i = wTrackIndex; i > wStartIndex; i--)
- {
- if ((i - 3) >= 0 && (i + 3) < PUB_SLOT_FRAME_LEN)
- {
- fLeftData3 = pfData[i - 3];
- fLeftData2 = pfData[i - 2];
- fLeftData1 = pfData[i - 1];
- fCenterData = pfData[i];
- fRightData1 = pfData[i + 1];
- fRightData2 = pfData[i + 2];
- fRightData3 = pfData[i + 3];
- if (fCenterData > fLeftData1 && fCenterData > fLeftData2 && fCenterData > fLeftData3 && fCenterData > fRightData1 && fCenterData > fRightData2 && fCenterData > fRightData3)
- {
- pwPeakList[wCounter] = i;
- i -= (byDistance + 1); // 调整峰值索引到下一个峰开始位置
- wCounter++;
- }
- }
- }
- // 计算向右侧选峰的结束索引
- if ((wTrackIndex + wGuardWidth + wTrackWindowWidth + 1) < PUB_SLOT_FRAME_LEN)
- {
- wStopIndex = wTrackIndex + wGuardWidth + wTrackWindowWidth + 1;
- }
- else
- {
- wStopIndex = PUB_SLOT_FRAME_LEN;
- }
- // 向右侧选峰
- for (int16 j = (wTrackIndex + byDistance); j < wStopIndex; j++)
- {
- if ((j + 3) < PUB_SLOT_FRAME_LEN)
- {
- fLeftData3 = pfData[j - 3];
- fLeftData2 = pfData[j - 2];
- fLeftData1 = pfData[j - 1];
- fCenterData = pfData[j];
- fRightData1 = pfData[j + 1];
- fRightData2 = pfData[j + 2];
- fRightData3 = pfData[j + 3];
- if (fCenterData > fLeftData1 && fCenterData > fLeftData2 && fCenterData > fLeftData3 && fCenterData > fRightData1 && fCenterData > fRightData2 && fCenterData > fRightData3)
- {
- pwPeakList[wCounter] = j;
- j += (byDistance - 1); // 调整峰值索引到下一个峰左侧侧位置
- wCounter++;
- }
- }
- }
- // 对峰值列表重新排序(从小到大)
- for (uint16 k = 0; k < wCounter; k++)
- {
- for (uint16 m = k + 1; m < wCounter; m++)
- {
- if (pwPeakList[m] < pwPeakList[k])
- {
- wTmpIndex = pwPeakList[k];
- pwPeakList[k] = pwPeakList[m];
- pwPeakList[m] = wTmpIndex;
- }
- }
- }
- // 过滤在最大值索引右侧的峰,包括最大值
- for (uint16 p = 0; p < wCounter; p++)
- {
- wTmpIndex = pwPeakList[p];
- if (wTmpIndex >= wMaxValueIndex)
- {
- wCounter = p;
- break;
- }
- }
- // 保存峰值列表长度
- *pwPeakListLen = wCounter;
- return;
- }
- // 计算锚点索引
- // pwPeakList:峰队列
- // wPeakListLen:峰队列长度
- // pfData:定位数据
- // fSnr:本帧的信噪比
- // pwAnchorIndex:锚点索引(返回参数)
- void lct_firstpath_cal_anchor_index(uint16 *pwPeakList, uint16 wPeakListLen, flt32 *pfData, flt32 fSnr, uint16 *pwAnchorIndex)
- {
- flt32 fMaxValue = 0;
- uint16 wMaxValueIndex = 0;
- uint8 byAnchorFactor = gg_stFirstPathParam.byAnchorFactor; // 锚点因子
- flt32 fAnchorThreshold = ((flt32)gg_stFirstPathParam.byAnchorThreshold) / 100; // 锚点默认门限值
- uint16 wAnchorIndex = 0; // 锚点索引
- uint16 wTempIndex = 0;
- uint32 fTempValue = 0;
- uint8 byExistFlag = 0;
- // 计算锚点门限值
- wMaxValueIndex = pwPeakList[wPeakListLen - 1];
- fMaxValue = pfData[wMaxValueIndex];
- // 信噪比较小,则抬升锚点门限
- if (fSnr < 10)
- {
- fSnr = fSnr > 1.5 ? fSnr : 1.5;
- fAnchorThreshold += (10 - fSnr) / byAnchorFactor; // 抬升锚点门限
- }
- // 计算锚点门限
- if (fMaxValue < 5000)
- {
- fAnchorThreshold = 0.45 * fMaxValue;
- }
- else
- {
- fAnchorThreshold = fMaxValue * fAnchorThreshold;
- }
- // 计算锚点索引
- if (wPeakListLen <= 1)
- { // 只有一个峰
- *pwAnchorIndex = pwPeakList[0];
- }
- else
- { // 有多个峰,则从多个峰中选择锚点
- for (int16 i = 0; i < wPeakListLen; i++)
- {
- wTempIndex = pwPeakList[i];
- fTempValue = pfData[wTempIndex];
- if (fTempValue > fAnchorThreshold)
- {
- wAnchorIndex = wTempIndex;
- byExistFlag = 1; // 找到了
- break;
- }
- }
- if (byExistFlag)
- { // 找到了锚点
- *pwAnchorIndex = wAnchorIndex;
- }
- else
- { // 未找到锚点,最大峰为锚点
- *pwAnchorIndex = pwPeakList[wPeakListLen - 1];
- }
- }
- return;
- }
- // 计算二次选峰门限
- // pfLocationData:定位数据
- // wMaxValueIndex:帧内最大值索引
- // wAnchorIndex:帧内锚点索引
- // fThreshold:一次选峰门限
- // 返回值:二次选峰门限
- flt32 lct_firstpath_recal_peak_value_threshold(flt32 *pfLocationData, uint16 wMaxValueIndex, uint16 wAnchorIndex, flt32 fThreshold)
- {
- int16 wIndexGap = 0;
- flt32 fAnchorValue = 0;
- flt32 fOutThreshold = fThreshold;
- fAnchorValue = pfLocationData[wAnchorIndex]; // 锚点值
- // 根据最大峰和锚点间距调整二次选峰门限
- if (wAnchorIndex != wMaxValueIndex)
- {
- wIndexGap = wMaxValueIndex - wAnchorIndex;
- // 严重多径
- if (wIndexGap > 2000)
- {
- if (0.35 * fAnchorValue > fThreshold)
- {
- fOutThreshold = 0.35 * fAnchorValue;
- }
- }
- else if (wIndexGap > 1500)
- {
- if (0.30 * fAnchorValue > fThreshold)
- {
- fOutThreshold = 0.30 * fAnchorValue;
- }
- }
- else if (wIndexGap > 1000)
- {
- if (0.25 * fAnchorValue > fThreshold)
- {
- fOutThreshold = 0.25 * fAnchorValue;
- }
- }
- else
- {
- if (0.15 * fAnchorValue > fThreshold)
- {
- fOutThreshold = 0.15 * fAnchorValue;
- }
- }
- }
- // 根据锚点幅度再次调整门限(小信号)
- if (fAnchorValue < 3000)
- {
- fOutThreshold = 0.35 * fAnchorValue;
- }
- return fOutThreshold;
- }
- // 根据锚点二次选锋,只选锚点左侧的峰
- // pwPeakList:峰值索引列表
- // wPeakListLen:峰值索引列表长度
- // wAnchorIndex:锚点
- // pwPeakIndexListLen:峰值索引列表长度(返回参数)
- // 返回值,1:成功,0:失败
- void lct_firstpath_select_peak_by_anchor(uint16 *pwPeakList, uint16 wPeakListLen, uint16 wAnchorIndex, flt32 *pfData, flt32 fThresholdWithAnchor, uint16 *pwPeakListLen)
- {
- uint16 wCounter = 0;
- uint16 wTempIndex = 0;
- flt32 fPeakValue = 0;
- // 选锋
- for (uint16 i = 0; i < wPeakListLen; i++)
- {
- wTempIndex = pwPeakList[i];
- fPeakValue = pfData[wTempIndex];
- if (fPeakValue > fThresholdWithAnchor && wTempIndex <= wAnchorIndex)
- {
- pwPeakList[wCounter] = wTempIndex;
- wCounter++;
- }
- }
- // 保存最大值
- if (wAnchorIndex < pwPeakList[wPeakListLen - 1])
- {
- pwPeakList[wCounter] = pwPeakList[wPeakListLen - 1];
- wCounter++;
- }
- // 队列长度
- *pwPeakListLen = wCounter;
- return;
- }
- // 通过噪声门限计算第一径点集
- // pfData:定位数据
- // wMaxValueIndex:最大值索引
- // fPeakValueThreshold:选峰门限
- // pwPeakList:峰值索引列表
- // wPeakListLen:峰值索引列表长度
- // byTrackFlag:跟踪标志(0:不跟踪,1:跟踪)
- // pwFirstPathLen:第一径长度(返回参数)
- void lct_firstpath_cal_first_path_by_peak_value_threshold(flt32 *pfData, uint16 wMaxValueIndex, flt32 fPeakValueThreshold, uint16 *pwPeakList, uint16 wPeakListLen, uint8 byTrackFlag, uint16 *pwFirstPathLen)
- {
- uint16 awList[PUB_SLOT_FRAME_LEN];
- uint16 wPeakIndex = 0;
- flt32 fTmpValue = 0;
- uint16 wCounter = 0;
- memset(awList, 0, sizeof(uint16) * PUB_SLOT_FRAME_LEN);
- // 遍历峰值索引队列,精选第一径
- for (uint16 i = 0; i < wPeakListLen; i++)
- {
- wPeakIndex = pwPeakList[i];
- fTmpValue = pfData[wPeakIndex];
- if (fTmpValue > fPeakValueThreshold)
- {
- pwPeakList[wCounter] = wPeakIndex;
- wCounter++;
- }
- }
- // 存在第一径
- if (wCounter > 0)
- {
- *pwFirstPathLen = wCounter; // 更新队列长度
- }
- // 不存在第一径
- else
- {
- // 不跟踪第一径
- if (byTrackFlag <= 0)
- {
- pwPeakList[0] = wMaxValueIndex; // 将最大值作为第一径
- *pwFirstPathLen = 1;
- }
- // 跟踪第一径
- else
- {
- pwPeakList[0] = PUB_SLOT_FRAME_LEN; // 索引默认值,标识跟踪失败
- *pwFirstPathLen = 0; // 标识跟踪失败
- }
- }
- return;
- }
- // 根据CFAR规则计算第一径
- // pfData:定位数据
- // wMaxValueIndex:最大值索引
- // pwPeakList:峰值索引列表(输入输出参数)
- // wPeakListLen:峰值索引列表长度
- // byTrackFlag:跟踪标志(0:不跟踪,1:跟踪)
- // pwFirstPathLen:第一径长度(返回参数)
- void lct_firstpath_cal_first_path_by_cfar(flt32 *pfData, uint16 wMaxValueIndex, uint16 *pwPeakList, uint16 wPeakListLen, uint8 byTrackFlag, uint16 *pwFirstPathLen)
- {
- // 左侧因子
- flt32 fCfarLeftFactor = ((flt32)gg_stFirstPathParam.byCfarLeftFactor) / 100;
- flt32 fLeftValueThres = 0; // 左侧门限
- flt32 fLeftMax = 0; // 左侧最大值
- flt32 fLeftTemp = 0;
- flt32 fSignalValue = 0; // 信号值
- uint16 wSignalIndex = 0; // 队列索引
- uint8 byErrorFlag = 0; // 是否满足cfar规格检查, 0:满足,1:不满足
- uint16 wCounter = 0; // 符合检查规则的峰值计数器
- // 遍历第一径队列,以cfar规则检查第一径
- for (uint16 k = 0; k < wPeakListLen; k++)
- {
- byErrorFlag = 0;
- wSignalIndex = pwPeakList[k]; // 第一径在信号队列中的索引
- // 检查该队列左边是否足够进行cfar判断
- if ((wSignalIndex - 2 * PUBLIC_LCT_CFAR_LEN) < 0)
- {
- byErrorFlag = 1;
- }
- // 左侧满足检测要求
- if (!byErrorFlag)
- {
- fSignalValue = pfData[wSignalIndex]; // 当前信号值
- // 选择左边最大值
- fLeftMax = 0;
- for (uint16 i = (wSignalIndex - 2 * PUBLIC_LCT_CFAR_LEN); i < (wSignalIndex - PUBLIC_LCT_CFAR_LEN); i++)
- {
- fLeftTemp = pfData[i];
- if (fLeftTemp > fLeftMax)
- {
- fLeftMax = fLeftTemp;
- }
- }
- fLeftValueThres = fLeftMax * fCfarLeftFactor; // cfar门限
- if (fSignalValue > fLeftValueThres)
- {
- pwPeakList[wCounter] = wSignalIndex;
- wCounter++;
- }
- }
- }
- // 存在第一径
- if (wCounter > 0)
- {
- // 将最大值插入第一径队列
- if (pwPeakList[wCounter - 1] != wMaxValueIndex)
- {
- pwPeakList[wCounter] = wMaxValueIndex;
- wCounter++;
- }
- *pwFirstPathLen = wCounter; // 更新队列长度
- }
- // 不存在第一径
- else
- {
- // 当前是计算径
- if (byTrackFlag <= 0)
- {
- pwPeakList[0] = wMaxValueIndex; // 将最大值作为第一径
- *pwFirstPathLen = 1;
- }
- // 当前是跟踪径
- else
- {
- pwPeakList[0] = PUB_SLOT_FRAME_LEN; // 索引默认值,标识跟踪失败
- *pwFirstPathLen = 0; // 标识跟踪失败
- }
- }
- return;
- }
- // 根据sinc规则计算第一径
- // pfData:定位数据
- // wMaxValueIndex:最大值索引
- // fNoise:噪声
- // pwPeakList:峰值索引列表
- // wPeakListLen:峰值索引列表长度
- // byTrackFlag:跟踪标志(0:不跟踪,1:跟踪)
- // pwFirstPathLen:第一径长度(返回参数)
- void lct_firstpath_cal_first_path_by_sinc(flt32 *pfData, uint16 wMaxValueIndex, flt32 fNoise, uint16 *pwPeakList, uint16 wPeakListLen, uint8 byTrackFlag, uint16 *pwFirstPathLen)
- {
- flt32 *pfSincDataModel = g_afSincFilterDataList; // sinc模型
- uint8 bySincFactor = gg_stFirstPathParam.bySincFactor; // sinc因子
- // flt32 fSnr = 0;
- flt32 fSincFactor = 0; // sinc门限因子
- flt32 fSincThreshold = 0; // sinc门限
- uint16 wSincValueIndex = 0;
- int16 wPeakPeakGap = 0; // 峰间距
- flt32 fPeakValue = 0; // 第一径峰值
- uint16 wPeakValuelIndex = 0; // 第一径峰值索引
- uint16 wTempIndex = 0;
- flt32 fTempValue = 0;
- uint16 awInvalidPeakValueList[PUB_SLOT_FRAME_LEN]; // 无效峰队列
- uint16 wInvalidPeakCounter = 0; // 无效峰计算器
- uint16 wInvalidPeakValuelIndex = 0; // 无效峰值索引
- uint8 byExistFlag = 0; // 存在标识
- uint16 wCounter = 0;
- // 保存sinc门限的测试用变量
- flt32 afSincDataTestList[2 * PUB_SLOT_FRAME_LEN + 1];
- memset(afSincDataTestList, 0, sizeof(flt32) * (2 * PUB_SLOT_FRAME_LEN + 1));
- memset(awInvalidPeakValueList, 0, sizeof(uint16) * PUB_SLOT_FRAME_LEN);
- // 根据信噪比调整信号门限
- // fSnr = (flt32)pfData[wMaxValueIndex] / fNoise;
- // if (fSnr < 10)
- // {
- // bySincFactor = bySincFactor * 0.95;
- // }
- // 遍历队列,以sinc规格重新计算第一径
- for (uint16 i = 0; i < wPeakListLen; i++)
- {
- // 生成sinc门限因子
- wPeakValuelIndex = pwPeakList[i]; // 当前峰值索引
- fPeakValue = pfData[wPeakValuelIndex]; // 当前峰值
- fSincFactor = fPeakValue * bySincFactor / 100; // sinc因子
- // 将sinc门限保存到文件
- // if (i >= 0) {
- // // 计算sinc门限索引
- // wStartIndex = 16000 - wPeakValuelIndex;
- // for (uint16 sincIndex = 0; sincIndex < 16000; sincIndex++) {
- // afSincDataTestList[sincIndex] = pfSincDataModel[wStartIndex] * fSincFactor;
- // wStartIndex++;
- // }
- // // 保存sinc门限到文件
- // char filePath[256];
- // char fileIndex[8];
- // memset(filePath, 0, 256);
- // memset(fileIndex, 0, 8);
- // char* fileName = "sincthres";
- // itoa(i, fileIndex, 10);
- // char* fileTail = ".txt";
- // char* filePathHead = "E:\\05item\\ips\\location\\output\\sincthres\\";
- // strcat(filePath, filePathHead);
- // strcat(filePath, fileName);
- // strcat(filePath, fileIndex);
- // strcat(filePath, fileTail);
- // util_write_real_number_to_txt_file(filePath, 16000, afSincDataTestList);
- // }
- // sinc检查
- for (uint16 j = 0; j < wPeakListLen; j++)
- {
- wTempIndex = pwPeakList[j];
- fTempValue = pfData[wTempIndex];
- if (wTempIndex != wPeakValuelIndex)
- {
- ////计算sinc滤波器的索引
- // 被检查峰在当前峰的左侧
- wSincValueIndex = 0;
- if (wPeakValuelIndex > wTempIndex)
- {
- wPeakPeakGap = wPeakValuelIndex - wTempIndex; // 两峰间距
- wSincValueIndex = PUB_SLOT_FRAME_LEN - wPeakPeakGap;
- // // 如果是遮挡峰,则降低主峰左侧700-1200点区间内的检查门限,以正确选出遮挡峰
- // if ((wPeakValuelIndex - wTempIndex) > 700 && (wPeakValuelIndex - wTempIndex) <= 1200 && i == (wPeakListLen - 1)) {
- // fSincThreshold = pfSincDataModel[wSincValueIndex] * fSincFactor * 0.6; // 门限
- // } else {
- // fSincThreshold = pfSincDataModel[wSincValueIndex] * fSincFactor; // 门限
- // }
- }
- // 被检查峰在当前峰的右侧
- else
- {
- wPeakPeakGap = wTempIndex - wPeakValuelIndex; // 两峰间距
- wSincValueIndex = PUB_SLOT_FRAME_LEN + wPeakPeakGap; // 检查峰在右侧
- }
- // 修正选峰门限。峰间隔超过1500,说明存在严重的多径现象
- if (wPeakPeakGap > 1500)
- {
- fSincThreshold = pfSincDataModel[wSincValueIndex] * fSincFactor * 0.90; // sinc门限
- }
- else
- {
- fSincThreshold = pfSincDataModel[wSincValueIndex] * fSincFactor; // sinc门限
- }
- // 当前峰不合法
- if (fTempValue <= fSincThreshold)
- {
- awInvalidPeakValueList[wInvalidPeakCounter] = wTempIndex;
- wInvalidPeakCounter++;
- }
- }
- }
- }
- // 存在无效峰
- if (wInvalidPeakCounter > 0)
- {
- wCounter = 0;
- // 遍历有效峰队列
- for (uint16 k = 0; k < wPeakListLen; k++)
- {
- byExistFlag = 0;
- wPeakValuelIndex = pwPeakList[k]; // 峰值索引;
- // 遍历无效峰队列
- for (uint16 m = 0; m < wInvalidPeakCounter; m++)
- {
- wInvalidPeakValuelIndex = awInvalidPeakValueList[m];
- if (wPeakValuelIndex == wInvalidPeakValuelIndex)
- {
- byExistFlag = 1;
- break;
- }
- }
- if (!byExistFlag)
- { // 在无效峰值队列总没有找到,则保存该峰值索引
- pwPeakList[wCounter] = wPeakValuelIndex;
- wCounter++;
- }
- }
- // 更新队列长度
- if (wCounter > 0)
- {
- *pwFirstPathLen = wCounter;
- }
- else
- {
- *pwFirstPathLen = 1;
- if (byTrackFlag == 0)
- {
- pwPeakList[0] = wMaxValueIndex; // 最大值索引
- }
- else if (byTrackFlag == 1)
- { // 跟踪径计算
- pwPeakList[0] = 0; // 索引默认值,标识跟踪失败
- }
- }
- }
- // 没有无效峰
- else
- {
- *pwFirstPathLen = wPeakListLen;
- }
- return;
- }
- // 检查锚点是否是合法峰
- // pwPeakList:峰值索引队列
- // wPeakListLen:峰值索引队列长度
- // wAnchorIndex:锚点索引
- // wMaxValueIndex:最大值索引
- // pwAnchorIndex:锚点索引,返回值
- // 返回值
- void lct_firstpath_check_anchor_index(uint16 *pwPeakList, uint16 wPeakListLen, uint16 wAnchorIndex, uint16 wMaxValueIndex, uint16 *pwAnchorIndex, uint16 *pwPeakListLen)
- {
- uint16 wTempIndex = 0;
- uint8 byExistFlag = 0;
- // int32 dwGap = 0;
- uint16 wCounter = wPeakListLen;
- uint16 wTemp = 0;
- // 遍历队列检查峰值索引是否包含锚点
- for (uint16 i = 0; i < wPeakListLen; i++)
- {
- wTempIndex = pwPeakList[i];
- if (wTempIndex == wAnchorIndex)
- {
- byExistFlag = 1;
- break;
- }
- }
- // // 锚点在峰值索引队列中
- // if (byExistFlag)
- // {
- // *pwAnchorIndex = wAnchorIndex;
- // }
- // // 锚点不在峰值索引队列中
- // else
- // {
- // dwGap = abs(wMaxValueIndex - wAnchorIndex);
- // // 相差了3.5米
- // if (dwGap > 500)
- // {
- // *pwAnchorIndex = wAnchorIndex; // 最大值与锚点间间隔大于440
- // // 把锚点重新加入队列
- // pwPeakList[wPeakListLen] = wAnchorIndex;
- // wCounter++;
- // // 对峰值列表重新排序(从小到大)
- // for (uint16 k = 0; k < wCounter; k++)
- // {
- // for (uint16 m = k + 1; m < wCounter; m++)
- // {
- // if (pwPeakList[m] < pwPeakList[k])
- // {
- // wTemp = pwPeakList[k];
- // pwPeakList[k] = pwPeakList[m];
- // pwPeakList[m] = wTemp;
- // }
- // }
- // }
- // }
- // // 相差不到3米
- // else
- // {
- // *pwAnchorIndex = wMaxValueIndex; // 最大值索引当成锚点
- // }
- // }
- // 锚点不在峰值队列中
- if (!byExistFlag)
- {
- // 把锚点重新加入队列
- pwPeakList[wPeakListLen] = wAnchorIndex;
- wCounter++;
- // 对峰值队列重新排序(从小到大)
- for (uint16 k = 0; k < wCounter; k++)
- {
- for (uint16 m = k + 1; m < wCounter; m++)
- {
- if (pwPeakList[m] < pwPeakList[k])
- {
- wTemp = pwPeakList[k];
- pwPeakList[k] = pwPeakList[m];
- pwPeakList[m] = wTemp;
- }
- }
- }
- }
- *pwAnchorIndex = wAnchorIndex;
- *pwPeakListLen = wCounter;
- return;
- }
- // 检测第一径各峰是否能关联到锚点
- // pdwData:定位数据
- // pwPeakList:峰值队列
- // wPeakListLen:峰值队列长度
- // pwOriginalList:原始峰值队列
- // wOriginalListLen:原始峰值队列长度
- // wAnchorIndex:锚点
- // wMaxValueIndex:最大值索引
- // pwFirstPathIndex:第一径索引
- // 返回值,1:成功,0:失败
- void lct_firstpath_check_first_path_contact(flt32 *pfData, uint16 *pwPeakList, uint16 wPeakListLen, uint16 *pwOriginalList, uint16 wOriginalListLen, uint16 wAnchorIndex, uint16 wMaxValueIndex, uint16 *pwFirstPathIndex)
- {
- uint8 byContactFactor = gg_stFirstPathParam.byFirstPathContactFactor;
- uint16 wContactDistance = gg_stFirstPathParam.wFirstPathContactDistance;
- uint16 wPeakValueIndex = 0; // 峰值索引
- // 第一峰
- flt32 fFirstpeakValue = 0;
- uint16 wFirstPeakIndex = 0;
- // 第二峰
- flt32 fSecondPeakValue = 0;
- uint16 wSecondPeakIndex = 0;
- flt32 fSecondpeakThreshold = 0; // 选择第二峰的门限
- uint8 bySelectFlag = 0; // 关联锚点标识,1:关联成功,0:关联失败
- // 依次检查第一径是否能关联到锚点
- if (wPeakListLen > 1)
- { // 有两个点或以上
- for (uint16 i = 0; i < wPeakListLen - 1; i++)
- {
- wPeakValueIndex = pwPeakList[i];
- wFirstPeakIndex = pwPeakList[i];
- fFirstpeakValue = pfData[wFirstPeakIndex]; // 第一峰峰值
- fSecondpeakThreshold = (fFirstpeakValue / 100) * byContactFactor;
- for (uint16 k = 0; k < wOriginalListLen; k++)
- {
- wSecondPeakIndex = pwOriginalList[k];
- if (wSecondPeakIndex > wFirstPeakIndex)
- {
- fSecondPeakValue = pfData[wSecondPeakIndex]; // 第二峰峰值
- // 第二峰有效
- if (fSecondPeakValue > fSecondpeakThreshold)
- {
- // 第二峰与第一峰间的距离“满足”系统要求
- if ((wSecondPeakIndex - wFirstPeakIndex) <= wContactDistance)
- {
- // 关联成功
- if ((wSecondPeakIndex == wAnchorIndex) || (wSecondPeakIndex == wMaxValueIndex))
- {
- *pwFirstPathIndex = wPeakValueIndex; // 保存真正的第一径索引
- bySelectFlag = 1;
- break;
- }
- else
- { // 关联失败,继续向后查找
- wFirstPeakIndex = wSecondPeakIndex;
- fFirstpeakValue = fSecondPeakValue;
- fSecondpeakThreshold = (fFirstpeakValue / 100) * byContactFactor;
- }
- }
- else
- { // 第二峰与第一峰间的距离“不满足”系统要求
- bySelectFlag = 0;
- break;
- }
- }
- }
- }
- if (bySelectFlag)
- {
- break;
- }
- }
- if (!bySelectFlag)
- { // 没有关联成功
- *pwFirstPathIndex = wAnchorIndex; // 锚点为第一径
- }
- }
- else
- { // 只有一个峰
- *pwFirstPathIndex = pwPeakList[wPeakListLen - 1];
- }
- return;
- }
- /******************************************************上面是计算径*********************************************/
- /******************************************************下面是跟踪径*********************************************/
- // 计算"跟踪径"
- // pfData:原始信号
- // wTrackIndex:跟踪索引
- // fNoise:噪声
- // fSelPeakThreshold:选峰门限
- // wAnchorIndex:锚点索引
- // pstTrackPath:跟踪径(返回参数)
- void lct_firstpath_cal_trackpath(flt32 *pfData, uint16 wTrackIndex, flt32 fNoise, flt32 fSelPeakThreshold, uint16 wAnchorIndex, uint16 wMaxValueIndex, FIRST_PATH_T *pstTrackPath)
- {
- uint16 awPeakList[2 * PUBLIC_LCT_TRACK_WINDOW_WIDTH + 1]; // 峰值索引队列
- uint16 wPeakListLen = 0; // 峰值索引队列长度
- memset(awPeakList, 0, sizeof(uint16) * (2 * PUBLIC_LCT_TRACK_WINDOW_WIDTH + 1));
- // 选跟踪峰,不超过最大峰值索引
- lct_firstpath_sel_track_peak(pfData, wMaxValueIndex, wTrackIndex, awPeakList, &wPeakListLen);
- // 补偿峰值增益
- lct_firstpath_compensate_peak_gain(pfData, awPeakList, wPeakListLen);
- // 将最大值添加到峰值队列中
- awPeakList[wPeakListLen] = wMaxValueIndex;
- wPeakListLen++;
- //// 基于门限规则计算第一径
- lct_firstpath_cal_first_path_by_peak_value_threshold(pfData, wMaxValueIndex, fSelPeakThreshold, awPeakList, wPeakListLen, 1, &wPeakListLen);
- // 基于CFAR规则检查第一径
- lct_firstpath_cal_first_path_by_cfar(pfData, wMaxValueIndex, awPeakList, wPeakListLen, 1, &wPeakListLen);
- // 基于SINC规则检查第一径
- lct_firstpath_cal_first_path_by_sinc(pfData, wMaxValueIndex, fNoise, awPeakList, wPeakListLen, 1, &wPeakListLen);
- // 跟踪失败
- if (wPeakListLen <= 1)
- {
- pstTrackPath->byTrackSuccessFlag = 0;
- }
- // 跟踪径成功
- else
- {
- pstTrackPath->byTrackSuccessFlag = 1;
- pstTrackPath->wFirstPathIndex = awPeakList[0];
- pstTrackPath->fSnr = pfData[awPeakList[0]] / fNoise;
- }
- return;
- }
- // // 选择跟踪窗口中的峰
- // // pfData:定位数据
- // // fPeakValueThreshold:选峰门限
- // // wTrackIndex:跟踪索引
- // // wMaxValueIndex:最大值索引
- // // pwPeakList:峰值索引队列
- // // pwPeakListLen:峰值索引队列长度
- // void lct_firstpath_trackpath_select_peak(flt32 *pfData, flt32 fPeakValueThreshold, uint16 wTrackIndex, uint16 wMaxValueIndex, uint16 *pwPeakList, uint16 *pwPeakListLen)
- // {
- // uint16 wGuardWidth = gg_stFirstPathParam.wFirstPathTrackPeakGuardWidth; // 跟踪峰保护带宽
- // uint16 wTrackWindowWidth = gg_stFirstPathParam.wFirstPathTrackWindowWidth; // 跟踪窗口宽度
- // uint16 wStartIndex = 0;
- // uint16 wStopIndex = 0;
- // uint16 wListLen = 0;
- // // 计算开始引
- // if ((wTrackIndex - wGuardWidth - wTrackWindowWidth) >= 0)
- // {
- // wStartIndex = wTrackIndex - wGuardWidth - wTrackWindowWidth;
- // }
- // else
- // {
- // wStartIndex = 0;
- // }
- // // 计算结束索引
- // if ((wTrackIndex + wGuardWidth + wTrackWindowWidth + 1) < PUB_SLOT_FRAME_LEN)
- // {
- // wStopIndex = wTrackIndex + wGuardWidth + wTrackWindowWidth + 1;
- // }
- // else
- // {
- // wStopIndex = PUB_SLOT_FRAME_LEN;
- // }
- // // 选左侧峰
- // // 选右侧峰
- // // 从定位数据中,在跟踪径左右两侧选峰
- // lct_firstpath_select_peak(pfData, fPeakValueThreshold, wMaxValueIndex, 1, wTrackIndex, wStartIndex, wStopIndex, pwPeakList, &wListLen);
- // // 跟踪径两侧未选到峰
- // if (!wListLen)
- // {
- // pwPeakList[0] = wTrackIndex;
- // wListLen++;
- // }
- // *pwPeakListLen = wListLen;
- // return;
- // }
- // 补偿跟踪窗口内的峰值增益
- // pfData:定位数据
- // pwPeakList:峰值索引队列
- // pwPeakListLen:峰值索引队列长度
- void lct_firstpath_compensate_peak_gain(flt32 *pfData, uint16 *pwPeakList, uint16 wPeakListLen)
- {
- uint16 wGuardWidth = gg_stFirstPathParam.wFirstPathTrackPeakGuardWidth; // 跟踪峰保护带宽
- uint16 wFindWidth = gg_stFirstPathParam.wFirstPathTrackNoiseFindWidth; // 补偿增益时噪声选择窗口宽度
- uint8 byPeakGainFactor = gg_stFirstPathParam.byFirstPathTrackPeakGainFactor; // 增益补偿因子
- flt32 fPeakRatio = 0; // 峰值比例
- uint16 wPeakValueIndex = 0;
- flt32 fPeakValue = 0;
- uint16 wStartIndex = 0;
- uint16 wStopIndex = 0;
- flt32 fNoiseValue = 0;
- flt32 fTmpValue = 0;
- // 遍历峰值队列,计算峰值补偿增益
- for (uint16 i = 0; i < wPeakListLen; i++)
- {
- wPeakValueIndex = pwPeakList[i];
- fPeakValue = pfData[wPeakValueIndex];
- fNoiseValue = 0;
- // 计算开始索引
- if ((wPeakValueIndex - wGuardWidth - wFindWidth) >= 0)
- {
- wStartIndex = wPeakValueIndex - wGuardWidth - wFindWidth;
- }
- else
- {
- wStartIndex = 0;
- }
- // 计算结束索引
- if ((wStartIndex + wFindWidth) <= (wPeakValueIndex - wGuardWidth))
- {
- wStopIndex = wStartIndex + wFindWidth;
- }
- else
- {
- wStopIndex = wPeakValueIndex - wGuardWidth;
- }
- // 查找噪声(wStartIndex 到 wStopIndex范围内的最大值)
- for (uint16 i = wStartIndex; i < wStopIndex; i++)
- {
- fTmpValue = pfData[i];
- if (fTmpValue > fNoiseValue)
- {
- fNoiseValue = fTmpValue;
- }
- }
- // 计算增益因子
- fPeakRatio = (fPeakValue / fNoiseValue * byPeakGainFactor) / 100;
- if (fPeakRatio > 1.2)
- {
- fPeakRatio = 1.2;
- }
- else if (fPeakRatio < 0.5)
- {
- fPeakRatio = 0.5;
- }
- // 补偿增益
- pfData[wPeakValueIndex] = fPeakValue * fPeakRatio;
- }
- return;
- }
- // 镜像当前第一径数据,以便一下次计算时使用
- void lct_firstpath_mirror_first_path_data(LCT_FIRSTPATH_LIST_T *pstFirstPathList, LCT_FIRSTPATH_LIST_T *pstAheadFirstPathList)
- {
- uint8 byCounter = pstFirstPathList->byBtsNum;
- // 镜像第一径数据
- for (uint8 i = 0; i < byCounter; i++)
- {
- memcpy(&pstAheadFirstPathList->astFirstPath[i], &pstFirstPathList->astFirstPath[i], sizeof(LCT_FIRSTPATH_T));
- }
- pstAheadFirstPathList->byBtsNum = byCounter;
- return;
- }
- // 反向镜像第一径数据(用前一次的第一径数据填充当前一次第一径数据)
- void lct_firstpath_demirror_first_path_data(LCT_FIRSTPATH_LIST_T *pstFirstPathList, LCT_FIRSTPATH_LIST_T *pstAheadFirstPathList)
- {
- uint8 byCounter = 0;
- byCounter = pstAheadFirstPathList->byBtsNum;
- // 镜像第一径数据
- for (uint8 i = 0; i < byCounter; i++)
- {
- memcpy(&pstFirstPathList->astFirstPath[i], &pstAheadFirstPathList->astFirstPath[i], sizeof(LCT_FIRSTPATH_T));
- pstFirstPathList->astFirstPath[i].dwCalPathIndex += PUB_SIGNAL_SAMPLE_RATIO;
- pstFirstPathList->astFirstPath[i].dwTrackPathIndex += PUB_SIGNAL_SAMPLE_RATIO;
- }
- pstFirstPathList->byBtsNum = byCounter;
- return;
- }
- // 从上一次第一径数据中获得当前需要跟踪的索引
- uint16 lct_firstpath_get_trackpath(LCT_FIRSTPATH_LIST_T *pstAheadFirstPathList, uint32 dwBuildId, uint32 dwLayerId, uint32 dwBtsId, uint8 byFreqIndex, uint8 bySlot)
- {
- uint8 byCounter = 0;
- uint32 dwTmpBuildId = 0;
- uint32 dwTmpLayerId = 0;
- uint32 dwTmpBtsId = 0;
- uint8 byTmpFreqIndex = 0;
- uint8 byTmpSlot = 0;
- uint16 wTrackIndex = 0;
- byCounter = pstAheadFirstPathList->byBtsNum;
- for (uint8 i = 0; i < byCounter; i++)
- {
- dwTmpBuildId = pstAheadFirstPathList->astFirstPath[i].dwBuildId;
- dwTmpLayerId = pstAheadFirstPathList->astFirstPath[i].dwLayerId;
- dwTmpBtsId = pstAheadFirstPathList->astFirstPath[i].dwBtsId;
- byTmpFreqIndex = pstAheadFirstPathList->astFirstPath[i].byFreqIndex;
- byTmpSlot = pstAheadFirstPathList->astFirstPath[i].bySlot;
- // 上一次第一径参数中有该基站
- if ((dwTmpBuildId == dwBuildId) && (dwTmpLayerId == dwLayerId) && (dwTmpBtsId == dwBtsId) && (byTmpFreqIndex == byFreqIndex) && (byTmpSlot == bySlot))
- {
- if (pstAheadFirstPathList->astFirstPath[i].wFrameTrackIndex)
- {
- wTrackIndex = pstAheadFirstPathList->astFirstPath[i].wFrameTrackIndex; // 上一次帧内跟踪索引
- }
- else
- {
- wTrackIndex = pstAheadFirstPathList->astFirstPath[i].wFrameCalIndex; // 上一次帧内计算索引
- }
- break;
- }
- }
- return wTrackIndex;
- }
- // 拷贝前一次第一径数据,本次bit表征值为0,则沿用前一次的第一径数据
- // pstFirstPath:第一径数据
- // pstAheadFirstPathList:前一次第一径数据
- // dwSyncOffset:同步偏移
- void lct_firstpath_copy_ahead_first_path(LCT_FIRSTPATH_T *pstFirstPath, uint32 dwLocationIndex, uint8 byCalSlot, LCT_FIRSTPATH_LIST_T *pstAheadFirstPathList)
- {
- uint8 byBtsNum = 0;
- LCT_FIRSTPATH_T stAheadFirstPath = {0};
- byBtsNum = pstAheadFirstPathList->byBtsNum;
- for (uint8 i = 0; i < byBtsNum; i++)
- {
- stAheadFirstPath = pstAheadFirstPathList->astFirstPath[i];
- if (pstFirstPath->dwBuildId == stAheadFirstPath.dwBuildId && pstFirstPath->dwLayerId == stAheadFirstPath.dwLayerId && pstFirstPath->dwBtsId == stAheadFirstPath.dwBtsId && pstFirstPath->byFreqIndex == stAheadFirstPath.byFreqIndex && pstFirstPath->bySlot == stAheadFirstPath.bySlot)
- {
- // 跟踪径有效,则用跟踪径
- if (stAheadFirstPath.wFrameTrackIndex > 0)
- {
- pstFirstPath->wFrameCalIndex = stAheadFirstPath.wFrameTrackIndex;
- pstFirstPath->wFrameTrackIndex = stAheadFirstPath.wFrameTrackIndex;
- pstFirstPath->dwCalPathIndex = dwLocationIndex + byCalSlot * PUB_SLOT_FRAME_LEN + stAheadFirstPath.wFrameTrackIndex;
- pstFirstPath->dwTrackPathIndex = dwLocationIndex + byCalSlot * PUB_SLOT_FRAME_LEN + stAheadFirstPath.wFrameTrackIndex;
- if (stAheadFirstPath.fTrackPathIndexSnr <= 0)
- {
- pstFirstPath->fCalPathIndexSnr = 3.5;
- pstFirstPath->fTrackPathIndexSnr = 3.5;
- }
- else
- {
- pstFirstPath->fCalPathIndexSnr = stAheadFirstPath.fTrackPathIndexSnr;
- pstFirstPath->fTrackPathIndexSnr = stAheadFirstPath.fTrackPathIndexSnr;
- }
- }
- // 跟踪径无效,则用计算径
- else
- {
- pstFirstPath->wFrameCalIndex = stAheadFirstPath.wFrameCalIndex;
- pstFirstPath->wFrameTrackIndex = stAheadFirstPath.wFrameCalIndex;
- pstFirstPath->dwCalPathIndex = dwLocationIndex + byCalSlot * PUB_SLOT_FRAME_LEN + stAheadFirstPath.wFrameCalIndex;
- pstFirstPath->dwTrackPathIndex = dwLocationIndex + byCalSlot * PUB_SLOT_FRAME_LEN + stAheadFirstPath.wFrameCalIndex;
- if (stAheadFirstPath.fCalPathIndexSnr <= 0)
- {
- pstFirstPath->fCalPathIndexSnr = 3.5;
- pstFirstPath->fTrackPathIndexSnr = 3.5;
- }
- else
- {
- pstFirstPath->fCalPathIndexSnr = stAheadFirstPath.fCalPathIndexSnr;
- pstFirstPath->fTrackPathIndexSnr = stAheadFirstPath.fCalPathIndexSnr;
- }
- }
- break;
- }
- }
- }
- // 所有基站拷贝前一次第一径数据,本次bit表征值为0,则沿用前一次的第一径数据
- // pstLocationDataList:定位数据队列
- // pstAheadFirstPathList:前一次第一径数据队列
- // pstFirstPathList:第一径数据队列(返回参数)
- void lct_firstpath_copy_ahead_first_path_for_all_bts(PUB_LOCATION_DATA_T *pstLocationDataList, LCT_FIRSTPATH_LIST_T *pstAheadFirstPathList, LCT_FIRSTPATH_LIST_T *pstFirstPathList)
- {
- uint8 byBtsNum = 0;
- LCT_FIRSTPATH_T *pstAheadFirstPath = NULL;
- LCT_FIRSTPATH_T *pstFirstPath = NULL;
- PUB_LOCATION_DATA_T *pstLctData = NULL;
- uint8 byIndex = 0;
- byBtsNum = pstAheadFirstPathList->byBtsNum;
- for (uint8 i = 0; i < byBtsNum; i++)
- {
- pstAheadFirstPath = &pstAheadFirstPathList->astFirstPath[i];
- byIndex = pstAheadFirstPath->byFreqIndex;
- pstLctData = &pstLocationDataList[byIndex];
- pstFirstPath = &pstFirstPathList->astFirstPath[i];
- memcpy(pstFirstPath, pstAheadFirstPath, sizeof(LCT_FIRSTPATH_T));
- // 跟踪径有效,则用跟踪径
- if (pstAheadFirstPath->wFrameTrackIndex > 0)
- {
- pstFirstPath->wFrameCalIndex = pstAheadFirstPath->wFrameTrackIndex;
- pstFirstPath->wFrameTrackIndex = pstAheadFirstPath->wFrameTrackIndex;
- pstFirstPath->dwCalPathIndex = pstLctData->dwLocationIndex + pstLctData->byCalSlot * PUB_SLOT_FRAME_LEN + pstAheadFirstPath->wFrameTrackIndex;
- pstFirstPath->dwTrackPathIndex = pstLctData->dwLocationIndex + pstLctData->byCalSlot * PUB_SLOT_FRAME_LEN + pstAheadFirstPath->wFrameTrackIndex;
- if (pstAheadFirstPath->fTrackPathIndexSnr <= 0)
- {
- pstFirstPath->fCalPathIndexSnr = 3.5;
- pstFirstPath->fTrackPathIndexSnr = 3.5;
- }
- else
- {
- pstFirstPath->fCalPathIndexSnr = pstAheadFirstPath->fTrackPathIndexSnr;
- pstFirstPath->fTrackPathIndexSnr = pstAheadFirstPath->fTrackPathIndexSnr;
- }
- }
- // 跟踪径无效,则用计算径
- else
- {
- pstFirstPath->wFrameCalIndex = pstAheadFirstPath->wFrameCalIndex;
- pstFirstPath->wFrameTrackIndex = pstAheadFirstPath->wFrameCalIndex;
- pstFirstPath->dwCalPathIndex = pstLctData->dwLocationIndex + pstLctData->byCalSlot * PUB_SLOT_FRAME_LEN + pstAheadFirstPath->wFrameCalIndex;
- pstFirstPath->dwTrackPathIndex = pstLctData->dwLocationIndex + pstLctData->byCalSlot * PUB_SLOT_FRAME_LEN + pstAheadFirstPath->wFrameCalIndex;
- if (pstAheadFirstPath->fCalPathIndexSnr <= 0)
- {
- pstFirstPath->fCalPathIndexSnr = 3.5;
- pstFirstPath->fTrackPathIndexSnr = 3.5;
- }
- else
- {
- pstFirstPath->fCalPathIndexSnr = pstAheadFirstPath->fCalPathIndexSnr;
- pstFirstPath->fTrackPathIndexSnr = pstAheadFirstPath->fCalPathIndexSnr;
- }
- }
- }
- pstFirstPathList->byBtsNum = byBtsNum;
- return;
- }
- // 重新计算绝对索引
- uint32 lct_firstpath_recal_absolute_index(uint32 dwOldIndex)
- {
- uint32 dwNewIndex = 0;
- if (dwOldIndex >= 0 && dwOldIndex < PUB_SLOT_FRAME_LEN)
- {
- dwNewIndex = dwOldIndex;
- }
- else if (dwOldIndex >= PUB_SLOT_FRAME_LEN && dwOldIndex < 2 * PUB_SLOT_FRAME_LEN)
- {
- dwNewIndex = dwOldIndex - PUB_SLOT_FRAME_LEN;
- }
- else if (dwOldIndex >= 2 * PUB_SLOT_FRAME_LEN && dwOldIndex < 3 * PUB_SLOT_FRAME_LEN)
- {
- dwNewIndex = dwOldIndex - 2 * PUB_SLOT_FRAME_LEN;
- }
- else if (dwOldIndex >= 3 * PUB_SLOT_FRAME_LEN && dwOldIndex < 4 * PUB_SLOT_FRAME_LEN)
- {
- dwNewIndex = dwOldIndex - 3 * PUB_SLOT_FRAME_LEN;
- }
- else
- {
- dwNewIndex = 0;
- }
- return dwNewIndex;
- }
- // 复位预测方向数据有效标识符
- // pstPredictionDirectionDataList:预测方向数据队列
- void lct_firstpath_reset_direction_valid_flag(LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList)
- {
- LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstData = NULL;
- for (uint8 i = 0; i < PUB_SYS_CARRIER_NUM; i++)
- {
- pstData = &pstPredictionDirectionDataList[i];
- pstData->byValidFlag = 0;
- }
- return;
- }
- // 保存第一径数据
- // pstLctData:定位数据
- // pstFirstPathData:第一径数据
- // pstPredictionDirectionDataList:预测方向数据队列,返回参数
- void lct_firstpath_save_first_path_data(PUB_LOCATION_DATA_T *pstLctData, LCT_FIRSTPATH_T *pstFirstPathData, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList)
- {
- uint8 byFreqIndex = 0;
- LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstResultData = NULL;
- uint32 dwBackupIndex = 0;
- byFreqIndex = pstLctData->byFreqIndex; // 频率索引
- pstResultData = &pstPredictionDirectionDataList[byFreqIndex]; // 预测方向的数据
- dwBackupIndex = pstResultData->dwFirstPathBackupIndex; // 数据备份索引
- if (dwBackupIndex < LCT_FIRST_PATH_BACKUP_NUM)
- {
- pstResultData->dwFirstPathBackupIndex++;
- pstResultData->astFirstPathBackupList[dwBackupIndex].dwFrameNo = pstLctData->dwFrameNo - 1; // 帧号
- pstResultData->astFirstPathBackupList[dwBackupIndex].fMaxAmplValue = pstFirstPathData->fMaxAmplValue; // 幅度
- pstResultData->astFirstPathBackupList[dwBackupIndex].dwCalPathIndex = pstFirstPathData->dwCalPathIndex; // 计算径
- pstResultData->astFirstPathBackupList[dwBackupIndex].dwTrackPathIndex = pstFirstPathData->dwTrackPathIndex; // 跟踪经
- }
- else
- {
- // 移动队列
- memmove(pstResultData->astFirstPathBackupList, &pstResultData->astFirstPathBackupList[1], sizeof(LCT_FIRSTPATH_BACKUP_T) * (LCT_FIRST_PATH_BACKUP_NUM - 1));
- // 保存数据
- dwBackupIndex = LCT_FIRST_PATH_BACKUP_NUM - 1;
- pstResultData->astFirstPathBackupList[dwBackupIndex].dwFrameNo = pstLctData->dwFrameNo - 1; // 帧号
- pstResultData->astFirstPathBackupList[dwBackupIndex].fMaxAmplValue = pstFirstPathData->fMaxAmplValue; // 幅度
- pstResultData->astFirstPathBackupList[dwBackupIndex].dwCalPathIndex = pstFirstPathData->dwCalPathIndex; // 计算径
- pstResultData->astFirstPathBackupList[dwBackupIndex].dwTrackPathIndex = pstFirstPathData->dwTrackPathIndex; // 跟踪经
- }
- pstResultData->dwCoordX = pstFirstPathData->dwCoordX;
- pstResultData->dwCoordY = pstFirstPathData->dwCoordY;
- pstResultData->dwCoordZ = pstFirstPathData->dwCoordZ;
- // 计算径
- pstResultData->dwCalPathIndex = pstFirstPathData->dwCalPathIndex;
- // 有效标识符置1
- pstResultData->byValidFlag = 1;
- }
- // 预测移动方向
- // pstPredictionDirectionDataList:预测方向的数据队列
- void lct_firstpath_prediction_move_direction(LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList)
- {
- LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionData = NULL;
- uint8 byLen = 0;
- LCT_FIRSTPATH_BACKUP_T *pstCurrentData = NULL; // 当前数据
- LCT_FIRSTPATH_BACKUP_T *pstAheadData = NULL; // 前一帧数据
- uint32 dwFrameGap = 0;
- uint8 byAheadTendency = 0;
- for (uint8 i = 0; i < PUB_SYS_CARRIER_NUM; i++)
- {
- pstPredictionData = &pstPredictionDirectionDataList[i];
- byAheadTendency = pstPredictionData->byDirectionTendency; // 保存上一次趋势
- pstPredictionData->byDirectionTendency = 0; // 方向趋势复位
- // 遍历方向数据队列
- byLen = pstPredictionData->dwFirstPathBackupIndex;
- if (byLen >= LCT_FIRST_PATH_BACKUP_NUM)
- {
- pstCurrentData = &pstPredictionData->astFirstPathBackupList[byLen - 1];
- pstAheadData = pstPredictionData->astFirstPathBackupList;
- dwFrameGap = pstCurrentData->dwFrameNo - pstAheadData->dwFrameNo;
- if (dwFrameGap == 8) // 数据有效
- {
- // 第一径维度靠近该基站
- if ((pstCurrentData->dwCalPathIndex <= pstAheadData->dwCalPathIndex) || (pstCurrentData->dwTrackPathIndex <= pstAheadData->dwTrackPathIndex))
- {
- pstPredictionData->byDirectionTendency = 1; // 靠近
- // 上一次是靠近该基站
- if (byAheadTendency == 1)
- {
- pstPredictionData->byDirectionTendency = 1; // 靠近
- }
- // 上一次是远离该基站
- else if (byAheadTendency == 2)
- {
- // 幅度维度靠近该基站
- if (pstCurrentData->fMaxAmplValue >= (0.85 * pstAheadData->fMaxAmplValue))
- {
- pstPredictionData->byDirectionTendency = 1; // 靠近
- }
- else
- {
- pstPredictionData->byDirectionTendency = 2; // 远离
- }
- }
- }
- // 第一径维度远离该基站
- else
- {
- pstPredictionData->byDirectionTendency = 2; // 远离
- // 上一次是靠近该基站
- if (byAheadTendency == 1)
- {
- // 幅度维度靠近该基站
- if (pstCurrentData->fMaxAmplValue >= (0.9 * pstAheadData->fMaxAmplValue))
- {
- pstPredictionData->byDirectionTendency = 1; // 靠近
- }
- else
- {
- pstPredictionData->byDirectionTendency = 2; // 远离
- }
- }
- // 上一次是远离该基站
- else if (byAheadTendency == 2)
- {
- pstPredictionData->byDirectionTendency = 2; // 远离
- }
- }
- }
- }
- }
- }
|