-
Notifications
You must be signed in to change notification settings - Fork 5
RockBLOCK Reports
The Rockblock Report Monitor is responsible for switching between the three types of Rockblock downlink report types: normal_report
, camera_report
, and imu_report
. The definition and implementation for the Rockblock Report Monitor lives in RockblockReportMonitor.cpp
and RockblockReportMonitor.hpp
. The execute()
method is called every main control loop cycle.
void schedule_report()
- Switches the current report type based on current state of
sfr::imu::imu_dlink_report_ready
, the current time,sfr::rockblock::last_downlink
, andsfr::camera::report_ready == true
. - The IMU report has the highest precedence, followed by the normal report, and the camera report.
void execute()
- Executes the scheduling report logic and updates the report type.
- Low power modes only allow normal reports
- All other modes alternate between the 3 kinds of reports (no priority)
- Camera reports and IMU reports should only be downlinked if they are "ready". If one report is "ready" but another is not, the one that is "ready" should be downlinked
- For example, if neither the imu report nor the camera reports are "ready" the normal report should be downlinked without waiting for them to be "ready"
The Normal report downlinks a variety of satellite-specific general data. The specific values and data points from the sensors and Rockblok can be found in the table below.
Format for downlinked data.
Index | Data | Min (if applicable) | Max (if applicable) |
---|---|---|---|
0 | 99 (normel report flag) | N/A | N/A |
1 | photoresistor covered | ||
2 | button pressed | ||
3 | mission mode | ||
4 | burn wire fire | ||
5 | burn wire arm | ||
6 | burn wire time | 0 | 60000 |
7 | burn wire armed time | 0 | 86400000 |
8 | burn wire mode | ||
9 | burn wire attempts | 10 | |
10 | downlink period | 1000 | 172800000 |
11 | waiting message | ||
12 | waiting command | ||
13 | mag_x | 0.0 | 0.0 |
14 | mag_y | 0.0 | 0.0 |
15 | mag_z | 0.0 | 0.0 |
16 | gyro_x | 0.0 | 0.0 |
17 | gryo_y | 0.0 | 0.0 |
18 | gyro_z | 0.0 | 0.0 |
19 | light val | ||
20 | temperature | 200 | |
21 | solar current | 500 | |
22 | in sun | ||
23 | acs mode | ||
24 | voltage | 3 | 5 |
25 | fault mode | ||
26 | fault1 | ||
27 | fault2 | ||
28 | fault3 | ||
29 | take photo | ||
30 | camera powered | ||
... | opcodes of received commands | ||
report.size() - 2 | 254 (end flag 1) | ||
report.size() - 2 | 255 (end flag 2) |
In MainControlLoop.cpp
, normal_report_monitor.execute_on_time()
will be called every cycle. This will generate the report to be downlinked by filling in the sfr::rockblock::normal_report
. Specifically, the function will first obtain the data necessary for generating the normal report. It will then continuously push the relevant information onto the sfr::rockblock::normal_report
queue. It will then append the list of opcodes of received uplink commands, which is stored in NormalReportMonitor::commands_received
, to the normal report. Finally, it will append the two end-of-downlink flags to the report. When the logic in RockBlockReport Monitor determines that it is time for a normal report to be downlinked, the generated report will be downlinked to the ground.
Opcodes of received commands will be added to the normal report to help team members understand what the satellite has received. It will contain at most 15 commands since the last downlink, with each command's opcode taking two bytes. The positions of these opcodes could be found in the table above.
In general, IMU Downlink is a piece of code that manages a buffer consisting of IMU gyro data. The buffer, which is called imu_dlink
, provides gyro data content for the IMU Report. The buffer is initialized inside the imu
namespace of sfr
. The buffer does not have a constant length. Instead, the gyro data will be continuously pushed into the buffer within a predefined time period. The buffer is a deque with type uint8_t
. Whenever we need data from the buffer, we will pop the data from its back.
- In MainControlLoop.cpp, the
imu_downlink
object will be called on theexecute_on_time()
function to start executing the IMU downlink report monitor; -
IMUDownlink::execute()
inIMUDownlink.cpp
will be called; - Inside the
IMUDownlink::execute()
, the IMU gyro data will be pushed into theimu_dlink
buffer ifsfr::imu::sample_gyro
istrue
.sfr::imu::smaple_gyro
is a condition to indicate whether we should downlink gyro data to our buffer or not. - To make
sfr::imu::sample_gyro
true
, we need:- Either the current mode is mandatory burns or regular burns, which is indicated by
sfr::mission::current_mode == sfr::mission::mandatoryBurns || sfr::mission::current_mode == sfr::mission::regularBurns
. This is controlled by mission modes. - Right after successful deployment AND before deploying for 1 minute, which is indicated by
sfr::mission::deployed == true
andmillis() - sfr::mission::time_deployed > 60 * constants::time::one_second
.
- Either the current mode is mandatory burns or regular burns, which is indicated by
- Before pushing the gyro data, we will:
- First use the
get_value()
fromsfr::imu::gyro_x_value
/sfr::imu::gyro_y_value
/sfr::imu::gyro_z_value
SensorReading object to get gyro values in float type - Map the float imu value to a number between
sfr::imu::gyro_min
andsfr::imu::gyro_max
.
- First use the
- After that, we will push the mapped gyro values to our
sfr::imu::imu_dlink
buffer by the push_front function (this is a default function for deque in cpp). - After deploying for 1 minute, we will stop pushing data to our
imu_dlink
buffer, indicated by setting thesfr::imu::sample_gyro
tofalse
. Also, we will setsfr::imu::report_written
totrue
to indicate that we can start creating the IMU report fragments.
The camera report downlinks fragments of a JPEG image so that we could reconstruct the image taken by the onboard optical sensor on the ground. Its start flag is 42 (2A in hex). After this flag comes the 1-byte image serial number and the 4-byte fragment number. The fragment number would increment by 1 for each camera report since each report is carrying another fragment of the original image. After this is the main content of the image fragment. This part is usually 64 bytes in length. Typically the number of bytes in the original image is not a multiple of the number of bytes in one image fragment, so the last fragment of an image will be shorter than the others. The camera report for that fragment will be correspondingly shorter. To support this variable-length structure, a deque is used to hold the camera report, similar to the normal report.
Format for downlinked data.
Index | Data |
---|---|
0 | 42 (flag in decimal). |
1 | Image Serial Number |
2-5 | Fragment Number |
6-report.size()-1. | Fragment Content |