Browse Source

完善代码(完善手机移动方向预测代码,并将预测方向应用到二维定位中(利用预测方向修订第一径); 修改信号同步模块中的设计缺陷,解决轨迹跳变问题,改善了定位效果

zhoutao 15 hours ago
parent
commit
c013c162ab

+ 1 - 1
main.c

@@ -45,7 +45,7 @@ void main_read_wav()
 {
     // const char *pFileName = "E:\\work\\ips8000\\aplm8000sdk\\wave\\zcq(20251203-09).wav";
     //  const char *pFileName = "E:\\work\\ips8000\\aplm8000sdk\\wave\\rec5-0-5(0245)-btsx.wav";
-    const char *pFileName = "E:\\work\\ips8000\\aplm8000sdk\\wave\\zcq_6bts_rect_0327.wav";
+    const char *pFileName = "E:\\work\\ips8000\\aplm8000sdk\\wave\\zhoutao_6bts_rect_0327.wav";
     int16 *pwData = NULL; // 音频数据存储地址
     uint8 byIsOver = 0;
     uint16 wCounter = 0;

+ 2 - 2
src/modules/basestation/bts_ampl.c

@@ -221,7 +221,7 @@ void bts_ampl_check_freq_valid(PUB_LOCATION_DATA_T *pstLocationData, BTS_AMPL_MI
     // 上一秒信号有效,则判断大值索引差值来检验当前信号是否有效
     if (pstLocationData->byCurrentAmplValidFlag)
     {
-        if (fMaxValue > 500 && fMaxValue > (0.10 * fAheadAmpl) && fSnr > 5)
+        if (fMaxValue > BTS_AMPL_BTS_AMPL_VALID_THRESHOLD && fMaxValue > (0.10 * fAheadAmpl) && fSnr > BTS_AMPL_BTS_SNR_VALID_THRESHOLD)
         {
             pstLocationData->byCurrentAmplValidFlag = 1;
             pstBtsAmplMirrorData->byAmplValidTimes++;
@@ -235,7 +235,7 @@ void bts_ampl_check_freq_valid(PUB_LOCATION_DATA_T *pstLocationData, BTS_AMPL_MI
     else
     {
         // 通过幅度判断基站是否有效,信号幅度绝对值大于500
-        if (fMaxValue > 500 && fSnr > 5)
+        if (fMaxValue > BTS_AMPL_BTS_AMPL_VALID_THRESHOLD && fSnr > BTS_AMPL_BTS_SNR_VALID_THRESHOLD)
         {
             pstLocationData->byCurrentAmplValidFlag = 1;
             pstBtsAmplMirrorData->byAmplValidTimes++;

+ 1 - 6
src/modules/basestation/bts_main.c

@@ -9,9 +9,7 @@
 // 定义在本模块使用的全局变量
 BTS_AMPL_MIRROR_DATA_T gBts_astBtsAmplMirrorDataList[PUB_SYS_CARRIER_NUM] = {0}; // 基站幅度镜像数据队列
 BTS_MAX_AMPL_DATA_T gBts_astBtsMaxAmplDataList[PUB_SYS_CARRIER_NUM] = {0};       // 基站最大幅度数据队列
-
-BTS_ID_JUDGEMENT_MAIN_BTS_T gBts_stJudgementMainBtsList = {0}; // 计算主站
-int32 *gBts_pstInstallBtsList = NULL;                          // 本地基站组
+int32 *gBts_pstInstallBtsList = NULL;                                            // 本地基站组
 
 // 导出全局变量
 extern PUB_SYS_STATUS_T gg_stSysStatus;
@@ -26,11 +24,8 @@ void bts_main_init()
     {
         gBts_astBtsAmplMirrorDataList[i].byFreqIndex = i;
     }
-
     memset(gBts_astBtsMaxAmplDataList, 0, sizeof(BTS_MAX_AMPL_DATA_T) * PUB_SYS_CARRIER_NUM);
 
-    memset(&gBts_stJudgementMainBtsList, 0, sizeof(BTS_ID_JUDGEMENT_MAIN_BTS_T));
-
     // 申请一片内存,供JS模块写入数据
     gBts_pstInstallBtsList = malloc(sizeof(BTS_INSTALL_BTS_LIST_T));
     memset(gBts_pstInstallBtsList, 0, sizeof(BTS_INSTALL_BTS_LIST_T));

+ 172 - 169
src/modules/basestation/bts_sync.c

@@ -35,11 +35,6 @@ void bts_sync_main(PUB_LOCATION_DATA_T *pstLocationDataList, BTS_AMPL_MIRROR_DAT
     uint32 dwFrameNo = 0;  // 当前帧号
     uint8 byRemainder = 0; // 取模余数
 
-    if (gg_dwFrameNo > 128)
-    {
-        uint8 byTmp = 0;
-    }
-
     // 该帧不需要任何处理
     dwFrameNo = gg_dwFrameNo - 1;
     if (dwFrameNo <= 0)
@@ -76,19 +71,22 @@ void bts_sync_main(PUB_LOCATION_DATA_T *pstLocationDataList, BTS_AMPL_MIRROR_DAT
                             bts_sync_cal_signal_slot(byMainBtsSlot, dwMainBtsSyncIndex, gg_stSysStatus.abySlotList);
                         }
 
-                        // 基站时隙同步(同步到0号时隙)
+                        // 计算基站时隙同步偏移(同步到0号时隙)
                         bts_sync_cal_slot_sync_offset(gg_stSysStatus.abySlotList, byMainBtsSlot, &bySlotOffset);
                         pstLocationData->dwSignalSlotSyncOffset = bySlotOffset * PUB_SLOT_FRAME_LEN; // 时隙同步
 
-                        // 基站位同步
-                        bts_sync_bts_bit_sync(pstLocationData, dwMainBtsSyncIndex, gg_stSysStatus.abySlotList);
+                        // 计算主站同步索引
+                        dwMainBtsSyncIndex = bts_sync_cal_main_bts_sync_index(byMainBtsSlot, pstBtsMaxAmplData->wMaxValueIndex, gg_stSysStatus.abySlotList);
+
+                        // 配置基站信号同步
+                        bts_sync_set_bts_signal_sync(pstLocationData, dwMainBtsSyncIndex);
 
                         byMainFlag = 1; // 主站找到了
                     }
                     // 从站(从站跟随主站同步)
                     else
                     {
-                        // 基站时隙同步(同步到0号时隙)
+                        // 计算基站时隙同步偏移(同步到0号时隙)
                         bySlaveBtsSlot = pstLocationData->bySetSlot; // 从站配置时隙
                         bts_sync_cal_slot_sync_offset(gg_stSysStatus.abySlotList, bySlaveBtsSlot, &bySlotOffset);
                         pstLocationData->dwSignalSlotSyncOffset = bySlotOffset * PUB_SLOT_FRAME_LEN; // 时隙同步
@@ -97,8 +95,8 @@ void bts_sync_main(PUB_LOCATION_DATA_T *pstLocationDataList, BTS_AMPL_MIRROR_DAT
                         pstBtsAmplMirrorData = (BTS_AMPL_MIRROR_DATA_T *)&pstBtsAmplMirrorDataList[byFreqIndex]; // 基站幅度镜像数据
                         dwSlaveBtsSyncIndex = bts_sync_cal_slave_bts_sync_index(pstLocationData, byMainBtsSlot, dwMainBtsSyncIndex, gg_stSysStatus.abySlotList, pstBtsAmplMirrorData->afMultiSecondData);
 
-                        // 基站位同步
-                        bts_sync_bts_bit_sync(pstLocationData, dwSlaveBtsSyncIndex, gg_stSysStatus.abySlotList);
+                        // 配置基站信号同步
+                        bts_sync_set_bts_signal_sync(pstLocationData, dwSlaveBtsSyncIndex);
                     }
                 }
             }
@@ -143,7 +141,7 @@ void bts_sync_check_valid_bts(BTS_MAX_AMPL_DATA_T *pstBtsMaxAmplDataList, uint8
     *pbyValidFlag = 0;
     for (uint8 i = 0; i < PUB_SYS_CARRIER_NUM; i++)
     {
-        // 基站幅度大于主站幅度有效门限
+        // 基站幅度大于主站幅度有效门限,表示当前手机靠近某个基站
         if (pstBtsMaxAmplDataList[i].fMaxValue > BTS_AMPL_MAIN_BTS_AMPL_VALID_THRESHOLD)
         {
             *pbyValidFlag = 1;
@@ -154,125 +152,6 @@ void bts_sync_check_valid_bts(BTS_MAX_AMPL_DATA_T *pstBtsMaxAmplDataList, uint8
     return;
 }
 
-// 计算从站信号同步索引
-int32 bts_sync_cal_slave_bts_sync_index(PUB_LOCATION_DATA_T *pstLocationData, uint8 byMainBtsSlot, int32 dwMainBtsSyncIndex, uint8 *pbySignalSoltList, flt32 *pfData)
-{
-    int32 dwSlaveBtsSyncIndex = 0;
-    uint8 bySlaveBtsSlot = pstLocationData->bySetSlot; // 从站配置时隙
-
-    uint8 byMainBtsSlotIndex = 0;
-    uint8 bySlaveBtsSlotIndex = 0;
-    int8 bySlotGap = 0; // 主从站时隙间隔
-
-    flt32 *pfHead = NULL; // 数据头指针
-    int32 dwSlaveBtsStartIndex = 0;
-    uint8 byBackFlag = 0; // 掉头标识符,0:无掉头,1:有掉头
-
-    flt32 fTmpValue = 0;
-    flt32 fMaxValue = 0;
-    uint16 wSlaveBtsMaxValueIndex = 0;
-
-    // 该基站是定位基站,并且该基站有效
-    if (pstLocationData->byLctBtsFlag && pstLocationData->byBtsValidFlag)
-    {
-        // 从站时隙不合法
-        if (bySlaveBtsSlot == PUB_SYS_SLOT_NUM)
-        {
-            bySlaveBtsSlot = byMainBtsSlot;
-        }
-
-        // 抽取时隙索引
-        for (uint8 i = 0; i < PUB_SYS_SLOT_NUM; i++)
-        {
-            if (pbySignalSoltList[i] == byMainBtsSlot)
-            {
-                byMainBtsSlotIndex = i;
-                if (byMainBtsSlot == bySlaveBtsSlot)
-                {
-                    bySlaveBtsSlotIndex = i;
-                    break;
-                }
-            }
-            else if (pbySignalSoltList[i] == bySlaveBtsSlot)
-            {
-                bySlaveBtsSlotIndex = i;
-            }
-        }
-
-        // 从站相对于主站的偏移量
-        bySlotGap = bySlaveBtsSlotIndex - byMainBtsSlotIndex;
-
-        // 1、计算从站同步索引
-        //  主站从站时隙相同
-        if (bySlaveBtsSlot == byMainBtsSlot)
-        {
-            dwSlaveBtsStartIndex = dwMainBtsSyncIndex;
-        }
-        // 主站从站时隙不同
-        else
-        {
-            dwSlaveBtsStartIndex = dwMainBtsSyncIndex + bySlotGap * PUB_SLOT_FRAME_LEN;
-            if (dwSlaveBtsStartIndex >= PUB_SIGNAL_SAMPLE_RATIO)
-            {
-                dwSlaveBtsStartIndex = dwSlaveBtsStartIndex % PUB_SIGNAL_SAMPLE_RATIO;
-            }
-            else if (dwSlaveBtsStartIndex < 0)
-            {
-                dwSlaveBtsStartIndex = PUB_SIGNAL_SAMPLE_RATIO + dwSlaveBtsStartIndex;
-            }
-        }
-
-        ////3、 查找信号的最大值索引
-        pfHead = &pfData[dwSlaveBtsStartIndex]; // 数据头指针
-        for (uint16 i = 0; i < PUB_SLOT_FRAME_LEN; i++)
-        {
-            if (dwSlaveBtsStartIndex >= PUB_SIGNAL_SAMPLE_RATIO)
-            {
-                dwSlaveBtsStartIndex = 0;
-                pfHead = &pfData[dwSlaveBtsStartIndex]; // 数据指针归0
-                byBackFlag = 1;                         // 数据掉头
-            }
-
-            fTmpValue = *pfHead;
-            if (fTmpValue > fMaxValue)
-            {
-                fMaxValue = fTmpValue;
-                wSlaveBtsMaxValueIndex = dwSlaveBtsStartIndex;
-            }
-
-            pfHead++;
-            dwSlaveBtsStartIndex++;
-        }
-
-        //// 计算从站位同步索引
-        // 队列未掉头
-        if (!byBackFlag)
-        {
-            dwSlaveBtsSyncIndex = wSlaveBtsMaxValueIndex - PUB_SYNC_INDEX_OFFSET_NUM;
-        }
-        // 队列有调头
-        else
-        {
-            // 最大值跑到了队列前侧
-            if (bySlaveBtsSlotIndex == 3 && wSlaveBtsMaxValueIndex < PUB_SLOT_FRAME_LEN)
-            {
-                dwSlaveBtsSyncIndex = PUB_SIGNAL_SAMPLE_RATIO + wSlaveBtsMaxValueIndex - PUB_SYNC_INDEX_OFFSET_NUM;
-            }
-            else
-            {
-                dwSlaveBtsSyncIndex = wSlaveBtsMaxValueIndex - PUB_SYNC_INDEX_OFFSET_NUM;
-            }
-        }
-    }
-    // 基站无效,跟随主站调整
-    else
-    {
-        dwSlaveBtsSyncIndex = dwMainBtsSyncIndex;
-    }
-
-    return dwSlaveBtsSyncIndex;
-}
-
 // 解算信号时隙
 // byMainBtsSetSlot:主站配置时隙
 // dwMainBtsFrameStartIndex:主站信号帧开始索引
@@ -458,6 +337,166 @@ void bts_sync_cal_signal_slot(uint8 byMainBtsSetSlot, int32 dwMainBtsFrameStartI
     }
 }
 
+// 计算主站信号同步索引
+// byMainBtsSetSlot:主站配置时隙
+// dwMainBtsMaxIndex:主站最值大值索引
+// pbySignalSoltList:信号时隙队列
+int32 bts_sync_cal_main_bts_sync_index(uint8 byMainBtsSetSlot, int32 dwMainBtsMaxIndex, uint8 *pbySignalSoltList)
+{
+    uint8 byMainBtsSlotIndex = 0;
+    int32 dwMainBtsSyncIndex = dwMainBtsMaxIndex - PUB_SYNC_INDEX_OFFSET_NUM;
+
+    // 抽取时隙索引
+    for (uint8 i = 0; i < PUB_SYS_SLOT_NUM; i++)
+    {
+        if (pbySignalSoltList[i] == byMainBtsSetSlot)
+        {
+            byMainBtsSlotIndex = i;
+            break;
+        }
+    }
+
+    //// 计算主站信号同步索引
+    // 信号在0号时隙上
+    if (byMainBtsSlotIndex == 0)
+    {
+        if (dwMainBtsMaxIndex > 3 * PUB_SLOT_FRAME_LEN)
+        {
+            // 修正主站信号同步索引
+            dwMainBtsSyncIndex = PUB_SIGNAL_SAMPLE_RATIO - dwMainBtsMaxIndex - PUB_SYNC_INDEX_OFFSET_NUM;
+        }
+    }
+    // 信号在3号时隙上
+    else if (byMainBtsSlotIndex == (PUB_SYS_SLOT_NUM - 1))
+    {
+        if (dwMainBtsMaxIndex < PUB_SLOT_FRAME_LEN)
+        {
+            // 修正主站信号同步索引
+            dwMainBtsSyncIndex = PUB_SIGNAL_SAMPLE_RATIO + dwMainBtsMaxIndex - PUB_SYNC_INDEX_OFFSET_NUM;
+        }
+    }
+
+    return dwMainBtsSyncIndex;
+}
+
+// 计算从站信号同步索引
+int32 bts_sync_cal_slave_bts_sync_index(PUB_LOCATION_DATA_T *pstLocationData, uint8 byMainBtsSlot, int32 dwMainBtsSyncIndex, uint8 *pbySignalSoltList, flt32 *pfData)
+{
+    int32 dwSlaveBtsSyncIndex = 0;                     // 从站信号同步索引
+    uint8 bySlaveBtsSlot = pstLocationData->bySetSlot; // 从站配置时隙
+
+    uint8 byMainBtsSlotIndex = 0;
+    uint8 bySlaveBtsSlotIndex = 0;
+    int8 bySlotGap = 0; // 主从站时隙间隔
+
+    flt32 *pfHead = NULL; // 数据头指针
+    int32 dwSlaveBtsStartIndex = 0;
+
+    flt32 fTmpValue = 0;
+    flt32 fMaxValue = 0;
+    uint16 wSlaveBtsMaxValueIndex = 0;
+
+    // 该基站是定位基站,并且该基站有效
+    if (pstLocationData->byLctBtsFlag && pstLocationData->byBtsValidFlag)
+    {
+        // 从站时隙不合法
+        if (bySlaveBtsSlot == PUB_SYS_SLOT_NUM)
+        {
+            bySlaveBtsSlot = byMainBtsSlot;
+        }
+
+        // 抽取时隙索引
+        for (uint8 i = 0; i < PUB_SYS_SLOT_NUM; i++)
+        {
+            if (pbySignalSoltList[i] == byMainBtsSlot)
+            {
+                byMainBtsSlotIndex = i;
+                if (byMainBtsSlot == bySlaveBtsSlot)
+                {
+                    bySlaveBtsSlotIndex = i;
+                    break;
+                }
+            }
+            else if (pbySignalSoltList[i] == bySlaveBtsSlot)
+            {
+                bySlaveBtsSlotIndex = i;
+            }
+        }
+
+        // 从站相对于主站的时隙偏移量
+        bySlotGap = bySlaveBtsSlotIndex - byMainBtsSlotIndex;
+
+        // 1、计算从站同步索引
+        //  主站从站时隙相同
+        if (bySlaveBtsSlot == byMainBtsSlot)
+        {
+            dwSlaveBtsStartIndex = dwMainBtsSyncIndex;
+        }
+        // 主站从站时隙不同
+        else
+        {
+            dwSlaveBtsStartIndex = dwMainBtsSyncIndex + bySlotGap * PUB_SLOT_FRAME_LEN;
+            if (dwSlaveBtsStartIndex >= PUB_SIGNAL_SAMPLE_RATIO)
+            {
+                dwSlaveBtsStartIndex = dwSlaveBtsStartIndex % PUB_SIGNAL_SAMPLE_RATIO;
+            }
+            else if (dwSlaveBtsStartIndex < 0)
+            {
+                dwSlaveBtsStartIndex = PUB_SIGNAL_SAMPLE_RATIO + dwSlaveBtsStartIndex;
+            }
+        }
+
+        ////3、 查找信号的最大值索引
+        pfHead = &pfData[dwSlaveBtsStartIndex]; // 数据头指针
+        for (uint16 i = 0; i < PUB_SLOT_FRAME_LEN; i++)
+        {
+            if (dwSlaveBtsStartIndex >= PUB_SIGNAL_SAMPLE_RATIO)
+            {
+                dwSlaveBtsStartIndex = 0;
+                pfHead = &pfData[dwSlaveBtsStartIndex]; // 数据指针归0
+            }
+
+            fTmpValue = *pfHead;
+            if (fTmpValue > fMaxValue)
+            {
+                fMaxValue = fTmpValue;
+                wSlaveBtsMaxValueIndex = dwSlaveBtsStartIndex;
+            }
+
+            pfHead++;
+            dwSlaveBtsStartIndex++;
+        }
+
+        //// 计算从站信号同步索引
+        dwSlaveBtsSyncIndex = wSlaveBtsMaxValueIndex - PUB_SYNC_INDEX_OFFSET_NUM;
+        // 信号在0号时隙上
+        if (bySlaveBtsSlotIndex == 0)
+        {
+            if (wSlaveBtsMaxValueIndex > 3 * PUB_SLOT_FRAME_LEN)
+            {
+                // 修正从站信号同步索引
+                dwSlaveBtsSyncIndex = PUB_SIGNAL_SAMPLE_RATIO - wSlaveBtsMaxValueIndex - PUB_SYNC_INDEX_OFFSET_NUM;
+            }
+        }
+        // 信号在3号时隙上
+        else if (bySlaveBtsSlotIndex == (PUB_SYS_SLOT_NUM - 1))
+        {
+            if (wSlaveBtsMaxValueIndex < PUB_SLOT_FRAME_LEN)
+            {
+                // 修正从站信号同步索引
+                dwSlaveBtsSyncIndex = PUB_SIGNAL_SAMPLE_RATIO + wSlaveBtsMaxValueIndex - PUB_SYNC_INDEX_OFFSET_NUM;
+            }
+        }
+    }
+    // 基站无效,跟随主站调整
+    else
+    {
+        dwSlaveBtsSyncIndex = dwMainBtsSyncIndex;
+    }
+
+    return dwSlaveBtsSyncIndex;
+}
+
 // 计算基站时隙同步偏移(相对于0号时隙的偏移)
 // pbySignalSoltList:信号时隙队列
 // byBtsSetSlot:基站配置时隙
@@ -489,49 +528,13 @@ void bts_sync_cal_slot_sync_offset(uint8 *pbySignalSoltList, uint8 byBtsSetSlot,
     *pbySlotOffset = byZeroSlotIndex - byBtsSlotIndex; // 相对于0号时隙的偏移
 }
 
-// 基站位同步
+// 配置基站信号同步
 // pstLocationData:定位数据
 // wBtsSyncIndex:基站同步索引
-void bts_sync_bts_bit_sync(PUB_LOCATION_DATA_T *pstLocationData, int32 dwBtsSyncIndex, uint8 *pbySignalSlotList)
+void bts_sync_set_bts_signal_sync(PUB_LOCATION_DATA_T *pstLocationData, int32 dwBtsSyncIndex)
 {
-    // uint8 bySlotIndex = 0;
     int32 dwSyncOffset = 0; // 同步偏移
 
-    // // 查找时隙索引
-    // for (uint8 i = 0; i < PUB_SYS_SLOT_NUM; i++)
-    // {
-    //     if (pbySignalSlotList[i] == pstLocationData->bySetSlot)
-    //     {
-    //         bySlotIndex = i;
-    //         break;
-    //     }
-    // }
-
-    // // 时隙在队列头上
-    // if (bySlotIndex == 0)
-    // {
-    //     // 时隙跑到了队尾
-    //     if (dwBtsSyncIndex > 12000)
-    //     {
-    //         dwBtsSyncIndex = -(PUB_SIGNAL_SAMPLE_RATIO - dwBtsSyncIndex - 1);
-    //     }
-    // }
-    // else if (bySlotIndex == 3)
-    // {
-    //     // 跑到了队列头
-    //     if (dwBtsSyncIndex < 12000)
-    //     {
-    //         if (dwBtsSyncIndex >= 0)
-    //         {
-    //             dwBtsSyncIndex = PUB_SIGNAL_SAMPLE_RATIO + abs(dwBtsSyncIndex) - PUB_SLOT_FRAME_LEN;
-    //         }
-    //         else
-    //         {
-    //             dwBtsSyncIndex = PUB_SIGNAL_SAMPLE_RATIO + abs(dwBtsSyncIndex) - PUB_SLOT_FRAME_LEN;
-    //         }
-    //     }
-    // }
-
     // 计算信号偏移量(第二个同步周期后方可计算同步偏移)
     if (pstLocationData->dwFrameNo > (BTS_SYNC_STABLE_SYNC_FRAMES + 1))
     {

+ 2 - 1
src/modules/basestation/bts_sync.h

@@ -15,7 +15,8 @@ void bts_sync_main(PUB_LOCATION_DATA_T *pstLocationDataList, BTS_AMPL_MIRROR_DAT
 void bts_sync_check_valid_bts(BTS_MAX_AMPL_DATA_T *pstBtsMaxAmplDataList, uint8 *pbyValidFlag);
 void bts_sync_cal_signal_slot(uint8 byMainBtsSetSlot, int32 dwMainBtsFrameStartIndex, uint8 *pbySignalSlotList);
 void bts_sync_cal_slot_sync_offset(uint8 *pbySignalSoltList, uint8 byBtsSetSlot, int8 *pbySlotOffset);
+int32 bts_sync_cal_main_bts_sync_index(uint8 byMainBtsSetSlot, int32 dwMainBtsMaxIndex, uint8 *pbySignalSoltList);
 int32 bts_sync_cal_slave_bts_sync_index(PUB_LOCATION_DATA_T *pstLocationData, uint8 byMainBtsSlot, int32 dwMainBtsSyncIndex, uint8 *pbySignalSoltList, flt32 *pfData);
-void bts_sync_bts_bit_sync(PUB_LOCATION_DATA_T *pstLocationData, int32 dwBtsSyncIndex, uint8 *pbySignalSlotList);
+void bts_sync_set_bts_signal_sync(PUB_LOCATION_DATA_T *pstLocationData, int32 dwBtsSyncIndex);
 
 #endif

+ 879 - 233
src/modules/location/lct_coordcal.c

@@ -54,12 +54,14 @@ void lct_coordcal_init(LCT_COORDCAL_PARAM_T stLctCoordcalParam)
 }
 
 // 计算定位点坐标
+// pstLctBtsList:定位基站队列
+// pstLctDataList:定位数据队列
 // pstFirstPathList:第一径数据队列
 // pbyPredictionFlag:预测标识符,0:预测失败,1:预测成功
 // pstPredictionCoord:预测坐标
 // pstMinimumValueGroup:极小值数据组(返回参数)
 // pwMinmumValueNum:极小值数量
-void lct_coordcal_main(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T *pstFirstPathList, uint8 *pbyPredictionFlag, COORD_T *pstPredictionCoord, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueGroup, uint16 *pwMinmumValueNum)
+void lct_coordcal_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T *pstFirstPathList, uint8 *pbyPredictionFlag, COORD_T *pstPredictionCoord, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueGroup, uint16 *pwMinmumValueNum)
 {
     LCT_FIRSTPATH_T *pstFirstPathDataList = pstFirstPathList->astFirstPath; // 第一径队列
     uint8 byFirstPathDataListLen = pstFirstPathList->byBtsNum;              // 第一径队列长度
@@ -76,18 +78,19 @@ void lct_coordcal_main(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T
     uint8 byPredictionFlag = 0; // 预测成功标识符
     COORD_T stPredictionCoord = {0};
     COORD_T stAheadPointCoord = {0};
+    uint8 byChangeXY = 0; // 在XY轴上变化大小趋势,1:X轴变化大,2:Y轴变化大
 
     LCT_MINIMUM_VALUE_GROUP_T stMinmumValueGroup = {0}; // 极小值点组
     uint16 wMinmumValueNum = 0;                         // 极小值个数
 
-    // 选择有效基站(过滤第一径跳变和信噪比差的基站)
-    lct_coordcal_sel_valid_bts(pstLctDataList, pstFirstPathDataList, byFirstPathDataListLen, astValidCalPathBtsList, &byValidCalPathBtsListLen, astValidTrackPathBtsList, &byValidTrackPathBtsListLen, &dwBuildId, &dwLayerId);
+    // 根据第一径和幅度选择有效基站(过滤第一径跳变和信噪比差的基站)
+    lct_coordcal_select_valid_bts_by_fp_and_ampl(pstLctDataList, pstFirstPathDataList, byFirstPathDataListLen, astValidCalPathBtsList, &byValidCalPathBtsListLen, astValidTrackPathBtsList, &byValidTrackPathBtsListLen, &dwBuildId, &dwLayerId);
 
     // 预测定位坐标
     gLct_dwSpeedX = 0; // x轴移动速度
     gLct_dwSpeedY = 0; // y轴移动速度
     // lct_coordcal_prediction_coord(&stPredictionCoord, &byPredictionFlag, &stAheadPointCoord, dwBuildId, dwLayerId);
-    lct_prediction_current_coord_by_history(dwBuildId, dwLayerId, &stPredictionCoord, &byPredictionFlag, &stAheadPointCoord, &gLct_dwSpeedX, &gLct_dwSpeedY);
+    lct_prediction_current_coord_by_history(dwBuildId, dwLayerId, &stPredictionCoord, &byPredictionFlag, &stAheadPointCoord, &gLct_dwSpeedX, &gLct_dwSpeedY, &byChangeXY);
 
     // // 修正预测坐标
     // if (byPredictionFlag)
@@ -97,8 +100,8 @@ void lct_coordcal_main(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T
     //     *pstPredictionCoord = stPredictionCoord;
     // }
 
-    // TODO 预测手机相对于基站的运动趋势(未调试成功)
-    //  lct_prediction_prediction_phone_move_tendency(gLct_astPredictionDirectionDataList);
+    // 预测手机相对于基站的移动趋势,1:靠近趋势,2:远离趋势,0:趋势不确定
+    lct_prediction_prediction_phone_move_tendency(gLct_astPredictionDirectionDataList);
 
     // 预测定位坐标失败
     if (!byPredictionFlag)
@@ -111,9 +114,9 @@ void lct_coordcal_main(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T
 
         ////2维定位
         // 计算径
-        lct_coordcal_two_dimension_location(astValidCalPathBtsList, byValidCalPathBtsListLen, byPredictionFlag, stPredictionCoord, CAL_PATH, &stMinmumValueGroup);
+        lct_coordcal_two_dimension_location(pstLctBtsList, astValidCalPathBtsList, byValidCalPathBtsListLen, byPredictionFlag, stPredictionCoord, CAL_PATH, &stMinmumValueGroup);
         // 跟踪径
-        lct_coordcal_two_dimension_location(astValidTrackPathBtsList, byValidTrackPathBtsListLen, byPredictionFlag, stPredictionCoord, TRACK_PATH, &stMinmumValueGroup);
+        lct_coordcal_two_dimension_location(pstLctBtsList, astValidTrackPathBtsList, byValidTrackPathBtsListLen, byPredictionFlag, stPredictionCoord, TRACK_PATH, &stMinmumValueGroup);
     }
     // 预测定位坐标成功
     else
@@ -127,7 +130,7 @@ void lct_coordcal_main(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T
         // 预测手机分别在x轴和y轴上的移动方向
         gLct_byDirectionX = 0; // x轴移动方向,1:向右移动,-1向左移动
         gLct_byDirectionY = 0; // y轴移动方向,1:向上移动,-1向下移动
-        lct_coordcal_prediction_x_y_move_direction(pstFirstPathDataList, byFirstPathDataListLen, gLct_astPredictionDirectionDataList, &gLct_byDirectionX, &gLct_byDirectionY);
+        lct_coordcal_prediction_x_y_move_direction(pstFirstPathDataList, byFirstPathDataListLen, gLct_astPredictionDirectionDataList, &stAheadPointCoord, byChangeXY, &gLct_byDirectionX, &gLct_byDirectionY);
         // lct_prediction_prediction_phone_x_y_move_direction(gLct_astPredictionDirectionDataList, stAheadPointCoord, &gLct_byDirectionX, &gLct_byDirectionY);
 
         // 根据手机移动方向修正预测坐标
@@ -141,12 +144,14 @@ void lct_coordcal_main(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T
 
         ////二维定位
         // 计算径
-        lct_coordcal_two_dimension_location(astValidCalPathBtsList, byValidCalPathBtsListLen, byPredictionFlag, stPredictionCoord, 0, &stMinmumValueGroup);
+        lct_coordcal_check_valid_bts_by_move_direction(CAL_PATH, astValidCalPathBtsList, byValidCalPathBtsListLen, pstLctDataList, &stAheadPointCoord, byChangeXY, gLct_byDirectionX, gLct_byDirectionY, &byValidCalPathBtsListLen);
+        lct_coordcal_two_dimension_location(pstLctBtsList, astValidCalPathBtsList, byValidCalPathBtsListLen, byPredictionFlag, stPredictionCoord, 0, &stMinmumValueGroup);
         // 跟踪径
-        lct_coordcal_two_dimension_location(astValidTrackPathBtsList, byValidTrackPathBtsListLen, byPredictionFlag, stPredictionCoord, 1, &stMinmumValueGroup);
+        lct_coordcal_check_valid_bts_by_move_direction(TRACK_PATH, astValidTrackPathBtsList, byValidTrackPathBtsListLen, pstLctDataList, &stAheadPointCoord, byChangeXY, gLct_byDirectionX, gLct_byDirectionY, &byValidTrackPathBtsListLen);
+        lct_coordcal_two_dimension_location(pstLctBtsList, astValidTrackPathBtsList, byValidTrackPathBtsListLen, byPredictionFlag, stPredictionCoord, 1, &stMinmumValueGroup);
 
-        // 校验二维定位的极小值
-        lct_coordcal_two_dimension_check(&stMinmumValueGroup, &stPredictionCoord, &stAheadPointCoord, gLct_byDirectionX, gLct_byDirectionY);
+        // TODO 校验二维定位的极小值
+        lct_coordcal_two_dimension_check(&stMinmumValueGroup, &stPredictionCoord, &stAheadPointCoord, byChangeXY, gLct_byDirectionX, gLct_byDirectionY);
     }
 
     // 没有极小值,则使用预测坐标
@@ -167,13 +172,13 @@ void lct_coordcal_main(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T
     return;
 }
 
-// 生成基站可用列表(去除第一径有跳变情况的基站,前后两次第一径索引差超过跳变门限即为跳变,该基站不可用)
+// 根据第一径和幅度选择有效基站列表(去除第一径有跳变情况的基站,前后两次第一径索引差超过跳变门限即为跳变,该基站不可用)
 // pstFirstPathList:第一径参数列表
 // byFirstPathListLen:第一径参数列表长度
 // pstValidBtsList:有效基站第一径参数列表(返回参数)
 // pbyValidBtsListLen:有效基站参数列表长度(返回参数)
 // 返回值,1:成功,0:失败
-void lct_coordcal_sel_valid_bts(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_T *pstValidCalBtsList, uint8 *pbyValidCalBtsListLen, LCT_FIRSTPATH_T *pstValidTrackBtsList, uint8 *pbyValidTrackBtsListLen, int32 *pdwBulidId, int32 *pdwLayerId)
+void lct_coordcal_select_valid_bts_by_fp_and_ampl(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_T *pstValidCalBtsList, uint8 *pbyValidCalBtsListLen, LCT_FIRSTPATH_T *pstValidTrackBtsList, uint8 *pbyValidTrackBtsListLen, int32 *pdwBulidId, int32 *pdwLayerId)
 {
     LCT_FIRSTPATH_T stBtsFirstPath = {0};
     LCT_FIRSTPATH_T *pststBtsFirstPath = NULL;
@@ -357,6 +362,311 @@ void lct_coordcal_sel_valid_bts(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPA
     return;
 }
 
+// 根据移动方向校验有效绩效
+// byFirstPathType:第一径类型
+// pstValidBtsList:有效基站队列
+// byValidBtsListLen:有效基站队列长度
+// pstAheadCoord:前一点定位坐标
+// byChangeXY:在XY轴上变化大小趋势,1:X轴变化大,2:Y轴变化大
+// byDirectionX:在X轴上的移动方向,1:向右,-1:向左
+// byDirectionY:在Y轴上的移动方向,1:向上,-1:向下
+// pbyValidBtsListLen:返回值,有效基站队列长度
+void lct_coordcal_check_valid_bts_by_move_direction(uint8 byFirstPathType, LCT_FIRSTPATH_T *pstValidBtsList, uint8 byValidBtsListLen, PUB_LOCATION_DATA_T *pstLctDataList, COORD_T *pstAheadCoord, uint8 byChangeXY, int8 byDirectionX, int8 byDirectionY, uint8 *pbyValidBtsListLen)
+{
+    LCT_FIRSTPATH_T *pstBtsFirstPath = NULL;
+    uint8 byFreqIndex = 0;
+    PUB_LOCATION_DATA_T *pstBtsLctData = NULL;
+    int32 dwGap = 0;
+
+    if (byDirectionX != 0 || byDirectionY != 0)
+    {
+        for (uint8 i = 0; i < byValidBtsListLen; i++)
+        {
+            pstBtsFirstPath = &pstValidBtsList[i];        // 第一径数据
+            byFreqIndex = pstBtsFirstPath->byFreqIndex;   // 基站频率
+            pstBtsLctData = &pstLctDataList[byFreqIndex]; // 定位数据
+
+            // 在X轴上变化趋势较大
+            if (byChangeXY == 1)
+            {
+                // 定位点在基站右侧
+                if (pstAheadCoord->dwX > pstBtsFirstPath->dwCoordX)
+                {
+                    // 向右移动,远离基站
+                    if (byDirectionX == 1)
+                    {
+                        if (byFirstPathType == CAL_PATH)
+                        {
+                            // 100点,表示有70cm的变动
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                dwGap = abs(dwGap);
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwCalPathIndex += dwGap;
+                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                dwGap = abs(dwGap);
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwTrackPathIndex += dwGap;
+                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
+                                }
+                            }
+                        }
+                    }
+                    // 向左移动,靠近基站
+                    else if (byDirectionX == -1)
+                    {
+                        if (byFirstPathType == CAL_PATH)
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwCalPathIndex -= dwGap;
+                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwTrackPathIndex -= dwGap;
+                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
+                                }
+                            }
+                        }
+                    }
+                }
+                // 定位点在基站左侧
+                else
+                {
+                    // 向右移动,靠近基站
+                    if (byDirectionX == 1)
+                    {
+                        if (byFirstPathType == CAL_PATH)
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwCalPathIndex -= dwGap;
+                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwTrackPathIndex -= dwGap;
+                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
+                                }
+                            }
+                        }
+                    }
+                    // 向左移动,远离基站
+                    else if (byDirectionX == -1)
+                    {
+                        if (byFirstPathType == CAL_PATH)
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                dwGap = abs(dwGap);
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwCalPathIndex += dwGap;
+                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                dwGap = abs(dwGap);
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwTrackPathIndex += dwGap;
+                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            // 在Y轴上变化趋势较大
+            else if (byChangeXY == 2)
+            {
+                // 定位点在基站上方
+                if (pstAheadCoord->dwY > pstBtsFirstPath->dwCoordY)
+                {
+                    // 向上移动,远离基站
+                    if (byDirectionY == 1)
+                    {
+                        if (byFirstPathType == CAL_PATH)
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                dwGap = abs(dwGap);
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwCalPathIndex += dwGap;
+                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                dwGap = abs(dwGap);
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwTrackPathIndex += dwGap;
+                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
+                                }
+                            }
+                        }
+                    }
+                    // 向下移动,靠近基站
+                    else if (byDirectionY == -1)
+                    {
+                        if (byFirstPathType == CAL_PATH)
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwCalPathIndex -= dwGap;
+                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwTrackPathIndex -= dwGap;
+                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
+                                }
+                            }
+                        }
+                    }
+                }
+                // 定位点在基站下方
+                else
+                {
+                    // 向上移动,靠近基站
+                    if (byDirectionY == 1)
+                    {
+                        if (byFirstPathType == CAL_PATH)
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwCalPathIndex -= dwGap;
+                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwTrackPathIndex -= dwGap;
+                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
+                                }
+                            }
+                        }
+                    }
+                    // 向下移动,远离基站
+                    else if (byDirectionY == -1)
+                    {
+                        if (byFirstPathType == CAL_PATH)
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                dwGap = abs(dwGap);
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwCalPathIndex += dwGap;
+                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
+                            {
+                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
+                                dwGap = abs(dwGap);
+                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
+                                {
+                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
+                                    pstBtsFirstPath->dwTrackPathIndex += dwGap;
+                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    *pbyValidBtsListLen = byValidBtsListLen; // 有效基站数量
+
+    return;
+}
+
 // 预测坐标
 // pstPredictionCoord:预测坐标
 // pbyPredictionFlag:预测标识,0:预测失败,1:预测成功
@@ -458,7 +768,7 @@ void lct_coordcal_check_move_tendency(LCT_FIRSTPATH_T *pstFirstPathList, uint8 b
         fDistancP = util_distance_cal_p2p_distance(pstFirstPathData->dwCoordX, pstFirstPathData->dwCoordY, pstPredictionCoord->dwX, pstPredictionCoord->dwY);
         fDistancA = util_distance_cal_p2p_distance(pstFirstPathData->dwCoordX, pstFirstPathData->dwCoordY, pstAheadCoord->dwX, pstAheadCoord->dwY);
 
-        // 预测点接近基站
+        // 预测点接近基站
         if (fDistancP < fDistancA)
         {
             if (pstBtsDirectionData->byDirectionTendency != 1)
@@ -481,18 +791,363 @@ void lct_coordcal_check_move_tendency(LCT_FIRSTPATH_T *pstFirstPathList, uint8 b
     }
 }
 
+// // 预测XY轴移动方向
+// // pstFirstPathList:第一径数据队列
+// // byFirstPathListLen:第一径数据队列长度
+// // pstPredictionDirectionDataList:预测移动方向的数据队列
+// // pbyDirectionX:X轴预测方向,返回参数,1:向右,-1:向左
+// // pbyDirectionY:Y轴预测方向,返回参数,1:向上,-1:向下
+// void lct_coordcal_prediction_x_y_move_direction(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, int8 *pbyDirectionX, int8 *pbyDirectionY)
+// {
+//     LCT_COORDSEL_MEAN_COORD_T *pstMeanLctCoordList = &gLct_stMeanLctCoordList;
+//     uint8 byListLen = pstMeanLctCoordList->byListLen;
+//     COORD_T stAheadCoord = {0};
+
+//     LCT_FIRSTPATH_T *pstFirstPathData = NULL;
+//     uint8 byFreqIndex = 0;
+//     LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstCurrentBtsDirectionData = NULL; // 当前基站方向预测数据
+
+//     LCT_FIRSTPATH_T *pstOtherFirstPathData = NULL;
+//     uint8 byOtherFreqIndex = 0;
+//     LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstOtherBtstDirectionData = NULL; // 其它基站方向预测数据
+
+//     int32 dwCurrentX = 0;
+//     int32 dwCurrentY = 0;
+//     uint32 dwCurrentIndex = 0;
+
+//     int32 dwOtherX = 0;
+//     int32 dwOtherY = 0;
+//     uint32 dwOtherIndex = 0;
+
+//     int8 byDirectionX = 0; // X轴预测标识符
+//     int8 byDirectionY = 0; // Y轴预测标识符
+
+//     // 方向预测次数
+//     uint8 byCounterPlusX = 0;
+//     uint8 byCounterMinusX = 0;
+//     uint8 byCounterPlusY = 0;
+//     uint8 byCounterMinusY = 0;
+
+//     // 参数容错
+//     if (byListLen < 1)
+//     {
+//         return;
+//     }
+//     stAheadCoord = pstMeanLctCoordList->astCoordList[byListLen - 1];
+
+//     // 预测方向
+//     for (uint8 i = 0; i < byFirstPathListLen; i++)
+//     {
+//         pstFirstPathData = &pstFirstPathList[i];
+//         byFreqIndex = pstFirstPathData->byFreqIndex; // 基站频率索引
+
+//         // 当前基站预测数据
+//         pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
+//         dwCurrentX = pstCurrentBtsDirectionData->dwCoordX;
+//         dwCurrentY = pstCurrentBtsDirectionData->dwCoordY;
+//         dwCurrentIndex = pstCurrentBtsDirectionData->dwCalPathIndex;
+
+//         // 当前站方向趋势有效
+//         if (pstCurrentBtsDirectionData->byValidFlag == 1)
+//         {
+//             for (uint8 j = i + 1; j < byFirstPathListLen; j++)
+//             {
+//                 // 其它基站预测数据
+//                 pstOtherFirstPathData = &pstFirstPathList[j];
+//                 byOtherFreqIndex = pstOtherFirstPathData->byFreqIndex; // 基站频率索引
+//                 pstOtherBtstDirectionData = &pstPredictionDirectionDataList[byOtherFreqIndex];
+
+//                 // 其它站方向趋势有效
+//                 if (pstOtherBtstDirectionData->byValidFlag == 1)
+//                 {
+//                     dwOtherX = pstOtherBtstDirectionData->dwCoordX;
+//                     dwOtherY = pstOtherBtstDirectionData->dwCoordY;
+//                     dwOtherIndex = pstOtherBtstDirectionData->dwCalPathIndex;
+
+//                     // 靠近当前站
+//                     if (pstCurrentBtsDirectionData->byDirectionTendency == 1)
+//                     {
+//                         // 靠近当前站,同时也靠近其它基站
+//                         if (pstOtherBtstDirectionData->byDirectionTendency == 1)
+//                         {
+//                             // 其它基站在当前基站右侧
+//                             if (dwOtherX > dwCurrentX)
+//                             {
+//                                 if (dwOtherIndex > dwCurrentIndex)
+//                                 {
+//                                     byCounterPlusX++;
+//                                 }
+//                                 else
+//                                 {
+//                                     byCounterMinusX++;
+//                                 }
+//                             }
+//                             // 其它基站在当前基站左侧
+//                             else if (dwOtherX < dwCurrentX)
+//                             {
+//                                 if (dwOtherIndex > dwCurrentIndex)
+//                                 {
+//                                     byCounterMinusX++;
+//                                 }
+//                                 else
+//                                 {
+//                                     byCounterPlusX++;
+//                                 }
+//                             }
+
+//                             // 其它基站在当前基站上方
+//                             if (dwOtherY > dwCurrentY)
+//                             {
+//                                 if (dwOtherIndex > dwCurrentIndex)
+//                                 {
+//                                     byCounterPlusY++;
+//                                 }
+//                                 else
+//                                 {
+//                                     byCounterMinusY++;
+//                                 }
+//                             }
+//                             // 其它基站在当前基站下方
+//                             else if (dwOtherY < dwCurrentY)
+//                             {
+//                                 if (dwOtherIndex > dwCurrentIndex)
+//                                 {
+//                                     byCounterMinusY++;
+//                                 }
+//                                 else
+//                                 {
+//                                     byCounterPlusY++;
+//                                 }
+//                             }
+//                             // 其它基站与当前基站Y坐标相同
+//                             else
+//                             {
+//                                 byDirectionY = 0; // 错误
+//                             }
+//                         }
+//                         // 靠近当前站,远离其它基站
+//                         else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
+//                         {
+//                             // 其它基站在当前基站右侧
+//                             if (dwOtherX > dwCurrentX)
+//                             {
+//                                 byCounterMinusX++;
+//                             }
+//                             // 其它基站在当前基站左侧
+//                             else if (dwOtherX < dwCurrentX)
+//                             {
+//                                 byDirectionX = 1;
+//                             }
+//                             // 其它基站与当前基站X坐标相同
+//                             else
+//                             {
+//                                 byDirectionX = 0; // 错误
+//                             }
+
+//                             // 其它基站在当前基站上方
+//                             if (dwOtherY > dwCurrentY)
+//                             {
+//                                 byCounterMinusY++;
+//                             }
+//                             // 其它基站在当前基站下方
+//                             else if (dwOtherY < dwCurrentY)
+//                             {
+//                                 byCounterPlusY++;
+//                             }
+//                             // 其它基站与当前基站Y坐标相同
+//                             else
+//                             {
+//                                 byDirectionY = 0; // 错误
+//                             }
+//                         }
+//                     }
+//                     // 远离当前站
+//                     else if (pstCurrentBtsDirectionData->byDirectionTendency == 2)
+//                     {
+//                         // 远离当前站,靠近其它基站
+//                         if (pstOtherBtstDirectionData->byDirectionTendency == 1)
+//                         {
+//                             // 其它基站在当前基站右侧
+//                             if (dwOtherX > dwCurrentX)
+//                             {
+//                                 byCounterPlusX++;
+//                             }
+//                             // 其它基站在当前基站左侧
+//                             else if (dwOtherX < dwCurrentX)
+//                             {
+//                                 byCounterMinusX++;
+//                             }
+//                             // 其它基站与当前基站X坐标相同
+//                             else
+//                             {
+//                                 byDirectionX = 0; // 错误
+//                             }
+
+//                             // 其它基站在当前基站上方
+//                             if (dwOtherY > dwCurrentY)
+//                             {
+//                                 byCounterPlusY++;
+//                             }
+//                             // 其它基站在当前基站下方
+//                             else if (dwOtherY < dwCurrentY)
+//                             {
+//                                 byCounterMinusY++;
+//                             }
+//                             // 其它基站与当前基站Y坐标相同
+//                             else
+//                             {
+//                                 byDirectionY = 0; // 错误
+//                             }
+//                         }
+//                         // 远离当前站,同时远离其它基站
+//                         else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
+//                         {
+//                             // 其它基站在当前基站右侧
+//                             if (dwOtherX > dwCurrentX)
+//                             {
+//                                 if (dwOtherIndex > dwCurrentIndex)
+//                                 {
+//                                     byCounterMinusX++;
+//                                 }
+//                                 else
+//                                 {
+//                                     byCounterPlusX++;
+//                                 }
+//                             }
+//                             // 其它基站在当前基站左侧
+//                             else if (dwOtherX < dwCurrentX)
+//                             {
+//                                 if (dwOtherIndex > dwCurrentIndex)
+//                                 {
+//                                     byCounterPlusX++;
+//                                 }
+//                                 else
+//                                 {
+//                                     byCounterMinusX++;
+//                                 }
+//                             }
+//                             // 其它基站与当前基站X坐标相同
+//                             else
+//                             {
+//                                 byDirectionX = 0; // 错误
+//                             }
+
+//                             // 其它基站在当前基站上方
+//                             if (dwOtherY > dwCurrentY)
+//                             {
+//                                 if (dwOtherIndex > dwCurrentIndex)
+//                                 {
+//                                     byCounterMinusY++;
+//                                 }
+//                                 else
+//                                 {
+//                                     byCounterPlusY++;
+//                                 }
+//                             }
+//                             // 其它基站在当前基站下方
+//                             else if (dwOtherY < dwCurrentY)
+//                             {
+//                                 if (dwOtherIndex > dwCurrentIndex)
+//                                 {
+//                                     byCounterPlusY++;
+//                                 }
+//                                 else
+//                                 {
+//                                     byCounterMinusY++;
+//                                 }
+//                             }
+//                             // 其它基站与当前基站Y坐标相同
+//                             else
+//                             {
+//                                 byDirectionY = 0; // 错误
+//                             }
+//                         }
+//                     }
+//                 }
+//             }
+
+//             if (byCounterPlusX != 0 || byCounterMinusX != 0 || byCounterPlusY != 0 || byCounterMinusY != 0)
+//             {
+//                 break;
+//             }
+//         }
+//     }
+
+//     // 方向预测失败
+//     if (byCounterPlusX == 0 && byCounterMinusX == 0 && byCounterPlusY == 0 && byCounterMinusY == 0)
+//     {
+//         *pbyDirectionX = 0;
+//         *pbyDirectionY = 0;
+//     }
+//     else
+//     {
+//         if (byCounterPlusX > byCounterMinusX)
+//         {
+//             byDirectionX = 1;
+//         }
+//         else if (byCounterPlusX < byCounterMinusX)
+//         {
+//             byDirectionX = -1;
+//         }
+//         else
+//         {
+//             byDirectionX = 0; // 不成功
+//         }
+
+//         if (byCounterPlusY > byCounterMinusY)
+//         {
+//             byDirectionY = 1;
+//         }
+//         else if (byCounterPlusY < byCounterMinusY)
+//         {
+//             byDirectionY = -1;
+//         }
+//         else
+//         {
+//             byDirectionY = 0; // 不成功
+//         }
+
+//         *pbyDirectionX = byDirectionX;
+//         *pbyDirectionY = byDirectionY;
+//     }
+
+//     // // 修正移动方向
+//     // if (byDirectionX == 0 && byDirectionY == 0)
+//     // {
+//     //     if (gLct_dwSpeedX < 0)
+//     //     {
+//     //         byDirectionX = -1;
+//     //     }
+//     //     else if (gLct_dwSpeedX > 0)
+//     //     {
+//     //         byDirectionX = 1;
+//     //     }
+
+//     //     if (gLct_dwSpeedY < 0)
+//     //     {
+//     //         byDirectionY = -1;
+//     //     }
+//     //     else if (gLct_dwSpeedY > 0)
+//     //     {
+//     //         byDirectionY = 1;
+//     //     }
+
+//     //     *pbyDirectionX = byDirectionX;
+//     //     *pbyDirectionY = byDirectionY;
+//     // }
+
+//     return;
+// }
+
 // 预测XY轴移动方向
 // pstFirstPathList:第一径数据队列
 // byFirstPathListLen:第一径数据队列长度
 // pstPredictionDirectionDataList:预测移动方向的数据队列
+// byChangeXY:在XY轴上变化大小趋势,1:X轴变化大,2:Y轴变化大
 // pbyDirectionX:X轴预测方向,返回参数,1:向右,-1:向左
 // pbyDirectionY:Y轴预测方向,返回参数,1:向上,-1:向下
-void lct_coordcal_prediction_x_y_move_direction(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, int8 *pbyDirectionX, int8 *pbyDirectionY)
+void lct_coordcal_prediction_x_y_move_direction(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, COORD_T *pstAheadCoord, uint8 byChangeXY, int8 *pbyDirectionX, int8 *pbyDirectionY)
 {
-    LCT_COORDSEL_MEAN_COORD_T *pstMeanLctCoordList = &gLct_stMeanLctCoordList;
-    uint8 byListLen = pstMeanLctCoordList->byListLen;
-    COORD_T stAheadCoord = {0};
-
     LCT_FIRSTPATH_T *pstFirstPathData = NULL;
     uint8 byFreqIndex = 0;
     LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstCurrentBtsDirectionData = NULL; // 当前基站方向预测数据
@@ -501,306 +1156,297 @@ void lct_coordcal_prediction_x_y_move_direction(LCT_FIRSTPATH_T *pstFirstPathLis
     uint8 byOtherFreqIndex = 0;
     LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstOtherBtstDirectionData = NULL; // 其它基站方向预测数据
 
+    // 主站
     int32 dwCurrentX = 0;
     int32 dwCurrentY = 0;
-    uint32 dwCurrentIndex = 0;
-
+    int8 byMainDirectionX = 0;         // 主站X轴预测标识符,-1:向左,1:向右,0:不确定
+    int8 byMainDirectionY = 0;         // 主站Y轴预测标识符,-1:向下,1:向上,0:不确定
+    uint8 byMainDirectionXCounter = 0; // 主站方向预测正确计数器
+    uint8 byMainDirectionYCounter = 0; // 主站方向预测正确计数器
+    uint8 byFirstPathIndexX = 0;
+    uint8 byFirstPathIndexY = 0;
+
+    // 从站
     int32 dwOtherX = 0;
     int32 dwOtherY = 0;
-    uint32 dwOtherIndex = 0;
-
-    int8 byDirectionX = 0; // X轴预测标识符
-    int8 byDirectionY = 0; // Y轴预测标识符
-
-    // 方向预测次数
-    uint8 byCounterPlusX = 0;
-    uint8 byCounterMinusX = 0;
-    uint8 byCounterPlusY = 0;
-    uint8 byCounterMinusY = 0;
-
-    // 参数容错
-    if (byListLen < 1)
-    {
-        return;
-    }
-    stAheadCoord = pstMeanLctCoordList->astCoordList[byListLen - 1];
 
     // 预测方向
     for (uint8 i = 0; i < byFirstPathListLen; i++)
     {
-        pstFirstPathData = &pstFirstPathList[i];
+        pstFirstPathData = &pstFirstPathList[i];     // 第一径数据
         byFreqIndex = pstFirstPathData->byFreqIndex; // 基站频率索引
 
         // 当前基站预测数据
         pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
+        pstCurrentBtsDirectionData->byDirectionX = 0;
+        pstCurrentBtsDirectionData->byDirectionY = 0;
+        pstCurrentBtsDirectionData->byDirectionXCounter = 0;
+        pstCurrentBtsDirectionData->byDirectionYCounter = 0;
         dwCurrentX = pstCurrentBtsDirectionData->dwCoordX;
         dwCurrentY = pstCurrentBtsDirectionData->dwCoordY;
-        dwCurrentIndex = pstCurrentBtsDirectionData->dwCalPathIndex;
 
         // 当前站方向趋势有效
         if (pstCurrentBtsDirectionData->byValidFlag == 1)
         {
-            for (uint8 j = i + 1; j < byFirstPathListLen; j++)
-            {
-                // 其它基站预测数据
-                pstOtherFirstPathData = &pstFirstPathList[j];
-                byOtherFreqIndex = pstOtherFirstPathData->byFreqIndex; // 基站频率索引
-                pstOtherBtstDirectionData = &pstPredictionDirectionDataList[byOtherFreqIndex];
+            // 基站手机相对于主站在x和y轴上的移动方向
+            lct_coordcal_cal_bts_move_direction(pstCurrentBtsDirectionData->byDirectionTendency, dwCurrentX, dwCurrentY, pstAheadCoord, &byMainDirectionX, &byMainDirectionY);
 
-                // 其它站方向趋势有效
-                if (pstOtherBtstDirectionData->byValidFlag == 1)
+            // 利用从站校验主站的移动方向正确性
+            for (uint8 j = 0; j < byFirstPathListLen; j++)
+            {
+                if (i != j)
                 {
-                    dwOtherX = pstOtherBtstDirectionData->dwCoordX;
-                    dwOtherY = pstOtherBtstDirectionData->dwCoordY;
-                    dwOtherIndex = pstOtherBtstDirectionData->dwCalPathIndex;
+                    // 其它基站预测数据
+                    pstOtherFirstPathData = &pstFirstPathList[j];
+                    byOtherFreqIndex = pstOtherFirstPathData->byFreqIndex; // 基站频率索引
+                    pstOtherBtstDirectionData = &pstPredictionDirectionDataList[byOtherFreqIndex];
 
-                    // 靠近当前站
-                    if (pstCurrentBtsDirectionData->byDirectionTendency == 1)
+                    // 其它站方向趋势有效
+                    if (pstOtherBtstDirectionData->byValidFlag == 1)
                     {
-                        // 靠近当前站,同时也靠近其它基站
-                        if (pstOtherBtstDirectionData->byDirectionTendency == 1)
+                        dwOtherX = pstOtherBtstDirectionData->dwCoordX;
+                        dwOtherY = pstOtherBtstDirectionData->dwCoordY;
+
+                        //// 用从站的趋势校验主站的运动方向
+                        // 主站X轴向右移动
+                        if (byMainDirectionX == 1)
                         {
-                            // 其它基站在当前基站右侧
-                            if (dwOtherX > dwCurrentX)
+                            // 手机靠近从站
+                            if (pstOtherBtstDirectionData->byDirectionTendency == 1)
                             {
-                                if (dwOtherIndex > dwCurrentIndex)
-                                {
-                                    byCounterPlusX++;
-                                }
-                                else
+                                // TODO,条件已经检查过,不需要再修改
+                                if ((dwOtherX > dwCurrentX && pstAheadCoord->dwX < dwOtherX) || (dwOtherX <= dwCurrentX && pstAheadCoord->dwX < dwOtherX))
                                 {
-                                    byCounterMinusX++;
+                                    byMainDirectionXCounter++;
                                 }
                             }
-                            // 其它基站在当前基站左侧
-                            else if (dwOtherX < dwCurrentX)
+                            // 手机远离从站
+                            else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
                             {
-                                if (dwOtherIndex > dwCurrentIndex)
-                                {
-                                    byCounterMinusX++;
-                                }
-                                else
+                                // TODO,条件已经检查过,不需要再修改
+                                if ((dwOtherX < dwCurrentX && pstAheadCoord->dwX >= dwOtherX) || (dwOtherX >= dwCurrentX && pstAheadCoord->dwX >= dwOtherX))
                                 {
-                                    byCounterPlusX++;
+                                    byMainDirectionXCounter++;
                                 }
                             }
-
-                            // 其它基站在当前基站上方
-                            if (dwOtherY > dwCurrentY)
+                        }
+                        // 主站X轴向左移动
+                        else if (byMainDirectionX == -1)
+                        {
+                            // 手机靠近从站
+                            if (pstOtherBtstDirectionData->byDirectionTendency == 1)
                             {
-                                if (dwOtherIndex > dwCurrentIndex)
-                                {
-                                    byCounterPlusY++;
-                                }
-                                else
+                                // TODO,条件已经检查过,不需要再修改
+                                if ((dwOtherX < dwCurrentX && pstAheadCoord->dwX > dwOtherX) || (dwOtherX >= dwCurrentX && pstAheadCoord->dwX > dwOtherX))
                                 {
-                                    byCounterMinusY++;
+                                    byMainDirectionXCounter++;
                                 }
                             }
-                            // 其它基站在当前基站下方
-                            else if (dwOtherY < dwCurrentY)
+                            // 手机远离从站
+                            else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
                             {
-                                if (dwOtherIndex > dwCurrentIndex)
+                                // TODO,条件已经检查过,不需要再修改
+                                if ((dwOtherX >= dwCurrentX && pstAheadCoord->dwX <= dwOtherX) || (dwOtherX <= dwCurrentX && pstAheadCoord->dwX <= dwOtherX))
                                 {
-                                    byCounterMinusY++;
+                                    byMainDirectionXCounter++;
                                 }
-                                else
-                                {
-                                    byCounterPlusY++;
-                                }
-                            }
-                            // 其它基站与当前基站Y坐标相同
-                            else
-                            {
-                                byDirectionY = 0; // 错误
                             }
                         }
-                        // 靠近当前站,远离其它基站
-                        else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
-                        {
-                            // 其它基站在当前基站右侧
-                            if (dwOtherX > dwCurrentX)
-                            {
-                                byCounterMinusX++;
-                            }
-                            // 其它基站在当前基站左侧
-                            else if (dwOtherX < dwCurrentX)
-                            {
-                                byDirectionX = 1;
-                            }
-                            // 其它基站与当前基站X坐标相同
-                            else
-                            {
-                                byDirectionX = 0; // 错误
-                            }
-
-                            // 其它基站在当前基站上方
-                            if (dwOtherY > dwCurrentY)
-                            {
-                                byCounterMinusY++;
-                            }
-                            // 其它基站在当前基站下方
-                            else if (dwOtherY < dwCurrentY)
-                            {
-                                byCounterPlusY++;
-                            }
-                            // 其它基站与当前基站Y坐标相同
-                            else
-                            {
-                                byDirectionY = 0; // 错误
-                            }
-                        }
-                    }
-                    // 远离当前站
-                    else if (pstCurrentBtsDirectionData->byDirectionTendency == 2)
-                    {
-                        // 远离当前站,靠近其它基站
-                        if (pstOtherBtstDirectionData->byDirectionTendency == 1)
-                        {
-                            // 其它基站在当前基站右侧
-                            if (dwOtherX > dwCurrentX)
-                            {
-                                byCounterPlusX++;
-                            }
-                            // 其它基站在当前基站左侧
-                            else if (dwOtherX < dwCurrentX)
-                            {
-                                byCounterMinusX++;
-                            }
-                            // 其它基站与当前基站X坐标相同
-                            else
-                            {
-                                byDirectionX = 0; // 错误
-                            }
 
-                            // 其它基站在当前基站上方
-                            if (dwOtherY > dwCurrentY)
-                            {
-                                byCounterPlusY++;
-                            }
-                            // 其它基站在当前基站下方
-                            else if (dwOtherY < dwCurrentY)
-                            {
-                                byCounterMinusY++;
-                            }
-                            // 其它基站与当前基站Y坐标相同
-                            else
-                            {
-                                byDirectionY = 0; // 错误
-                            }
-                        }
-                        // 远离当前站,同时远离其它基站
-                        else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
+                        // 主站Y轴向上移动
+                        if (byMainDirectionY == 1)
                         {
-                            // 其它基站在当前基站右侧
-                            if (dwOtherX > dwCurrentX)
+                            // 手机靠近从站
+                            if (pstOtherBtstDirectionData->byDirectionTendency == 1)
                             {
-                                if (dwOtherIndex > dwCurrentIndex)
-                                {
-                                    byCounterMinusX++;
-                                }
-                                else
+                                // TODO,条件已经检查过,不需要再修改
+                                if ((dwOtherY > dwCurrentY && pstAheadCoord->dwY < dwOtherY) || (dwOtherY <= dwCurrentY && pstAheadCoord->dwY < dwOtherY))
                                 {
-                                    byCounterPlusX++;
+                                    byMainDirectionYCounter++;
                                 }
                             }
-                            // 其它基站在当前基站左侧
-                            else if (dwOtherX < dwCurrentX)
+                            // 手机远离从站
+                            else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
                             {
-                                if (dwOtherIndex > dwCurrentIndex)
-                                {
-                                    byCounterPlusX++;
-                                }
-                                else
+                                // TODO,条件已经检查过,不需要再修改
+                                if ((dwOtherY <= dwCurrentY && pstAheadCoord->dwY >= dwOtherY) || (dwOtherY >= dwCurrentY && pstAheadCoord->dwY >= dwOtherY))
                                 {
-                                    byCounterMinusX++;
+                                    byMainDirectionYCounter++;
                                 }
                             }
-                            // 其它基站与当前基站X坐标相同
-                            else
-                            {
-                                byDirectionX = 0; // 错误
-                            }
-
-                            // 其它基站在当前基站上方
-                            if (dwOtherY > dwCurrentY)
+                        }
+                        // 主站Y轴向下移动
+                        else if (byMainDirectionY == -1)
+                        {
+                            // 手机靠近从站
+                            if (pstOtherBtstDirectionData->byDirectionTendency == 1)
                             {
-                                if (dwOtherIndex > dwCurrentIndex)
+                                // TODO,条件已经检查过,不需要再修改
+                                if ((dwOtherY >= dwCurrentY && pstAheadCoord->dwY > dwOtherY) || (dwOtherY < dwCurrentY && pstAheadCoord->dwY > dwOtherY))
                                 {
-                                    byCounterMinusY++;
-                                }
-                                else
-                                {
-                                    byCounterPlusY++;
+                                    byMainDirectionYCounter++;
                                 }
                             }
-                            // 其它基站在当前基站下方
-                            else if (dwOtherY < dwCurrentY)
+                            // 手机远离从站
+                            else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
                             {
-                                if (dwOtherIndex > dwCurrentIndex)
-                                {
-                                    byCounterPlusY++;
-                                }
-                                else
+                                // TODO,条件已经检查过,不需要再修改
+                                if ((dwOtherY > dwCurrentY && pstAheadCoord->dwY <= dwOtherY) || (dwOtherY <= dwCurrentY && pstAheadCoord->dwY <= dwOtherY))
                                 {
-                                    byCounterMinusY++;
+                                    byMainDirectionYCounter++;
                                 }
                             }
-                            // 其它基站与当前基站Y坐标相同
-                            else
-                            {
-                                byDirectionY = 0; // 错误
-                            }
                         }
                     }
                 }
             }
 
-            if (byCounterPlusX != 0 || byCounterMinusX != 0 || byCounterPlusY != 0 || byCounterMinusY != 0)
-            {
-                break;
-            }
+            // 保存主站方向预判信息
+            pstCurrentBtsDirectionData->byDirectionX = byMainDirectionX;
+            pstCurrentBtsDirectionData->byDirectionY = byMainDirectionY;
+            pstCurrentBtsDirectionData->byDirectionXCounter = byMainDirectionXCounter;
+            pstCurrentBtsDirectionData->byDirectionYCounter = byMainDirectionYCounter;
+
+            // 变量复位
+            byMainDirectionX = 0;
+            byMainDirectionY = 0;
+            byMainDirectionXCounter = 0;
+            byMainDirectionYCounter = 0;
         }
     }
 
-    // 方向预测失败
-    if (byCounterPlusX == 0 && byCounterMinusX == 0 && byCounterPlusY == 0 && byCounterMinusY == 0)
+    // 统计XY轴移动方向正确校验最多的方向
+    for (uint8 i = 0; i < byFirstPathListLen; i++)
+    {
+        pstFirstPathData = &pstFirstPathList[i];     // 第一径数据
+        byFreqIndex = pstFirstPathData->byFreqIndex; // 基站频率索引
+        pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
+        if (pstCurrentBtsDirectionData->byDirectionXCounter > byMainDirectionXCounter)
+        {
+            byMainDirectionXCounter = pstCurrentBtsDirectionData->byDirectionXCounter;
+            byFirstPathIndexX = i;
+        }
+
+        if (pstCurrentBtsDirectionData->byDirectionYCounter > byMainDirectionYCounter)
+        {
+            byMainDirectionYCounter = pstCurrentBtsDirectionData->byDirectionYCounter;
+            byFirstPathIndexY = i;
+        }
+    }
+
+    // 选择一个轴向,X轴或者Y轴
+    if (byMainDirectionXCounter > byMainDirectionYCounter)
+    {
+        // X轴
+        pstFirstPathData = &pstFirstPathList[byFirstPathIndexX]; // 第一径数据
+        byFreqIndex = pstFirstPathData->byFreqIndex;             // 基站频率索引
+        pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
+        byMainDirectionX = pstCurrentBtsDirectionData->byDirectionX;
+    }
+    else if (byMainDirectionXCounter < byMainDirectionYCounter)
     {
-        *pbyDirectionX = 0;
-        *pbyDirectionY = 0;
+        // Y轴
+        pstFirstPathData = &pstFirstPathList[byFirstPathIndexY]; // 第一径数据
+        byFreqIndex = pstFirstPathData->byFreqIndex;             // 基站频率索引
+        pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
+        byMainDirectionY = pstCurrentBtsDirectionData->byDirectionY;
     }
     else
     {
-        if (byCounterPlusX > byCounterMinusX)
+        // 在X轴移动较大
+        if (byChangeXY == 1)
         {
-            byDirectionX = 1;
+            // X轴
+            pstFirstPathData = &pstFirstPathList[byFirstPathIndexX]; // 第一径数据
+            byFreqIndex = pstFirstPathData->byFreqIndex;             // 基站频率索引
+            pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
+            byMainDirectionX = pstCurrentBtsDirectionData->byDirectionX;
         }
-        else if (byCounterPlusX < byCounterMinusX)
+        // 在Y轴移动较大
+        else
+        {
+            // Y轴
+            pstFirstPathData = &pstFirstPathList[byFirstPathIndexY]; // 第一径数据
+            byFreqIndex = pstFirstPathData->byFreqIndex;             // 基站频率索引
+            pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
+            byMainDirectionY = pstCurrentBtsDirectionData->byDirectionY;
+        }
+    }
+
+    // 保存参数
+    *pbyDirectionX = byMainDirectionX;
+    *pbyDirectionY = byMainDirectionY;
+
+    return;
+}
+
+// 计算手机相对于基站的移动方向
+// byDirectionTendency:手机相对于基站的运动趋势
+// dwBtsCoordX:基站X坐标
+// dwBtsCoordY:基站Y坐标
+// pstAheadCoord:前一个定位点
+// pbyDirectionX:X轴预测方向,返回参数,1:向右,-1:向左
+// pbyDirectionY:Y轴预测方向,返回参数,1:向上,-1:向下
+void lct_coordcal_cal_bts_move_direction(uint8 byDirectionTendency, int32 dwBtsCoordX, int32 dwBtsCoordY, COORD_T *pstAheadCoord, int8 *pbyDirectionX, int8 *pbyDirectionY)
+{
+    int8 byDirectionX = 0;
+    int8 byDirectionY = 0;
+
+    //// 预判当前手机相对于当前基站在x和y轴上的移动方向
+    // 手机靠近当前站
+    if (byDirectionTendency == 1)
+    {
+        // 从右侧靠近
+        if (pstAheadCoord->dwX > dwBtsCoordX)
         {
             byDirectionX = -1;
         }
-        else
+        // 从左侧靠近
+        else if (pstAheadCoord->dwX < dwBtsCoordX)
         {
-            byDirectionX = 0; // 不成功
+            byDirectionX = 1;
         }
 
-        if (byCounterPlusY > byCounterMinusY)
+        // 从上方靠近
+        if (pstAheadCoord->dwY > dwBtsCoordY)
+        {
+            byDirectionY = -1;
+        }
+        // 从下方靠近
+        else if (pstAheadCoord->dwY < dwBtsCoordY)
         {
             byDirectionY = 1;
         }
-        else if (byCounterPlusY < byCounterMinusY)
+    }
+    // 手机远离当前站
+    else if (byDirectionTendency == 2)
+    {
+        // 从右侧远离
+        if (pstAheadCoord->dwX > dwBtsCoordX)
         {
-            byDirectionY = -1;
+            byDirectionX = 1;
         }
-        else
+        // 从左侧远离
+        else if (pstAheadCoord->dwX < dwBtsCoordX)
         {
-            byDirectionY = 0; // 不成功
+            byDirectionX = -1;
         }
 
-        *pbyDirectionX = byDirectionX;
-        *pbyDirectionY = byDirectionY;
+        // 从上方远离
+        if (pstAheadCoord->dwY > dwBtsCoordY)
+        {
+            byDirectionY = 1;
+        }
+        // 从下方远离
+        else if (pstAheadCoord->dwY < dwBtsCoordY)
+        {
+            byDirectionY = -1;
+        }
     }
 
+    *pbyDirectionX = byDirectionX;
+    *pbyDirectionY = byDirectionY;
+
     return;
 }
 

+ 13 - 13
src/modules/location/lct_coordcal.h

@@ -11,25 +11,25 @@
 
 // 供外部使用接口
 void lct_coordcal_init(LCT_COORDCAL_PARAM_T stLctCoordcalParam);
-void lct_coordcal_main(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T *pstFirstPathList, uint8 *pbyPredictionFlag, COORD_T *pstPredictionCoord, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueGroup, uint16 *pwMinmumValueNum);
+void lct_coordcal_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T *pstFirstPathList, uint8 *pbyPredictionFlag, COORD_T *pstPredictionCoord, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueGroup, uint16 *pwMinmumValueNum);
 
 // 内部使用接口
-void lct_coordcal_sel_valid_bts(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_T *pstValidCalBtsList, uint8 *pbyValidCalBtsListLen, LCT_FIRSTPATH_T *pstValidTrackBtsList, uint8 *pbyValidTrackBtsListLen, int32 *pdwBulidId, int32 *pdwLayerId);
+void lct_coordcal_select_valid_bts_by_fp_and_ampl(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_T *pstValidCalBtsList, uint8 *pbyValidCalBtsListLen, LCT_FIRSTPATH_T *pstValidTrackBtsList, uint8 *pbyValidTrackBtsListLen, int32 *pdwBulidId, int32 *pdwLayerId);
+void lct_coordcal_check_valid_bts_by_move_direction(uint8 byFirstPathType, LCT_FIRSTPATH_T *pstValidBtsList, uint8 byValidBtsListLen, PUB_LOCATION_DATA_T *pstLctDataList, COORD_T *pstAheadCoord, uint8 byChangeXY, int8 byDirectionX, int8 byDirectionY, uint8 *pbyValidBtsListLen);
 void lct_coordcal_check_move_tendency(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, COORD_T *pstPredictionCoord, COORD_T *pstAheadCoord);
-void lct_coordcal_prediction_x_y_move_direction(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, int8 *pbyDirectionX, int8 *pbyDirectionY);
+void lct_coordcal_prediction_x_y_move_direction(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, COORD_T *pstAheadCoord, uint8 byChangeXY, int8 *pbyDirectionX, int8 *pbyDirectionY);
+void lct_coordcal_cal_bts_move_direction(uint8 byDirectionTendency, int32 dwBtsCoordX, int32 dwBtsCoordY, COORD_T *pstAheadCoord, int8 *pbyDirectionX, int8 *pbyDirectionY);
 void lct_coordcal_prediction_coord(COORD_T *pstPredictionCoord, uint8 *pbyPredictionFlag, COORD_T *pstAheadPointCoord, int32 dwBulidId, int32 dwLayerId);
 void lct_coordcal_check_prediction_coord_by_xy_move_tendency(COORD_T *pstPredictionCoord, COORD_T *pstAheadCoord, int8 byDirectionX, int8 byDirectionY, int32 dwSpeedX, int32 dwSpeedY);
 void lct_coordcal_check_prediction_coord_by_bts_coord(COORD_T *pstPredicCoord, LCT_FIRSTPATH_T *pstCalBtsList, uint8 byCalBtsListLen, LCT_FIRSTPATH_T *pstTrackBtsList, uint8 byTrackBtsListLen);
 
 // 二维定位
-void lct_coordcal_two_dimension_location(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, uint8 byPredictionFlag, COORD_T stPredictionCoord, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueList);
-void lct_coordcal_cal_rectangle_end_point_by_bts_coord(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, COORD_T *pstLeftBottom, COORD_T *pstRightTop);
-void lct_coordcal_cal_rectangle_two_end_point_by_coord(COORD_T stPredictionCoord, COORD_T *pstLeftBottom, COORD_T *pstRightTop);
-void lct_coordcal_gen_location_ref_point(COORD_T stLeftBottom, COORD_T stRightTop, uint8 byTrackFlag, COORD_T *pstLocationRefPoint, uint16 *pwMatrixRow, uint16 *pwMatrixCol);
-void lct_coordcal_cal_coord_points(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, COORD_T *pstLocationRefPoint, uint16 wMatrixRow, uint16 wMatrixCol, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueGroup);
-void lct_coordcal_cal_ref_point_delay(COORD_T *pstRefPointMatrix, uint16 wMatrixRow, uint16 wMatrixCol, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, uint8 byFirstPathFlag, flt32 *pfDelayDeviationMatrix);
-void lct_coordcal_cal_two_point_transmit_times_by_coord(COORD_T stFirstPoint, COORD_T stSecondPoint, flt32 *pfTimes);
-void lct_coordcal_cal_delay_by_first_path_index(uint32 dwMainBtsIndex, uint32 dwSlaveBtsIndex, flt32 *pfTwoBtsDelay);
-void lct_coordcal_sel_minimum_value(flt32 *pfDelayDeviationSumMatrix, uint16 wMatrixRow, uint16 wMatrixCol, COORD_T *pstRefPointMatrix, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueList);
-void lct_coordcal_dbcheck_minimum_value(uint8 byFirstPathFlag, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueList);
+// void lct_coordcal_cal_rectangle_two_end_point_by_coord(COORD_T stPredictionCoord, COORD_T *pstLeftBottom, COORD_T *pstRightTop);
+// void lct_coordcal_gen_location_ref_point(COORD_T stLeftBottom, COORD_T stRightTop, uint8 byTrackFlag, COORD_T *pstLocationRefPoint, uint16 *pwMatrixRow, uint16 *pwMatrixCol);
+// void lct_coordcal_cal_coord_points(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, COORD_T *pstLocationRefPoint, uint16 wMatrixRow, uint16 wMatrixCol, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueGroup);
+// void lct_coordcal_cal_ref_point_delay(COORD_T *pstRefPointMatrix, uint16 wMatrixRow, uint16 wMatrixCol, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, uint8 byFirstPathFlag, flt32 *pfDelayDeviationMatrix);
+// void lct_coordcal_cal_two_point_transmit_times_by_coord(COORD_T stFirstPoint, COORD_T stSecondPoint, flt32 *pfTimes);
+// void lct_coordcal_cal_delay_by_first_path_index(uint32 dwMainBtsIndex, uint32 dwSlaveBtsIndex, flt32 *pfTwoBtsDelay);
+// void lct_coordcal_sel_minimum_value(flt32 *pfDelayDeviationSumMatrix, uint16 wMatrixRow, uint16 wMatrixCol, COORD_T *pstRefPointMatrix, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueList);
+// void lct_coordcal_dbcheck_minimum_value(uint8 byFirstPathFlag, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueList);
 #endif

+ 95 - 68
src/modules/location/lct_coordcal_two.c

@@ -4,7 +4,8 @@
 // 2023-03-25
 
 #include "../../includes/includes.h"
-#include "./lct_public.h"
+// #include "../../sysdefine/struct.h"
+// #include "./lct_public.h"
 
 // 导入全局变量
 extern COORD_T gLct_astLocationRefPoint[LCT_REF_POINT_MATRIX_LEN * LCT_REF_POINT_MATRIX_LEN]; // 定位参考点
@@ -12,13 +13,14 @@ extern flt32 gLct_fDelayDeviationMatrix[LCT_REF_POINT_MATRIX_LEN * LCT_REF_POINT
 extern LCT_COORDCAL_PARAM_T gg_stLctCoordcalParam;
 
 // 二维计算
+// pstLctBtsList:定位基站队列
 // pstFirstPathList:基站第一径列表
 // byFirstPathListLen:基站第一径列表长度
 // byPredictionFlag:预测标识符,0:预测失败,1:预测成功
 // stPredictionCoord:预测坐标
 //// byFirstPathFlag:第一径类型标识(0:计算径,1:跟踪径)
 // pstMinmumValueList:极小值列表(返回参数)
-void lct_coordcal_two_dimension_location(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, uint8 byPredictionFlag, COORD_T stPredictionCoord, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueList)
+void lct_coordcal_two_dimension_location(PUB_LCT_BTS_LIST_T *pstLctBtsList, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, uint8 byPredictionFlag, COORD_T stPredictionCoord, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueList)
 {
     LCT_FIRSTPATH_T astValidPathBtsList[PUB_LCT_BTS_MAX_NUM]; // 有效计算径基站队列
     uint8 byValidPathBtsListLen = 0;                          // 有效计算径基站队列长度
@@ -49,8 +51,8 @@ void lct_coordcal_two_dimension_location(LCT_FIRSTPATH_T *pstFirstPathList, uint
     {
         if (byValidPathBtsListLen > 2)
         {
-            // 基于基站坐标计算搜索框端点坐标
-            lct_coordcal_cal_rectangle_end_point_by_bts_coord(astValidPathBtsList, byValidPathBtsListLen, &stLeftBottom, &stRightTop);
+            // 基于定位基站坐标计算搜索框端点
+            lct_coordcal_cal_rectangle_end_point_by_bts_coord(pstLctBtsList, &stLeftBottom, &stRightTop);
 
             // 根据搜索矩形端点坐标生成定位参考点
             lct_coordcal_gen_location_ref_point(stLeftBottom, stRightTop, 0, (COORD_T *)gLct_astLocationRefPoint, &wRefPointMatrixRow, &wRefPointMatrixCol);
@@ -82,16 +84,16 @@ void lct_coordcal_two_dimension_location(LCT_FIRSTPATH_T *pstFirstPathList, uint
 }
 
 // 根据基站坐标计算定位搜索框两个端点坐标(左下和右上)
-// pstFirstPathList:基站第一径列表
-// byFirstPathListLen:基站第一径列表长度
-// byLocationTimes:定位次数
+// pstLctBtsList:定位基站队列
 // pstLeftBottom:左下点(返回参数)
 // pstRightTop:右上点(返回参数)
-void lct_coordcal_cal_rectangle_end_point_by_bts_coord(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, COORD_T *pstLeftBottom, COORD_T *pstRightTop)
+void lct_coordcal_cal_rectangle_end_point_by_bts_coord(PUB_LCT_BTS_LIST_T *pstLctBtsList, COORD_T *pstLeftBottom, COORD_T *pstRightTop)
 {
     int16 wPhoneCoordZ = (uint16)gg_stLctCoordcalParam.dwPhoneCoordZ;        // 手机Z坐标默认高度
     uint16 wCoordExpendLen = (uint16)gg_stLctCoordcalParam.dwCoordExpendLen; // 默认状态下矩形框边长扩展长度
 
+    PUB_LCT_BTS_T *pstLctBtsData = NULL; // 定位基站数据
+
     int32 dwTemp = 0;
     int32 dwMinValueX = 2147483647;
     int32 dwMaxValueX = -2147483648;
@@ -102,27 +104,31 @@ void lct_coordcal_cal_rectangle_end_point_by_bts_coord(LCT_FIRSTPATH_T *pstFirst
     COORD_T stRightTop = {0};   // 搜索矩形右上端点
 
     ////计算端点坐标的最大值与最小值
-    for (uint8 i = 0; i < byFirstPathListLen; i++)
+    for (uint8 i = 0; i < pstLctBtsList->byBtsNum; i++)
     {
-        dwTemp = pstFirstPathList[i].dwCoordX;
-        if (dwTemp > dwMaxValueX)
+        pstLctBtsData = &pstLctBtsList->astLocationBts[i];
+        if (pstLctBtsData->dwLctType == 2 || pstLctBtsData->dwLctType == 3)
         {
-            dwMaxValueX = dwTemp;
-        }
+            dwTemp = pstLctBtsData->dwCoordX;
+            if (dwTemp > dwMaxValueX)
+            {
+                dwMaxValueX = dwTemp;
+            }
 
-        if (dwTemp < dwMinValueX)
-        {
-            dwMinValueX = dwTemp;
-        }
+            if (dwTemp < dwMinValueX)
+            {
+                dwMinValueX = dwTemp;
+            }
 
-        dwTemp = pstFirstPathList[i].dwCoordY;
-        if (dwTemp > dwMaxValueY)
-        {
-            dwMaxValueY = dwTemp;
-        }
-        if (dwTemp < dwMinValueY)
-        {
-            dwMinValueY = dwTemp;
+            dwTemp = pstLctBtsData->dwCoordY;
+            if (dwTemp > dwMaxValueY)
+            {
+                dwMaxValueY = dwTemp;
+            }
+            if (dwTemp < dwMinValueY)
+            {
+                dwMinValueY = dwTemp;
+            }
         }
     }
 
@@ -787,44 +793,56 @@ void lct_coordcal_dbcheck_minimum_value(uint8 byFirstPathFlag, LCT_FIRSTPATH_T *
 // pstMinmumValueGroup:极小值组
 // pstPredictionCoord:预测坐标
 // pstAheadCoord:前一点坐标
+// byChangeXY:xy轴变化趋势,1:X轴变化大,2:Y轴变化大
 // byDirectionX:手机在x轴的移动方向,1:向右,-1:向左
 // byDirectionY:手机在y轴的移动方向,1:向上,-1:向下
-void lct_coordcal_two_dimension_check(LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueGroup, COORD_T *pstPredictionCoord, COORD_T *pstAheadCoord, int8 byDirectionX, int8 byDirectionY)
+void lct_coordcal_two_dimension_check(LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueGroup, COORD_T *pstPredictionCoord, COORD_T *pstAheadCoord, uint8 byChangeXY, int8 byDirectionX, int8 byDirectionY)
 {
+    int32 dwGap = 0;
+
     // 校验计算径
     for (uint8 i = 0; i < pstMinmumValueGroup->byCalMinimumListLen; i++)
     {
-        // x轴向右移动
-        if (byDirectionX == 1)
+        if (byChangeXY == 1)
         {
-            if (pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwX <= pstAheadCoord->dwX)
+            // x轴向右移动
+            if (byDirectionX == 1)
             {
-                pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwX = pstPredictionCoord->dwX;
+                dwGap = pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwX - pstAheadCoord->dwX;
+                if (dwGap < -LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES)
+                {
+                    pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwX = pstPredictionCoord->dwX;
+                }
             }
-        }
-        // x轴向左移动
-        else if (byDirectionX == -1)
-        {
-            if (pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwX >= pstAheadCoord->dwX)
+            // x轴向左移动
+            else if (byDirectionX == -1)
             {
-                pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwX = pstPredictionCoord->dwX;
+                dwGap = pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwX > pstAheadCoord->dwX;
+                if (dwGap > LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES)
+                {
+                    pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwX = pstPredictionCoord->dwX;
+                }
             }
         }
-
-        // y轴向上移动
-        if (byDirectionY == 1)
+        else if (byChangeXY == 2)
         {
-            if (pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwY <= pstAheadCoord->dwY)
+            // y轴向上移动
+            if (byDirectionY == 1)
             {
-                pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwY = pstPredictionCoord->dwY;
+                dwGap = pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwY < pstAheadCoord->dwY;
+                if (dwGap < -LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES)
+                {
+                    pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwY = pstPredictionCoord->dwY;
+                }
             }
-        }
-        // y轴向下移动
-        else if (byDirectionY == -1)
-        {
-            if (pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwY >= pstAheadCoord->dwY)
+            // y轴向下移动
+            else if (byDirectionY == -1)
             {
-                pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwY = pstPredictionCoord->dwY;
+                dwGap = pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwY > pstAheadCoord->dwY;
+                if (dwGap > LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES)
+                {
+                    pstMinmumValueGroup->astCalMinimumList[i].stCoord.dwY = pstPredictionCoord->dwY;
+                }
             }
         }
     }
@@ -832,37 +850,46 @@ void lct_coordcal_two_dimension_check(LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueG
     // 校验跟踪径
     for (uint8 i = 0; i < pstMinmumValueGroup->byTrackMinimumListLen; i++)
     {
-        // x轴向右移动
-        if (byDirectionX == 1)
+        if (byChangeXY == 1)
         {
-            if (pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwX <= pstAheadCoord->dwX)
+            // x轴向右移动
+            if (byDirectionX == 1)
             {
-                pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwX = pstPredictionCoord->dwX;
+                dwGap = pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwX < pstAheadCoord->dwX;
+                if (dwGap < -LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES)
+                {
+                    pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwX = pstPredictionCoord->dwX;
+                }
             }
-        }
-        // x轴向左移动
-        else if (byDirectionX == -1)
-        {
-            if (pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwX >= pstAheadCoord->dwX)
+            // x轴向左移动
+            else if (byDirectionX == -1)
             {
-                pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwX = pstPredictionCoord->dwX;
+                dwGap = pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwX > pstAheadCoord->dwX;
+                if (dwGap > LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES)
+                {
+                    pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwX = pstPredictionCoord->dwX;
+                }
             }
         }
-
-        // y轴向上移动
-        if (byDirectionY == 1)
+        else if (byChangeXY == 2)
         {
-            if (pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwY <= pstAheadCoord->dwY)
+            // y轴向上移动
+            if (byDirectionY == 1)
             {
-                pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwY = pstPredictionCoord->dwY;
+                dwGap = pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwY < pstAheadCoord->dwY;
+                if (dwGap < -LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES)
+                {
+                    pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwY = pstPredictionCoord->dwY;
+                }
             }
-        }
-        // y轴向下移动
-        else if (byDirectionY == -1)
-        {
-            if (pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwY >= pstAheadCoord->dwY)
+            // y轴向下移动
+            else if (byDirectionY == -1)
             {
-                pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwY = pstPredictionCoord->dwY;
+                dwGap = pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwY > pstAheadCoord->dwY;
+                if (dwGap > LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES)
+                {
+                    pstMinmumValueGroup->astTrackMinimumList[i].stCoord.dwY = pstPredictionCoord->dwY;
+                }
             }
         }
     }

+ 4 - 3
src/modules/location/lct_coordcal_two.h

@@ -7,11 +7,12 @@
 #define __LCT_COORDCAL_TWO_H__
 
 #include "../../sysdefine/sysdef.h"
+#include "../../sysdefine/struct.h"
 #include "./lct_public.h"
 
 // 二维定位
-void lct_coordcal_two_dimension_location(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, uint8 byPredictionFlag, COORD_T stPredictionCoord, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueList);
-void lct_coordcal_cal_rectangle_end_point_by_bts_coord(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, COORD_T *pstLeftBottom, COORD_T *pstRightTop);
+void lct_coordcal_two_dimension_location(PUB_LCT_BTS_LIST_T *pstLctBtsList, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, uint8 byPredictionFlag, COORD_T stPredictionCoord, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueList);
+void lct_coordcal_cal_rectangle_end_point_by_bts_coord(PUB_LCT_BTS_LIST_T *pstLctBtsList, COORD_T *pstLeftBottom, COORD_T *pstRightTop);
 void lct_coordcal_cal_rectangle_two_end_point_by_coord(COORD_T stPredictionCoord, COORD_T *pstLeftBottom, COORD_T *pstRightTop);
 void lct_coordcal_gen_location_ref_point(COORD_T stLeftBottom, COORD_T stRightTop, uint8 byTrackFlag, COORD_T *pstLocationRefPoint, uint16 *pwMatrixRow, uint16 *pwMatrixCol);
 void lct_coordcal_cal_coord_points(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, COORD_T *pstLocationRefPoint, uint16 wMatrixRow, uint16 wMatrixCol, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueGroup);
@@ -20,5 +21,5 @@ void lct_coordcal_cal_two_point_transmit_times_by_coord(COORD_T stFirstPoint, CO
 void lct_coordcal_cal_delay_by_first_path_index(uint32 dwMainBtsIndex, uint32 dwSlaveBtsIndex, flt32 *pfTwoBtsDelay);
 void lct_coordcal_sel_minimum_value(flt32 *pfDelayDeviationSumMatrix, uint16 wMatrixRow, uint16 wMatrixCol, COORD_T *pstRefPointMatrix, uint8 byFirstPathFlag, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueList);
 void lct_coordcal_dbcheck_minimum_value(uint8 byFirstPathFlag, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueList);
-void lct_coordcal_two_dimension_check(LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueGroup, COORD_T *pstPredictionCoord, COORD_T *pstAheadCoord, int8 byDirectionX, int8 byDirectionY);
+void lct_coordcal_two_dimension_check(LCT_MINIMUM_VALUE_GROUP_T *pstMinmumValueGroup, COORD_T *pstPredictionCoord, COORD_T *pstAheadCoord, uint8 byChangeXY, int8 byDirectionX, int8 byDirectionY);
 #endif

+ 8 - 7
src/modules/location/lct_firstpath.c

@@ -100,7 +100,7 @@ void lct_firstpath_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *
         // TODO测试
         if (PUB_DEBUG_ENABLE)
         {
-            if (pstLctData->byFreqIndex < 8 && pstLctData->dwFrameNo > 232)
+            if (pstLctData->byFreqIndex < 8 && pstLctData->dwFrameNo > 1000)
             {
                 char *pfileName = "E:\\work\\ips8000\\aplm8000sdk\\output\\lctdata\\firstpath.bin";
                 util_write_flt32_to_bin_file(pfileName, PUB_SLOT_FRAME_LEN, gg_afOneFrameLocationData, 1);
@@ -108,7 +108,7 @@ void lct_firstpath_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *
             }
         }
 
-        // 当前一秒数据有效(是定位基站、定位基站有效、当前幅度值有效)
+        // 当前一秒数据有效(byLctBtsFlag是定位基站、byBtsValidFlag定位基站有效(前4秒信号的幅度有效,并且已实现同步)byCurrentAmplValidFlag当前幅度值有效)
         if (pstLctData->byLctBtsFlag && pstLctData->byBtsValidFlag && pstLctData->byCurrentAmplValidFlag)
         {
             // 帧内跟踪索引
@@ -148,7 +148,7 @@ void lct_firstpath_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *
                 // TODO测试
                 if (PUB_DEBUG_ENABLE)
                 {
-                    if (pstLctData->byFreqIndex < 8 && pstLctData->dwFrameNo > 220)
+                    if (pstLctData->byFreqIndex < 8 && pstLctData->dwFrameNo > 1000)
                     {
                         printf("frame no:%d, freq index:%d, sync index:%d, cal frame index:%d, cal index:%d\n", pstLctData->dwFrameNo - 1, pstFirstPath->byFreqIndex, pstLctData->dwSignalSyncIndex, pstFirstPath->wFrameCalIndex, pstFirstPath->dwCalPathIndex);
                         uint8 byTmp = 0;
@@ -195,7 +195,7 @@ void lct_firstpath_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *
             // TODO测试
             if (PUB_DEBUG_ENABLE)
             {
-                if (pstFirstPath->wFrameTrackIndex > 0 && pstLctData->byFreqIndex < 8 && pstLctData->dwFrameNo > 220)
+                if (pstFirstPath->wFrameTrackIndex > 0 && pstLctData->byFreqIndex < 8 && pstLctData->dwFrameNo > 1000)
                 {
                     printf("frame no:%d, freq index:%d, sync index:%d, track frame index:%d, track index:%d\n", pstLctData->dwFrameNo - 1, pstFirstPath->byFreqIndex, pstLctData->dwSignalSyncIndex, pstFirstPath->wFrameTrackIndex, pstFirstPath->dwTrackPathIndex);
                     uint8 byTmp = 0;
@@ -207,7 +207,7 @@ void lct_firstpath_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *
             {
                 byCounter++;
 
-                // 备份第一径数据,用于预测移动方向
+                // 备份第一径数据,用于后续模块预测手机移动方向
                 lct_firstpath_save_first_path_data(pstLctData, pstFirstPath, gLct_astPredictionDirectionDataList);
             }
         }
@@ -216,8 +216,8 @@ void lct_firstpath_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *
     // 保存第一径数据队列的基站数量
     pstFirstPathList->byBtsNum = byCounter;
 
-    // 预测移动方向
-    lct_firstpath_prediction_move_direction(gLct_astPredictionDirectionDataList);
+    // TODO预测移动方向,放到了计算模块去预测了
+    // lct_firstpath_prediction_move_direction(gLct_astPredictionDirectionDataList);
 
     return;
 }
@@ -1731,6 +1731,7 @@ uint32 lct_firstpath_recal_absolute_index(uint32 dwOldIndex)
 }
 
 // 复位预测方向数据有效标识符
+// pstPredictionDirectionDataList:预测方向数据队列
 void lct_firstpath_reset_direction_valid_flag(LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList)
 {
     LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstData = NULL;

+ 52 - 16
src/modules/location/lct_main.c

@@ -41,6 +41,7 @@ void lct_main_reset()
         memset(&gLct_stFirstPathList, 0, sizeof(LCT_FIRSTPATH_LIST_T));
         memset(&gLct_stOriginalLctCoordList, 0, sizeof(LCT_COORDSEL_ORIGINAL_COORD_T));
         memset(&gLct_stMeanLctCoordList, 0, sizeof(LCT_COORDSEL_MEAN_COORD_T));
+        memset(gLct_astPredictionDirectionDataList, 0, sizeof(LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T) * PUB_SYS_CARRIER_NUM);
 
         gLct_dwPredictionTimes = 0;
         gg_stSysStatus.byBtsCaptureFlag = 0; // 系统处于捕获基站状态
@@ -105,7 +106,7 @@ void lct_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *pstLctData
             }
 
             // 2、根据基站第一径数据组计算“极小值数据组”
-            lct_coordcal_main(pstLctDataList, &gLct_stFirstPathList, &byPredictionFlag, &stPredictionCoord, &stMinimumValueGroup, &wMinimumNum);
+            lct_coordcal_main(pstLctBtsList, pstLctDataList, &gLct_stFirstPathList, &byPredictionFlag, &stPredictionCoord, &stMinimumValueGroup, &wMinimumNum);
 
             // 3、根据“极小值数据组”选择最优定位坐标
             if (wMinimumNum > 0)
@@ -140,17 +141,8 @@ void lct_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *pstLctData
                         pstCurrentLctResult->dwCpltFlag = 1;    // 定位完成
                         pstCurrentLctResult->dwSuccessFlag = 1; // 定位成功
 
-                        // 完成基站捕获
-                        if (!gg_stSysStatus.byBtsCaptureFlag)
-                        {
-                            gg_stSysStatus.byBtsCaptureFlag = 1; // 系统进入基站跟踪阶段
-                        }
-
-                        // 进入正常定位状态
-                        if (gg_stSysStatus.byReLocationFlag)
-                        {
-                            gg_stSysStatus.byReLocationFlag = 0;
-                        }
+                        gg_stSysStatus.byBtsCaptureFlag = 1; // 系统进入基站跟踪阶段
+                        gg_stSysStatus.byReLocationFlag = 0; // 重新定位标识符置0
                     }
 
                     // 二次校验坐标(已改成在计算模块校验)
@@ -159,16 +151,19 @@ void lct_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *pstLctData
                     // 根据定位结果,更新基站第一径帧内跟踪索引
                     lct_main_update_bts_firstpath_trace_index(stOptimumCoord.bySourceFlag, &gLct_stFirstPathList, pstLctDataList);
 
-                    // 查找主站
+                    // 查找主站,包括所在的大楼编号、楼层编号和基站编号
                     lct_main_find_main_bts(&gLct_stFirstPathList, &dwMainBtsId, &dwMainBtsBuildId, &dwMainBtsLayerId);
 
                     // 保存原始坐标
                     lct_main_save_original_coord(dwMainBtsBuildId, dwMainBtsLayerId, stOptimumCoord.stCoord, &gLct_stOriginalLctCoordList);
                     stMeanCoord = stOptimumCoord.stCoord;
 
-                    // 平滑定位坐标
+                    // 平滑原始坐标
                     lct_main_mean_original_coord(&gLct_stOriginalLctCoordList, gLct_afMeanWeight, &gLct_stMeanLctCoordList, &stMeanCoord);
 
+                    // 根据定位坐标修改手机相对于基站的移动趋势
+                    lct_main_update_phone_tendency(&gLct_stMeanLctCoordList, gLct_astPredictionDirectionDataList);
+
                     // 通过imu计算位移,判断手机是否移动
                     byImuMoveFlag = imu_cal_distance_lct();
 
@@ -178,7 +173,7 @@ void lct_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *pstLctData
                     // TODO测试
                     if (PUB_DEBUG_ENABLE)
                     {
-                        printf("source:%d, x :%d, y: %d\n", stOptimumCoord.bySourceFlag, stMeanCoord.dwX, stMeanCoord.dwY);
+                        printf("frame no:%d, source:%d, x :%d, y: %d\n", gg_dwFrameNo - 1, stOptimumCoord.bySourceFlag, stMeanCoord.dwX, stMeanCoord.dwY);
 
                         char *filePathx = "E:\\work\\ips8000\\aplm8000sdk\\output\\coord\\coordx.bin";
                         char *filePathy = "E:\\work\\ips8000\\aplm8000sdk\\output\\coord\\coordy.bin";
@@ -786,4 +781,45 @@ void lct_main_write_text_file(LCT_FIRSTPATH_LIST_T *pstFirstPahtGroup)
     }
 
     return;
-}
+}
+
+// 修改手机相对于基站的移动趋势
+// pstMeanLctCoordList:定位坐标平滑队列
+// pstPredictionDirectionDataList:预测手机移动方向数据队列
+void lct_main_update_phone_tendency(LCT_COORDSEL_MEAN_COORD_T *pstMeanLctCoordList, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList)
+{
+    LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstDirectionData = NULL;
+
+    flt32 fDistanceC = 0; // 基站到当前一点的距离
+    flt32 fDistanceA = 0; // 基站到前一点的距离
+
+    uint8 byLen = pstMeanLctCoordList->byListLen;
+    if (byLen < 2)
+    {
+        return;
+    }
+
+    COORD_T stPointC = pstMeanLctCoordList->astCoordList[byLen - 1];
+    COORD_T stPointA = pstMeanLctCoordList->astCoordList[byLen - 2];
+    for (uint8 i = 0; i < PUB_SYS_CARRIER_NUM; i++)
+    {
+        pstDirectionData = &pstPredictionDirectionDataList[i];
+        if (pstDirectionData->byValidFlag)
+        {
+            fDistanceC = util_distance_cal_p2p_distance(pstDirectionData->dwCoordX, pstDirectionData->dwCoordY, stPointC.dwX, stPointC.dwY);
+            fDistanceA = util_distance_cal_p2p_distance(pstDirectionData->dwCoordX, pstDirectionData->dwCoordY, stPointA.dwX, stPointA.dwY);
+            if (fDistanceC > fDistanceA)
+            {
+                pstDirectionData->byDirectionTendency = 2;
+            }
+            else if (fDistanceC < fDistanceA)
+            {
+                pstDirectionData->byDirectionTendency = 1;
+            }
+            else
+            {
+                pstDirectionData->byDirectionTendency = 0;
+            }
+        }
+    }
+}

+ 1 - 0
src/modules/location/lct_main.h

@@ -27,6 +27,7 @@ void lct_main_save_mean_coord(COORD_T stCoord, LCT_COORDSEL_MEAN_COORD_T *pstMea
 void lct_main_adjust_firstpath_index_offset(LCT_FIRSTPATH_LIST_T *pstAheadLctFirstPahtGroup, COORD_T stLctCoord, uint8 byPathSource, PUB_LOCATION_DATA_T *pstLctDataList);
 void lct_main_adjust_slave_bts_list_index(uint8 byFreqIndex, PUB_LOCATION_DATA_T *pstLctDataList, uint32 dwBtsId, int32 dwIndexOffset);
 void lct_main_adjust_frame_index(LCT_FIRSTPATH_T *pstSlaveBtsFirstPath, int32 dwIndexOffset);
+void lct_main_update_phone_tendency(LCT_COORDSEL_MEAN_COORD_T *pstMeanLctCoordList, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList);
 
 void lct_main_write_text_file(LCT_FIRSTPATH_LIST_T *pstFirstPahtGroup);
 #endif

+ 60 - 11
src/modules/location/lct_prediction.c

@@ -20,7 +20,8 @@ extern LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T gLct_astPredictionDirectionData
 // pstAheadPointCoord:前一个点坐标(返回参数)
 // pdwSpeedX:x轴位移速度(返回参数)
 // pdwSpeedY:y轴位移速度(返回参数)
-void lct_prediction_current_coord_by_history(int32 dwBulidId, int32 dwLayerId, COORD_T *pstPredictionCoord, uint8 *pbyPredictionFlag, COORD_T *pstAheadPointCoord, int32 *pdwSpeedX, int32 *pdwSpeedY)
+// pbyChangeXY:X轴或Y轴变化大小趋势(返回参数),1:X轴变化大,2:Y轴变化大
+void lct_prediction_current_coord_by_history(int32 dwBulidId, int32 dwLayerId, COORD_T *pstPredictionCoord, uint8 *pbyPredictionFlag, COORD_T *pstAheadPointCoord, int32 *pdwSpeedX, int32 *pdwSpeedY, uint8 *pbyChangeXY)
 {
     LCT_COORDSEL_MEAN_COORD_T *pstData = (LCT_COORDSEL_MEAN_COORD_T *)&gLct_stMeanLctCoordList; // 平滑定位点队列
     uint8 byMeanListLen = pstData->byListLen;                                                   // 平滑定位点队列长度
@@ -29,6 +30,8 @@ void lct_prediction_current_coord_by_history(int32 dwBulidId, int32 dwLayerId, C
     uint8 byOriginalListLen = pstOriginalLctCoordList->byListLen;                          // 原始定位点队列长度
 
     COORD_T stPrediction = {0};
+    COORD_T *pstBaseCoord = NULL;
+    uint8 byChangeXY = 0; // X轴或Y轴变化大,1:X轴变化大,2:Y轴变化大
 
     // 处于同一大楼和楼层
     if (dwBulidId == gg_stSysStatus.dwBuildId && dwLayerId == gg_stSysStatus.dwLayerId)
@@ -75,11 +78,17 @@ void lct_prediction_current_coord_by_history(int32 dwBulidId, int32 dwLayerId, C
         // 保存预测坐标
         *pstPredictionCoord = stPrediction;
 
+        // 保存基准点坐标
+        pstBaseCoord = &pstData->astCoordList[byMeanListLen - 3];
+
         // 保存上一个定位点坐标
         *pstAheadPointCoord = pstData->astCoordList[byMeanListLen - 1];
 
         // 预测成功
         *pbyPredictionFlag = 1;
+
+        // 坐标轴变化大小趋势
+        *pbyChangeXY = abs(pstAheadPointCoord->dwX - pstBaseCoord->dwX) > abs(pstAheadPointCoord->dwY - pstBaseCoord->dwY) ? 1 : 2;
     }
     // 不在同一大楼和楼层,系统进入基站捕获状态
     else
@@ -124,7 +133,7 @@ void lct_prediction_prediction_phone_move_tendency(LCT_FIRSTPATH_PREDICTION_DIRE
             pstAheadData = pstPredictionData->astFirstPathBackupList;
             dwFrameGap = pstCurrentData->dwFrameNo - pstAheadData->dwFrameNo;
 
-            if (dwFrameGap == 8) // 数据有效
+            if (dwFrameGap == 8 && pstPredictionData->byValidFlag) // 数据有效
             {
                 // “第一径维度”靠近该基站
                 if ((pstCurrentData->dwCalPathIndex <= pstAheadData->dwCalPathIndex) || (pstCurrentData->dwTrackPathIndex <= pstAheadData->dwTrackPathIndex))
@@ -134,13 +143,30 @@ void lct_prediction_prediction_phone_move_tendency(LCT_FIRSTPATH_PREDICTION_DIRE
                     // 上一次是靠近该基站
                     if (byAheadTendency == 1)
                     {
-                        pstPredictionData->byDirectionTendency = 1; // 靠近
+                        // 前一秒是面向基站,当前一秒从基站下方走过变成背向基站,幅度快速下降
+                        if (pstCurrentData->fMaxAmplValue < (0.65 * pstAheadData->fMaxAmplValue))
+                        {
+                            pstPredictionData->byDirectionTendency = 2; // 远离
+                        }
                     }
                     // 上一次是远离该基站
                     else if (byAheadTendency == 2)
                     {
-                        // 幅度维度靠近该基站(掉头了)
-                        if (pstCurrentData->fMaxAmplValue >= (1.5 * pstAheadData->fMaxAmplValue))
+                        // 前一秒是背向远离基站,当前一秒是面向靠近基站(掉头或者转弯),幅度快速增加
+                        if (pstCurrentData->fMaxAmplValue > (1.35 * pstAheadData->fMaxAmplValue))
+                        {
+                            pstPredictionData->byDirectionTendency = 1; // 靠近
+                        }
+                        else
+                        {
+                            pstPredictionData->byDirectionTendency = 0; // 方向不确定
+                        }
+                    }
+                    // 上一次趋势不确定
+                    else
+                    {
+                        // 第一径是靠近趋势,幅度也是靠近趋势
+                        if (pstCurrentData->fMaxAmplValue > pstAheadData->fMaxAmplValue)
                         {
                             pstPredictionData->byDirectionTendency = 1; // 靠近
                         }
@@ -155,11 +181,11 @@ void lct_prediction_prediction_phone_move_tendency(LCT_FIRSTPATH_PREDICTION_DIRE
                 {
                     pstPredictionData->byDirectionTendency = 2; // 远离
 
-                    // 上一次是靠近该基站
+                    // 前一秒是面向靠近基站,当前第一径远离背向基站,相当于进行了一次掉头或者拐弯,幅度会快速下降
                     if (byAheadTendency == 1)
                     {
-                        // 幅度维度远离该基站
-                        if (pstCurrentData->fMaxAmplValue <= (0.5 * pstAheadData->fMaxAmplValue))
+                        // 幅度变化剧烈,掉头或者拐弯
+                        if (pstCurrentData->fMaxAmplValue < (0.6 * pstAheadData->fMaxAmplValue))
                         {
                             pstPredictionData->byDirectionTendency = 2; // 远离
                         }
@@ -168,24 +194,36 @@ void lct_prediction_prediction_phone_move_tendency(LCT_FIRSTPATH_PREDICTION_DIRE
                             pstPredictionData->byDirectionTendency = 0; // 方向不确定
                         }
                     }
-                    // 上一次是远离该基站
                     else if (byAheadTendency == 2)
                     {
                         pstPredictionData->byDirectionTendency = 2; // 远离
                     }
+                    else
+                    {
+                        // 第一径远离,幅度远离
+                        if (pstCurrentData->fMaxAmplValue < pstAheadData->fMaxAmplValue)
+                        {
+                            pstPredictionData->byDirectionTendency = 2; // 远离
+                        }
+                        else
+                        {
+                            pstPredictionData->byDirectionTendency = 0; // 方向不确定
+                        }
+                    }
                 }
             }
         }
     }
 }
 
-// 预测手机相对于每一个基站在X/Y轴移动方向
+// 预测手机在X/Y轴移动方向
 // pstPredictionDirectionDataList:预测移动方向的数据队列
 // pbyDirectionX:X轴移动方向
 // pbyDirectionY:Y轴移动方向
 void lct_prediction_prediction_phone_x_y_move_direction(LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, COORD_T stAheadCoord, int8 *pbyDirectionX, int8 *pbyDirectionY)
 {
     LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstCurrentBtsDirectionData = NULL; // 当前基站方向预测数据
+    LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstOtherBtsDirectionData = NULL;   // 其它基站方向预测数据
     int8 byDirectionX = 0;
     int8 byDirectionY = 0;
 
@@ -196,6 +234,17 @@ void lct_prediction_prediction_phone_x_y_move_direction(LCT_FIRSTPATH_PREDICTION
         pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[i];
         if (pstCurrentBtsDirectionData->byValidFlag && pstCurrentBtsDirectionData->byDirectionTendency)
         {
+            for (uint8 j = 0; j < PUB_SYS_CARRIER_NUM; j++)
+            {
+                if (i != j)
+                {
+                    pstOtherBtsDirectionData = &pstPredictionDirectionDataList[j];
+                    if (pstOtherBtsDirectionData->byValidFlag && pstOtherBtsDirectionData->byDirectionTendency)
+                    {
+                    }
+                }
+            }
+
             // 靠近该基站
             if (pstCurrentBtsDirectionData->byDirectionTendency == 1)
             {
@@ -270,4 +319,4 @@ void lct_prediction_prediction_phone_x_y_move_direction(LCT_FIRSTPATH_PREDICTION
     *pbyDirectionY = byDirectionY;
 
     return;
-}
+}

+ 1 - 1
src/modules/location/lct_prediction.h

@@ -10,7 +10,7 @@
 #include "./lct_public.h"
 
 // 供外部使用接口
-void lct_prediction_current_coord_by_history(int32 dwBulidId, int32 dwLayerId, COORD_T *pstPredictionCoord, uint8 *pbyPredictionFlag, COORD_T *pstAheadPointCoord, int32 *pdwSpeedX, int32 *pdwSpeedY);
+void lct_prediction_current_coord_by_history(int32 dwBulidId, int32 dwLayerId, COORD_T *pstPredictionCoord, uint8 *pbyPredictionFlag, COORD_T *pstAheadPointCoord, int32 *pdwSpeedX, int32 *pdwSpeedY, uint8 *pbyChangeXY);
 void lct_prediction_prediction_phone_move_tendency(LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList);
 void lct_prediction_prediction_phone_x_y_move_direction(LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, COORD_T stAheadCoord, int8 *pbyDirectionX, int8 *pbyDirectionY);
 

+ 2 - 0
src/sysdefine/struct_bts.h

@@ -13,6 +13,8 @@
 #define BTS_AMPL_MIRROR_SECONDS 4                            // 镜像秒数,几秒计算一次最强频点
 #define BTS_AMPL_MIRROR_FRAMES (4 * BTS_AMPL_MIRROR_SECONDS) // 镜像帧数,每秒4帧
 #define BTS_AMPL_MAIN_BTS_AMPL_VALID_THRESHOLD 1500          // 主站幅度有效门限(用户在某个时刻一定会更靠近某个基站,所以该基站幅度至少要大于该门限值)
+#define BTS_AMPL_BTS_AMPL_VALID_THRESHOLD 350                // 基站幅度有效门限
+#define BTS_AMPL_BTS_SNR_VALID_THRESHOLD 5                   // 基站SNR有效门限
 
 // 同步模块宏定义
 #define BTS_SYNC_STABLE_SYNC_FRAMES BTS_AMPL_MIRROR_FRAMES // 同步帧数,即几帧进行一次同步

+ 8 - 0
src/sysdefine/struct_lct.h

@@ -18,6 +18,12 @@
 #define LCT_MINIMUM_NUM 18           // 极小值队列长度
 #define LCT_FIRST_PATH_BACKUP_NUM 3  // 第一径备份数据深度(用于预测移动方向)
 
+#define LCT_COORDCAL_FIRSTPATH_ADJUST_THRES 150 // 第一径调整门限(100厘米)
+#define LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE 75  // 第一径调整值(50厘米)
+
+#define LCT_COORDCAL_MINIMUM_VALUE_ADJUST_THRES 120 // 极小值调整门限(120厘米)
+#define LCT_COORDCAL_MINIMUM_VALUE_ADJUST_VALUE 50  // 极小值调整值(50厘米)
+
 // 最优定位坐标选择模块
 #define LCT_COORDSEL_PP_TIME_GAP 1        // 两点之间的时长间隔(单位秒)
 #define LCT_COORDSEL_MINIMUM_VALUE_NUM 11 // 极小值点数(当前径5个,跟踪径5个,IMU1个)
@@ -136,6 +142,8 @@ typedef struct
     uint8 byDirectionTendency; // 当前一秒方向趋势,0:趋势不一致, 1:趋势一致靠近,2:趋势一致远离
     int8 byDirectionX;         // X轴方向,1:向右、-1:向左,0:未知
     int8 byDirectionY;         // Y轴方向,1:向上、-1:向下,0:未知
+    uint8 byDirectionXCounter; // 方向校验正确次数
+    uint8 byDirectionYCounter; // 方向校验正确次数
 
     // 基站坐标
     int32 dwCoordX; // 基站x坐标

+ 5 - 3
src/sysdefine/sysmacro.h

@@ -12,8 +12,10 @@
 
 // V2.1.00 2025-02-08 by zt 增加软件版本接口
 // V2.1.01 2025-04-14 by zt 修改代码缺陷(修复轨迹跳变,修改极小值选择方法、用运动方向二次校验极小值)
+// V2.1.02 2025-04-22 by zt 完善代码(完善手机移动方向预测代码,并将预测方向应用到二维定位中(利用预测方向修订第一径);
+// 修改信号同步模块中的设计缺陷,解决轨迹跳变问题,改善了定位效果)
 #define PUB_SOFTWARE_VERSION_LEN 7
-#define PUB_SOFTWARE_VERSION "V2.1.01" // 软件版本
+#define PUB_SOFTWARE_VERSION "V2.1.02" // 软件版本
 
 #define PUB_M_PI 3.14159265358979323846
 #define PUB_2PI (2 * 3.14159265358979323846)
@@ -71,7 +73,7 @@
 #define PUB_MAC_ADDRESS_LEN 12 // MAC地址字节数
 
 // 测试宏定义
-// #define PUB_DEBUG_ENABLE 1 // 打开调试开关
-#define PUB_DEBUG_ENABLE 0 // 关闭调试开关
+#define PUB_DEBUG_ENABLE 1 // 打开调试开关
+// #define PUB_DEBUG_ENABLE 0 // 关闭调试开关
 
 #endif

+ 4 - 4
src/sysmain/sysmain.c

@@ -61,7 +61,7 @@ void sysmain_init_lct()
     stFirstPathParam.byNoiseSignalFactor = 7;
     stFirstPathParam.byNoiseLowScale = 25;   // 底噪放大低倍数,放大10倍保存
     stFirstPathParam.byNoiseHightScale = 50; // 底噪放大高倍数,放大10倍保存
-    stFirstPathParam.byCfarLeftFactor = 135; // 120; //update 135 by zt 2025-01-09
+    stFirstPathParam.byCfarLeftFactor = 120; // 120; //update 125 by zt 2025-01-09
     stFirstPathParam.bySincFactor = 94;      // 95;
     stFirstPathParam.byFirstPathContactFactor = 75;
     stFirstPathParam.wFirstPathContactDistance = 1200; // 8米
@@ -87,9 +87,9 @@ void sysmain_init_lct()
     stLctCoordcalParam.dwMinimumValueNum = 5;
 
     // 判断二维基站第一径是否有效参数
-    stLctCoordcalParam.dwFirstPahtValueThres = 150;     // 二维第一径幅度有效门限
-    stLctCoordcalParam.dwFirstPahtSnrThres = 35;        // 二维第一径信噪有效门限(放大10倍)
-    stLctCoordcalParam.dwFirstPathIndexJumpThres = 500; // 二维第一径跳变又有效门限
+    stLctCoordcalParam.dwFirstPahtValueThres = 150;      // 二维第一径幅度有效门限
+    stLctCoordcalParam.dwFirstPahtSnrThres = 35;         // 二维第一径信噪有效门限(放大10倍)
+    stLctCoordcalParam.dwFirstPathIndexJumpThres = 1000; // 500; // 二维第一径跳变又有效门限
 
     // 判断一维基站第一径是否有效参数
     stLctCoordcalParam.dwOneFirstPahtValueThres = 300;     // 一维第一径幅度有效门限