Ruby's Software Architecture
Ruby is organised in a series of individual processes that talk with each other using an IPC mechanism.
Each process handles a particular task (see the diagram below for an overview of the processes).

Overall system architecture
At the core of RubyFPV system there is a mechanism for routing packets between local component and to/from remote components over radio links. You can read more about streams and how routing works here.
To ease the transportation of packets, all packets have the same structure and a common header so that they can be easely routed locally between local processes or across devices, using the available radio links.
The main responsability of most other processes, besides the routers, is to either just injest data in a particular format (UARTs, USB, RC Input, audio, video) and packetize it and send it to the router to be processed and sent to destination; either to get data packets from router and transform the data back to the desired output consumption (UARTs, telemetry, RC output, audio, video, etc);
Below is an explanation of what each process does and what it's responsabilities are:
Controller Router/Vehicle Router:
- Main responsability is to route packets between local components and over air;
- It's aware of and manages the radio configuration
- It's the only component that manages the radio links (sets frequencies, modulations schemes, etc);
- It's the only component that sends/receives packets over the air; All other components and processes in the system do not directly interact with the radio links, they just specify a destination for a packet they want to send and the router is the one that decides where and how to route the packet in question;
- To speed up the live FPV feed (lower latency), some of the logic that should be present in Video Streamer and Video Capture processes is moved directly to the Router, in order to avoid an IPC between two local processes;
Notes on the router packets/messages routing:
- If a unique packet is received from multiple radio interfaces (if a controller or vehicle has multiple radio links), router takes care of eliminating the duplicate;
- Ruby packets can be marked as high priority (for example a request for a video retransmission of a frame). In that case the router will send those packets first and they take priority in processing them through the system;
User Interface/GUI:
- Main responsability is to present the user interface on screen, to manage the user interface;
- Main responsability is to present the OSD on screen, to manage the OSD layout based on the current vehicle options;
- It updates and stores the local vehicle model objects;
- It interacts with the Router if/when it needs to send messages to the air side;
Video Streamer:
- Main responsability is ingest the video stream packets it receives from Router and send them to the HDMI output;
- It's also used to playback offline video files, in which case it works standalone, as a simple video file playback program;
Video Capture:
- Main responsability is to connect to the SBC camera/ISP processor, using the APIs provided by the SBC and to injest the raw video data and packetize it and send it to router;
- It's also responsible for interfacing with the SBC in order to configure the video capture parameters (video resolution, FPS, etc)
RC:
- Main responsability (on the controller) is ingest the RC input from user (if one is present, in form of USB joystick/gamepad/RC Transmitter or from Pico addon SBUS, and packetize it and send it to the router to be sent to the other side to the flight controller;
- Main responsability (on the vehicle) is to receive packets from router (packets containing RC info and MAVLink info) and send it to the flight controller as RC messages;
Telemetry/Data Streams:
- Main responsability (on the controller) is ingest the serial streams (if one or more is/are present and configured as such, from UART ports) and to packetize it and send it to the router to be sent to the other side to a matching UART port
- Main responsability (on the vehicle) is to receive packets from router (packets containing serial data streams) and reconstruct the serial data stream and send it to the appropiate/configured as such UART port on the vehicle side;
- Taken together with the Router, this is more like a transparent bidirectional UART/serial link between ground and vehicle;
Commands:
- Main responsability is to receive from router commands sent by the ground controller and update the vehicle settings and the persistent storage of the vehicle's settings.
- For many of the settings changes done by the user, it just persist the change to local storage and forwards the change to the router (using the same common IPC mechanism and same common packets structure) so that the router can route it to the component/process that needs to do any particular updates on the SBC based on the settings changed (ie. change capture video resolution);
Below is a sample of how Ruby messages travel through the system. Usually a message travels from one end (controller or vehicle) to another (vehicle or controller).

Overall flow of Ruby messages
In Ruby, all settings related to a vehicle (video resolution, FPS, telemetry ports, OSD settings, etc) are stored in a C++ object called Model. This object persists the settings to persistent storage.
On vehicles, there is a single Model object, as the vehicle is a single entity;
On controllers, there are as many Model objects as there are vehicles paired with the controller. The controller manages the list of Models and presents the user, in the user interface, the option to switch between models, search and pair with new vehicles (so new Models gets created and managed by the controller);
Now, to get more technical details, read the development guide
Related read:
Radio Links and Interfaces: How They WorkRadio Streams: How They Work
Ruby's Development Guide
Ruby