Skip to content

AvantOpsIO/dronekit-runtime

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dronekit-runtime

What this is

dronekit-runtime is a Go library that exposes drone capabilities over the network. It is a runtime that composes pluggable services (MAVLink listeners, video transport, and future adapters); it is not a flight simulator or physics engine. Operators and ground-control software connect to the endpoints each service advertises.

Architecture

Every capability implements the service.Service interface: a stable name, lifecycle methods (Start / Shutdown), and structured []service.Endpoint values (not raw strings). An Endpoint carries an optional logical name, a protocol label (for example udp or rtp+udp), and the resolved listen address after bind.

The drone.Drone type is the container: services are stored in registration order as a slice, with a name-to-index map for fast lookup. That ordering is reserved for future ordered or dependency-aware startup without refactoring. The Drone type knows nothing about MAVLink, video codecs, or simulators—it only manages service.Service values.

The video subsystem composes three package-local interfaces—Source (ingest), optional Pipeline (processing), and Transport (egress)—with fixed-size buffered channels between stages. Network-based sources can optionally implement Endpointer so the video service can append an ingest endpoint next to the transport’s egress endpoint; sources that are not network-bound omit it.

Packages are laid out as: service/ for the core contract, drone/ for orchestration, services/mavlink/ and services/video/ for built-in services, services/adapters/ reserved for third-party or product-specific bridges, and example/ for a runnable demo.

External systems and SITL

SITL (Software-In-The-Loop) means running real autopilot or flight-stack software against simulated physics and sensors instead of a physical airframe; network links still look like a vehicle even when multiple processes implement them.

Boundaries: Gazebo plugins, a Gazebo video bridge (separate repository or container), and any RTSP server that publishes camera video live outside this module. This library does not ship C++ build trees, bridge Dockerfiles, or an RTSP server implementation.

services/adapters: only importable Go sub-packages that implement service.Service or video stage interfaces. A C++/Docker bridge belongs in another repository or a top-level contrib/ (or similar) layout—not under services/adapters, which implies Go import paths.

Developer-facing drone surface: when you register services on a drone.Drone, aggregated Endpoints() should let integrators treat MAVLink and video as two facets of the same vehicle. dronekit-runtime is where you configure the video stream URL (for example with video.NewRTSPAdvertise) so it appears next to MAVLink; an external bridge serves that RTSP stream at the configured location. The runtime advertises the link; it does not encode video or terminate RTSP for GCS unless you add separate components.

Non-goals: MJPEG re-encoding, WebSocket video, WebRTC, and other browser-specific delivery stacks are consumer concerns (GCS, web C2), not responsibilities of this library.

Video subsystem

Data moves from producers into the runtime and out toward consumers (for example a GCS):

flowchart LR
  ING["INGEST: simulator/camera → runtime"] --> Source[Source]
  Source --> Pipeline["Pipeline (optional)"]
  Pipeline --> Transport[Transport]
  Transport --> EGR["EGRESS: runtime → GCS"]
Loading

Ingest is the Source: it accepts opaque []byte frames or packets from cameras, simulators, pipes, or UDP listeners. Egress is the Transport: it is always network-facing and exposes an Endpoint(). The optional Pipeline sits between them for encode, transcode, or other transforms. Network sources such as UDPSource also implement Endpointer, so Endpoints() lists where to send simulator or camera traffic as well as where the GCS attaches.

Recommended SITL video integration: an external Gazebo bridge (other repo) publishes H.264 over RTSP to ground consumers. dronekit-runtime should list that stream on the drone via runtime configuration—for example video.NewRTSPAdvertise with a URL that matches what the bridge serves (host:port/path, logged as rtsp://…). The bridge implements the stream; this library does not run an RTSP server for that path.

Current library (UDP pipeline): UDPSource and UDPTransport implement a generic opaque-[]byte pipeline and power the default go run ./example demo (ingest/egress UDP ports). That path is useful for labs and tooling; it is not the same as “GCS consumes bridge RTSP.”

UDPTransport v1 binds UDP and drains the internal channel (logging in v1); it does not replace an external RTSP endpoint served by the Gazebo bridge for typical SITL GCS workflows.

Usage patterns:

  1. SITL / configured RTSP URL — Register video.NewRTSPAdvertise so Drone.Endpoints() includes rtsp://… alongside MAVLink; run the external bridge so it serves that URL. No in-process RTSP server in this repo.
  2. Passthrough UDP — An external encoder (GStreamer, ffmpeg, etc.) sends datagrams into UDPSource; Pipeline is nil and UDPTransport (v1) binds egress and consumes the stream (logging in v1). See go run ./example.
  3. Full pipeline — A custom Source feeds a GStreamer-style Pipeline for H.264/RTP, then a Transport (or future transports) for egress.
  4. Future transports — Any Source and optional Pipeline can pair with a Transport implementation such as WebRTC without changing the core video orchestration.

Adding a backend adapter

Adapters live under services/adapters/<name>/ and implement service.Service (or a video stage interface). They are wired like any other service:

type PX4Adapter struct{}

func (p *PX4Adapter) Name() string { return "px4" }

func (p *PX4Adapter) Start(ctx context.Context) error {
	// connect to PX4 / open ports / begin loops
	return nil
}

func (p *PX4Adapter) Shutdown(ctx context.Context) error {
	// close connections and wait for goroutines
	return nil
}

func (p *PX4Adapter) Endpoints() []service.Endpoint {
	return []service.Endpoint{{Name: "mavlink", Protocol: "udp", Address: "0.0.0.0:14540"}}
}

func example() {
	d := drone.New()
	_ = d.AddService(&PX4Adapter{})
}

This snippet is illustrative only; no PX4 logic ships in this repository.

Running the examples

UDP video pipeline (lab / generic ingest):

go run ./example

Registers MAVLink UDP on 14550, video ingest on 5601, and video egress bind on 5600, logs every endpoint, and shuts down cleanly on Ctrl+C.

SITL-style MAVLink + advertised RTSP URL (no UDP video sockets):

go run ./example/sitl

Registers MAVLink and video.NewRTSPAdvertise with a placeholder RTSP address; logs MAVLink and rtsp://… endpoints. Point the URL at your external Gazebo bridge (separate repository).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages