RDI SDK documentation
Overview
The RDI (Raptor Drone Integration) SDK enables integration of custom drone platforms into Raptor Ace. This documentation provides the information required to develop, build, deploy and validate a RDI plugin that connects a drone platform to Raptor Ace.
Included in the SDK
- API headers:
rdi_api.handrdi_api_lens_param.h - Example plugin: Example plugin with full source code
- This documentation: Integration guide
Quick start
Minimal plugin example
The following code demonstrates the minimum required for a working RDI plugin:
#include "rdi_api.h"
// Lifecycle functions
rdi_result_t init_func(rdi_func_t* func, rdi_context_t* context) {
// Initialize plugin, allocate resources
return RDI_RESULT_OK;
}
rdi_result_t run_func(rdi_func_t* func, rdi_context_t* context) {
// Process one frame, submit it using func->frame_submit()
return RDI_RESULT_OK;
}
rdi_result_t shutdown_func(rdi_func_t* func, rdi_context_t* context) {
// Clean up resources
return RDI_RESULT_OK;
}
// Plugin declaration
static const rdi_plugin_decl_t plugin_decl = {
.api_version = RDI_API_VERSION,
.init = init_func,
.run = run_func,
.shutdown = shutdown_func,
.name = "Example Drone",
.version = "1.0",
.description = "Example drone platform",
.config = "{}"
};
// Required export function
RDI_PLUGIN_EXPORT const rdi_plugin_decl_t* rdi_get_plugin_decl(void) {
return &plugin_decl;
}
Build requirements
Plugins must be compiled as a shared library (.so) with:
- C99 or later (plugin implementations may require later standards)
- Exported symbols marked with
RDI_PLUGIN_EXPORT
Example CMake configuration:
add_library(rdiplugin_example SHARED example.c)
target_link_libraries(rdiplugin_example PRIVATE ...)
set_target_properties(rdiplugin_example PROPERTIES
PREFIX ""
SUFFIX ".so"
)
System overview
Core structures
The RDI system refers to the runtime component within Raptor Ace that loads the plugin, manages its lifecycle, and processes the frames submitted by the plugin.
The RDI API is built around four key structures:
- RDI Declaration (
rdi_plugin_decl_t) - Structure containing plugin's lifecycle functions and metadata, provided to the RDI system via therdi_get_plugin_decl()function - RDI Context (
rdi_context_t) - Provides connection information and stores plugin data for one stream instance. See Context fields for details - RDI Functions (
rdi_func_t) - API functions provided by the RDI system for frame allocation, time parsing, etc. - RDI Frame (
rdi_frame_t) - Structure for providing frame image and metadata to the RDI system
Plugin operation
The RDI system loads the plugin shared library (.so) and obtains the plugin declaration (see Plugin configuration).
The RDI system then manages stream instances by calling lifecycle functions:
- Initialization: The
init()function is called once to establish connection to the drone and set up resources. Must complete before returning. - Runtime loop: The
run()function is called repeatedly after successful initialization for the plugin to fetch frames from the drone. The plugin is then expected to populate RDI frames with image data as well as the necessary metadata and submit them to the RDI system. - Shutdown: The
shutdown()function is called once to close connections and clean up resources. Must complete before returning.
The RDI system processes submitted frames by applying lens undistortion (depending on the lens model) and timestamp corrections to ensure a smooth video stream. The processed frames are then integrated into Raptor Ace for GNSS-denied navigation and video presentation. See the Lens models section for detailed information on supported lens models and when undistortion is applied.
Plugin responsibilities
The plugin is responsible for:
- Connecting to the drone, e.g. via RTSP
- Decoding video frames to one of the supported image formats (GRAY8, RGB8, YUV420, YUV444)
- Extracting metadata, e.g. field of view, timestamp
- Providing camera calibration (lens model and parameters)
- Submitting frames to RDI via the provided API functions
- Cleaning up resources and closing connections
Context fields
User data (userdata):
Plugin-managed pointer for storing plugin state (e.g., connection handles, buffers, configuration) for the stream instance. Persists across init(), run(), and shutdown() calls for the stream. Typically allocated in init() and freed in shutdown().
Stream location (filepath and url):
The context provides stream location in one of two mutually exclusive ways:
-
Opening file (
filepathis non-NULL):- Absolute file path on file system (null-terminated UTF-8 string)
- Example:
/home/user/video.mp4 urland all URL component fields are NULL- Use
filepathdirectly to open the file
-
Opening URL (
urlis non-NULL):- Complete URL, including
file://URLs (null-terminated UTF-8 string).file://will be treated as a URL - URL is parsed into components:
url_scheme,url_hostname,url_port,url_path, etc. (seerdi_api.h) - All URL component fields are non-NULL (empty string for components not present in the URL)
- For network streams (e.g.,
rtsp://192.168.1.100:8554/stream), useurlor URL components for connection - For
file://URLs (e.g.,file:///home/user/video.mp4), useurl_pathto get the actual file path (/home/user/video.mp4)
- Complete URL, including
// Example: handling both regular filepath and file:// URL
if (context->filepath || (context->url_scheme && strcmp(context->url_scheme, "file") == 0)) {
// Local file - handle both regular filepath and file:// URL
const char* path = context->filepath ? context->filepath : context->url_path;
open_file(path);
}
else if (context->url) {
// URL-based stream
if (context->url_scheme && strcmp(context->url_scheme, "rtsp") == 0) {
connect_rtsp(context->url);
}
else {
// Handle other URL schemes...
}
}
Plugin configuration
The plugin must provide a declaration structure (rdi_plugin_decl_t) containing lifecycle functions, metadata, and configuration. This declaration is provided to the RDI system via the exported rdi_get_plugin_decl() function.
Important: The plugin must export the rdi_get_plugin_decl symbol using the RDI_PLUGIN_EXPORT macro.
Configuration field
The config field is a null-terminated UTF-8 string containing a JSON document that specifies processing options affecting how the RDI system handles frames from the plugin.
If no configuration is needed, typically use an empty JSON object: .config = "{}"
Stream lifecycle
1. Initialization phase
When: Stream is opened
Function: init(rdi_func_t* func, rdi_context_t* context)
Tasks:
- Parse the stream location from the context (see Context fields)
- Establish connection to drone or open video file
- Initialize video decoder
- Allocate internal data structures
- Store state in
context->userdata
Return Values:
RDI_RESULT_OK- Initialization successfulRDI_RESULT_ERROR- Initialization failed
2. Run phase
When: Called repeatedly to process frames
Function: run(rdi_func_t* func, rdi_context_t* context)
Tasks:
- Fetch one frame from the drone
- Decode the frame to a supported format
- Allocate an RDI frame using
func->frame_alloc() - Fill in image data, timestamp and lens parameters
- Submit the frame using
func->frame_submit()or drop it usingfunc->frame_drop()
Return Values:
RDI_RESULT_OK- Frame processed successfullyRDI_RESULT_STREAM_COMPLETED- Clean end of streamRDI_RESULT_ERRORRDI_RESULT_ERROR_STREAM_DISRUPTED- Stream broken/disconnected (e.g., network error, connection lost)
3. Shutdown phase
When: Application shutdown
Function: shutdown(rdi_func_t* func, rdi_context_t* context)
Tasks:
- Close connection to drone
- Free all stream-related resources
- Clean up
context->userdata
Return Values:
RDI_RESULT_OK- Shutdown successful
Lens models
The RDI system supports multiple lens models to represent different camera types. The plugin must specify which lens model matches the camera that provides the video feed and provide the corresponding parameters with the submitted RDI frame. The lens parameters that need to be provided depend on the lens model used, as defined in rdi_api_lens_param.h. The RDI system uses this information to decide if and how to perform lens undistortion, converting the distorted image from the camera into an ideal pinhole projection. If the plugin or drone system performs undistortion on the image, the pinhole model should be used to pass through the undistortion step in the RDI system.
Camera intrinsics in the form of focal length parameters expressed as pixel units (fx, fy) as well as the principal point (cx, cy) are expected to be provided with the submitted RDI frame for all models. For some lenses the principal point moves with changes to the focal length. For these models it is expected that the plugin provides cx and cy parameters tailored for the given focal length and then use the appropriate lens model based on the lens distortion. The principal point are given in image pixel coordinates, with the origin at the upper-left corner of the image. The cx parameter increases with x to the right and cy increases with y downward.
For lenses with very high field of view, undistortion may be insufficient and tracking performance can be negatively affected. For these cases it is recommended that the plugin performs the undistortion and crops the image until all distortion effects are removed.
It is the processed image that is used for both for GNSS-denied navigation as well as displayed in the video feed for the Raptor Ace user.
Supported models
Pinhole
A simple pinhole model with no distortion. This can be set if the plugin or drone performs undistortion on the image or if the camera lens can be approximated as a pinhole (performance of the GNSS denied navigation can be affected if a distorted image is provided using this model). Focal length parameters expressed as pixel units as well as the principal point are still expected to be provided with the submitted RDI frame.
Distorted
A model that supports distorted images given that the distortion parameters for radial distortion are provided. The RDI system will apply undistortion to convert the image to a pinhole model. The undistorted image will be used for GNSS denied navigation as well as displayed in the video feed for the Raptor Ace user.
Fisheye
For higher field of view fisheye lenses, the fisheye model should be used. The RDI system will apply undistortion to convert the image to a pinhole model. The undistorted image will be used for GNSS denied navigation as well as displayed in the video feed for the Raptor Ace user. Notice that undistortion may not be sufficient for very high FOV fisheye lenses and it is recommended that the plugin performs the necessary processing to achieve an undistorted image before submitting it to the RDI system.
Important: Fisheye lenses are not directly supported by Raptor Ace (refer to Raptor Ace Product Specification for more information). If using this lens model, thorough testing and validation of results from initialization, navigation and point extraction should be performed. Use of the fisheye lens model is at own risk and performance stated in the Raptor Ace Product Specification cannot be guaranteed.
Plugin requirements
For each frame, the plugin must set:
- Lens model type (
rdiframe->lens.model) - Which model to use - Image dimensions (
rdiframe->lens.width,rdiframe->lens.height) - Must match the image size - Model parameters - Camera intrinsics and distortion parameters depending on the model used, as defined in
rdi_api_lens_param.h
Build and deployment
Build requirements
Output format: The plugin must be built as a shared library (.so) with the naming convention rdiplugin_<plugin-name>.so.
C standard: C99 or later is required for the RDI API headers. Plugin implementations may require later standards depending on their specific needs.
Symbol export: The plugin must export exactly one symbol: rdi_get_plugin_decl. This is accomplished using the RDI_PLUGIN_EXPORT macro defined in rdi_api.h:
#include "rdi_api.h"
// Required export - provides plugin declaration to RDI system
RDI_PLUGIN_EXPORT const rdi_plugin_decl_t* rdi_get_plugin_decl(void) {
return &plugin_decl;
}
Plugin installation
The plugin shared library must be installed in the following location within the Raptor Ace package:
RaptorAce/rdiplugin/rdiplugin_<plugin-name>.so
Dependencies: Any additional shared libraries that the plugin depends on must also be placed in the RaptorAce/rdiplugin/ directory. Standard system libraries do not need to be included.
Testing and validation
Thorough testing and validation are critical to ensure the plugin performs correctly and meets operational requirements.
Conformance testing
The Raptor Ace application can be launched as a command-line tool to perform conformance testing of the plugin. This validates that the plugin correctly implements the RDI API and provides properly formatted data suitable for GNSS denied navigation within Raptor Ace.
Basic API implementation test (plugin only):
./RaptorAce --rdiplugintest=/path/to/rdiplugin_example.so
This basic test verifies:
- Plugin loads successfully
- Declaration structure is valid
- Lifecycle functions are properly implemented
Full stream health test (plugin + stream):
./RaptorAce --rdiplugintest=RaptorAce/rdiplugin/rdiplugin_example.so \
--rditeststream=rtsp://user:pass@192.168.1.100:8554/stream
Adding the --rditeststream parameter runs additional tests that verify:
- Stream connection is established successfully
- Frame data arrives at the expected rate without excessive frame drops
- RDI frames contain valid image data and lens parameters
Plugin location requirements:
- Basic test: The plugin can be located anywhere on the filesystem during development
- Full stream health test: The plugin must be in its final installation location (as described in Build and deployment)
Optional parameters:
--rditestduration=<seconds> # Test duration (default: 10)
--rditestexpectedfps=<fps> # Expected frame rate (default: 30)
Complete example:
./RaptorAce --rdiplugintest=/RaptorAce/rdiplugin/rdiplugin_example.so \
--rditeststream=rtsp://user:pass@192.168.1.100:8554/stream \
--rditestduration=10 \
--rditestexpectedfps=30
Functional testing
For comprehensive functional testing, launch the full Raptor Ace application with the plugin. Note: 3D data supplied by Vantor is required to perform initialization, tracking, and coordinate extraction.
Refer to the Raptor Ace User Guide for detailed instructions on how to prepare the application and perform initialization, tracking, and coordinate extraction steps correctly.
Coordinate extraction validation
Extracted coordinates must be carefully validated against reference coordinates to verify plugin performance:
-
Reference measurements: Obtain reference coordinates using high-precision equipment operated by skilled personnel
-
Comparison testing: Extract coordinates using Raptor Ace with the plugin and compare against reference measurements. Critical: Ensure that both the extracted coordinates and reference measurements are expressed in the same coordinate reference system and epoch. Skilled personnel should be consulted to perform any necessary coordinate transformations to maintain accurate and correct results
-
Accuracy verification: Verify that coordinate extraction accuracy meets the required specifications
-
Comprehensive coverage testing: Perform repeated tests that cover the operational envelope, including various zoom levels and slant angles
Operational envelope considerations
Important: The operational envelope may differ from standard Raptor Ace specifications depending on:
- Drone platform characteristics: Camera quality, gimbal characteristics, stabilization, flight dynamics
- Plugin implementation: Stream health, lens calibration
Recommendation: Conduct thorough field testing across the expected operational conditions to characterize the actual performance envelope for the specific drone platform and plugin implementation.