Skip to content Link Search Menu Expand Document
ModalAI DOCS
Store

voxl-osd

Renders the on-screen telemetry overlay for FPV video as MSP DisplayPort text, sent to voxl-vtx or an HDZero VTX.

Table of contents

  1. Overview
  2. Data Flow
  3. voxl-configure-osd
  4. Configuration File
    1. Input and Output
    2. Display Toggles
    3. Element Positions
    4. Menu and Flight Mode Fields
  5. OSD Menu
  6. External Flight Controller (MSP)
  7. HDZero Output
  8. Debugging
  9. Source Code

Overview

voxl-osd draws the on-screen display (OSD) for FPV video: battery, RC link, flight mode, arm state, position, heading, VIO state, VTX temperature and power, and warnings. It does not touch video pixels. It lays out a character-cell text canvas and streams it as MSP DisplayPort commands, which the video transmitter composites over the live video. On ModalAI FPV products the consumer is voxl-vtx; the same canvas can also be sent over UART to a third-party HDZero VTX.

The service also owns the OSD menu, a stick-driven menu shown in the goggles for changing flight modes, failsafe behavior, logging, and VTX settings without a ground station.

voxl-osd is enabled by voxl-configure-mpa on FPV SKUs such as Stinger and the VTX Air Unit, and disabled by default everywhere else. It runs as the systemd service voxl-osd.service, starting after voxl-px4 (without requiring it) and restarting automatically.

On-screen display elements, labeled

Data Flow

By default the service reads everything it displays from MPA pipes and writes the finished canvas to one output pipe.

PipeDirectionUsed for
mavlink_onboardinPX4 telemetry from voxl-mavlink-server: battery, attitude, GPS, RC channels, arm state, flight mode
mavlink_from_gcsinMANUAL_CONTROL from the ground, so the menu also responds to a joystick sent over IP
ov, qvioinVIO quality from voxl-open-vins-server or voxl-qvio-server
vfcinAssisted flight mode state from voxl-vision-hub, shown instead of PX4’s “OFFBOARD”
vtx_latencyinVTX temperature, TX power, and link stats from voxl-vtx
cpu_stats2inCPU and memory usage from voxl-cpu-monitor, for the optional usage lines and overload warnings
payload_statusinOptional payload arm and position strings shown at the top right
msp_osdoutMSP DisplayPort packets consumed by voxl-vtx
msp_ext_fc_statusoutArm state of an external flight controller, published only in MSP input mode

In external flight controller mode (see below) the MAVLink, VIO, and VFC inputs are replaced by an MSP UART link to the other flight controller.

voxl-configure-osd

voxl-configure-osd writes /etc/modalai/voxl-osd.conf and enables or disables the service. It must be run as root.

voxl-configure-osd factory_enable              # reset the config to defaults and enable
voxl-configure-osd factory_enable_no_compass   # defaults with the compass tape and degrees hidden
voxl-configure-osd external_fc                 # take input from an external MSP flight controller over UART
voxl-configure-osd hdzero                      # send the canvas over UART to an HDZero VTX
voxl-configure-osd enable                      # enable the service without touching the config
voxl-configure-osd disable                     # stop and disable the service

external_fc and hdzero pick the UART by platform:

Platformexternal_fc input porthdzero output port
M0054, M0154 (VOXL 2)/dev/ttyHS1/dev/ttyHS1
M0104, M0204 (VOXL 2 Mini)/dev/ttyHS0/dev/ttyHS0

Other platforms fall back to /dev/ttyHS1 for input and leave the output port empty. Edit input_port or output_port in the config file if your wiring differs.

Configuration File

/etc/modalai/voxl-osd.conf is JSON. It is created with defaults the first time the service runs, and any missing keys are added with their defaults on load. To print the loaded values without starting the service:

voxl-osd -c

Input and Output

FieldDefaultMeaning
input_protocol11 = MAVLink, 2 = MSP
input_type11 = MPA pipes, 2 = UART
input_port""UART device when input_type is 2
output_type10 = none, 1 = MPA (to voxl-vtx), 2 = UART (HDZero), 3 = both
output_port""UART device when output includes UART
emit_canvastrueEmit the DisplayPort text canvas on the MPA output. UART output is never gated by this
resolution1Canvas size in character cells: 0 = SD 30x16, 1 = HD 50x18, 2 = HD 30x16, 3 = HD 53x20
font_type0Font index reported to the VTX

Display Toggles

FieldDefaultMeaning
show_compass_tapetrueScrolling compass tape along the top of the canvas
show_compass_degreestrueNumeric heading in degrees. Shown even when the tape is off
compass_fov_deg120Field of view of the compass tape
show_mgrstrueMGRS grid reference line
mgrs_precision5MGRS digits per axis, 0 to 5
craft_name""Free-text craft name drawn on the canvas
show_vtx_cpu_mem_usagefalseVTX CPU and memory usage lines
show_vrx_stream_statsfalseVRX stream statistics
show_vio_overlayfalseVIO overlay
show_thermal_flowfalseThermal flow status
show_mavlinkfalseRaw MAVLink status

Element Positions

Every movable element has a *_col / *_row pair giving its character cell, origin top left. Set either value to -1 to hide the element. Defaults are for the HD 50x18 canvas.

ElementFieldsDefault (col, row)
RC link RSSIrssi_col, rssi_row0, 0
Compass tapecompass_col, compass_row22, 0
VIO statevio_col, vio_row1, 1
Payload actuator statepayload_actuator_col, payload_actuator_row42, 2
Payload statuspayload_status_col, payload_status_row42, 3
Craft namecraft_name_col, craft_name_row10, 3
VTX temperaturevtx_temp_col, vtx_temp_row0, 4
VTX TX powervtx_dbm_col, vtx_dbm_row0, 5
VTX CPU usagevtx_cpu_usage_col, vtx_cpu_usage_row0, 6
VTX memory usagevtx_mem_usage_col, vtx_mem_usage_row0, 7
Crosshaircrosshair_col, crosshair_row26, 8
Velocityvelocity_col, velocity_row47, 13
Altitudealtitude_col, altitude_row47, 14
Distance and direction to hometo_home_col, to_home_row39, 14
VTX overheat warningvtx_overheat_warn_col, vtx_overheat_warn_row0, 14
VTX overheat criticalvtx_overheat_crit_col, vtx_overheat_crit_row0, 15
MGRS grid referencemgrs_col, mgrs_row39, 15
Armed / disarmeddisarmed_col, disarmed_row25, 15
VTX CPU overload warningvtx_overload_col, vtx_overload_row0, 16
Latitudelatitude_col, latitude_row46, 16
Status textstatus_col, status_row24, 17
VTX memory warningvtx_mem_leak_col, vtx_mem_leak_row0, 17
Longitudelongitude_col, longitude_row46, 17
Flight modeflight_mode_col, flight_mode_row24, 19

Current draw, pack voltage, and per-cell voltage are pinned to the bottom right (column 43, rows 17 to 19) and cannot be moved.

FieldDefaultMeaning
menu_up_threshold1550Pitch stick value (us) above which the cursor moves up
menu_down_threshold1450Pitch stick value below which the cursor moves down
menu_right_threshold1550Roll stick value above which a value is incremented
menu_left_threshold1450Roll stick value below which a value is decremented
fltmode1_pset_mode, fltmode4_pset_mode, fltmode6_pset_mode0VFC assisted mode assigned to each flight-mode switch position, written by the Flight Mode menu
shortcut"OPT_A"Unused, kept for compatibility

Menu thresholds were 1650 / 1350 / 1850 / 1150 in voxl-osd 0.4.x. Versions from 1.0.0 on use the values above, so the menu needs less stick travel.

OSD Menu

With the vehicle disarmed, hold yaw up, throttle down, roll down, pitch down to open the menu. It always opens at the main menu. Pitch up and down moves the cursor. Roll left and right changes the value on the selected row or enters the highlighted submenu. Every menu ends with BACK, EXIT (discard), and SAVE AND EXIT rows. When flying over IP with voxl-joystick-server instead of an RC link, the same inputs come from the joystick.

MenuRowsWhat it changes
MainFLIGHT MODE, ADVANCEDEntry point
Flight ModeFLIGHT MODE, SWITCH VALUEAssigns a mode to the switch position currently selected on the transmitter. Writes COM_FLTMODE* and PSET_MODE and pushes a live SET_MODE over MAVLink. Modes that need GPS are hidden when SYS_HAS_GPS is off. Not shown for an external flight controller
AdvancedLOGGING, RC CHANNELS, FAILSAFE, and on newer versions ELRS and AR WAYPOINTSSubmenu index
LoggingVOXL-LOGGER-AUTO, DEBUG LOGToggles automatic voxl-logger recording on arm, and sets the VTX debug log to DISABLED, ENABLED, or ON ARM via voxl-send-command vtx_latency debug_log
RC Channelslive tableRead-only view of every RC channel value
FailsafeRC LOSS TIME, RC LOSS ACT, RC FINAL DELAY, RC FINAL ACT, GCS LOSS TIME, GCS LOSS ACTWrites COM_RC_LOSS_T, NAV_RCL_ACT, COM_RCL_ACT_T, COM_RCL_ACT, COM_DL_LOSS_T, and NAV_DLL_ACT. Actions: AUTO RTL, AUTO LAND, HOLD, TERMINATE, DISARM, DESCEND, plus DISABLED for GCS loss
ELRSCustom Domain RXELRS receiver option, voxl-osd 0.4.15 and later
AR Waypointssetup promptsAugmented-reality waypoint markers on the video, voxl-osd 1.1.0 and later

The menu can also change VTX channel, video profile, and PIT mode. Those rows are driven by voxl-vtx and are described in the VTX Air Unit Software Guide.

External Flight Controller (MSP)

The VTX can act as the digital video system for a non-VOXL flight controller that speaks MSP over UART, such as Betaflight:

voxl-configure-osd external_fc

This sets input_type to UART and input_protocol to MSP. The service then polls the external flight controller at 20 Hz for RC channels, status, box IDs, battery, analog, and GPS, renders the OSD from those, and publishes the arm state on msp_ext_fc_status. No MAVLink or PX4 is involved. Wiring and cable options are in the VTX Air Unit Quick Start Guide.

HDZero Output

To drive a third-party HDZero VTX instead of, or as well as, voxl-vtx:

voxl-configure-osd hdzero

This sets output_type to UART and the platform’s default output_port. Set output_type to 3 to keep the MPA output as well. See VOXL 2 with Third-Party VTX for the hardware side.

Debugging

voxl-inspect-services              # is voxl-osd running and enabled?
journalctl -u voxl-osd -f          # live service log
voxl-osd -c                        # print the loaded config and exit
ls /run/mpa/                       # msp_osd should exist once the service is up
  • No OSD in the goggles but video is fine: check that voxl-osd is running and that output_type is 1 or 3. voxl-vtx must be running to composite the canvas.
  • Telemetry fields blank: the service is up but mavlink_onboard has no data. Check voxl-mavlink-server and voxl-px4.
  • Menu does not open: the vehicle must be disarmed, and the sticks must pass the thresholds in the config. The RC Channels menu is the quickest way to see the values the service is reading.
  • After editing the config file, restart the service with systemctl restart voxl-osd.

Source Code

Source is at voxl-public/voxl-sdk/services/voxl-osd. It builds in the voxl-cross docker image per the repository README. Package versions shipped in each SDK are in the release notes.