using ProjectBase.Data.Logs;
using ProjectBase.Data.Redis;
using ProjectBase.Util;
using SIASUN.Autopilot.Device;
using SIASUN.Autopilot.EventMessage;
using SIASUN.Autopilot.GNSS;
using System;
namespace SIASUN.Autopilot.BLL
{
///
/// GNSS定位导航信息感知模块
///
public class BlGNSSPerception
{
public static SerialPortBase GNSSSerialPort;
// public event EventGNSSInfoHandler GNSSHandler;
public event EventHandler GNSSHandler;
public static BlGNSSPerception Instance { get; private set; }
private string lastLatitude = "0000.00000000";
private string lastlongitude = "00000.00000000";
static BlGNSSPerception()
{
Instance = new BlGNSSPerception();
}
public void Init()
{
string PortNumber = System.Configuration.ConfigurationManager.AppSettings["PortNumber"];
int baudRate = int.Parse(System.Configuration.ConfigurationManager.AppSettings["baudRate"]);
int DataBits = int.Parse(System.Configuration.ConfigurationManager.AppSettings["DataBits"]);
GNSSSerialPort = new SerialPortBase(PortNumber, baudRate, DataBits);
GNSSSerialPort.serialDataReceived += GNSSSerialPort_serialDataReceived;
}
private void GNSSSerialPort_serialDataReceived(SerialPortDataReceiveEventArgs e)
{
LogHelper.log.Debug("接收的报文为:" + e.Value);
string[] split = e.Value.Split('$');
if (split.Length != 4)
{
LogHelper.log.Error("接收到的GNSS信号格式出现错误");
return;
}
NMEA0183 nmea = new NMEA0183();
if (!GetNMEA0183(ref split, out nmea))
{
return;
}
GNSSInfoEventArgs gnss = new GNSSInfoEventArgs(nmea);
gnss.Raise(this,ref GNSSHandler);
//GNSSHandler(gnss);
}
///
/// 解析NMEA0183协议
///
///
///
private bool GetNMEA0183(ref string[] strNMEA, out NMEA0183 nmea)
{
try
{
string[] strValues = strNMEA;
NMEA0183 temp = new NMEA0183();
for (int i = 1; i < strValues.Length; i++)
{
string[] protocol = strValues[i].Split('*');
string[] value = protocol[0].Split(',');
if (value[0].Equals("GPGGA"))
{
if (value[2].Contains(lastLatitude.Substring(0, 9)))// 精确到分米
{
LogHelper.log.Debug("通过纬度去掉重复点");
lastLatitude = value[2];
nmea = null;
return false;
}
lastLatitude = value[2];
if (value[4].Contains(lastlongitude.Substring(0, 10)))// 精确到分米
{
LogHelper.log.Debug("通过经度去掉重复点");
lastlongitude = value[4];
nmea = null;
return false;
}
lastlongitude = value[4];
GPGGA gpgga = new GPGGA();
GetGPGGA(value, out gpgga);
temp.gpgga = gpgga;
}
else if (value[0].Equals("GPRMC"))
{
GPRMC gprmc = new GPRMC();
GetGPRMC(value, out gprmc);
temp.gprmc = gprmc;
}
else
{
string pashr = protocol[0];
temp.pashr = pashr;
}
}
nmea = temp;
return true;
}
catch(Exception ex)
{
LogHelper.log.Error("nmea协议解析出现错误",ex);
nmea = null;
return false;
}
}
///
/// 解析GPGGA协议
///
private void GetGPGGA(string [] value, out GPGGA nmea)
{
GPGGA temp = new GPGGA();
temp.utcTime = value[1];
temp.Latitude = GetDegrees(value[2], 2);
temp.LatType = value[3];
temp.Longitude = GetDegrees(value[4], 3);
temp.LonType = value[5];
temp.GPSStatus = Convert.ToInt32(value[6]);
temp.SatelliteNumber = Convert.ToInt32(value[7]);
temp.Hdop = Convert.ToDecimal(value[8]);
temp.Height = Convert.ToDecimal(value[9]);
temp.ReleaveHeight = value[10];
temp.CTKTime = value[11];
temp.Check = value[12];
nmea = temp;
}
///
/// 解析GPRMC协议
///
private void GetGPRMC(string[] value, out GPRMC nmea)
{
GPRMC temp = new GPRMC();
temp.utcTime = value[1];
temp.locationStatus = value[2];
temp.Latitude = GetDegrees(value[3], 2);
temp.LatType = value[4];
temp.Longitude = GetDegrees(value[5], 3);
temp.LonType = value[6];
temp.Speed = Convert.ToDecimal(value[7]);
temp.Deviated = Convert.ToDecimal(value[8]);
temp.Date = value[9];
temp.Magnetic = Convert.ToDecimal(value[10]);
temp.MagneticDirection = value[11];
temp.Mode = value[12];
nmea = temp;
}
///
/// 把经度和纬度坐标转换成度
///
/// ddmm.mmmmmmmm
private decimal GetDegrees(string para, int pos)
{
decimal degrees = 0;
try
{
degrees = Convert.ToDecimal(para.Substring(0, pos)) +
Convert.ToDecimal(para.Substring(pos, para.Length - pos))/60;
}
catch (Exception ex)
{
LogHelper.log.Error("经纬度坐标转换出现错误", ex);
}
return degrees;
}
public void Close()
{
GNSSSerialPort.Close();
}
}
///
/// 串口接收数据
///
public delegate void EventGNSSInfoHandler(GNSSInfoEventArgs e);
public class GNSSInfoEventArgs : EventArgs
{
public NMEA0183 Nmea { get; set; }
public GNSSInfoEventArgs(NMEA0183 value)
{
this.Nmea = value;
}
}
}