Skip to content

Commit

Permalink
Merge pull request #43 from asv-soft/feat/air-talk
Browse files Browse the repository at this point in the history
Add audio and radio mavlink interfaces
  • Loading branch information
asvol authored Jan 8, 2024
2 parents b261356 + 15538e4 commit 5c92289
Show file tree
Hide file tree
Showing 71 changed files with 2,550 additions and 161 deletions.
2 changes: 2 additions & 0 deletions regenerate_asv.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
"src\Asv.Mavlink.Shell\bin\Debug\net7.0\Asv.Mavlink.Shell.exe" gen -t=asv_gbs.xml -i=src/Asv.Mavlink/Protocol/Dialects -o=src/Asv.Mavlink/Protocol/Messages -e=cs src/Asv.Mavlink.Shell/Resources/csharp.tpl
"src\Asv.Mavlink.Shell\bin\Debug\net7.0\Asv.Mavlink.Shell.exe" gen -t=asv_sdr.xml -i=src/Asv.Mavlink/Protocol/Dialects -o=src/Asv.Mavlink/Protocol/Messages -e=cs src/Asv.Mavlink.Shell/Resources/csharp.tpl
"src\Asv.Mavlink.Shell\bin\Debug\net7.0\Asv.Mavlink.Shell.exe" gen -t=asv_audio.xml -i=src/Asv.Mavlink/Protocol/Dialects -o=src/Asv.Mavlink/Protocol/Messages -e=cs src/Asv.Mavlink.Shell/Resources/csharp.tpl
"src\Asv.Mavlink.Shell\bin\Debug\net7.0\Asv.Mavlink.Shell.exe" gen -t=asv_radio.xml -i=src/Asv.Mavlink/Protocol/Dialects -o=src/Asv.Mavlink/Protocol/Messages -e=cs src/Asv.Mavlink.Shell/Resources/csharp.tpl
4 changes: 2 additions & 2 deletions src/Asv.Mavlink.Shell/Adsb/VirtualAdsbCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ public override int Run(string[] remainingArguments)
var server1 = new AdsbServerDevice(
conn,
new PacketSequenceCalculator(),
new MavlinkServerIdentity{ComponentId = 13, SystemId = 13},
new MavlinkIdentity(13, 13),
new AdsbServerDeviceConfig(),
Scheduler.Default);

var server2 = new AdsbServerDevice(
conn,
new PacketSequenceCalculator(),
new MavlinkServerIdentity{ComponentId = 14, SystemId = 14},
new MavlinkIdentity(14, 14),
new AdsbServerDeviceConfig(),
Scheduler.Default);

Expand Down
1 change: 1 addition & 0 deletions src/Asv.Mavlink.Shell/CodeGen/Generator/LiquidGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public string Generate(string template, MavlinkProtocolModel model)
Value = en.Value,
Desc = en.Desc,
Name = en.Name,
IsFlag = en.IsFlag,
CamelCaseName = NameConverter(en.Name),
Entries = en.Entries.Select(
enEntry => new
Expand Down
1 change: 1 addition & 0 deletions src/Asv.Mavlink.Shell/CodeGen/Model/MavlinkEnumModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public class MavlinkEnumModel:MavlinkModelBase
public string Name { get; set; }
public int Value { get; set; }
public IList<MavlinkEnumEntryModel> Entries { get; set; } = new List<MavlinkEnumEntryModel>();
public bool IsFlag { get; set; }
}
}
4 changes: 3 additions & 1 deletion src/Asv.Mavlink.Shell/CodeGen/Parsers/MavlinkParserXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,9 @@ private static void ParseEnum(XmlReader rdr, MavlinkEnumModel enumItem)
switch (rdr.Name)
{
case "description":
enumItem.Desc = ConvertDesc(rdr.ReadElementContentAsString());;
var content = rdr.ReadElementContentAsString();
enumItem.Desc = ConvertDesc(content);
enumItem.IsFlag = content.Contains("[!THIS_IS_ENUM_FLAG!]");
break;
case "entry":
ParseEnumEntry(rdr,enumItem.Entries);
Expand Down
9 changes: 9 additions & 0 deletions src/Asv.Mavlink.Shell/Resources/csharp.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

using System;
using System.Text;
using System.ComponentModel;
using Asv.Mavlink.V2.Common;
using Asv.Mavlink.V2.Minimal;
using Asv.IO;
Expand All @@ -50,6 +51,9 @@ namespace Asv.Mavlink.V2.{{ Namespace }}
{%- endfor -%}
/// {{ en.Name }}
/// </summary>
{%- if en.IsFlag -%}
[Flags]
{%- endif -%}
public enum {{ en.CamelCaseName }}:uint
{
{%- for entry in en.Entries -%}
Expand Down Expand Up @@ -482,8 +486,10 @@ namespace Asv.Mavlink.V2.{{ Namespace }}
{%- if field.IsEnum -%}
{%- if field.IsArray -%}
{%- if field.IsTheLargestArrayInMessage -%}
public const int {{ field.CamelCaseName }}MaxItemsCount = {{ field.ArrayLength }};
public {{ field.EnumCamelCaseName }}[] {{ field.CamelCaseName }} { get; set; } = new {{ field.EnumCamelCaseName }}[{{ field.ArrayLength }}];
{%- else -%}
public const int {{ field.CamelCaseName }}MaxItemsCount = {{ field.ArrayLength }};
public {{ field.EnumCamelCaseName }}[] {{ field.CamelCaseName }} { get; } = new {{ field.EnumCamelCaseName }}[{{ field.ArrayLength }}];
{%- endif -%}
{%- else -%}
Expand All @@ -492,9 +498,12 @@ namespace Asv.Mavlink.V2.{{ Namespace }}
{%- else -%}
{%- if field.IsArray -%}
{%- if field.IsTheLargestArrayInMessage -%}
public const int {{ field.CamelCaseName }}MaxItemsCount = {{ field.ArrayLength }};
public {{ field.Type }}[] {{ field.CamelCaseName }} { get; set; } = new {{ field.Type }}[{{ field.ArrayLength }}];
[Obsolete("This method is deprecated. Use Get{{ field.CamelCaseName }}MaxItemsCount instead.")]
public byte Get{{ field.CamelCaseName }}MaxItemsCount() => {{ field.ArrayLength }};
{%- else -%}
public const int {{ field.CamelCaseName }}MaxItemsCount = {{ field.ArrayLength }};
public {{ field.Type }}[] {{ field.CamelCaseName }} { get; } = new {{ field.Type }}[{{ field.ArrayLength }}];
{%- endif -%}
{%- else -%}
Expand Down
1 change: 1 addition & 0 deletions src/Asv.Mavlink.Test/Asv.Mavlink.Test.csproj.DotSettings
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=microservices/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=microservices_005Cadsbvehicle/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=microservices_005Casvaudio/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=microservices_005Casvgbs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=microservices_005Casvsdr/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=microservices_005Cdebugsvc/@EntryIndexedValue">True</s:Boolean>
Expand Down
40 changes: 13 additions & 27 deletions src/Asv.Mavlink.Test/Devices/Base/BaseDevicesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public Task ServerDeviceVirtualLinkArgumentNullExceptionTest()
{
var serverDevice = new ServerDevice(null,
new PacketSequenceCalculator(),
new MavlinkServerIdentity(),
new MavlinkIdentity(),
new ServerDeviceConfig(),
Scheduler.Default);
});
Expand All @@ -93,28 +93,14 @@ public Task ServerDeviceSequenceArgumentNullExceptionTest()

var serverDevice = new ServerDevice(link.Server,
null,
new MavlinkServerIdentity(),
new MavlinkIdentity(),
new ServerDeviceConfig(),
Scheduler.Default);
});
return Task.CompletedTask;
}

[Fact]
public Task ServerDeviceIdentityArgumentNullExceptionTest()
{
Assert.Throws<ArgumentNullException>(() =>
{
var link = new VirtualMavlinkConnection();

var serverDevice = new ServerDevice(link.Server,
new PacketSequenceCalculator(),
null,
new ServerDeviceConfig(),
Scheduler.Default);
});
return Task.CompletedTask;
}


// [Fact]
// public async Task ServerDeviceConfigHeartbeatArgumentNullExceptionTest()
Expand All @@ -125,7 +111,7 @@ public Task ServerDeviceIdentityArgumentNullExceptionTest()
//
// var serverDevice = new ServerDevice(link.Server,
// new PacketSequenceCalculator(),
// new MavlinkServerIdentity(),
// new MavlinkIdentity(),
// new ServerDeviceConfig
// {
// Heartbeat = null
Expand All @@ -143,7 +129,7 @@ public Task ServerDeviceConfigStatusTextArgumentNullExceptionTest()

var serverDevice = new ServerDevice(link.Server,
new PacketSequenceCalculator(),
new MavlinkServerIdentity(),
new MavlinkIdentity(),
new ServerDeviceConfig
{
StatusText = null
Expand All @@ -162,7 +148,7 @@ public void ServerDeviceSchedulerArgumentNullExceptionTest()

var serverDevice = new ServerDevice(link.Server,
new PacketSequenceCalculator(),
new MavlinkServerIdentity(),
new MavlinkIdentity(),
new ServerDeviceConfig(),
null);
});
Expand Down Expand Up @@ -195,7 +181,7 @@ public async Task BaseDevicesStatusTextTest(string messageText)
var link = new VirtualMavlinkConnection();

var serverDevice = new ServerDevice(link.Server, new PacketSequenceCalculator(),
new MavlinkServerIdentity(), new ServerDeviceConfig(), Scheduler.Default);
new MavlinkIdentity(), new ServerDeviceConfig(), Scheduler.Default);

var clientDevice = new AbstractClientDevice(link.Client, new MavlinkClientIdentity(),
new ClientDeviceConfig(), new PacketSequenceCalculator(), Scheduler.Default);
Expand All @@ -221,7 +207,7 @@ public async Task BaseDevicesStatusTextOverloadTest()
var link = new VirtualMavlinkConnection();

var serverDevice = new ServerDevice(link.Server, new PacketSequenceCalculator(),
new MavlinkServerIdentity(), new ServerDeviceConfig(), Scheduler.Default);
new MavlinkIdentity(), new ServerDeviceConfig(), Scheduler.Default);

var clientDevice = new AbstractClientDevice(link.Client, new MavlinkClientIdentity(),
new ClientDeviceConfig(), new PacketSequenceCalculator(), Scheduler.Default);
Expand Down Expand Up @@ -269,7 +255,7 @@ public async Task BaseDevicesHeartbeatConnectionQualityTest()
var link = new VirtualMavlinkConnection(_ => true, _ => ++packetsCount % 2 == 1);

var serverDevice = new ServerDevice(link.Server, new PacketSequenceCalculator(),
new MavlinkServerIdentity(),
new MavlinkIdentity(),
new ServerDeviceConfig()
{
Heartbeat = new MavlinkHeartbeatServerConfig()
Expand Down Expand Up @@ -308,7 +294,7 @@ public async Task BaseDevicesHeartbeatConnectionStateTest()
var link = new VirtualMavlinkConnection(_ => canSend, _ => canSend);

var serverDevice = new ServerDevice(link.Server, new PacketSequenceCalculator(),
new MavlinkServerIdentity(), new ServerDeviceConfig(), Scheduler.Default);
new MavlinkIdentity(), new ServerDeviceConfig(), Scheduler.Default);

var clientDevice = new AbstractClientDevice(link.Client, new MavlinkClientIdentity(),
new ClientDeviceConfig(), new PacketSequenceCalculator(), Scheduler.Default);
Expand Down Expand Up @@ -364,7 +350,7 @@ public async Task BaseDevicesCustomModeTest()
var mode = 23;

var serverDevice = new ServerDevice(link.Server, new PacketSequenceCalculator(),
new MavlinkServerIdentity(), new ServerDeviceConfig(), Scheduler.Default);
new MavlinkIdentity(), new ServerDeviceConfig(), Scheduler.Default);

serverDevice.Heartbeat.Set(_ => _.CustomMode = (uint)mode);

Expand Down Expand Up @@ -396,7 +382,7 @@ public async Task BaseDevicesPacketsLossTest()
var link = new VirtualMavlinkConnection(_ => true,_ => ++packetsCount > lostPacketsCount);

var serverDevice = new ServerDevice(link.Server, new PacketSequenceCalculator(),
new MavlinkServerIdentity { ComponentId = 13, SystemId = 13 }, new ServerDeviceConfig(),
new MavlinkIdentity (13,13), new ServerDeviceConfig(),
Scheduler.Default);

var clientDevice = new AbstractClientDevice(link.Client,
Expand Down Expand Up @@ -426,7 +412,7 @@ private AbstractClientDevice CreateClientDevice(VirtualMavlinkConnection link, P
}

private ServerDevice CreateServerDevice(VirtualMavlinkConnection link, PacketSequenceCalculator seq,
MavlinkServerIdentity identity, ServerDeviceConfig cfg)
MavlinkIdentity identity, ServerDeviceConfig cfg)
{
return new ServerDevice(link.Server,
seq, identity, cfg, Scheduler.Default);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public async Task Check_Single_Adsb_Vehicle()
var server = new AdsbServerDevice(
link.Server,
new PacketSequenceCalculator(),
new MavlinkServerIdentity { ComponentId = 2, SystemId = 2 },
new MavlinkIdentity (2,2),
new AdsbServerDeviceConfig(),
Scheduler.Default);

Expand Down Expand Up @@ -74,7 +74,7 @@ public async Task Check_Multiple_Adsb_Vehicles()
var server = new AdsbServerDevice(
link.Server,
new PacketSequenceCalculator(),
new MavlinkServerIdentity { ComponentId = 2, SystemId = 2 },
new MavlinkIdentity (2,2),
new AdsbServerDeviceConfig(),
Scheduler.Default);

Expand Down Expand Up @@ -153,7 +153,7 @@ public async Task Check_If_Old_Vehicles_Are_Deleted()
var server = new AdsbServerDevice(
link.Server,
new PacketSequenceCalculator(),
new MavlinkServerIdentity { ComponentId = 2, SystemId = 2 },
new MavlinkIdentity (2,2),
new AdsbServerDeviceConfig(),
Scheduler.Default);

Expand Down
75 changes: 75 additions & 0 deletions src/Asv.Mavlink.Test/Microservices/AsvAudio/AsvAudioTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using DynamicData;
using DynamicData.Binding;
using Xunit;
using Xunit.Abstractions;

namespace Asv.Mavlink.Test;

public class AsvAudioTest
{
private readonly ITestOutputHelper _output;

public AsvAudioTest(ITestOutputHelper output)
{
_output = output;
}


[Theory]
[InlineData(1)]
[InlineData(16)]
[InlineData(127)]
[InlineData(AsvAudioHelper.MaxPacketStreamData)]
[InlineData(AsvAudioHelper.MaxPacketStreamData + 1)]
[InlineData(256)]
[InlineData(1024)]
[InlineData(byte.MaxValue * AsvAudioHelper.MaxPacketStreamData)]
public async Task All_devices_send_status(int dataLength)
{
var link = new VirtualMavlinkConnection();
var rawPart = new RawCodecFactoryPart();
var factory = new CompositeAudioCodecFactory(new []{rawPart});
var device1 = new AudioService(factory, link.Client, new MavlinkIdentity(1,1), new PacketSequenceCalculator(), TimeSpan.FromSeconds(5),TimeSpan.FromSeconds(1));
var device2 = new AudioService(factory, link.Server, new MavlinkIdentity(2,2), new PacketSequenceCalculator(), TimeSpan.FromSeconds(5),TimeSpan.FromSeconds(1));

device1.GoOnline("device1", RawCodecFactoryPart.Raw8KHz16BitMono, true, true);
device2.GoOnline("device2", RawCodecFactoryPart.Raw8KHz16BitMono, true, true);

await Task.Delay(2000);

using var subscribe1 = device1.Devices.BindToObservableList(out var device1List).Subscribe();
using var subscribe2 = device2.Devices.BindToObservableList(out var device2List).Subscribe();

Assert.Equal(1, device1List.Count);
Assert.Equal(1, device2List.Count);
var audio1 = device1List.Items.First();
var audio2 = device2List.Items.First();

var tcs = new TaskCompletionSource();
var cancel = new CancellationTokenSource();
cancel.CancelAfter(TimeSpan.FromSeconds(10));
await using var c1 = cancel.Token.Register(()=>tcs.TrySetCanceled(), false);

var data = new byte[dataLength];
Random.Shared.NextBytes(data);

device2.OnReceiveAudio += (device, bytes, dataSize) =>
{
Assert.Equal(data.Length, dataSize);
for (var i = 0; i < dataSize; i++)
{
Assert.Equal(data[i], bytes[i]);
}
tcs.SetResult();
};

await audio1.SendAudio(data, data.Length, default);
await tcs.Task;


}
}
4 changes: 2 additions & 2 deletions src/Asv.Mavlink.Test/Microservices/AsvGbs/AsvGbsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public async Task Server_Send_Status_And_Client_Check_It(int lat,int lon,int alt
var link = new VirtualMavlinkConnection();
var cfg = new InMemoryConfiguration();
var mode = AsvGbsCustomMode.AsvGbsCustomModeAuto;
IGbsServerDevice serverDevice = new GbsServerDevice(link.Server, new MavlinkServerIdentity(),new PacketSequenceCalculator(),Scheduler.Default,new GbsServerDeviceConfig(), new List<IMavParamTypeMetadata>(), new MavParamCStyleEncoding(),cfg);
IGbsServerDevice serverDevice = new GbsServerDevice(link.Server, new MavlinkIdentity(),new PacketSequenceCalculator(),Scheduler.Default,new GbsServerDeviceConfig(), new List<IMavParamTypeMetadata>(), new MavParamCStyleEncoding(),cfg);
serverDevice.Gbs.AccuracyMeter.OnNext(0.15);
serverDevice.Gbs.ObservationSec.OnNext(1);
serverDevice.Gbs.DgpsRate.OnNext(2);
Expand Down Expand Up @@ -77,7 +77,7 @@ public async Task Client_Call_Command_And_Server_Catch_It(float duration,float a
var link = new VirtualMavlinkConnection();

var called = false;
var serverDevice = new GbsServerDevice(link.Server, new MavlinkServerIdentity(),new PacketSequenceCalculator(),Scheduler.Default, new GbsServerDeviceConfig(), new List<IMavParamTypeMetadata>(), new MavParamCStyleEncoding(),new InMemoryConfiguration());
var serverDevice = new GbsServerDevice(link.Server, new MavlinkIdentity(),new PacketSequenceCalculator(),Scheduler.Default, new GbsServerDeviceConfig(), new List<IMavParamTypeMetadata>(), new MavParamCStyleEncoding(),new InMemoryConfiguration());
serverDevice.Gbs.StartAutoMode = (dur, acc, cancel) =>
{
called = true;
Expand Down
10 changes: 5 additions & 5 deletions src/Asv.Mavlink.Test/Microservices/AsvSdr/AsvSdrExTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ public class AsvSdrExTests
var asvSdrClientEx = new AsvSdrClientEx(asvSdrClient, heartBeatClient, commandClient, new AsvSdrClientExConfig());

var pkt = new PacketSequenceCalculator();
var mavlinkServerIdentity = new MavlinkServerIdentity() { SystemId = 2, ComponentId = 2 };
var heartBeatServer = new HeartbeatServer(link.Server, pkt, mavlinkServerIdentity, new MavlinkHeartbeatServerConfig(), Scheduler.Default);
var commandServer = new CommandServer(link.Server, pkt, mavlinkServerIdentity, Scheduler.Default);
var MavlinkIdentity = new MavlinkIdentity(2, 2 );
var heartBeatServer = new HeartbeatServer(link.Server, pkt, MavlinkIdentity, new MavlinkHeartbeatServerConfig(), Scheduler.Default);
var commandServer = new CommandServer(link.Server, pkt, MavlinkIdentity, Scheduler.Default);
var commandLongServerEx = new CommandLongServerEx(commandServer);
var status = new StatusTextServer(link.Server, pkt, mavlinkServerIdentity, new StatusTextLoggerConfig(), Scheduler.Default);
var asvSdrServer = new AsvSdrServer(link.Server, mavlinkServerIdentity, new AsvSdrServerConfig(), pkt, Scheduler.Default);
var status = new StatusTextServer(link.Server, pkt, MavlinkIdentity, new StatusTextLoggerConfig(), Scheduler.Default);
var asvSdrServer = new AsvSdrServer(link.Server, MavlinkIdentity, new AsvSdrServerConfig(), pkt, Scheduler.Default);
var asvSdrServerEx = new AsvSdrServerEx(asvSdrServer,status, heartBeatServer, commandLongServerEx);

heartBeatServer.Start();
Expand Down
6 changes: 1 addition & 5 deletions src/Asv.Mavlink.Test/Microservices/AsvSdr/AsvSdrTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ private void SetupClientServer(out IAsvSdrServer serverSdr, out IAsvSdrClient cl
{
var link = new VirtualMavlinkConnection();
serverSdr = new AsvSdrServer(link.Server,
new MavlinkServerIdentity
{
ComponentId = 2,
SystemId = 2
}, new AsvSdrServerConfig(),
new MavlinkIdentity (2, 2), new AsvSdrServerConfig(),
new PacketSequenceCalculator(), Scheduler.Default);

clientSdr = new AsvSdrClient(link.Client, new MavlinkClientIdentity
Expand Down
Loading

0 comments on commit 5c92289

Please sign in to comment.