y-matsui::weblog

電子楽器、音楽、コンピュータ、プログラミング、雑感。面倒くさいオヤジの独り言

具体的な処理方法やらC#ソースやら

仮にUSBのGPS受信機を購入して、仮想COMポートから信号を取り出せるとする。
次は、具体的な処理方法や、もっと言っちゃえば、他人の仕事が気になってくる。
・・と調べていたら、やっぱりちゃんと記事にしている人がいる。
処理手順の参考
1.行頭の'$'を待つ
GGA(Global Positioning System Fix Data)
RMC(RMC - Recommended Minimum Specific GNSS Data)センテンスのみを取得
2.文字数チェック GGAの場合 1行64〜74文字の場合のみ有効データとする。
3.1行のデータを構造体に入れてそれぞれパラメータをチェック
4.データを計算用に整形
5.GPSから吸い出したウエィポイントと突き合わせ

C#のソース

/***
GpsConnectorLib.cs
GPSを動かすライブラリ

for C#2.0(VisualStudio2005)
Date: 2007/12/21
Author: Sho Hashimoto
WebSite: http://shokai.org
***/

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;

namespace Org.Shokai.Gis.Gps
{

///


/// 北半球/南半球を表す列挙体
///

public enum HemiSpheriumNS
{
///
/// 北半球
///

North,
///
/// 南半球
///

South
}

///


/// 東半球/西半球を表す列挙体
///

public enum HemiSpheriumEW
{
///
/// 東半球
///

East,
///
/// 西半球
///

West
}

///


/// GPS Information Data
///

class GpsData
{
///
/// 経度
///

public double lon = Int32.MinValue; // 緯度
///
/// 緯度
///

public double lat = Int32.MinValue; // 経度
///
/// 北半球/南半球を表す列挙体
///

public HemiSpheriumNS NS;
///
/// 東半球/西半球を表す列挙体
///

public HemiSpheriumEW EW;
public GpsData()
{
NS = HemiSpheriumNS.North; // 北半球
EW = HemiSpheriumEW.East; // 東半球
}
}

class GpsConnector
{
public GpsData gpsData = new GpsData();

public GpsConnector()
{
serialPort = new SerialPort();
PortName = "COM1";
BaudRate = 4800;
serialPort.DataReceived += serialPort_DataReceived;
hasError = true;
}

#region Property and Accessor

public Boolean hasError;
private SerialPort serialPort;

public String PortName
{
set
{
this.serialPort.PortName = value;
}
get
{
return this.serialPort.PortName;
}
}

public int BaudRate
{
set
{
this.serialPort.BaudRate = value;
}
get
{
return this.serialPort.BaudRate;
}
}

public Boolean IsOpen
{
get
{
return this.serialPort.IsOpen;
}
}

#endregion

#region Method
public Boolean Open()
{
if (IsOpen) return false; // 既に開いている
try
{
serialPort.Open();
}
catch
{
}
return serialPort.IsOpen;
}

public Boolean Close()
{
if (!IsOpen) return false; // 既に閉じている
try
{
serialPort.Close();
}
catch
{
}
return serialPort.IsOpen;
}

override public String ToString()
{
String gpsStat = "";
if (hasError) gpsStat += "エラー有り\r\n";
else gpsStat += "エラー無し\r\n";
gpsStat += "経度:" + gpsData.lon + " 緯度:" + gpsData.lat;

if (gpsData.EW == HemiSpheriumEW.East)
{
gpsStat += ",東半球";
}
else if (gpsData.EW == HemiSpheriumEW.West)
{
gpsStat += ",西半球";
}
if (gpsData.NS == HemiSpheriumNS.North)
{
gpsStat += ",北半球";
}
else if (gpsData.NS == HemiSpheriumNS.South)
{
gpsStat += ",南半球";
}
gpsStat += "\r\n";

gpsStat += "Port:" + PortName + ",BaudRate:" + BaudRate;

return gpsStat;
}

#endregion

#region Event
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
String recvData = serialPort.ReadLine();

// parse Data from GPS
String[] data = recvData.Split(',');
switch (data[0])
{
#region case "$CPGGA":
case "$GPGGA":
hasError = false; // reset error flag

if (data[2] != "") // 緯度
{
Double value = Double.Parse(data[2]);
gpsData.lat = (value % 100)/60 + (int)value / 100;
}
else
{
//gpsData.lat = Int32.MinValue;
hasError = true;
}

if (data[3] == "N") // 北半球
{
gpsData.NS = HemiSpheriumNS.North;
}
else if (data[3] == "S") // 南半球
{
gpsData.lat *= -1; // 南緯
gpsData.NS = HemiSpheriumNS.South;
}
else hasError = true;

if (data[4] != "") // 経度
{
Double value = Double.Parse(data[4]);
gpsData.lon = (value%100)/60 + (int)value / 100;
}
else
{
//gpsData.lon = Int32.MinValue;
hasError = true;
}

if (data[5] == "E") // 東半球
{
gpsData.EW = HemiSpheriumEW.East;
}
else if (data[5] == "W") // 西半球
{
gpsData.lon *= -1; // 西経
gpsData.EW = HemiSpheriumEW.West;
}
else hasError = true;

break;
#endregion
case "$GPRMC":
break;
case "$GPGSA":
break;
}
#if DEBUG
Console.WriteLine(recvData);
#endif
}
#endregion

}
}