### Install Ruby Development Tools on Raspberry Pi Source: https://rubyfpv.com/development.php This command installs the necessary tools like cmake, gcc, and libraries for compiling custom plugins on a Raspberry Pi board. ```bash sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential ``` -------------------------------- ### getDefaultHeight Source: https://rubyfpv.com/development_osd.php Provides the default height for a plugin after installation. This height is within the (0...1) range. If not implemented, Ruby selects a default. ```APIDOC ## getDefaultHeight ### Description This method returns the default height for a plugin. The user can resize and reposition the plugin after installation. If this function is not implemented, Ruby will choose a default height. All sizes are in the (0...1) range. ### Method `float getDefaultHeight();` ### Parameters None ### Response - **float**: The default height of the plugin. ``` -------------------------------- ### I2C_COMMAND_ID_RC_GET_CHANNELS Source: https://rubyfpv.com/development_extensions.php Gets the current RC channels values from the slave device. ```APIDOC ## I2C_COMMAND_ID_RC_GET_CHANNELS ### Description Retrieve the current values of RC channels from the slave device. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for getting RC channels (0x21). ### Response #### Slave Responds - **flags** (byte) - Bit 0 is set if RC input failsafe event occurred. - **frame number** (byte) - Monotonically increasing on each received RC frame. - **RC channels values** (24 bytes) - LSBits (8 bits) for channels 1-16, followed by MSBits (4 bits) for channels 1-16. Unused channels are set to zero. ``` -------------------------------- ### Basic OSD Plugin Structure in C Source: https://rubyfpv.com/development_osd.php This C code provides the fundamental structure for an OSD plugin, including initialization, name and UID retrieval, and the main rendering function. It demonstrates how to interact with the render engine to draw basic shapes and text. ```c #include #include #include "render_engine_ui.h" #include "telemetry_info.h" #include "settings_info.h" PLUGIN_VAR RenderEngineUI* g_pEngine = NULL; PLUGIN_VAR const char* g_szPluginName = "My Example Plugin"; PLUGIN_VAR const char* g_szUID = "542AST-G3432Q-WE19J-0024"; #ifdef __cplusplus extern "C" { #endif void init(void* pEngine) { g_pEngine = (RenderEngineUI*)pEngine; } char* getName() { return (char*)g_szPluginName; } char* getUID() { return (char*)g_szUID; } void render(vehicle_and_telemetry_info_t* pTelemetryInfo, plugin_settings_info_t* pCurrentSettings, float xPos, float yPos, float fWidth, float fHeight) { if ( NULL == g_pEngine || NULL == pTelemetryInfo ) return; float xCenter = xPos + 0.5*fWidth; float yCenter = yPos + 0.5*fHeight; g_pEngine->setColors(g_pEngine->getColorOSDInstruments()); g_pEngine->drawCircle(xCenter, yCenter, fWidth * 0.5); char szBuff[64]; sprintf(szBuff, "%d", pTelemetryInfo->heading); u32 fontId = g_pEngine->getFontIdRegular(); float height_text = g_pEngine->textHeight(fontId); float width_text = g_pEngine->textWidth(fontId, szBuff); g_pEngine->setColors(g_pEngine->getColorOSDText()); g_pEngine->drawText(xCenter - 0.5 * width_text, yCenter - 0.5 * height_text, fontId, szBuff); } #ifdef __cplusplus } #endif ``` -------------------------------- ### VSCode C/C++ Configuration for Raspberry Pi Source: https://rubyfpv.com/development_osd_tutorial.php This JSON file configures VSCode's C/C++ extension for a Raspberry Pi development environment. It specifies include paths, defines, the compiler path, and IntelliSense mode for cross-compilation. ```json { "configurations": [ { "name": "Raspberry", "includePath": [ "${workspaceRoot}/**", "${workspaceRoot}/../RubyFPV/code" ], "defines": [ "_GNU_SOURCE" ], "compilerPath": "arm-linux-gnueabihf-g++.exe", "cppStandard": "gnu++17", "intelliSenseMode": "linux-gcc-arm", "configurationProvider": "ms-vscode.makefile-tools", "cStandard": "gnu17", "mergeConfigurations": false, "browse": { "path": [ "${workspaceRoot}/**", "${workspaceRoot}/../RubyFPV/code" ], "limitSymbolsToIncludedHeaders": true } } ], "version": 4 } ``` -------------------------------- ### I2C_COMMAND_ID_CAMERA_CTRL_QUERY Source: https://rubyfpv.com/development_extensions.php Ask the slave device if they have any pending camera params changes or wants to change something. ```APIDOC ## I2C_COMMAND_ID_CAMERA_CTRL_QUERY ### Description Check with the slave device if there are any pending camera parameter changes or if it intends to modify something. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for camera control query (0x50). ``` -------------------------------- ### Makefile for Plugin Compilation Source: https://rubyfpv.com/development_osd.php A sample Makefile used to compile a C/C++ source file into a shared Linux library (plugin) for the Ruby system. It defines compilation flags and linking options. ```makefile LDFLAGS=-lrt -lpcap -lpthread CPPFLAGS=-Wall -O0 -D _GNU_SOURCE CFLAGS := $(CFLAGS) all: my_plugin %.o: %.cpp g++ $(CFLAGS) -c -o $@ $< $(CPPFLAGS) my_plugin: my_plugin_source.o gcc my_plugin_source.o -shared -Wl,-soname,my_plugin.so.1 -o my_plugin.so.1.0.1 -lc clean: rm -f my_plugin.so.* *.o ``` -------------------------------- ### I2C_COMMAND_ID_GET_VERSION Source: https://rubyfpv.com/development_extensions.php Master asks the slave for its software version. ```APIDOC ## I2C_COMMAND_ID_GET_VERSION ### Description Get the software version of the I2C slave device. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for getting the version (0x02). ### Response #### Slave Responds - **version** (byte) - The version of the software on the I2C slave device. ``` -------------------------------- ### Makefile for OSD Plugin Compilation Source: https://rubyfpv.com/development_osd_tutorial.php This Makefile defines variables for versioning, compiler prefixes, platform-specific flags, include paths, and linker options. It includes targets for building the plugin and cleaning build artifacts. ```makefile VER_MAJOR := 1 VERSION := $(VER_MAJOR).0.1 PREFIX := arm-linux-gnueabihf- GPP := $(PREFIX)g++ GCC := $(PREFIX)gcc PLATFORM = -march=armv7-a -mfloat-abi=hard -mfpu=neon-vfpv4 INCLUDES += -I../../RubyFPV/code LDFLAGS= -lrt -lpthread -lc -shared $(LIBS) CFLAGS += $(PLATFORM) -fno-stack-protector -Wall -O0 -D _GNU_SOURCE -Wno-address-of-packed-member $(INCLUDES) CPPFLAGS= $(PLATFORM) $(CFLAGS) --std=gnu++17 OUTPUT := build .PHONY: clean all all: my_plugin $(OUTPUT)/%.o: %.cpp mk-dirs $(GPP) $(CPPFLAGS) -c -o $@ $< my_plugin: $(OUTPUT)/my_plugin_source.o mk-dirs $(GCC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)/my_plugin_source.o -Wl,-soname, my_plugin.so.$(VER_MAJOR) -o $(OUTPUT)/my_plugin.so.$(VERSION) mk-dirs: mkdir ./$(OUTPUT) clean: rm -fr $(OUTPUT) ``` -------------------------------- ### I2C_COMMAND_ID_FLIGHT_CTRL_QUERY_MODE Source: https://rubyfpv.com/development_extensions.php Ask the slave device if the vehicle should receive a new flight mode. ```APIDOC ## I2C_COMMAND_ID_FLIGHT_CTRL_QUERY_MODE ### Description Query the slave device to determine if a new flight mode should be set. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for querying flight mode (0x41). ### Response #### Slave Responds - **flight mode info** (byte): - **bit 0**: 0 - no change; 1 - has new flight mode. - **bits 1-7**: new flight mode as defined by ArduPilot. ``` -------------------------------- ### I2C_COMMAND_ID_GET_BUTTONS_EVENTS Source: https://rubyfpv.com/development_extensions.php Master asks slave if any buttons were pressed. ```APIDOC ## I2C_COMMAND_ID_GET_BUTTONS_EVENTS ### Description Query the slave device to check if any buttons have been pressed or long pressed. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for getting button events (0x10). ### Response #### Slave Responds - **pressed buttons** (2 bytes) - Each bit represents 1 if a button was pressed (up to 16 buttons). - **long pressed buttons** (2 bytes) - Each bit represents 1 if a button was long pressed (up to 16 buttons). ### Button Mapping - **bit 0**: Menu/Ok button - **bit 1**: Cancel button - **bit 2**: Plus button - **bit 3**: Minus button - **bit 4**: QA1 button - **bit 5**: QA2 button - **bit 6**: QA3 button - **bit 7**: Action Plus button - **bit 8**: Action Minus button - **bit 9...**: future use ``` -------------------------------- ### I2C_COMMAND_ID_GET_NAME Source: https://rubyfpv.com/development_extensions.php Master asks slave for the device name, to be used in the user interface. ```APIDOC ## I2C_COMMAND_ID_GET_NAME ### Description Get the device name from the I2C slave device. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for getting the name (0x03). ### Response #### Slave Responds - **device name** (string) - Null terminated string, padded with 0 up to I2C_PROTOCOL_STRING_LENGTH bytes. ``` -------------------------------- ### I2C_COMMAND_ID_FLIGHT_CTRL_QUERY_ARM Source: https://rubyfpv.com/development_extensions.php Ask the slave device if the vehicle should receive the arm or disarm command. ```APIDOC ## I2C_COMMAND_ID_FLIGHT_CTRL_QUERY_ARM ### Description Query the slave device to determine if an arm or disarm command should be issued. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for querying arm state (0x40). ### Response #### Slave Responds - **arm state info** (byte): - **bit 0**: 0 - no change; 1 - has new arm state. - **bit 1**: 0 - disarm; 1 - arm. ``` -------------------------------- ### I2C Capability Flag: Sounds Source: https://rubyfpv.com/development_extensions.php Defines the flag to indicate if a slave device is capable of playing sounds, such as alarms. This is for extensions that provide audio feedback. ```c I2C_CAPABILITY_FLAG_SOUNDS ((u16)(((u16)0x01)<<10)) // Set if the slave device can play sounds (alarms); ``` -------------------------------- ### I2C_COMMAND_ID_SET_RC_OUTPUT_FLAGS Source: https://rubyfpv.com/development_extensions.php Master tells the slave what RC protocol to generate and if the RC output UART should be inverted. ```APIDOC ## I2C_COMMAND_ID_SET_RC_OUTPUT_FLAGS ### Description Configure the slave device to generate a specific RC protocol and set UART inversion for RC output. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for setting RC output flags (0x30). - **RC output flags** (byte) - Flags for RC output configuration: - **bits 0-4**: RC protocol (1 - SBUS, 2 - IBUS, 4 - PPM). - **bit 4**: UART inversion (0 - non inverted, 1 - inverted). ### Response #### Slave Responds - **status** (byte) - 0 for OK, 1 for error. ``` -------------------------------- ### Mandatory Plugin Functions Source: https://rubyfpv.com/development_osd.php The minimum set of functions required for a plugin to operate correctly within the Ruby system. These functions handle initialization, naming, unique identification, and rendering. ```c void init(void* pEngine); char* getName(); char* getUID(); void render(vehicle_and_telemetry_info_t* pTelemetryInfo, plugin_settings_info_t* pCurrentSettings, float xPos, float yPos, float fWidth, float fHeight); ``` -------------------------------- ### onNewVehicle Source: https://rubyfpv.com/development_osd.php Callback function invoked when the controller connects to a vehicle or switches to a different one. Useful for resetting plugin state. ```APIDOC ## onNewVehicle ### Description This method is called when the controller connects to a vehicle or switches to a different vehicle. It is useful for resetting internal data or state within the plugin. ### Method `void onNewVehicle(u32 uVehicleId);` ### Parameters * **uVehicleId** (u32) - The ID of the newly connected or selected vehicle. ### Response None ``` -------------------------------- ### I2C Capability Flag: Buttons Source: https://rubyfpv.com/development_extensions.php Defines the flag to indicate if a slave device has buttons for UI navigation within Ruby. This flag should be set in the capabilities response. ```c I2C_CAPABILITY_FLAG_BUTTONS ((u16)(((u16)0x01)<<2)) // Set if the slave device has buttons (for UI navigation in Ruby); ``` -------------------------------- ### I2C_COMMAND_ID_SET_RC_INPUT_FLAGS Source: https://rubyfpv.com/development_extensions.php Master tells the slave what RC protocol to read and if the RC input UART should be inverted. ```APIDOC ## I2C_COMMAND_ID_SET_RC_INPUT_FLAGS ### Description Configure the slave device to read a specific RC protocol and set UART inversion for RC input. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for setting RC input flags (0x20). - **RC input flags** (byte) - Flags for RC input configuration: - **bits 0-4**: RC protocol (1 - SBUS, 2 - IBUS, 4 - PPM). - **bit 4**: UART inversion (0 - non inverted, 1 - inverted). ### Response #### Slave Responds - **status** (byte) - 0 for OK, 1 for error. ``` -------------------------------- ### onTelemetryStreamData Source: https://rubyfpv.com/development_osd.php Callback for receiving telemetry data. Parses MAVLink or LTM data and allows for OSD display. ```APIDOC ## onTelemetryStreamData ### Description This method is invoked each time telemetry data is received from a vehicle. The `nTelemetryType` parameter indicates the data format: 1 for MAVLink and 2 for LTM. Plugins are responsible for parsing the data, extracting necessary information, and displaying it on the OSD. ### Method `void onTelemetryStreamData(u8* pData, int nDataLength, int nTelemetryType);` ### Parameters * **pData** (u8*) - A pointer to the raw telemetry data. * **nDataLength** (int) - The length of the telemetry data in bytes. * **nTelemetryType** (int) - The type of telemetry data (1 for MAVLink, 2 for LTM). ### Response None ``` -------------------------------- ### I2C Capability Flag: LEDs Source: https://rubyfpv.com/development_extensions.php Defines the flag to indicate if a slave device has LEDs that can be controlled by the Ruby controller. This capability is reported via I2C. ```c I2C_CAPABILITY_FLAG_LEDS ((u16)(((u16)0x01)<<5)) // Set if the slave device has LEDs to be controlled by the Ruby controller; ``` -------------------------------- ### I2C Capability Flag: SPI Support Source: https://rubyfpv.com/development_extensions.php Defines the flag to indicate if a slave device supports SPI communication with the Ruby controller. Used when querying device capabilities. ```c I2C_CAPABILITY_FLAG_SPI ((u16)(((u16)0x01)<<1)) // Set if the slave device does support SPI communication with the Ruby controller (if not, only I2C is used) ``` -------------------------------- ### I2C_COMMAND_ID_SET_ADDRESS Source: https://rubyfpv.com/development_extensions.php Master asks slave to set its address to a custom one, to avoid conflicts. ```APIDOC ## I2C_COMMAND_ID_SET_ADDRESS ### Description Set a custom I2C address for the slave device to avoid conflicts. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for setting the address (0x04). - **new I2C address** (byte) - The new I2C address to be used by the slave device. ### Response #### Slave Responds - **status** (byte) - 0 for OK, 1 for error. ``` -------------------------------- ### I2C_COMMAND_ID_GET_ROTARY_EVENTS / I2C_COMMAND_ID_GET_ROTARY_EVENTS2 Source: https://rubyfpv.com/development_extensions.php Master asks slave if any rotary encoder events (main or secondary) took place. ```APIDOC ## I2C_COMMAND_ID_GET_ROTARY_EVENTS / I2C_COMMAND_ID_GET_ROTARY_EVENTS2 ### Description Query the slave device for events from the main or secondary rotary encoders. ### Method I2C Master to Slave Request ### Parameters #### Master Sends - **command id** (byte) - The command ID for getting rotary events (0x11 or 0x12). ### Response #### Slave Responds - **rotary events** (byte) - Each bit represents a specific rotary encoder event: - **bit 0**: rotary encoder was pressed - **bit 1**: rotary encoder was long pressed - **bit 2**: rotary encoder was rotated CCW - **bit 3**: rotary encoder was rotated CW - **bit 4**: rotary encoder was rotated fast CCW - **bit 5**: rotary encoder was rotated fast CW ``` -------------------------------- ### I2C Capability Flag: Camera Control Source: https://rubyfpv.com/development_extensions.php Defines the flag to indicate if a slave device can send camera commands, such as brightness or contrast adjustments. This is for extensions that manage camera settings. ```c I2C_CAPABILITY_FLAG_CAMERA_CONTROL ((u16)(((u16)0x01)<<9)) // Set if the slave device wants to send camera commands (brightness, contrast, etc); ``` -------------------------------- ### requestTelemetryStreams Source: https://rubyfpv.com/development_osd.php Requests access to telemetry streams from vehicles. Returning 1 enables telemetry data callbacks. ```APIDOC ## requestTelemetryStreams ### Description If your plugin requires access to telemetry streams from vehicles, you must implement this method and return 1. This action prompts Ruby to call the `onTelemetryStreamData` function whenever telemetry data is received. ### Method `int requestTelemetryStreams();` ### Parameters None ### Response * **int**: Returns 1 to enable telemetry stream data callbacks. Returns 0 or other values to disable. ``` -------------------------------- ### Packet Header Structure Source: https://rubyfpv.com/development_guide.php Defines the structure of a packet header used in the Ruby system. It includes fields for packet flags, total length, radio link packet index, and source/destination vehicle IDs. Some fields are automatically managed by the Ruby router. ```c typedef struct { u16 packet_flags_extended; // Added in 7.4: it replaced (length of all headers) // byte 0: // not used // byte 1: // bit 0: 1: send on high capacity links only; // bit 1: 1: sent on low capacity links only; // bit 2: 1: requires ACK for this packet u16 total_length; // Total length, including all the header data, including CRC u16 radio_link_packet_index; // Introduced in 7.7: monotonically increasing for each radio packet sent on a radio link // used to detect missing packets on receive side on a radio link, not for duplicate detection u32 vehicle_id_src; u32 vehicle_id_dest; } __attribute__((packed)) t_packet_header; ```