Skip to content
/ librid Public

An ASTM F3411 message encoding and decoding library written in C programming language.

License

Notifications You must be signed in to change notification settings

tuupola/librid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

259 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

librid

An ASTM F3411 message encoding and decoding library written in C programming language.

The library provides struct definitions for all Remote ID messages. It also provides getter and setter functions for all members of the structure. You should not access the struct members directly. Instead use the provided functions which will decode and encode the data to and from the correct wire format.

Important

This is a read only mirror of the repository. Actual developing happens elsewhere. I do monitor the bug reports, feature requests and any discussion here though.

Message types

Basic ID (0x00)

Provides UAS identification (serial number, registration ID, or UUID) and characterizes the aircraft type.

rid_basic_id_t basic_id;
char uas_id[21];
char json[255];

rid_basic_id_init(&basic_id);
rid_basic_id_set_type(&basic_id, RID_ID_TYPE_SERIAL_NUMBER);
rid_basic_id_set_ua_type(&basic_id, RID_UA_TYPE_HELICOPTER_OR_MULTIROTOR);
rid_basic_id_set_uas_id(&basic_id, "1ABCD2345EF678XYZ");

rid_basic_id_validate(&basic_id);

rid_basic_id_type_t id_type = rid_basic_id_get_type(&basic_id);
rid_ua_type_t ua_type = rid_basic_id_get_ua_type(&basic_id);
rid_basic_id_get_uas_id(&basic_id, uas_id, sizeof(uas_id));

const char *id_type_string = rid_basic_id_type_to_string(id_type);
const char *ua_type_string = rid_ua_type_to_string(ua_type);

rid_basic_id_to_json(&basic_id, json, sizeof(json));

See examples/basic_id/ for usage example.

Location (0x01)

Contains current position, altitude, speed, direction, and timestamp of the UA.

rid_location_t location;
char json[512];

rid_location_init(&location);
rid_location_set_operational_status(&location, RID_OPERATIONAL_STATUS_AIRBORNE);
rid_location_set_height_type(&location, RID_HEIGHT_TYPE_ABOVE_TAKEOFF);
rid_location_set_latitude(&location, 62.683472);
rid_location_set_longitude(&location, 21.974944);
rid_location_set_geodetic_altitude(&location, 120.5f);
rid_location_set_pressure_altitude(&location, 101.3f);
rid_location_set_height(&location, 50.0f);
rid_location_set_speed(&location, 15.5f);
rid_location_set_vertical_speed(&location, 2.0f);
rid_location_set_track_direction(&location, 45);
rid_location_set_timestamp(&location, 12345);
rid_location_set_unixtime(&location, 1234567890);
rid_location_set_horizontal_accuracy(&location, RID_HORIZONTAL_ACCURACY_10M);
rid_location_set_vertical_accuracy(&location, RID_VERTICAL_ACCURACY_10M);
rid_location_set_speed_accuracy(&location, RID_SPEED_ACCURACY_1MS);
rid_location_set_baro_altitude_accuracy(&location, RID_VERTICAL_ACCURACY_3M);
rid_location_set_timestamp_accuracy(&location, RID_TIMESTAMP_ACCURACY_0_1S);

rid_location_validate(&location);

rid_height_type_t height_type = rid_location_get_height_type(&location);
rid_operational_status_t status = rid_location_get_operational_status(&location);
uint16_t direction = rid_location_get_track_direction(&location);
float speed = rid_location_get_speed(&location);
float vspeed = rid_location_get_vertical_speed(&location);
double latitude = rid_location_get_latitude(&location);
double longitude = rid_location_get_longitude(&location);
float pressure_altitude = rid_location_get_pressure_altitude(&location);
float geodetic_altitude = rid_location_get_geodetic_altitude(&location);
float height = rid_location_get_height(&location);
rid_horizontal_accuracy_t h_accuracy = rid_location_get_horizontal_accuracy(&location);
rid_vertical_accuracy_t v_accuracy = rid_location_get_vertical_accuracy(&location);
rid_speed_accuracy_t s_accuracy = rid_location_get_speed_accuracy(&location);
rid_vertical_accuracy_t baro_accuracy = rid_location_get_baro_altitude_accuracy(&location);
uint16_t timestamp = rid_location_get_timestamp(&location);
rid_timestamp_accuracy_t ts_accuracy = rid_location_get_timestamp_accuracy(&location);

const char *height_type_string = rid_height_type_to_string(height_type);
const char *status_string = rid_operational_status_to_string(status);
const char *horizontal_accuracy_string = rid_horizontal_accuracy_to_string(h_accuracy);
const char *vertical_accuracy_string = rid_vertical_accuracy_to_string(v_accuracy);
const char *speed_accuracy_string = rid_speed_accuracy_to_string(s_accuracy);
const char *timestamp_accuracy_string = rid_timestamp_accuracy_to_string(ts_accuracy);

rid_location_to_json(&location, json, sizeof(json));

See examples/location/ for usage example.

Auth (0x02)

Provides authentication data for verifying the identity of the UA sending the message.

rid_auth_t auth;
uint8_t signature[64];
uint8_t retrieved[64];
char json[512];

rid_auth_init(&auth);
rid_auth_set_type(&auth, RID_AUTH_TYPE_UAS_ID_SIGNATURE);
rid_auth_set_timestamp(&auth, 3600);
rid_auth_set_unixtime(&auth, (uint32_t)time(NULL));
rid_auth_set_signature(&auth, signature, sizeof(signature));

rid_auth_validate(&auth);

rid_auth_type_t auth_type = rid_auth_get_type(&auth);
uint32_t timestamp = rid_auth_get_timestamp(&auth);
uint32_t unixtime = rid_auth_get_unixtime(&auth);
uint8_t page_count = rid_auth_get_page_count(&auth);
uint8_t length = rid_auth_get_length(&auth);
rid_auth_get_signature(&auth, retrieved, sizeof(retrieved));

const char *auth_type_string = rid_auth_type_to_string(auth_type);

rid_auth_to_json(&auth, json, sizeof(json));

See examples/auth/ for usage example.

Self ID (0x03)

Allows operators to declare their identity or describe the purpose of a flight.

rid_self_id_t self_id;
char description[24];
char json[256];

rid_self_id_init(&self_id);
rid_self_id_set_description_type(&self_id, RID_DESCRIPTION_TYPE_TEXT);
rid_self_id_set_description(&self_id, "Drone delivery test");

rid_self_id_validate(&self_id);

rid_description_type_t description_type = rid_self_id_get_description_type(&self_id);
rid_self_id_get_description(&self_id, description, sizeof(description));

const char *description_type_string = rid_description_type_to_string(desc_type);

rid_self_id_to_json(&self_id, json, sizeof(json));

See examples/self_id/ for usage example.

System (0x04)

Contains remote pilot location, operating area details, and group aircraft information.

rid_system_t system;
char json[512];

rid_system_init(&system);
rid_system_set_operator_location_type(&system, RID_OPERATOR_LOCATION_TYPE_TAKEOFF);
rid_system_set_classification_type(&system, RID_CLASSIFICATION_TYPE_EUROPEAN_UNION);
rid_system_set_ua_classification_category(&system, RID_UA_CLASSIFICATION_CATEGORY_OPEN);
rid_system_set_ua_classification_class(&system, RID_UA_CLASSIFICATION_CLASS_1);
rid_system_set_operator_latitude(&system, 60.2870324);
rid_system_set_operator_longitude(&system, 24.5397187);
rid_system_set_operator_altitude(&system, 50.0f);
rid_system_set_area_count(&system, 1);
rid_system_set_area_radius(&system, 100);
rid_system_set_area_ceiling(&system, 120.0f);
rid_system_set_area_floor(&system, 0.0f);
rid_system_set_timestamp(&system, 3600);
rid_system_set_unixtime(&system, 1234567890);

rid_system_validate(&system);

rid_operator_location_type_t operator_location_type = rid_system_get_operator_location_type(&system);
rid_classification_type_t classification_type = rid_system_get_classification_type(&system);
rid_ua_classification_category_t ua_category = rid_system_get_ua_classification_category(&system);
rid_ua_classification_class_t ua_class = rid_system_get_ua_classification_class(&system);
double operator_latitude = rid_system_get_operator_latitude(&system);
double operator_longitude = rid_system_get_operator_longitude(&system);
float operator_altitude = rid_system_get_operator_altitude(&system);
uint16_t area_count = rid_system_get_area_count(&system);
uint16_t area_radius = rid_system_get_area_radius(&system);
float area_ceiling = rid_system_get_area_ceiling(&system);
float area_floor = rid_system_get_area_floor(&system);
uint32_t timestamp = rid_system_get_timestamp(&system);
uint32_t unixtime = rid_system_get_unixtime(&system);

const char *operator_location_type_string = rid_operator_location_type_to_string(operator_location_type);
const char *classification_type_string = rid_classification_type_to_string(classification_type);
const char *ua_category_string = rid_ua_classification_category_to_string(ua_category);
const char *ua_class_string = rid_ua_classification_class_to_string(ua_class);

rid_system_to_json(&system, json, sizeof(json));

See examples/system/ for usage example.

Operator ID (0x05)

Provides CAA-issued registration or license ID for the remote pilot or operator.

rid_operator_id_t operator_id;
char id[21];
char json[256];

rid_operator_id_init(&operator_id);
rid_operator_id_set_type(&operator_id, RID_ID_TYPE_OPERATOR_ID);
rid_operator_id_set(&operator_id, "FIN87astrdge12k8");

rid_operator_id_validate(&operator_id);

rid_operator_id_type_t id_type = rid_operator_id_get_type(&operator_id);
rid_operator_id_get(&operator_id, id, sizeof(id));

const char *id_type_string = rid_operator_id_type_to_string(id_type);

rid_operator_id_to_json(&operator_id, json, sizeof(json));

See examples/operator_id/ for usage example.

Message Pack (0x0F)

Combines multiple message types into a single payload for transmission.

rid_message_pack_t pack;
rid_basic_id_t basic_id;
rid_location_t location;
char json[1024];

rid_message_pack_init(&pack);
rid_message_pack_add_message(&pack, &basic_id);
rid_message_pack_add_message(&pack, &location);
rid_message_pack_set_message_count(&pack, 2);
rid_message_pack_replace_message_at(&pack, 0, &basic_id);
rid_message_pack_delete_message_at(&pack, 1);

rid_message_pack_validate(&pack);

uint8_t count = rid_message_pack_get_message_count(&pack);
const void *message = rid_message_pack_get_message_at(&pack, 0);

rid_message_pack_to_json(&pack, json, sizeof(json));

See examples/message_pack/ for usage example.

Differences to the Open Drone ID library

This library output is byte compatible to the Open Drone ID library which is the reference implementation. There are a couple of behavior differences though.

Clamp Instead of Reject

According to ASTM F3411-22, the ground speed in a Location message must be clamped to a maximum of 254.25 m/s. The vertical speed must be clamped to either -62 m/s or 62 m/s depending on direction.

"Ground speed of flight. This value is provided in meters per second with a minimum resolution of 0.25 m/s. Special Values: Invalid, No Value, or Unknown: 255 m/s, if speed is >= 254.25 m/s: 254.25 m/s"

"Vertical speed upward relative to the WGS-84 datum, meters per second. Special Values: Invalid, No Value, or Unknown: 63 m/s, if speed is >= 62 m/s: 62 m/s, if speed is <= -62 m/s: -62 m/s"

ODID rejects any input value outside the valid bounds. Instead of rejecting this library clamps the values.

Build examples

$ mkdir build && cd build
$ cmake -DRID_BUILD_EXAMPLES=ON ..
$ make

Build and run tests

$ mkdir build && cd build
$ cmake -DRID_BUILD_TESTS=ON ..
$ make
$ ctest

Installation

Build and install a static library.

$ mkdir build && cd build
$ cmake ..
$ make
$ sudo make install

Or install to a custom location.

$ cmake -DCMAKE_INSTALL_PREFIX=/opt/librid ..
$ make
$ make install

Build and install a shared library.

$ cmake -DBUILD_SHARED_LIBS=ON ..
$ make
$ sudo make install

Uninstall

$ cd build
$ sudo make uninstall

License

The MIT License (MIT). Please see License File for more information.

About

An ASTM F3411 message encoding and decoding library written in C programming language.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages