This repository should be used as a git submodule for the RF interface such as packet definition. The goal is to minimize the protocol interface difficulties encountered between the AV-GS-GSE-PL subsystems. By having this git submodule repository shared between subsystems, no more interface documents are required as a git pull would be sufficient to be updated.
Follow this link or directly the instructions below.
Go in your main project folder, which is alreay a git repository, and run:
git submodule add https://github.com/EPFLRocketTeam/ERT_RF_Protocol_Interface.git
By default, it will create a folder name "ERT_RF_Protocol_Interface". You can add a different path at the end of the command if you want it to go elsewhere.
Then in your C++ code, you can simply do:
#include <ERT_RF_Protocol_Interface/Protocol.h>Now you can have access to the struct definitions in your code, see the example at the end.
From your project source directory, you can run:
git submodule update --remote
This will pull and checkout your submodule to the branch specified in your .gitmodules file.
Once you made some modifications to the code of this submodule, you need to go in the submodule folder (ERT_RF_Protocol_Interface), then you can run git status to see if some changes are seen. If yes you need to add this files, commit with a message and finally push.
git add --all
git commit -m "uplink packet update"
git push
Note that as it is a private repository, you will need to connect to your account. You can read the next section for more infos.
- TODO: Maybe it is possible to directly push on this repo from the main repo ?
TODO
Some useful links:
- Git command cheat sheet https://education.github.com/git-cheat-sheet-education.pdf
- Markdown summary https://www.markdownguide.org/basic-syntax/
In Reception mode, imagine that a serial interface (e.g. UART, USB, LoRa, WiFi) sent you a byte array (in C++ it would be a pointer of uint8_t* with its length in bytes). Then here is a code example:
void get_packet_content(uint8_t* byte-array_ptr, size_t byte_array_length) { // arguments given by serial interface
PacketAV_uplink packetAV_uplink; // declare a new variable, in some case it may required dynamic allocation
if (byte_array_length == packetAV_uplink_size) { // check if same size, but you should use a better method
// This is the key function, copy the byte array at the struct address
memcpy(&packetAV_uplink, byte_array_ptr, packetAV_uplink_size);
// Now you can use & check every fields of the structure
if (packetAV_uplink.ventN2O == CMD_ACTIVE) {
printf("N2O valve active !");
}
}
}In Transmission mode, this is quite similar, once your packet structure is filled with what you need, you can send the associated byte array to your serial interface function.
void send_packet_content(PacketAV_downlink &packetAV_downlink) { // you can pass the pointer directly or by reference
// Here are some examples
Serial.write(&packetAV_downlink, packetAV_downlink_size); // with write(uint8_t* byte_array, size_t size)
LoRa.write(&packetAV_downlink, packetAV_downlink_size);
udp.broadcastTo(&packetAV_downlink, packetAV_downlink_size, 1234); // UDP broadcast on port 1234
}In order to increase the downlink frequency, there are now two downlink structures.
av_downlink_thas the same name as before, and will be sent as a packet by radio, received and parsed by GS with Capsule.- The new struct
av_downlink_unpacked_tuses the same types asav_downlink_tbut is not packed into bitfields.
Here is how to use the compression on the Tx side:
void send_downlink() {
av_downlink_unpacked_t data;
// Replace with your internal variables
data.packet_nbr = 384461;
data.gnss_lon = -9.138279;
data.gnss_lat = 38.713138;
data.gnss_alt = 2394;
data.N2_pressure = 322;
data.N2_temp = 45;
data.fuel_pressure = 59;
data.LOX_temp = -197;
data.engine_state = 0b11001101;
data.lpb_voltage = 3.8756;
data.lpb_current = 2.83;
data.hpb_voltage = 25.08;
data.hpb_current = 20.33;
// Compress the data into a smaller packet
send_packet(encode_downlink(data));
}And how to decompress the packet on the Rx side:
void receive_downlink(const av_downlink_t& packet) {
av_downlink_unpacked_t downlink_data(decode_downlink(packet));
// Parse the received data...
}
