** Last Updated: 2/22/2021 **
The Quail Dashboard is a Python Tkinter application that reads data from serial USB communication and displays it in real time. Additionally, the dashboard provides users the option to define complex commands without knowing the Quail command codes off-hand. The program starts two independent processes: a "greedy" serial collector (called the data process) and the user-interface applciation (called the GUI). The two interact via process-safe queues, ensuring that all serial messages are collected even if the GUI locks up or otherwise delays program execution (note that threading is not equivalent to multiple processes- the Python GIL prevents threads from executing simultaneously, so the 'multiprocessing' library is used instead).
The application has currently been verified on Windows 10 and Linux (via WSL2 & Ubuntu).
All required modules and minimum versions are listed in 'requirements.txt' - to ensure that you have all required modules, run 'python -m pip install -r requirements.txt' in your terminal.
To run the application, double-click 'QuailDashboard_v1,1.py' in File Explorer or run 'python QuailDashboard_v1,1.py' in your preferred terminal.
The dashboard consists of a MainWindow instance, an inheritor of the Tk.tk() "root" application. This primary container is broken down into several sub-components, as seen in the image below:
- GraphPanes - this object owns 1A and 1B, the two panes that have live-updating sensor data.
The GraphPanes object owns and handles Quail data, as well as the identifying features of the data (channel/solenoid names, units, colors, etc.). Users can adjust the channel name, the units of the data sent via Quail, and the units of the data displayed on screen (allowing conversions) during runtime.
A) ChannelPane - this child of the GraphPanes object displays all data received from Quail numerically (including channel data and solenoid statuses) and provides quick access to buttons for changing channel or solenoid names/units.
B) FocusPane - this child of the GraphPanes object plots two of the channels for easier viewing (the user can select which channels are displayed using the dropdowns at the top). The Graphpanes object owns 3 FocusPanes in total, and the user can switch between them using the tabs at the top. - ButtonPane - this pane holds a set of buttons that send user-defined command sequences to Quail. Which commands are available on the buttons can be adjusted during runtime (with the exception of Abort, which is always present).
- ManualCmdPane - this pane allows the user to interface directly with Quail by sending numeric commands. Additionally, users can input "equations" consisting of numeric commands joined by + and/or "wait" commands followed by the time delay between the commands in seconds (e.g., ' 10 + wait2 + 20 ' sends the command '10', then waits 2 seconds, then sends '20'). Users can also select aliased command equations from the dropdown (and add more aliases during runtime).
- RecordPane - this pane allows the user to start and stop local recording of the data recieved from Quail. Raw data is written to a '.csv' file that is time-and-date stamped. Users can also specify a test name in the text entry box prior to starting the recording.
- PrintBar - this scrollable text bar prints out messages from Quail or other messages.
- MenuBar - the menu bar allows the adjustment of various on-screen options. Users can adjust the channel names/units, re-scale or tare plots, choose which commands are displayed in the ButtonPane, and more.
The dataPlotter.py
file allows for quick display of recorded data - after a test, users can open this separate program. They will be prompted to select a data file to open for plotting: all data channels are plotted in interactive mode, allowing for panning, zooming, and saving.
Future additional features would include the ability to visualize command input, solenoid status, and the capacity to calculate thrust or CdA from test data.
Consult the list below for helpful tips and useful features of the GUI.
- In the ChannelPane, clicking the table headers "Ch. Name", "Ch. Units", or "Sol. Name" will open dialogs to modify those values.
- In the FocusPanes, double-clicking on the plot will cause the plot to force a redraw; this can be useful if the graphics blitting has caused some minor error, by flushing the plots and re-drawing from scratch.
- To modify the duration of solenoid pulses, press the Pulse Time button in the top right corner - a dialog will open, allowing you to set the duration of a pulse.
- You can change the units displayed on the plots to be different than the units of the data sent by Quail. Using the Quail menu on the top menubar, select "Edit Ch. Units" - the Quail Channel Unit is the unit of the data sent over Serial by Quail, while the Display Unit is the unit to which data is converted for display on the GUI.
- There are technically two ButtonPanes - you can switch between Fuel Commands and Ox Commands by pressing the button in the top right corner.
- The line between the ChannelPane and FocusPanes can be dragged to re-apportion space between the two sections.
- There are two scaling options adjustable during runtime, and you can switch between them in the Plotting menu. "Scale to All Data" is the default - the y-axis will be scaled to ensure that all data within the plot width is visible. "Scale to Recent Data" will only consider the last 25% of data points within the plot width when scaling - this will cause recent data to be better scaled, but may cause previous data to go off-screen.
- You can tare any data channel from the Plotting menu on the top menubar. Click "Untare All Channels" to remove any tareing effects.
- You can manually add or modify offsets to the plotted data by clicking "Update Offset Values" in the Plotting menu on the top menubar.
In your local version of the Quail Dashboard, it may be useful to define your own button commands (complex sequences of numeric commands or multiple commands sent synchronously), modify the default options (for plot width, channel names, etc), or otherwise personalize the GUI to your preferences and needs. As a simple guide to making these edits, consult the key below.
- Changing Default Parameters
- Default parameters are collected in the lib/defaults.py folder, along with descriptions of their use and requirements.
- Adding Button Commands
- Button commands and the general Quail command structure is defined in
lib/QuailCommands.py
. - To add a function, define it within the Quail commands object and add it to the
self.command_funcs
dictionary with a descriptive name as the key. (e.g. the key "Open Bleeds" corresponds to theopen_bleeds()
command). - On next start-up, you new command should be selectable in the Edit Button Commands menu. You can also set you command as a default by modifying 'defaults.py'.
- Button commands and the general Quail command structure is defined in
- Adding Quail Codes to the ManualCmdPane
- To add more default options to the ManualCmdPane dropdown or to edit the values in the dropdown, make modifications to the 'Quail_Command_Defs.csv' file (the format is command_code, command_description)
- Adding Custom Units
lib/units.py
contains code for switching between compatible units. At times, it may be useful to define a unique, custom unit (for example, if Quail is reading raw analog data from a sensor, you can add a conversion factor+offset to adjust it to a standard unit).- Add your unit(s) to the
unit_lib
dictionary, following the format specified in the header comments. To add an offset for your unit, modifyunit_offset
as well.
- Modifying the Quail Emulator
lib/QuailEmulator.py
contains the definition of the QuailEmulator object. Add or modify functions to expand/adjust the functionality of the emulator (the functionsreadline
,flush
, andwrite
must be present).
Developed by Max Newport ('newpomax@stanford.edu' or 'newpomax@gmail.com') for Stanford Student Space Initiative's Propulsion Team. Original framework developed by Luke Upton + Damian Loya.