mirror of
https://github.com/dotMorten/NmeaParser.git
synced 2026-01-20 15:40:16 +01:00
Add signal id to GSV
This commit is contained in:
parent
84bb5f5118
commit
abf660df7e
|
|
@ -75,9 +75,12 @@ namespace NmeaParser.Gnss
|
|||
List<string> properties = new List<string>();
|
||||
lock (m_lock)
|
||||
{
|
||||
if(m_allMessages.ContainsKey(message.MessageType) && m_allMessages[message.MessageType].Equals(message))
|
||||
string msgid = message.MessageType;
|
||||
if (message is Gsv gsv && gsv.GnssSignalId != '0')
|
||||
msgid = msgid + "|" + gsv.GnssSignalId;
|
||||
if (m_allMessages.ContainsKey(msgid) && m_allMessages[msgid].Equals(message))
|
||||
return; // Nothing to update/notify
|
||||
m_allMessages[message.MessageType] = message;
|
||||
m_allMessages[msgid] = message;
|
||||
}
|
||||
properties.Add(nameof(AllMessages));
|
||||
if(message.TalkerId != NmeaParser.Talker.GlobalNavigationSatelliteSystem && !(message is Gsv) && message.MessageType.Length > 2)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace NmeaParser.Messages
|
||||
{
|
||||
|
|
@ -58,12 +59,20 @@ namespace NmeaParser.Messages
|
|||
else if ( satellites != SatellitesInView)
|
||||
return false; // Messages do not match
|
||||
|
||||
if ((message.Length - 3) % 4 == 1) // v4.1+ adds system id to the last message. Example L1=1, and L2=6 on GPS satellites
|
||||
{
|
||||
var id = message.Last();
|
||||
if (id.Length == 1)
|
||||
{
|
||||
GnssSignalId = id[0];
|
||||
}
|
||||
}
|
||||
for (int i = 3; i < message.Length - 3; i += 4)
|
||||
{
|
||||
if (message[i].Length == 0)
|
||||
continue;
|
||||
else
|
||||
svs.Add(new SatelliteVehicle(talkerType, message, i));
|
||||
svs.Add(new SatelliteVehicle(talkerType, GnssSignalId, message, i));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -79,6 +88,78 @@ namespace NmeaParser.Messages
|
|||
/// </summary>
|
||||
public IReadOnlyList<SatelliteVehicle> SVs => svs.AsReadOnly();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GNSS Signal ID
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <table>
|
||||
/// <thead>
|
||||
/// <tr><th>System</th><th>Signal ID</th><th>Signal Channel</th></tr>
|
||||
/// </thead>
|
||||
/// <tbody>
|
||||
/// <tr><td>GPS</td><td>0</td><td>All signals</td></tr>
|
||||
/// <tr><td></td><td>1</td><td>L1 C/1</td></tr>
|
||||
/// <tr><td></td><td>2</td><td>L1 P(Y)</td></tr>
|
||||
/// <tr><td></td><td>3</td><td>L1 M</td></tr>
|
||||
/// <tr><td></td><td>4</td><td>L2 P(Y)</td></tr>
|
||||
/// <tr><td></td><td>5</td><td>L2C-M</td></tr>
|
||||
/// <tr><td></td><td>6</td><td>L2C-L</td></tr>
|
||||
/// <tr><td></td><td>7</td><td>L5-I</td></tr>
|
||||
/// <tr><td></td><td>8</td><td>L5-Q</td></tr>
|
||||
/// <tr><td></td><td>9-F</td><td>Reserved</td></tr>
|
||||
/// <tr><td>GLONASS</td><td>0</td><td>All signals</td></tr>
|
||||
/// <tr><td></td><td>1</td><td>G1 C/A</td></tr>
|
||||
/// <tr><td></td><td>2</td><td>G1 P</td></tr>
|
||||
/// <tr><td></td><td>3</td><td>G2 C/A</td></tr>
|
||||
/// <tr><td></td><td>4</td><td>GLONASS (M) G2 P</td></tr>
|
||||
/// <tr><td></td><td>5-F</td><td>Reserved</td></tr>
|
||||
/// <tr><td>GALILEO</td><td>0</td><td>All signals</td></tr>
|
||||
/// <tr><td></td><td>1</td><td>E5a</td></tr>
|
||||
/// <tr><td></td><td>2</td><td>E5b</td></tr>
|
||||
/// <tr><td></td><td>3</td><td>E5 a+b</td></tr>
|
||||
/// <tr><td></td><td>4</td><td>E6-A</td></tr>
|
||||
/// <tr><td></td><td>5</td><td>E6-BC</td></tr>
|
||||
/// <tr><td></td><td>6</td><td>L1-A</td></tr>
|
||||
/// <tr><td></td><td>7</td><td>L1-BC</td></tr>
|
||||
/// <tr><td></td><td>8-F</td><td>Reserved</td></tr>
|
||||
/// <tr><td>BeiDou System</td><td>0</td><td>All signals</td></tr>
|
||||
/// <tr><td></td><td>1</td><td>B1I</td></tr>
|
||||
/// <tr><td></td><td>2</td><td>B1Q</td></tr>
|
||||
/// <tr><td></td><td>3</td><td>B1C</td></tr>
|
||||
/// <tr><td></td><td>4</td><td>B1A</td></tr>
|
||||
/// <tr><td></td><td>5</td><td>B2-a</td></tr>
|
||||
/// <tr><td></td><td>6</td><td>B2-b</td></tr>
|
||||
/// <tr><td></td><td>7</td><td>B2 a+b</td></tr>
|
||||
/// <tr><td></td><td>8</td><td>B3I</td></tr>
|
||||
/// <tr><td></td><td>9</td><td>B3Q</td></tr>
|
||||
/// <tr><td></td><td>A</td><td>B3A</td></tr>
|
||||
/// <tr><td></td><td>B</td><td>B2I</td></tr>
|
||||
/// <tr><td></td><td>C</td><td>B2Q</td></tr>
|
||||
/// <tr><td></td><td>D-F</td><td>Reserved</td></tr>
|
||||
/// <tr><td>QZSS</td><td>0</td><td>All signals</td></tr>
|
||||
/// <tr><td></td><td>1</td><td>L1 C/A</td></tr>
|
||||
/// <tr><td></td><td>2</td><td>L1C (D)</td></tr>
|
||||
/// <tr><td></td><td>3</td><td>L1C (P)</td></tr>
|
||||
/// <tr><td></td><td>4</td><td>LIS</td></tr>
|
||||
/// <tr><td></td><td>5</td><td>L2C-M</td></tr>
|
||||
/// <tr><td></td><td>6</td><td>L2C-L</td></tr>
|
||||
/// <tr><td></td><td>7</td><td>L5-I</td></tr>
|
||||
/// <tr><td></td><td>8</td><td>L5-Q</td></tr>
|
||||
/// <tr><td></td><td>9</td><td>L6D</td></tr>
|
||||
/// <tr><td></td><td>A</td><td>L6E</td></tr>
|
||||
/// <tr><td></td><td>B-F</td><td>Reserved</td></tr>
|
||||
/// <tr><td>NavIC (IRNSS)</td><td>0</td><td>All signals</td></tr>
|
||||
/// <tr><td></td><td>1</td><td>L5-SPS</td></tr>
|
||||
/// <tr><td></td><td>2</td><td>S-SPS</td></tr>
|
||||
/// <tr><td></td><td>3</td><td>L5-RS</td></tr>
|
||||
/// <tr><td></td><td>4</td><td>S-RS</td></tr>
|
||||
/// <tr><td></td><td>5</td><td>L1-SPS</td></tr>
|
||||
/// <tr><td></td><td>6-F</td><td>Reserved</td></tr>
|
||||
/// </tbody>
|
||||
///</table>
|
||||
/// </remarks>
|
||||
public char GnssSignalId { get; private set; } = '0';
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the collection.
|
||||
/// </summary>
|
||||
|
|
@ -103,7 +184,7 @@ namespace NmeaParser.Messages
|
|||
/// </summary>
|
||||
public sealed class SatelliteVehicle
|
||||
{
|
||||
internal SatelliteVehicle(Talker talker, string[] message, int startIndex)
|
||||
internal SatelliteVehicle(Talker talker, char signalId, string[] message, int startIndex)
|
||||
{
|
||||
Id = int.Parse(message[startIndex], CultureInfo.InvariantCulture);
|
||||
if (double.TryParse(message[startIndex + 1], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double e))
|
||||
|
|
@ -113,6 +194,7 @@ namespace NmeaParser.Messages
|
|||
int snr = -1;
|
||||
if (int.TryParse(message[startIndex + 3], out snr))
|
||||
SignalToNoiseRatio = snr;
|
||||
GnssSignalId = signalId;
|
||||
TalkerId = talker;
|
||||
}
|
||||
|
||||
|
|
@ -121,6 +203,12 @@ namespace NmeaParser.Messages
|
|||
/// </summary>
|
||||
public Talker TalkerId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GNSS Signal ID.
|
||||
/// </summary>
|
||||
/// <seealso cref="Gsv.GnssSignalId"/>
|
||||
public char GnssSignalId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Satellite ID number
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -54,8 +54,30 @@
|
|||
BorderBrush="Black"
|
||||
Margin="5,0" Width="20"
|
||||
BorderThickness="1"
|
||||
ToolTip="{Binding SignalToNoiseRatio}"
|
||||
VerticalAlignment="Bottom">
|
||||
<Border.ToolTip>
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="System: " />
|
||||
<TextBlock Text="{Binding Converter={StaticResource heightconv}, ConverterParameter=Name}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Azimuth: " />
|
||||
<TextBlock Text="{Binding Azimuth}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Elevation: " />
|
||||
<TextBlock Text="{Binding Elevation}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="SNR: " />
|
||||
<TextBlock Text="{Binding SignalToNoiseRatio}" />
|
||||
<TextBlock Text="dB" />
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Border.ToolTip>
|
||||
|
||||
<Border.Background>
|
||||
<SolidColorBrush Color="{Binding Converter={StaticResource conv}}" />
|
||||
</Border.Background>
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ namespace SampleApp.WinDesktop
|
|||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
Dictionary<Talker, Gsv> messages = new Dictionary<Talker, Gsv>();
|
||||
Dictionary<string, Gsv> messages = new Dictionary<string, Gsv>();
|
||||
public void SetGsv(Gsv message)
|
||||
{
|
||||
messages[message.TalkerId] = message;
|
||||
messages[message.TalkerId + "+" + message.GnssSignalId] = message;
|
||||
UpdateSatellites();
|
||||
}
|
||||
public void ClearGsv()
|
||||
|
|
@ -41,16 +41,128 @@ namespace SampleApp.WinDesktop
|
|||
|
||||
private void UpdateSatellites()
|
||||
{
|
||||
satellites.ItemsSource = messages.Values.SelectMany(g => g.SVs);
|
||||
}
|
||||
}
|
||||
satellites.ItemsSource = messages.Values.SelectMany(g => g.SVs).OrderBy(s=>s.GnssSignalId).OrderBy(s => s.Id).OrderByDescending(s => s.TalkerId);
|
||||
}
|
||||
|
||||
internal static string SignalIdToName(char signalId, Talker talkerId)
|
||||
{
|
||||
if (signalId != '0')
|
||||
{
|
||||
var talker = talkerId;
|
||||
if (talker == Talker.GlobalPositioningSystem)
|
||||
{
|
||||
switch (signalId)
|
||||
{
|
||||
case '1': return "L1 C/A";
|
||||
case '2': return "L1 P(Y)";
|
||||
case '3': return "L1 M";
|
||||
case '4': return "L2 P(Y)";
|
||||
case '5': return "L2C-M";
|
||||
case '6': return "L2C-L";
|
||||
case '7': return "L5-I";
|
||||
case '8': return "L5-Q";
|
||||
}
|
||||
}
|
||||
else if (talker == Talker.GlonassReceiver)
|
||||
{
|
||||
switch (signalId)
|
||||
{
|
||||
case '1': return "G1 C/A";
|
||||
case '2': return "G1 P";
|
||||
case '3': return "G2 C/A";
|
||||
case '4': return "GLONASS (M) G2 P";
|
||||
}
|
||||
}
|
||||
else if (talker == Talker.GalileoPositioningSystem)
|
||||
{
|
||||
switch (signalId)
|
||||
{
|
||||
case '1': return "E5a";
|
||||
case '2': return "E5b";
|
||||
case '3': return "E5 a+b";
|
||||
case '4': return "E6-A";
|
||||
case '5': return "E6-BC";
|
||||
case '6': return "L1-A";
|
||||
case '7': return "L1-BC";
|
||||
}
|
||||
}
|
||||
else if (talker == Talker.BeiDouNavigationSatelliteSystem)
|
||||
{
|
||||
switch (signalId)
|
||||
{
|
||||
case '1': return "B1I";
|
||||
case '2': return "B1Q";
|
||||
case '3': return "B1C";
|
||||
case '4': return "B1A";
|
||||
case '5': return "B2-a";
|
||||
case '6': return "B2-b";
|
||||
case '7': return "B2 a+b";
|
||||
case '8': return "B3I";
|
||||
case '9': return "B3Q";
|
||||
case 'A': return "B3A";
|
||||
case 'B': return "B2I";
|
||||
case 'C': return "B2Q";
|
||||
}
|
||||
}
|
||||
else if (talker == Talker.QuasiZenithSatelliteSystem)
|
||||
{
|
||||
switch (signalId)
|
||||
{
|
||||
case '1': return "L1 C/A";
|
||||
case '2': return "L1C (D)";
|
||||
case '3': return "L1C (P)";
|
||||
case '4': return "LIS";
|
||||
case '5': return "L2C-M";
|
||||
case '6': return "L2C-L";
|
||||
case '7': return "L5-I";
|
||||
case '8': return "L5-Q";
|
||||
case '9': return "L6D";
|
||||
case 'A': return "L6E";
|
||||
}
|
||||
}
|
||||
else if (talker == Talker.IndianRegionalNavigationSatelliteSystem)
|
||||
{
|
||||
switch (signalId)
|
||||
{
|
||||
case '1': return "L5-SPS";
|
||||
case '2': return "S-SPS<";
|
||||
case '3': return "L5-RS";
|
||||
case '4': return "S-RS";
|
||||
case '5': return "L1-SPS";
|
||||
}
|
||||
}
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
public class SnrToHeightConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if(value is SatelliteVehicle sv)
|
||||
{
|
||||
return Math.Max(10, sv.SignalToNoiseRatio * 2);
|
||||
if (parameter as string == "Name")
|
||||
{
|
||||
string name;
|
||||
if (sv.TalkerId == Talker.GlobalPositioningSystem)
|
||||
name = "GPS";
|
||||
else if (sv.TalkerId == Talker.GlonassReceiver)
|
||||
name = "GLONASS";
|
||||
else if (sv.TalkerId == Talker.BeiDouNavigationSatelliteSystem)
|
||||
name = "BeiDou";
|
||||
else if (sv.TalkerId == Talker.QuasiZenithSatelliteSystem)
|
||||
name = "QZSS";
|
||||
else if (sv.TalkerId == Talker.IndianRegionalNavigationSatelliteSystem)
|
||||
name = "NavIC IRNSS";
|
||||
else
|
||||
name = sv.TalkerId.ToString();
|
||||
var signalName = SatelliteSnr.SignalIdToName(sv.GnssSignalId, sv.TalkerId);
|
||||
if (!string.IsNullOrEmpty(signalName))
|
||||
name += " (" + signalName + ")";
|
||||
return name;
|
||||
}
|
||||
else
|
||||
return Math.Max(10, sv.SignalToNoiseRatio * 2);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ namespace SampleApp.WinDesktop
|
|||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
Dictionary<Talker, Gsv> messages = new Dictionary<Talker, Gsv>();
|
||||
Dictionary<string, Gsv> messages = new Dictionary<string, Gsv>();
|
||||
public void SetGsv(Gsv message)
|
||||
{
|
||||
messages[message.TalkerId] = message;
|
||||
messages[message.TalkerId + "+" + message.GnssSignalId] = message;
|
||||
UpdateSatellites();
|
||||
}
|
||||
public void ClearGsv()
|
||||
|
|
|
|||
Loading…
Reference in a new issue