Exemplo n.º 1
0
        /// <summary>
        /// 对帧缓冲进行处理
        /// </summary>
        /// <param name="frame">帧缓冲</param>
        /// <param name="index">帧的索引号</param>
        private void SelfDeal(Gps_NmeaFrame frame, int type)
        {
            string content_frame = frame.GetFrame();

            // 添加信息到队列中
            mCustomDataModel.Rev_Msg_Queue.Enqueue(content_frame);

            if (frame.TalkerId == "GP")
            {
                mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_GP_AVAILABLE] = true;
            }
            else if (frame.TalkerId == "BD")
            {
                mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_GB_AVAILABLE] = true;
            }
            else if (frame.TalkerId == "GN")
            {
                mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_GP_AVAILABLE] = true;
                mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_GB_AVAILABLE] = true;
            }

            // 将结果组
            try
            {
                // 根据结果进行赋值
                switch (type)
                {
                case NMEA_FRAME_TYPE_GGA:
                    // GGA帧处理
                    #region
                    mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_GGA_AVAILABLE] = true;

                    // utc
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_UTC_TIME].Info     = frame.DataSrc[NMEA_FRAME_GGA_POS_TIME];
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_UTC_TIME].IsUpdate = true;

                    // 纬度
                    string str_lat = frame.DataSrc[NMEA_FRAME_GGA_POS_LAT];

                    if (str_lat.Length > 5)
                    {
                        try
                        {
                            double val = Convert.ToDouble(str_lat.Substring(0, 2)) + Convert.ToDouble(str_lat.Substring(2, (str_lat.Length - 2))) / 60.0;
                            LattitudeDataArr.AddData(val);
                        }
                        catch
                        { }

                        str_lat  = str_lat.Insert(2, "°");
                        str_lat += "'";
                    }
                    // 存储纬度
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_LATITUDE].Info     = str_lat;
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_LATITUDE].IsUpdate = true;
                    // 存储纬度std
                    mCustomDataModel.DataBaseList[CustomDataModel.STR_LATITUDE_STD].Info     = LattitudeDataArr.GetStdVal().ToString("#.##E+00") + "°";
                    mCustomDataModel.DataBaseList[CustomDataModel.STR_LATITUDE_STD].IsUpdate = true;
                    // 经度
                    string str_long = frame.DataSrc[NMEA_FRAME_GGA_POS_LONG];
                    if (str_long.Length > 5)
                    {
                        try
                        {
                            double val = Convert.ToDouble(str_long.Substring(0, 3)) + Convert.ToDouble(str_long.Substring(3, (str_long.Length - 3))) / 60.0;
                            LongtitudeDataArr.AddData(val);
                        }
                        catch
                        { }


                        str_long  = str_long.Insert(3, "°");
                        str_long += "'";
                    }
                    // 存储经度
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_LONGTITUDE].Info     = str_long;
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_LONGTITUDE].IsUpdate = true;
                    // 存储经度std
                    mCustomDataModel.DataBaseList[CustomDataModel.STR_LONGTITUDE_STD].Info     = LongtitudeDataArr.GetStdVal().ToString("#.##E+00") + "°";
                    mCustomDataModel.DataBaseList[CustomDataModel.STR_LONGTITUDE_STD].IsUpdate = true;

                    // 高度
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_ALTITUDE].Info     = frame.DataSrc[NMEA_FRAME_GGA_POS_ALT];
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_ALTITUDE].IsUpdate = true;

                    // 椭球高度
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_ELLIPSOIDAL_HEIGHT].Info     = frame.DataSrc[NMEA_FRAME_GGA_POS_SEP];
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_ELLIPSOIDAL_HEIGHT].IsUpdate = true;

                    // 卫星数量
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_SATELLITE_NUM].Info     = frame.DataSrc[NMEA_FRAME_GGA_POS_NUMSV];
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_SATELLITE_NUM].IsUpdate = true;

                    // 定位精度
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_POSITION_ACC].Info     = frame.DataSrc[NMEA_FRAME_GGA_POS_HDOP];
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_POSITION_ACC].IsUpdate = true;

                    // 定位状态
                    mCustomDataModel.DataBaseList[CustomDataModel.POS_STATE].Info     = frame.DataSrc[NMEA_FRAME_GGA_POS_QUALITY];
                    mCustomDataModel.DataBaseList[CustomDataModel.POS_STATE].IsUpdate = true;

                    break;

                    #endregion
                case NMEA_FRAME_TYPE_RMC:
                    mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_RMC_AVAILABLE] = true;
                    break;

                case NMEA_FRAME_TYPE_GSV:
                    mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_GSV_AVAILABLE] = true;
                    // GSV帧处理函数
                    #region
                    // 预估当前帧中的卫星个数
                    int NumSatelite = frame.DataSrc.Count - NMEA_FRAME_GSV_POS_SATELLITE_SV;

                    // 获取卫星数量
                    int numsv = Convert.ToInt32(frame.DataSrc[NMEA_FRAME_GSV_POS_NUMSV]);

                    // 如果卫星数为0,则直接返回
                    if (numsv == 0)
                    {
                        break;
                    }

                    // 判断帧是否正确,不正确直接跳出
                    if (NumSatelite % NMEA_FRAME_GSV_SATALITES_INFO_LEN != 0)
                    {
                        // 该处对NMEA4.1极其以上做出兼容,末尾端有一个字符
                        if ((NumSatelite - NMEA_FRAME_GSV_SIGNAL_ID_LEN) % NMEA_FRAME_GSV_SATALITES_INFO_LEN != 0)
                        {
                            break;
                        }
                    }

                    // 计算卫星个数
                    NumSatelite /= NMEA_FRAME_GSV_SATALITES_INFO_LEN;

                    // 帧头字符串
                    string headlabel = "";

                    // 如果为北斗卫星
                    if (frame.TalkerId.Equals(NMEA_FRAME_TALKERID_BD))
                    {
                        // 生成标签
                        headlabel = "B";
                    }    // 否则为GPS卫星
                    else
                    {
                        headlabel = "G";
                    }

                    for (int i = 0; i < NumSatelite; i++)
                    {
                        // 清空字符串
                        string label = "";

                        // 生成label
                        label = headlabel + frame.DataSrc[NMEA_FRAME_GSV_POS_SATELLITE_SV + i * NMEA_FRAME_GSV_SATALITES_INFO_LEN];

                        // 生成值
                        double val = 0.0;
                        double elv = 0.0;
                        double azi = 0.0;

                        // 将内容转换出来
                        try
                        {
                            val = Convert.ToDouble(frame.DataSrc[NMEA_FRAME_GSV_POS_SATELLITE_CNO + i * NMEA_FRAME_GSV_SATALITES_INFO_LEN]);
                        }
                        catch
                        {
                            val = 0.0;
                        }

                        try
                        {
                            elv = Convert.ToDouble(frame.DataSrc[NMEA_FRAME_GSV_POS_SATELLITE_ELV + i * NMEA_FRAME_GSV_SATALITES_INFO_LEN]);
                        }
                        catch
                        {
                            elv = CustomDataModel.GPS_SAT_ANG_INVALID;
                        }

                        try
                        {
                            azi = Convert.ToDouble(frame.DataSrc[NMEA_FRAME_GSV_POS_SATELLITE_AZ + i * NMEA_FRAME_GSV_SATALITES_INFO_LEN]);
                        }
                        catch
                        {
                            azi = CustomDataModel.GPS_SAT_ANG_INVALID;
                        }

                        // 生成一个对象
                        SateLiteInfoItem item = new SateLiteInfoItem(label, val, NMEA_FRAME_GSV_SIGNAL_STRENGTH_MAX, azi, elv);

                        // 添加数据到链表中
                        mCustomDataModel.SateLiteStrengthData_Add_Intelligence(item);
                    }
                    break;

                    #endregion
                case NMEA_FRAME_TYPE_GAS:
                    mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_GAS_AVAILABLE] = true;

                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_GAS_COORDINATION_X].Info = frame.DataSrc[NMEA_FRAME_GAS_X_COODINATION];
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_GAS_COORDINAIION_Y].Info = frame.DataSrc[NMEA_FRAME_GAS_Y_COODINATION];
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_PDOP].Info = frame.DataSrc[NMEA_FRAME_GAS_PDOP];
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_GAS_COORDINATION_X].IsUpdate = true;
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_GAS_COORDINAIION_Y].IsUpdate = true;
                    mCustomDataModel.DataBaseList[CustomDataModel.LABEL_PDOP].IsUpdate = true;
                    break;

                case NMEA_FRAME_TYPE_GSA:
                    // PDOP
                    //mCustomDataModel.DataBaseList[CustomDataModel.LABEL_PDOP].Info = frame.DataSrc[NMEA_FRAME_GSA_POS_PDOP];
                    //mCustomDataModel.DataBaseList[CustomDataModel.LABEL_PDOP].IsUpdate = true;
                    break;

                case NMEA_FRAME_TYPE_HPD:
                    mCustomDataModel.Gps_Receiver_State[CustomDataModel.GPS_REV_STATE_HPD_AVAILABLE] = true;



                    break;

                default: break;
                }
            }
            catch (Exception exp)
            {
                Console.Write(exp.ToString());
                return;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 初始化解析状态机,初始化每个动作所执行的操作
        /// </summary>
        private void NmeaParseMoniterInit()
        {
            // 初始化状态机
            ParseMoniter  = new Dictionary <NmeaFrame_ParseState, Action <byte> >();
            Current_State = NmeaFrame_ParseState.Null_State;

            //帧头状态
            ParseMoniter[NmeaFrame_ParseState.Head_State] = (byte data) =>
            {
                // 计算crc
                Current_Crc ^= data;

                // 如果获得分隔符
                if (data == Gps_NmeaFrame.NMEA_FRAME_SEPARATE_BYTE)
                {
                    string talkerid;
                    string contentid;

                    // 如果分析成功
                    if (Gps_NmeaFrame.GetHeadInfo(mStrBuffer, out talkerid, out contentid) == true)
                    {
                        // 清除缓冲
                        mStrBuffer = "";
                        // 清除计数器
                        ParseMoniterCnt = 0;

                        // 根据帧类型保存帧类型状态
                        if (contentid.Equals(NMEA_FRAME_CONTENTID_GGA))
                        {
                            mTmpFrameType = NMEA_FRAME_TYPE_GGA;
                        }
                        else if (contentid.Equals(NMEA_FRAME_CONTENTID_RMC))
                        {
                            mTmpFrameType = NMEA_FRAME_TYPE_RMC;
                        }
                        else if (contentid.Equals(NMEA_FRAME_CONTENTID_GSV))
                        {
                            mTmpFrameType = NMEA_FRAME_TYPE_GSV;
                        }
                        else if (contentid.Equals(NMEA_FRAME_CONTENTID_GAS))
                        {
                            mTmpFrameType = NMEA_FRAME_TYPE_GAS;
                        }
                        else if (contentid.Equals(NMEA_FRAME_CONTENTID_GSA))
                        {
                            mTmpFrameType = NMEA_FRAME_TYPE_GSA;
                        }
                        else if (contentid.Equals(NMEA_FRAME_CONTENTID_HPD))
                        {
                            mTmpFrameType = NMEA_FRAME_TYPE_HPD;
                        }
                        else
                        {
                            Current_State = NmeaFrame_ParseState.Null_State;
                            return;
                        }
                        // 清除缓冲数组
                        mGpsMsgBuff[mTmpFrameType].Clear();

                        // 添加帧头到头部
                        mGpsMsgBuff[mTmpFrameType].AddHead(talkerid, contentid);

                        // 切换到下一个状态
                        Current_State = NmeaFrame_ParseState.Data_State;
                    } // 分析出错
                    else
                    {   // 复位状态机
                        Current_State = NmeaFrame_ParseState.Null_State;
                    }
                } // 如果没有获得分隔符
                else
                {
                    // 添加数据到临时缓冲
                    mStrBuffer += (char)data;
                }

                // 如果索引值超出限制,直接恢复状态机
                if (ParseMoniterCnt++ > (Gps_NmeaFrame.NMEA_FRAME_HEAD_LEN - 1))
                {
                    Current_State = NmeaFrame_ParseState.Null_State;
                }
            };

            //帧数据状态
            ParseMoniter[NmeaFrame_ParseState.Data_State] = (byte data) =>
            {
                // 是否获取到了校验位指示符
                if (data == Gps_NmeaFrame.NMEA_FRAME_CRC_IDENTIFIER_BYTE)
                {
                    // 添加到缓冲区
                    mGpsMsgBuff[mTmpFrameType].AddData(mStrBuffer);
                    // 清除缓冲
                    mStrBuffer = "";
                    // 清除计数器
                    ParseMoniterCnt = 0;
                    // 跳转到CrcState
                    Current_State = NmeaFrame_ParseState.Crc_State;
                }
                else
                {
                    // 计算校验
                    Current_Crc ^= data;

                    // 是否为分隔符
                    if (data == Gps_NmeaFrame.NMEA_FRAME_SEPARATE_BYTE)
                    {
                        // 添加到缓冲区
                        mGpsMsgBuff[mTmpFrameType].AddData(mStrBuffer);
                        // 清楚缓冲区
                        mStrBuffer = "";
                    }
                    else
                    {
                        // 添加字符到缓冲
                        mStrBuffer += (char)data;
                    }
                }
                // 如果超出限制,直接复位状态机
                if (ParseMoniterCnt++ > Gps_NmeaFrame.NMEA_FRAME_DATA_LEN_MAX)
                {
                    Current_State = NmeaFrame_ParseState.Null_State;
                }
            };

            // 帧校验状态
            ParseMoniter[NmeaFrame_ParseState.Crc_State] = (byte data) =>
            {
                // 如果接收到了第一个结束字符
                if (data == Gps_NmeaFrame.NMEA_FRAME_END_IDENTIFIER1_BYTE)
                {
                    byte crc;
                    // 获取crc
                    crc = Convert.ToByte(mStrBuffer, 16);

                    if (crc == Current_Crc)
                    {
                        mGpsMsgBuff[mTmpFrameType].AddCrc(mStrBuffer);
                        Current_State = NmeaFrame_ParseState.End_State;
                        return;
                    }
                }
                else
                {
                    mStrBuffer += (char)data;
                }

                // 如果超出限制,复位状态机
                if (ParseMoniterCnt++ > Gps_NmeaFrame.NMEA_FRAME_DATA_CRC_LEN)
                {
                    Current_State = NmeaFrame_ParseState.Null_State;
                }
            };

            // 帧结束状态
            ParseMoniter[NmeaFrame_ParseState.End_State] = (byte data) =>
            {
                // 如果接收到第二个字符
                if (data == Gps_NmeaFrame.NMEA_FRAME_END_IDENTIFIER2_BYTE)
                {
                    // 处理当前帧
                    SelfDeal(mGpsMsgBuff[mTmpFrameType], mTmpFrameType);
                    // 此处需要清除帧缓冲
                    mGpsMsgBuff[mTmpFrameType].Clear();
                }
                Current_State = NmeaFrame_ParseState.Null_State;
            };
        }