Skip to content Link Search Menu Expand Document
ModalAI DOCS
Store

voxl-rc-server

Bridge RC channels from a USB joystick or MAVLink stream to an ELRS transmitter or a MAVLink link.

Table of contents

  1. Overview
  2. Enable the Service
  3. Command Line
  4. Configuration File
  5. voxl-configure-rc-server

Overview

voxl-rc-server takes RC channel input from a receive (RX) source and sends it to a transmit (TX) sink. It ships with the VOXL SDK. On FPV systems it runs on the VRX to bridge a transmitter or joystick to the vehicle.

DirectionModuleDescription
RXjoystickA Linux evdev joystick, for example a USB radio in joystick mode
RXmavlinkMAVLink over UDP: RC_CHANNELS, RC_CHANNELS_RAW, RC_CHANNELS_SCALED, or MANUAL_CONTROL
TXcrsfAn ELRS transmitter on a serial port, driven with CRSF RC frames
TXmavlinkMAVLink over UDP: RC_CHANNELS, or MANUAL_CONTROL with arm and mode commands

With no configuration file and no command-line options, the server builds a working setup from what it finds:

  • It listens for MAVLink on UDP port 14550 over IPv6 multicast (ff12::5352:5243) and sends what it receives to a locally connected ELRS transmitter, if one is present.
  • If a joystick is plugged in, it sends the joystick’s channels over IPv6 multicast.
  • If a joystick and a transmitter are both connected locally, it translates the joystick input directly to the transmitter and does not multicast.

With no CRSF device given, the server opens the first serial device it finds under /dev/serial/by-id, then /dev/ttyUSB*, then /dev/ttyACM*, at 921600 baud, and sets the transmitter’s ELRS packet rate (50 Hz by default).

Enable the Service

systemctl enable voxl-rc-server
systemctl start voxl-rc-server

The service runs /usr/bin/voxl-rc-server with no arguments, so it uses /etc/modalai/voxl-rc-server.json when that file exists and the defaults above otherwise.

Command Line

Command-line options override the matching entries in the configuration file.

OptionDescription
--rx <spec>RX source: joystick (auto-detect), joystick:/dev/input/eventN, or mavlink:PORT
--tx <spec>TX sink: crsf:/dev/ttyUSB0 (optionally crsf:/dev/ttyUSB0@BAUD) or mavlink:IP:PORT
--bindBind at start-up. A CRSF sink sends the ELRS bind frame; a MAVLink sink broadcasts MAV_CMD_START_RX_PAIR
--list-joysticksList the available /dev/input devices and exit
--monitorShow a live channel monitor (needs a terminal)
--no-heartbeatDo not send MAVLink heartbeats
--rx-debugPrint verbose debug output from the RX module
--debug-statePrint the joystick state on input events
--debug-joystick-publish, --debug-mavlink-publish, --debug-crsf-publishPrint each publish call of that module
-h, --helpShow the help text and exit

For example, to drive an ELRS transmitter on /dev/ttyUSB0 from a local joystick and watch the channels:

voxl-rc-server --rx joystick --tx crsf:/dev/ttyUSB0 --monitor

The monitor prints one row of RX values in microseconds and one row of TX values (CRSF ticks for a CRSF output, microseconds for a MAVLink output), labeled with the channel labels from the configuration.

There is no unbind option on the command line. Unbind is available from a joystick button; see unbind_button below.

Configuration File

The configuration lives in /etc/modalai/voxl-rc-server.json. Every key is optional. Top-level keys:

KeyDescription
orchestrator.rx, orchestrator.txPreference-ordered lists of RX and TX modules. Default ["joystick", "mavlink"] and ["crsf", "mavlink"]
orchestrator.hysteresisSource selection timing in ms: rx_min_hold_ms (default 300), rx_stale_ms (1000), rx_fallback_grace_ms (600), tx_retry_ms (500), status_poll_ms (100), reselect_backoff_ms (750)
modulesPer-module settings, below
channel_labelsUp to 16 channel labels for the monitor. Default ROL PIT THR YAW ARM FM LED SUP0 SUP1 REC CAM

Module keys:

ModuleKeys
rx_joystickdevice, update_rate_hz (default 200), axes (with limit_throttle_range, center_zero_throttle), axes_channels, buttons (code, channel, press, release), bind_button, unbind_button, vrx_scan_button
rx_manual_controlaxes, buttons
rx_mavlinkport (default 14550), mcast (default true), iface
tx_crsfdevice, baud (default 921600), packet_rate (default "50Hz")
tx_mavlinkip, port (default 14550), mcast (default true; used when no ip is set), iface, system_id, component_id, rate_hz, manual_control, heartbeat_hz (default 1), no_heartbeat, target_system, target_component (default 1), axis, buttons

Joystick bind_button, unbind_button, and vrx_scan_button take a Linux input event code, the same value used for code in buttons. Pressing the button sends bind, unbind, or VRX scan to the active TX sink.

With tx_mavlink.manual_control set to true, the MAVLink sink sends MANUAL_CONTROL instead of RC_CHANNELS. Its buttons entries watch a channel (channel, pressed value, epsilon tolerance) and run an on_press or on_release action: arm, disarm, terminate, or set_mode with main_mode and sub_mode.

The package ships presets for the rx_joystick, rx_manual_control, and tx_mavlink modules. They include mappings for Zorro joysticks and a VOXL-FPV MAVLink preset that maps arm and flight-mode switches to commands.

voxl-configure-rc-server

voxl-configure-rc-server writes /etc/modalai/voxl-rc-server.json. With no arguments it opens an interactive menu, which includes a Custom flow that builds a configuration from the installed presets. The script needs jq in every mode; the package ships its own copy of gum for the menu prompts.

The scripted modes write the configuration and enable the service. They do not start it, so start it or reboot afterwards:

voxl-configure-rc-server factory_enable_fiber
voxl-configure-rc-server factory_enable_lte_joystick 192.168.1.10 14550
voxl-configure-rc-server disable
systemctl start voxl-rc-server

The script also has non-interactive factory modes for specific vehicle radio setups:

ModeResult
factory_enable_fiberJoystick with the Zorro preset, sent as MAVLink with the VOXL-FPV preset to 10.0.0.10:14550 (unicast)
factory_enable_dtcJoystick, sent as MAVLink with the DTC preset to 192.168.0.100:14550 (unicast)
factory_enable_dgcs_towerReceives MAVLink manual control on UDP port 14551 (voxl-joystick-server input preset) and sends it out as CRSF on /dev/ttyHS1 at 921600 baud and as MAVLink with the VOXL-FPV preset to 10.1.0.2:14550 (unicast)
factory_enable_dgcs_pilotJoystick with the Zorro preset, sent as MAVLink MANUAL_CONTROL to 10.0.0.10:14551 (unicast)
factory_enable_lte_joystick IP PORTJoystick, sent as MAVLink with the VOXL-FPV preset to the given IP and port (unicast)
disableDisable and stop the service
helpPrint the usage text

On the vehicle, voxl-mavlink-server receives the MAVLink RC. For ELRS receivers and transmitters, see voxl-elrs.