// 秒寻科技
// 定位模块参数
// zt
// 2023-03-30

#ifndef __STRUCT_LCT_H__
#define __STRUCT_LCT_H__

#include "./datatype.h"
#include "./sysmacro.h"

#define LCT_INIT_LCT_TIMES (LCT_COORDSEL_ORIGINAL_COORD_LIST_LEN + LCT_COORDSEL_MEAN_COORD_LIST_LEN) // 初始化阶段计定位次数

#define LCT_RECTANGLE_LEN 4000                         // 默认搜索矩阵边长，单位厘米
#define LCT_INIT_SEARCH_LEN (500 * LCT_INIT_LCT_TIMES) // 初始阶段搜索矩形单边边长，单位厘米

#define LCT_REF_POINT_MATRIX_LEN 200 // 定位参考点时延二维矩阵长度（搜索矩形最大为40米*40米）
#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 300 // 极小值调整门限（300厘米）
// #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个)

// 预测秒数
#define LCT_MAIN_MAX_USE_PREDICTION_COORD_TIMES 4 // 最大使用预测坐标次数

/***********************************************************************************************/
/***************************************计算第一径模块*********************************************/

// 计算第一径模块参数
typedef struct
{
    uint8 byMinValueFactor;
    // 帧内锚点选择因子，默认值21
    uint8 byAnchorFactor;
    // 锚点门限默认值(30),放大100倍保存
    uint8 byAnchorThreshold;
    // 从信号中选择峰的最小间距（两峰之间的距离要大于等于该值才合法），默认值50
    uint8 byPeakPeakDistance;

    // 计算噪声门限时的信号因子，默认值7
    uint8 byNoiseSignalFactor;
    // （计算噪声门限时）底噪一级放大倍数（帧内噪声*该放大倍数），默认值3
    uint8 byNoiseHightScale;
    // （计算噪声门限时）底噪二级放大倍数（帧内噪声*该放大倍数），默认值5
    uint8 byNoiseLowScale;

    // cfar左侧因子,放大100倍保存(检查左侧峰)，默认值120
    uint8 byCfarLeftFactor;

    // sinc模型因子，放大100倍保存（基于sinc规则选择第一径时，帧内最大值*该因子），默认值95
    uint8 bySincFactor;

    // 第一径各峰间联系因子和联系距离
    uint8 byFirstPathContactFactor;   // 第一径的峰值*该因子，作为选择第二径的门限，默认值75
    uint16 wFirstPathContactDistance; // 第一径与第二径之间的距离需要小于该距离才合法，默认值1000

    uint16 wFirstPathTrackWindowWidth;    // 第一径跟踪窗口宽度（单边宽度），默认值280
    uint16 wFirstPathTrackPeakGuardWidth; // 第一径跟踪峰值保护宽度，默认值160
    uint16 wFirstPathTrackNoiseFindWidth; // 第一径跟踪噪声查找宽度，默认值1000（应该是880）
    uint8 byFirstPathTrackPeakGainFactor; // 第一径跟踪峰值增益因子(放大100倍保存)，默认值120
} LCT_FIRSTPATH_PARAM_T;

// 第一径峰结构
typedef struct
{
    uint16 wPeakIndex;  // 峰值索引
    uint32 dwPeakValue; // 峰值
} LCT_FIRSTPATH_PEAK_T;

// 计算定位坐标所需的基站第一径结构
typedef struct
{
    uint8 byMainFlag; // 主站标识，1：主站，2：从站

    uint32 dwBuildId; // 基站所在大楼编号
    uint32 dwLayerId; // 基站所在楼层编号

    uint32 dwBtsId;    // 基站ID
    uint8 byFreqIndex; // 基站频率
    uint8 bySlot;      // 基站时隙

    int32 dwCoordX; // 基站x坐标
    int32 dwCoordY; // 基站y坐标
    int32 dwCoordZ; // 基站z坐标

    uint32 dwLctType;                          // 定位类型，1：单站定位，2：双站定位，3：三站定位，4：多站定位
    uint32 dwTwoBtsNum;                        // 本站与几个站进行双站定位
    uint32 adwTwoBtsList[PUB_TWO_BTS_MAX_NUM]; // 与本站进行双站定位的基站ID列表

    // 帧内径
    flt32 fMaxAmplValue;        // 最大值幅度
    flt32 fFrameCalPathValue;   // 帧内计算径最大值
    uint16 wFrameCalIndex;      // 帧内计算径索引，相对索引
    flt32 fFrameTrackPathValue; // 第一径帧内跟踪径最大值
    uint16 wFrameTrackIndex;    // 第一径帧内跟踪索引

    // 绝对径
    uint32 dwCalPathIndex;    // 计算径索引，绝对索引
    flt32 fCalPathIndexSnr;   // 计算径信噪比
    uint32 dwTrackPathIndex;  // 跟踪径索引，绝对索引
    flt32 fTrackPathIndexSnr; // 跟踪径信噪比

    // 手机相对于基站的移动方向
    int8 byDirectionX; // X轴移动方向，-1：减小，1：增大，0，不变
    int8 byDirectionY; // Y轴移动方向，-1：减小，1：增大，0，不变
} LCT_FIRSTPATH_T;

// 计算定位坐标所需的第一径队列
typedef struct
{
    uint8 byBtsNum;                                    // 基站数
    LCT_FIRSTPATH_T astFirstPath[PUB_LCT_BTS_MAX_NUM]; // 第一径队列
} LCT_FIRSTPATH_LIST_T;

// 第一径备份数据
typedef struct
{
    uint32 dwFrameNo;        // 帧号
    flt32 fMaxAmplValue;     // 最大幅度
    uint32 dwCalPathIndex;   // 计算径索引
    uint32 dwTrackPathIndex; // 跟踪径索引
} LCT_FIRSTPATH_BACKUP_T;

// 第一径预测方向数据
typedef struct
{
    // 有效标识符，0：无效，1：有效
    uint8 byValidFlag;

    // 第一径备份数据队列
    uint32 dwFirstPathBackupIndex;                                            // 第一径备份数据索引
    LCT_FIRSTPATH_BACKUP_T astFirstPathBackupList[LCT_FIRST_PATH_BACKUP_NUM]; // 第一径备份数据队列，前两秒数据，前一秒数据，当前数据
    // uint8 byAheadDirectionTendency;                                           // 上一秒方向趋势，0:趋势不一致， 1：趋势一致靠近，2：趋势一致远离
    uint8 byDirectionTendency; // 当前一秒方向趋势，0:趋势不一致， 1：趋势一致靠近，2：趋势一致远离
    int8 byDirectionX;         // X轴方向，1：向右、-1：向左，0：未知
    int8 byDirectionY;         // Y轴方向，1：向上、-1：向下，0：未知
    uint8 byDirectionXCounter; // 方向校验正确次数
    uint8 byDirectionYCounter; // 方向校验正确次数

    // 基站坐标
    int32 dwCoordX; // 基站x坐标
    int32 dwCoordY; // 基站y坐标
    int32 dwCoordZ; // 基站z坐标

    // 计算径索引
    uint32 dwCalPathIndex;
} LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T;

/***********************************************************************************************/
/***************************************计算坐标模块*********************************************/
// 计算定位坐标模块参数结构
typedef struct
{
    // 声音速度，默认340米/秒
    uint32 dwAudioSpeed;

    // 手机Z坐标，默认120，单位厘米
    uint32 dwPhoneCoordZ;

    // 初始状态下搜索矩形坐标扩展长度，默认250，单位厘米
    uint32 dwCoordExpendLen;

    // 初始状态下定位参考点间隔，默认50，单位厘米
    uint32 dwIntervalDistance;

    // 跟踪状态下，搜索矩形坐标扩展长度，默认值150，单位厘米
    uint32 dwTrackCoordExpendLen;

    // 跟踪状态下，定位参考点间隔，默认25，单位厘米
    uint32 dwTrackIntervalDistance;

    // 有效极小值点个数(传回上层的极小值点个数)，默认值最多5个
    uint32 dwMinimumValueNum;

    uint32 dwFirstPahtValueThres;     // 二维第一径幅度值门限，默认值150
    uint32 dwFirstPahtSnrThres;       // 二维第一径信噪比门限(放大10倍)，默认值35
    uint32 dwFirstPathIndexJumpThres; // 二维第一径跳变门限，默认值500

    uint32 dwOneFirstPahtValueThres;     // 一维 第一径幅度值门限，默认值300
    uint32 dwOneFirstPahtSnrThres;       // 一维第一径信噪比门限(放大10倍)，默认值50
    uint32 dwOneFirstPathIndexJumpThres; // 一维第一径跳变门限，默认值400

    uint32 dwBtsEdgeExpendLen;            // 基站围成的矩形框向外扩展长度，默认值200
    uint32 dwOneDimensionExpendLen;       // 一维定位时向外扩展长度，默认值200
    uint32 dwOneDimensionSquareExpendLen; // 一维定位检查时向外扩展长度，默认值500，用于判断定位点是否在基站对围城的矩形框内部
} LCT_COORDCAL_PARAM_T;

// 第一径标识符枚举
enum LCT_COORDCAL_PATH_FLAG
{
    CAL_PATH = 0, // 计算径
    TRACK_PATH,   // 跟踪径
};

#define LCT_COORDCAL_ONE_DIMENSION_BTS_DUAD_MAX_NUM 32 // 1维基站队最大数
// 一维基站对结构
typedef struct
{
    uint32 dwFirstBtsId;
    uint32 dwSecondBtsId;
    LCT_FIRSTPATH_T astBtsList[2]; // 基站第一径数据
    uint8 byBtsNum;                // 一维基站对的基站数量，可以时1或者2
    COORD_T stLctCoord;            // 定位坐标
    flt32 fDelayDeviation;         // 时延误差
    uint8 byInsideFlag;            // 预测坐标在该组基站矩形内部标识符，0：外部，1：内部，2：边缘，
    flt32 fSnr;                    // 一维基站对SNR总和
    flt32 fAmplMaxValue;           // 帧内幅度最大值
} LCT_COORDCAL_ONE_DIMENSION_BTS_DUAD_T;

// 一维基站队列
typedef struct
{
    uint8 byBtsDuadNum;                                                                                // 基站对数量
    LCT_COORDCAL_ONE_DIMENSION_BTS_DUAD_T astBtsDuadList[LCT_COORDCAL_ONE_DIMENSION_BTS_DUAD_MAX_NUM]; // 基站对数量
} LCT_COORDCAL_ONE_DIMENSION_BTS_DUAD_LIST_T;

// 一维线性方程结构
typedef struct
{
    uint8 byVerticalFlag; // 0:不垂直，1：垂直于X轴，2：垂直于Y轴
    int32 dwValueCoordX;  // 垂直于X坐标的X值
    int32 dwValueCoordY;  // 垂直于Y坐标的Y值
    flt32 fK;             // K系数
    flt32 fB;             // B系数
    uint8 byDirection;    // 1:X轴延伸，2：Y轴延伸
} LCT_COORDCAL_LINEAR_FUNC_T;

/***********************************************************************************************/
/***************************************选择坐标模块*********************************************/

// 最优坐标选择模块
#define LCT_COORDSEL_ORIGINAL_COORD_LIST_LEN 3                                      // 原始坐标队列长度
#define LCT_COORDSEL_MEAN_COORD_LIST_LEN (LCT_COORDSEL_ORIGINAL_COORD_LIST_LEN + 1) // 平滑坐标队列长度
#define LCT_COORDSEL_WEIGHT_LIST_LEN (LCT_COORDSEL_MEAN_COORD_LIST_LEN - 1)         // 权重队列深度

// 选择最优定位坐标模块参数结构
typedef struct
{
    uint32 dwValidDistanceThres; // 合法距离门限，默认值350，放大100倍保存
    uint32 dwPredictionRadius;   // 预测半径
} LCT_COORDSEL_PARAM_T;

// // 历史定位坐标结构(保存几次定位点，预测后面一个点)
// typedef struct
// {
//     uint32 dwLocationedTimes; // 定位次数
//     uint8 byListLen;
//     COORD_T astCoordList[LCT_COORDSEL_MEAN_COORD_LIST_LEN];

//     int32 dwPredicX; // 预测点X坐标
//     flt32 fParamA;   // 拟合直线参数A
//     flt32 fParamB;   // 拟合直线参数A
// } LCT_COORDSEL_LCT_COORD_T;

// 原始定位坐标
typedef struct
{
    uint32 dwBuildId; // 大楼编号
    uint32 dwLayerId; // 楼层编号
    uint8 byListLen;  // 队列长度
    COORD_T astCoordList[LCT_COORDSEL_ORIGINAL_COORD_LIST_LEN];
} LCT_COORDSEL_ORIGINAL_COORD_T;

// 平滑定位坐标
typedef struct
{
    uint32 dwBuildId; // 大楼编号
    uint32 dwLayerId; // 楼层编号
    uint8 byListLen;
    COORD_T astCoordList[LCT_COORDSEL_MEAN_COORD_LIST_LEN];
    uint32 adwFirstPathOffset[LCT_COORDSEL_MEAN_COORD_LIST_LEN];
} LCT_COORDSEL_MEAN_COORD_T;

// 手机与基站间距离趋势(靠近或者远离)
typedef struct
{
    uint32 dwBtsId;    // 基站ID
    uint8 byFreqIndex; // 频率索引

    flt32 afDist[2];      // 上一次定位点到基站的距离
    uint8 byDistTendency; // 距离趋势， 1:靠近，2：远离
    flt32 fAheadAmpl;     // 上一次定位点到基站的距离
    flt32 fCurrentAmpl;   // 当前定位点到基站的距离
    uint8 byAmplTendency; // 幅度趋势， 1:靠近，2：远离

} LCT_BTS_DISTANCE_TENDENCY_T;

// 定位点与基站间距离趋势列表
typedef struct
{
    uint8 byBtsNum; // 基站数量
    LCT_BTS_DISTANCE_TENDENCY_T astBts[PUB_SYS_CARRIER_NUM];
} LCT_BTS_DISTANCE_TENDENCY_LIST_T;

#endif