-
Notifications
You must be signed in to change notification settings - Fork 0
3. Overall Design and Control Flow
The overall design of the system is depicted below.
The system consists of 4 main subsystems.
The main orchestrator of my program is the rendering loop. All other actions on the Pi, other than input handling, are controlled by this main loop.
When the program first starts, we first do some housekeeping to get everything in working order. We initialize the display device and any information related to it that we might need during our computations. Next, we import the planet data files stored in cspice_database/planets/ and spawn the input handling thread.
Once everything is initialized, we begin the main rendering loop. First we process any input we may have received over the course of the last frame and we adjust simulation parameters accordingly. Next, we perform some matrix transformations to rotate the target body into the frame of the camera (and every other body as well). The projection transform then begins by first determining which bodies are in view of the camera and then calculating their positions and sizes on the display. Finally, we render these bodies and display helpful information like body distance, body name, current time and camera FOV.
The input handling constists of an additional two systems which run independently: one on the Pi and one on the Arduino.
The Arduino basically sits in a 100ms control loop which continually polls the analog joystick and pushbuttons. In addition, it features an interrupt handler for when the rotary turndial lines change state. The interrupt handler is required because of the very quick voltage changes and without it, the Arduino actually misses some of them and the turn direction becomes ambiguous.
Once the Arduino reaches the end of the 100ms loop, it gathers all of the input data that it collected and begins transmission to the Raspberry Pi. This is accomplished over a set of 4 wires: ready, clk, data, and acknowledge. The Arduino begins by asserting the ready line and if the Raspberry Pi responds with the acknowledge line, serial communication begins. In total, we transfer one InputPacket (c struct type) which consists of 4 bytes of information. Once the 4 bytes are transmitted, the Arduino restarts the loop again.
The Raspberry Pi's job, when compared to the Arduino's is relatively simple. The input handling operates in a separate thread from the main rendering loop. When the Arduino's ready line goes high, the Pi acknowledges and begins serial communication to receive the InputPacket. In then stores this in a known memory area for the main rendering thread.
The main rendering thread at the end of a frame then checks to see if new input data has been received and if so, copies it and transfers control to the Parameter Controller (subsection 4 below).
The NAIF SPICE database (info found here: https://naif.jpl.nasa.gov/naif/toolkit.html) contains ephemeris data for many bodies found within our solar system. I had originally planned to access this database directly from the Pi but the libraries unfortunately don't support ARM. Instead, I decided to use my desktop and another c program to "download" all the data that I specifically wanted. On my desktop, I begin by retreiving the database files from the NAIF website and I then use the program located in cspice_database/spice.c to collect data for the 15 bodies that my device supports. In total, I collect ephemeris or position data for each body over the course of 2 years and in 10 minute time intervals. This results in each body.dat file (located in cspice_database/planets/ being around 5.5MB. The files are then transfered over to the Raspberry Pi and it uses them to load around 75MB of planetary data during program execution.
The Simulation Parameters Controller is pretty straight forward. It reads the data that the main rendering loop gathered and, depending on the input received, adjusts the FOV, time and target body accordingly.