Pamoja.Mavlink
0.1.18
dotnet add package Pamoja.Mavlink --version 0.1.18
NuGet\Install-Package Pamoja.Mavlink -Version 0.1.18
<PackageReference Include="Pamoja.Mavlink" Version="0.1.18" />
<PackageVersion Include="Pamoja.Mavlink" Version="0.1.18" />
<PackageReference Include="Pamoja.Mavlink" />
paket add Pamoja.Mavlink --version 0.1.18
#r "nuget: Pamoja.Mavlink, 0.1.18"
#:package Pamoja.Mavlink@0.1.18
#addin nuget:?package=Pamoja.Mavlink&version=0.1.18
#tool nuget:?package=Pamoja.Mavlink&version=0.1.18
Pamoja.Mavlink
MAVLink v1 and v2 framing, signing, named message fields, and the mission, command, and offboard protocols. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.
Install
dotnet add package Pamoja.Mavlink
using Pamoja.Mavlink;
This pulls in Pamoja.Native, the compiled engine. dotnet add package Pamoja is the whole framework in one package.
Example
The guide project's example, spliced here as it ran in CI.
From bindings/dotnet/samples/Pamoja.Guides/MavlinkGuide.cs:
const byte Vehicle = 1;
const byte Autopilot = 1;
const byte Station = 255;
// The values the MAVLink common dialect gives these fields.
const byte MavTypeGcs = 6;
const byte MavTypeQuadrotor = 2;
const byte MavAutopilotInvalid = 8;
const byte MavAutopilotArdupilotmega = 3;
const byte MavStateActive = 4;
const byte MavStateStandby = 3;
const ushort MavCmdComponentArmDisarm = 400;
const ushort MavCmdNavTakeoff = 22;
const byte MavResultAccepted = 0;
// Every MAVLink node broadcasts a heartbeat to say what it is and that it is
// alive. The fields are set by name rather than by writing the payload out byte
// by byte.
using MavlinkSchema heartbeatShape = MavlinkSchema.ForName("HEARTBEAT");
using MavlinkMessage announce = heartbeatShape.CreateMessage();
announce.Set("type", MavTypeGcs);
announce.Set("autopilot", MavAutopilotInvalid);
announce.Set("system_status", MavStateActive);
announce.Set("mavlink_version", 3);
using MavlinkFrame sent = announce.ToFrame(new MavlinkHeader(Station, 190, 0));
Console.WriteLine($"sent HEARTBEAT in {sent.Bytes.Length} bytes");
// The vehicle answers with its own heartbeat. This copy arrives after some bytes
// that were already on the wire, and after a copy with one bit flipped in flight.
using MavlinkMessage vehicle = heartbeatShape.CreateMessage();
vehicle.Set("type", MavTypeQuadrotor);
vehicle.Set("autopilot", MavAutopilotArdupilotmega);
vehicle.Set("system_status", MavStateStandby);
vehicle.Set("mavlink_version", 3);
using MavlinkFrame good = vehicle.ToFrame(new MavlinkHeader(Vehicle, Autopilot, 0));
byte[] garbled = [.. good.Bytes];
garbled[^1] ^= 0xFF;
byte[] delivered = [.. "???"u8, .. garbled, .. good.Bytes];
// The parser skips whatever does not start a frame and drops one whose checksum
// fails, so the frame it hands back is the good copy rather than the garbled one.
using MavlinkParser parser = new();
using MavlinkFrame received = parser.Push(delivered)[0];
using MavlinkMessage heard = heartbeatShape.Decode(received.Payload);
Console.WriteLine(
$"heard a type-{heard.Get("type")} vehicle in state {heard.Get("system_status")}");
// Arming it is a command, not a message a sender fires and forgets: the vehicle
// has to answer, and the sender keeps asking until it does. The protocol numbers
// each resend, which is how a vehicle tells a retry from a deliberate second one.
using MavlinkCommand arming = new(MavCmdComponentArmDisarm, 3);
using MavlinkSchema commandShape = MavlinkSchema.ForName("COMMAND_LONG");
using MavlinkMessage arm = commandShape.CreateMessage();
arm.Set("param1", 1.0); // 1 arms, 0 disarms
arm.Set("target_system", Vehicle);
arm.Set("target_component", Autopilot);
arm.Set("command", arming.Command);
arm.Set("confirmation", arming.Confirmation);
Console.WriteLine($"sent arm request, confirmation {arming.Confirmation}");
arm.ToFrame(new MavlinkHeader(Station, 190, 1)).Dispose();
// Nothing comes back in time, so it goes again with the next confirmation number.
byte? resend = arming.OnTimeout();
Console.WriteLine($"silence, resending with confirmation {resend}");
// An acknowledgment names the command it answers, so one for a different command
// is not this exchange finishing.
using MavlinkSchema ackShape = MavlinkSchema.ForName("COMMAND_ACK");
MavlinkAckOutcome? stray = Acknowledge(ackShape, arming, MavCmdNavTakeoff);
Console.WriteLine($"an ack for another command: {stray?.Kind}");
MavlinkAckOutcome? outcome = Acknowledge(ackShape, arming, MavCmdComponentArmDisarm);
Console.WriteLine(
outcome?.Kind == MavlinkAckKind.Final && outcome?.Value == MavResultAccepted
? "armed the vehicle is ready"
: $"the vehicle answered {outcome?.Kind} {outcome?.Value}");
static MavlinkAckOutcome? Acknowledge(
MavlinkSchema shape,
MavlinkCommand tracked,
ushort command)
{
using MavlinkMessage ack = shape.CreateMessage();
ack.Set("command", command);
ack.Set("result", 0);
using MavlinkFrame frame = ack.ToFrame(new MavlinkHeader(1, 1, 0));
return tracked.OnFrame(frame);
}
The same capability in every language
| Language | Package | Reference |
|---|---|---|
| Rust | pamoja-mavlink |
reference, docs.rs, install |
| TypeScript | @pamoja/mavlink |
reference, install |
| Python | pamoja-mavlink |
reference, install |
| C# | Pamoja.Mavlink |
reference, install |
Documentation
Pamoja.Mavlinkreference, every type in this namespace.- The MAVLink guide, with the same example in Rust, TypeScript, and Python.
- Every capability, and the install page.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Pamoja.Native (>= 0.1.18)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Pamoja.Mavlink:
| Package | Downloads |
|---|---|
|
Pamoja
The whole pamoja framework in one package: every capability of one memory-safe Rust core, behind an idiomatic C# facade, for IoT, robotics, and drones. |
GitHub repositories
This package is not used by any popular GitHub repositories.