OpenExo GUI¶
Overview¶
This application runs on any system with Python 3.12 installed. Required libraries can be installed via pip.
Open Source Application utilizing the OpenExo API to search, connect to, and control NAU Biomechatronics Lab’s OpenExo systems.
This project is licensed under the MIT License and provides an open-source solution for accessible, modifiable control of the OpenExo system.
Minimum System Requirements¶
Operating System:
Windows 7 or newer
macOS 10.9 or newer
Python Version:
Python 3.2 or newer
Hardware:
Processor: Dual-core (e.g., Intel Core i3 or AMD equivalent)
Memory (RAM): 2 GB minimum (4 GB recommended)
Storage: 100 MB free space (1 GB recommended for large datasets)
Display: 768×1024 resolution minimum
Installation Guide¶
Video Guide: https://youtu.be/VnQeUM2K6Vg
BLE (Bluetooth Low Energy) provides connections between this API and the exoskeletons. We use [Bleak](https://bleak.readthedocs.io/en/latest/) for all BLE operations.
Required Python libraries:
matplotlib
async_tkinter_loop
pygame
numpy
bleak
pandas
scikit-learn
micromlgen
pillow
To install all dependencies, run:
python install_dependencies.py
General Workflow¶
Program control flow diagram:
.. image:: programflow.png
:alt: Program Control Flow
:width: 500px
Starting the Application¶
Ensure Bluetooth is enabled on your device.
Open a terminal and navigate to the project directory.
Run:
python3 GUI.py
The GUI will launch with frames for system interaction.
Scanning for Devices¶
Press the Scan button to search for exoskeletons.
If Bluetooth is disabled, an error message will appear.
Video Example¶
Modifying the Graphing¶
Adjust the BasePlot.update_plot method:
def update_plot(self, xValues, yValues, secondY, title):
max_points = -20 # change to display more/fewer points
xValues = xValues[max_points:]
yValues = yValues[max_points:]
secondY = secondY[max_points:]
Customize axes and titles:
self.ax.set_title(title)
self.ax.set_xlabel("Time")
self.ax.set_ylabel("Value")
Each plot subclass has an animate() method—modify it to change data sourcing or display.
Adding a New Frame¶
1. Create the frame class: Add a new file (e.g., views/newFeature.py)
import tkinter as tk
class NewFeature(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
label = tk.Label(self, text="New Feature Frame", font=("Arial", 24))
label.pack(pady=20)
button = tk.Button(
self,
text="Go to Scan Window",
command=lambda: controller.show_frame("ScanWindow")
)
button.pack(pady=10)
2. Update the controller: In your main app file, import and register the new frame
from views.newFeature import NewFeature
for F in (ScanWindow, ActiveTrial, UpdateTorque, BioFeedback, MachineLearning, NewFeature):
# existing frame setup
3. Add navigation: Create a button in any frame to show the new feature
button = tk.Button(
self,
text="Go to New Feature",
command=lambda: controller.show_frame("NewFeature")
)
button.pack(pady=10)
Biofeedback Frame¶
Purpose: Provides visual and auditory feedback during sessions, helping users reach performance goals using real-time sensor data.
Signal Source:
Uses force-sensitive resistors (FSRs) for plantar pressure or estimated ankle power.
Accessed via:
self.master.controller.deviceManager._realTimeProcessor._chart_data
Switch between legs:
_chart_data.leftFsr or _chart_data.rightFsr
Modifying the Signal¶
Locate the
FSRPlotclass inchart.py.Update the data source variable:
self.master.controller.deviceManager._realTimeProcessor._chart_data
Features and Controls¶
Graphing:
Real-time display of pressure sensor data.
Goal threshold lines when targets are set.
Buttons:
Back: Return to the Active Trial frame.
Left/Right Leg Toggle: Switch graph between legs.
Set Target Value: Input and display training goals.
Reset Target Value: Clear goals.
Mark Trial: Flag events for analysis.
Recalibrate FSRs: Initiate sensor recalibration.