Skip to content

RockBLOCK Reports

Maria-Boza edited this page Sep 16, 2023 · 18 revisions

RockBLOCK Report Monitor

Introduction

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.

Documentation

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, and sfr::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.

New version to be implemented as of 6/7/2022

  • 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"

Normal Report

Introduction

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. The report may be as long as 70 bytes but can be as short as 33 bytes.

Structure

Format for downlinked data.

Index Data Min (if applicable) Max (if applicable) Units (if applicable)
0 99 (normal report flag) N/A N/A
1 photoresistor covered
2 button pressed
3 mission mode
4 burnwire burn time 0 5000 milliseconds
5 burnwire arm time 0 864000000 milliseconds
6 burn wire mode
7 burn wire attempts 10
8 downlink period 60000 172800000 milliseconds
9 waiting message
10 waiting command
11 mag_x -150 150 microTesla
12 mag_y -150 150 microTesla
13 mag_z -150 150 microTesla
14 gyro_x -5 5 rad/s
15 gryo_y -5 5 rad/s
16 gyro_z -5 5 rad/s
17 photoresistor 0 1023
18 temperature -50 200 Celsius
19 solar current mA
20 in sun
21 voltage 3 5 Volts
22 fault1
23 fault2
24 fault3
25 camera powered
26 EEPROM boot counter
27 packed sensor faults
28 packed sensor faults 2
[29...48] mission mode history
49 delimiter ('0xAA')
[50...67] opcodes of received commands
report.size() - 2 254 (end flag 1)
report.size() - 1 255 (end flag 2)

Indices 27-28 are assigned encoded sensor validity data in a bitwise manner in the following order:

27 — mag_x_average, mag_y_average, mag_z_average, gyro_x_average, gyro_y_average, gyro_z_average, temp_c_average, solar_current_average

28 - 000000, voltage_average, photoresistor_average

The contents of indices 30-70 will vary based on the length of the mission mode history (max 20 bytes/mission mode switches) and received opcode sections(max 18 bytes/9 opcodes). The numbering in the table above illustrates the maximum length state of 70 bytes.

Processing

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. Sensor data that does not fit in a 1 btye integer will be packed using the mapping bounds above. 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.

Acknowledgement of Received Commands

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.

IMU Report

Introduction

IMU Downlink

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. The deque is used as a FIFO (First In First Out) buffer.

IMU Report

A whole IMU report consists of multiple IMU fragments(number varies). We need multiple downlinks to downlink each IMU report fragment (70 Bytes each with every byte represented in Hex). The IMU report fragments will be downlinked after we successfully populate the gyro data(gyro-x, gyro-y, gyro-z) to the IMU Downlink buffer. We downlink one fragment every command cycle and only stop downlinking when the buffer(imu_dlink buffer) that we popped data from becomes empty. We didn’t expect the number of fragments to exceed the maximum capacity we set for it given we won’t downlink too much data, but we’ve taken care of this situation. There will be 18 fragments that add up to a total of 1,188 bytes of gyro data which is equivalent to 39.6 seconds. It is timed to 20 seconds before the door is opened, 9.6 seconds while the door is opening, and 10 seconds after the door is opened.

Structure

Sent: 70 Bytes (140 digits)
Report ID: 18 (in Hex, 1 Byte)
Fragment Number: starting from 00 and increasing by 1 (in Hex, 1 Byte)
End Flag: 0xFE92 (in Hex, 2 Bytes)
Cycle the following content:

  • Gyro-x value (in Hex, 1 Byte)
  • Gyro-y value (in Hex, 1 Byte)
  • Gyro-z value (in Hex, 1 Byte) 22 complete cycles total of 66 bytes Example:
    Given that we have 70 bytes, the report ID is 0x18, the fragment id is 0x00, the end flag is 0xFE92, the gyro-x value, gyro-y, and gyro-z values are all 0x7F, this report fragment should look like: 18007F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7FFE92

Processing

  1. In MainControlLoop.cpp, the imudownlink_report_monitor object will be called on the execute_on_time() function to start executing the IMU downlink report monitor;
  2. IMUDownlinkReportMonitor::execute() in IMUDownlinkReportMonitor.cpp will be called;
  3. The IMU report fragment will be downlinked if sfr::rockblock::imu_report is empty, sfr::imu::report_written is true, and fragment_number is less than sfr::imu::max_fragments;
    • sfr::rockblock::imu_report is cleared every time a fragment is transmitted. When this happens, we are able to load in the next fragment for transmission;
    • To make sfr::imu::report_written be true, we need to have IMU data be pushed to the imu_dlink buffer for 60 seconds after successful deployment, which is indicated inside the IMUDownlink::execute() function;
  4. Inside the IMUDownlinkReportMonitor::execute(), function create_imu_downlink_report(int fragment_number) will be called to create one IMU downlink report fragment from the imu_dlink buffer
    • Inside the create_imu_downlink_report(int fragment_number) function, we first push the IMU report ID to the sfr::rockblock::imu_report. The number will be pushed in decimal because it will be later convert to Hex in ground station side;
    • Then we will push the fragment number to the sfr::rockblock::imu_report;
    • Then we will push the gyro-x, gyro-y, gyro-z values in order to the sfr::rockblock::imu_report;
    • The gyro values will be popped out from the imu_dlink buffer as well;
    • We will have 22 complete cycles;
  5. After successfully creating one report fragment, sfr::imu::report_ready will become true to indicate successful report population;
  6. Outside the function create_imu_downlink_report(int fragment_number), sfr::imu::fragment_number will be increased for the next fragment downlink;
  7. We will continue downlinking the IMU report fragment until: the imu_dlink buffer and the imu_report buffer are both empty, indicated by sfr::imu::imu_dlink.size() == 0 && sfr::rockblock::imu_report.size() == 0; OR the current fragment number is greater than the maximum number of fragments we could have, indicated by sfr::imu::fragment_number >= sfr::imu::max_fragments:
    • In the first case, if both buffers have size 0, the imu_dlink buffer is empty and all fragments have been downlinked. Then sfr::imu::report_ready will be set to false so that in the RockblockReportMonitor::schedule_report() function so that the main control logic knows it’s not the time to downlink the IMU report;
    • In the second case, if sfr::imu::fragment_number is greater or reaches sfr::imu::max_fragments, we have reached the maximum capacity we could have for the fragments. Then sfr::imu::report_ready will be set to false so that in the RockblockReportMonitor::schedule_report() function so that the main control logic knows it’s not the time to downlink the IMU report. And sfr::imu::fragment_number will be reset to 0.

Testing

Rockblock Simulator Testing on FlatSat

  1. Make sure you are ESD-safe

  2. Connect your computer to the FlatSat with a cable

  3. Turn on the power for teensy

  4. Make sure the environment is in the env:simulator: Screen Shot 2022-05-07 at 8 36 18 PM

  5. Upload the code to the teensy on the CubeSat by clicking the “->” symbol at the very bottom of your VSCode: Screen Shot 2022-05-07 at 7 25 35 PM

    • If you didn’t ever see a message which asks you to press reset button, but instead saw a message in your terminal like:
      Programming -----------------------------------------------------------
      Then you have uploaded successfully.
    • Otherwise, Control + C (either on Windows or on MacOS) to stop uploading and continue unscrew the flight screw to make sure you have turned on the CubeSat
  6. Click on the PlatformIO: Serial Monitor icon to start monitor/testing:
    Screen Shot 2022-05-07 at 7 26 08 PM

Testing on EDU

  1. Make sure you are ESD-safe
  2. Turn on the CubeSat:
    • Unscrew the flight screw near the bottom of the CubeSat (this is on the side of the CubeSat, not on the bottom). Tutorial Video here.
    • Continue unscrew until you see the tiny orange flash near the bottom (you need to look through the gap parallel to the top of the bottom)
  3. Connect CubeSat with your computer using a cable.
  4. Make sure the environment is in env:teensy35.
  5. Upload the code to the teensy on the CubeSat by clicking the “->” symbol at the very bottom of your vscode (just like what you did for the test on FlatSat)
    • If you didn’t ever see a message which asks you to press reset button, but instead saw a message in your terminal like:
      Programming -----------------------------------------------------------
      Then you have uploaded successfully.
    • Otherwise, Control + C (either on Windows or on MacOS) to stop uploading and continue unscrew the flight screw to make sure you have turned on the CubeSat
  6. Put the CubeSat on the ESD-safe bag (a transparent backpack) and zip up
  7. Bring both the computer and the CubeSat to the 6th floor of Rhodes Hall
    • This is because we have a better signal on the higher floors.
    • With your back to the elevator, you need to turn left until you see a gray door.
    • Open the door and enter and you will see a large glass stairwell.
    • Put the bag and computer on the gray platform near the glass.
    • Make sure the antenna is facing to the sky (you might need to lay down the bag)
  8. Click on the PlatformIO: Serial Monitor icon to start monitor/testing

Addition:

For both testing, you may only want to print the message that is related to your own testing. What you need to do is to set a flag in the build_flags section of the platformio.ini file and format your print statements in the right way. In this way, the terminal will only show the prints within your flags, making your code more maintainable.

To set the flags right in your code:

  1. Go to the file that you want to add print statements
  2. Add:
    #ifdef FLAG_NAME 
    Serial.println(“whatever you want to print out”); 
    #endif
    
  3. Reminder:
  • println = print + \n
  • You can add as many print statements as you want between the #ifdef FLAG_NAME and #endif
  • The FLAG_NAME is what you want to indicate in the build_flags section of the platformio.ini file

To manage the flags in the platformio.ini:

  1. Go to platformio.ini
  2. Go to your intended env section
  3. After the build_flags, add -D FLAG_NAME
  4. You can add as many flag names as you want. In this way the terminal will show the print statements under multiple flags.

The below example shows the scenario that I’m under the env:simulator, and I want to print my statements under both the flags VERBOSE_IMUD and SIMULATOR.

Screen Shot 2022-05-07 at 8 03 12 PM

This screenshot shows how I set flags for my print statements inside the code for flag VERBOSE. Screen Shot 2022-05-07 at 7 51 51 PM

Camera Report

Introduction

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.

Camera Report Structure

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