Librnp is a library developed to implement the Ricardo network protocol (RNP). RNP is designed to allow transparent communication between all nodes on all flight and ground systems over many different physical layers. There is a C++ library (here) which is the main implementation of Librnp and a python daughter library (here) which contains a deserialiser and serialised for rnp based packets and default packets.
Addressing in RNP consists of 2 single byte values, the address and the service, giving a maximum of 256 values. Each node on the network has a uniquely assigned address, each running multiple services. There are two reserved addresses and three reserved services detailed below.
| Address | Description |
| 0 | Redirects to the node's current address |
| 1 | Debug port - typically the serial port |
Address 0 is useful when sending packets to a node with an unknown address on the debug port.
| Service | Description |
| 0 | No Service |
| 1 | Network Manager Service |
| 2 | Command Handler Service |
Each packet in RNP contains an 11 byte header which contains addressing and packet type information.
//header packet defintion
uint8_t start_byte = 0xAF; // Marks the begin of the header and the expected protocol. 0xAF indicates RNP
uint16_t packet_len = 0x00; // packet length not including header length
uint16_t uid = 0x00000000; // unique id -> used for request response needs to be unique for source desintaiton pair
uint8_t source_service = 0x00; //source service id
uint8_t destination_service = 0x00; //service id
uint8_t type = 0x00; // Type of the packet
uint8_t source = 0x00; // Source address for the packet
uint8_t destination = 0x00; // Destination address for the packet
uint8_t hops = 0x00; // number of hops, increments each time the packet is sent
The routing algorithm used within the rnp_networkmanager is shown below:

A packet generator (Ricardo-PacketGen) has been created to generate either c++ header and source files or a python class providing serialisers and deserialisers for a given fixed packet structure. The packet descriptor is given as a JSON file. The full telemetry packet for pickle rick is given as an example below.
{
"packet_name":"TelemetryPacket",
"packet_type":100,
"packet_descriptor": {
"pn": "float",
"pe": "float",
"pd": "float",
"vn": "float",
"ve": "float",
"vd": "float",
"an": "float",
"ae": "float",
"ad": "float",
"roll": "float",
"pitch": "float",
"yaw": "float",
"q0": "float",
"q1": "float",
"q2": "float",
"q3": "float",
"lat": "float",
"lng": "float",
"alt": "int",
"sat": "uint8_t",
"ax": "float",
"ay": "float",
"az": "float",
"h_ax": "float",
"h_ay": "float",
"h_az": "float",
"gx": "float",
"gy": "float",
"gz": "float",
"mx": "float",
"my": "float",
"mz": "float",
"baro_temp": "float",
"baro_press": "float",
"baro_alt": "float",
"batt_voltage": "uint16_t",
"batt_percent": "uint16_t",
"launch_lat": "float",
"launch_lng": "float",
"launch_alt": "int",
"system_status": "uint32_t",
"system_time": "uint64_t",
"rssi": "int16_t",
"snr": "float"
}
}
The following data types are permitted when using the packet generator.
| Type | Size |
|---|---|
| char | 1 |
| int8_t | 1 |
| uint8_t | 1 |
| bool | 1 |
| int16_t | 2 |
| uint16_t | 2 |
| int | 4 |
| int32_t | 4 |
| uint32_t | 4 |
| int64_t | 8 |
| uint64_t | 8 |
| float | 4 |
| double | 8 |