🛰️
RTKをUnityでやってみた
IoTLTのアドベントカレンダー2024の5日目です!
(もしかしたら投稿日より前に記事完成したの初めてかも)
RTKってこんな感じ
動画ではいい感じのところを切り取っていますが、中央に戻ってくる箇所が結構ずれることがあります。
それでも10cmくらいのずれ(体感)っぽいので、GPSと比べると精度高い
RTK(Real Time Kinematic)とは
ざっくり言えば、高精度になったGPS!
色々な人が解説しているので、ここでは省略
自分なりに簡略化しつつ、用語整理もかねて図を作ってみた
この他にもNTRIP
って用語とかがあります。
今回はこの中の「Client」部分のみです。
「Caster」は有志の方からもらってます。
「Server」部分だったり、「Caster」のrtk2go.comを試してみたり、ローカルで構築してみたりってのもやっていますので、いずれ機会があればまた記事書きます。
RTKの用途
- ドローン
- 自動運転
- 測量
とからしい
Unityでやってみた
買ったやつ
usbケーブルでPCと繋いで、シリアル通信でやりとりできます!すばらしい
大枠の流れ
- NTRIPでRTCMデータ受け取り
- Unity的に、
TcpClient
作って、GetStream();
からStreamReader
作って、受け取り - バイナリー形式で受け取ったらうまくいった
- Unity的に、
- (今回は)シリアル通信で、手元のRTCMデバイスへ書き込み
- Unity的に、
SerialPort
作って、Write();
で書き込み
- Unity的に、
- シリアル通信で、読み込み
- Unity的に、
ReadLine();
で読み込み
- Unity的に、
ソースコード一部
NTRIPの通信準備
client = new TcpClient();
await client.ConnectAsync(host, port);
networkStream = client.GetStream();
reader = new StreamReader(networkStream);
writer = new StreamWriter(networkStream);
await writer.WriteLineAsync("GET /" + mountpoint + " HTTP/1.1");
await writer.WriteLineAsync("Host " + host);
await writer.WriteLineAsync("User-Agent: NTRIP curl/0.0");
await writer.WriteLineAsync("Authorization: " + GetAuthenticate(username, password));
await writer.WriteLineAsync("");
await writer.FlushAsync();
スレッドとか用意して受け取り
byte[] buffer = new byte[1024];
int len = await reader.BaseStream.ReadAsync(buffer, 0, buffer.Length, cancellationTokenSource.Token);
シリアル通信準備して、
serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
書き込み
タイミングはUpdateとかじゃなく、NTRIP通信で受け取ったタイミングがいい
serialPort.Write(buffer, 0, buffer.Length);
スレッドとか用意して読み込み
message = serialPort.ReadLine();
NMEA形式のデータをいったんGGAだけのものをパースしてみた
public struct GGAData
{
public string OriginalString;
public string TimeString;
public int Hours;
public int Minits;
public float Seconds;
public double Latitude;
public double Longitude;
public int Quality;
}
public GGAData ggaData = new GGAData();
public void ParseRoverData(string data)
{
if (data.Contains("GGA"))
{
ggaData.OriginalString = data;
string[] dataArr = data.Split(',');
ggaData.TimeString = dataArr[1];
ggaData.Hours = int.Parse(ggaData.TimeString.Substring(0, 2)) + 9;
ggaData.Minits = int.Parse(ggaData.TimeString.Substring(2, 2));
ggaData.Seconds = float.Parse(ggaData.TimeString.Substring(4, 4));
ggaData.Latitude = double.Parse(dataArr[2].Substring(2, dataArr[2].Length - 2));
ggaData.Longitude = double.Parse(dataArr[4].Substring(3, dataArr[4].Length - 3));
ggaData.Quality = int.Parse(dataArr[6]);
}
}
プロジェクト全体は準備中です
これつかってなにしようかな
- 床にプロジェクションして、なんかついてくるとか
- プロジェクションするなら暗い部屋内とかがいいけど、GPSとかには不向きか
- まだまだ機材が大きいので卓上くらいだと効果的じゃないか
- 本当の最短距離を測る
- 徒歩でしか行けない道とか、道幅大きいとアウトインアウトで短くなるとかで、GoogleMapの最短距離の計算とはまた違った結果になるんじゃないかな
- 毎回の保育園への送り迎えとかで測りたい!
- でも冬は日が当たるほうを歩きたいっとかってのも思ったりしてる
- 鬼ごっこのお助けアイテム的な
- FPSのゲームみたいな壁腰に相手が見えるとか
- 近距離でも正確なセカイカメラ
Discussion