/// <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; } }
/// <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; }; }