XMAVLink.Router (xmavlink v0.11.1)

Copy Markdown View Source

Connect to serial, udp and tcp ports and listen for, validate and forward MAVLink messages towards their destinations on other connections and/or Elixir processes subscribing to messages.

The rules for MAVLink packet forwarding are described here:

https://mavlink.io/en/guide/routing.html

and here:

http://ardupilot.org/dev/docs/mavlink-routing-in-ardupilot.html

Summary

Types

Represents the state of the XMAVLink.Router. Initial values should be set in config.exs.

t()

Functions

Send a MAVLink message to one or more recipients using available connections. For now if destination is unreachable it will log a warning

Start the MAVLink Router service. You should not call this directly, use the MAVLink application to start this under a supervision tree with the services it expects to use.

Subscribes the calling process to MAVLink messages from the installed dialect matching the query.

Un-subscribes calling process from all existing subscriptions

Types

connection_key()

@type connection_key() ::
  :local
  | binary()
  | port()
  | {port(), XMAVLink.Types.net_address(), XMAVLink.Types.net_port()}

router_name()

@type router_name() :: atom() | {:global, term()} | {:via, module(), term()}

router_ref()

@type router_ref() :: GenServer.server()

subscribe_query()

@type subscribe_query() :: [
  {:message, XMAVLink.Message.t() | :unknown}
  | {subscribe_query_id_key(), 0..255}
  | {:as_frame, boolean()}
]

subscribe_query_id_key()

@type subscribe_query_id_key() ::
  :source_system | :source_component | :target_system | :target_component

t()

@type t() :: %XMAVLink.Router{
  connection_retry_ms: non_neg_integer(),
  connection_strings: [String.t()],
  connection_supervisor: pid() | nil,
  connection_worker_monitors: %{required(reference()) => pid()},
  connection_workers: %{required(connection_key()) => pid()},
  connections: %{required(connection_key()) => mavlink_connection()},
  dialect: module() | nil,
  name: router_name() | nil,
  routes: %{required(mavlink_address()) => connection_key()},
  subscription_cache: router_name() | nil
}

Functions

pack_and_send(message)

@spec pack_and_send(XMAVLink.Message.t()) :: :ok | {:error, :protocol_undefined}

Send a MAVLink message to one or more recipients using available connections. For now if destination is unreachable it will log a warning

Parameters

  • router: Optional router name or pid. Defaults to XMAVLink.Router.
  • message: A MAVLink message structure from the installed dialect
  • version: Force sending using a specific MAVLink protocol (default 2)
  • opts: Optional send settings:
    • :source_system and :source_component override the router's configured local identity for this message. Provide both or neither.

Example

  XMAVLink.Router.pack_and_send(
    %Common.RcChannelsOverride{
      target_system: 1,
      target_component: 1,
      chan1_raw: 1500,
      chan2_raw: 1500,
      chan3_raw: 1500,
      chan4_raw: 1500,
      chan5_raw: 1500,
      chan6_raw: 1500,
      chan7_raw: 1500,
      chan8_raw: 1500,
      chan9_raw: 0,
      chan10_raw: 0,
      chan11_raw: 0,
      chan12_raw: 0,
      chan13_raw: 0,
      chan14_raw: 0,
      chan15_raw: 0,
      chan16_raw: 0,
      chan17_raw: 0,
      chan18_raw: 0
    }
  )

pack_and_send(router, message)

@spec pack_and_send(router_ref(), XMAVLink.Message.t()) ::
  :ok | {:error, :protocol_undefined}
@spec pack_and_send(XMAVLink.Message.t(), XMAVLink.Types.version() | keyword()) ::
  :ok | {:error, :protocol_undefined}

pack_and_send(router, message, opts)

@spec pack_and_send(
  router_ref(),
  XMAVLink.Message.t(),
  XMAVLink.Types.version() | keyword()
) ::
  :ok | {:error, :protocol_undefined}
@spec pack_and_send(XMAVLink.Message.t(), XMAVLink.Types.version(), keyword()) ::
  :ok | {:error, :protocol_undefined}

pack_and_send(router, message, version, opts)

@spec pack_and_send(
  router_ref(),
  XMAVLink.Message.t(),
  XMAVLink.Types.version(),
  keyword()
) ::
  :ok | {:error, :protocol_undefined}

start_link(args, opts \\ [])

@spec start_link(
  %{
    :system => 1..255,
    :component => 1..255,
    :dialect => module(),
    optional(:name) => router_name() | nil,
    optional(:connection_strings) => [String.t()],
    optional(:connections) => [String.t()],
    optional(:connection_retry_ms) => non_neg_integer()
  },
  [{atom(), any()}]
) :: {:ok, pid()}

Start the MAVLink Router service. You should not call this directly, use the MAVLink application to start this under a supervision tree with the services it expects to use.

Parameters

  • dialect: Name of the module generated by mix mavlink task to represent the enumerations

                    and messages of a particular MAVLink dialect
  • system: The System id of this system 1..255, typically low for vehicles and high for

                    ground stations
  • component: The component id of this system 1..255, typically 1 for the autopilot

  • connection_strings: A list of strings in the following formats:

                    udpin:<local ip>:<local port>
                    udpout:<remote ip>:<remote port>
                    tcpout:<remote ip>:<remote port>
                    serial:<device>:<baud rate>
  • connection_retry_ms:

                    Retry delay for configured connection workers after
                    open failures or TCP/serial disconnects. Defaults to
                    1000 ms.
  • opts: Standard GenServer options. Pass :name to register

                    a non-default router, or `name: nil` in the args map to
                    start an unregistered router addressed by pid.

subscribe()

@spec subscribe() :: :ok | {:error, :invalid_message}

Subscribes the calling process to MAVLink messages from the installed dialect matching the query.

Parameters

  • router: Optional router name or pid. Defaults to XMAVLink.Router.

  • query: Keyword list of zero or more of the following query keywords:

    message: message_module | :unknown (use latter with as_frame) source_system: integer 0..255 source_component: integer 0..255 target_system: integer 0..255 target_component: integer 0..255 as_frame: true|false (default false, shows entire message frame with sender/target details)

Example

  XMAVLink.Router.subscribe message: XMAVLink.Message.Heartbeat, source_system: 1

subscribe(router)

@spec subscribe(router_ref() | subscribe_query()) :: :ok | {:error, :invalid_message}

subscribe(router, query)

@spec subscribe(router_ref(), subscribe_query()) :: :ok | {:error, :invalid_message}

unsubscribe()

@spec unsubscribe() :: :ok

Un-subscribes calling process from all existing subscriptions

Example

  XMAVLink.Router.unsubscribe

unsubscribe(router)

@spec unsubscribe(router_ref()) :: :ok