Implementation
The GUI was built over seven iterations across 18 weeks (December 2025 to April 2026). Each iteration had a defined objective, produced working software, and closed with a review before the next iteration began. This section documents the development timeline, the system architecture, and the key engineering decisions that shaped the final system.
V-Model alignment: This page corresponds to the base of the V, where decomposed GUI concepts are integrated into a single, testable subsystem build.
The implementation story is still a product story. Each release turned the GUI from a set of selected concepts into something a boxer could actually use in training, with the architecture serving the user flow rather than the other way around.
Development Iterations
The iteration plan followed the product development sequence from Chapter 3: select the concept, build the minimum viable version, check it against user needs, then refine the training flow before moving to the next layer.
A key product insight emerged from user testing at the Robotics Meets AI Showcase in late January 2026 (mid-Iteration 3). Interviews with boxers of varying skill levels revealed distinct patterns in how beginners, intermediate, and advanced practitioners approached the equipment. These observations directly informed the design of the proficiency assessment—a 6-question checklist administered during signup that classifies users into three tiers based on their responses. This user-centred approach meant the assessment reflected real training behaviour rather than arbitrary difficulty levels.
System Architecture
The application follows a five-layer architecture. Each layer has a single responsibility, so changes in one layer do not cascade into unrelated parts of the codebase.
From the user's perspective, that architecture exists to keep the training experience smooth. A user should see a stable drill flow and fast feedback, even when the underlying data, integration, or session logic changes.
Presentation Layer
PySide6 widgets: all pages, buttons, labels, input fields, event callbacks, visual feedback
Application Layer
Navigation stack and page history, user session state, configuration management
Business Logic Layer
Combo Curriculum Engine (mastery algorithm), Performance Testing Logic, User Management, Proficiency Assessment
Integration Layer
GuiBridge (ROS 2 QThread bridge), CV interface (ROS topics + file-based fallback), Robot arm control (ROS command topics), Phone dashboard (shared SQLite + JSON command file)
Data Layer
SQLite databases (per-user files), configuration file management
The Integration Layer is the critical enabler for parallel development. Rather than calling hardware interfaces directly, all hardware communication is routed through this layer. During development on a Windows laptop with no hardware connected, the layer switches automatically to mock interfaces that simulate hardware responses. When deployed on the Jetson Orin NX, the mock interfaces are replaced by real implementations without any changes to the layers above.
That separation mattered because the product had to keep moving while the rest of the robot was still being developed. The GUI could be tested with realistic training flows before the physical system was fully available.
ROS 2 Integration
The GUI communicates with the broader BoxBunny system through a GuiBridge interface that receives session events and sends user commands. This keeps interface behavior responsive while preserving a clean boundary between user interaction flow and backend processing. From the user's perspective, this enables live updates for punch confirmations, drill progress, session state, and coaching prompts.
In product terms, the bridge is what makes the GUI feel alive during training. The user sees the session react immediately, rather than feeling like they are waiting on a separate machine in the background.
During laptop-only development, the same interface runs in mock mode so the GUI can be validated without connected hardware. Internal node architecture, transport details, and backend implementation are documented in Section 5.3.
IMU Navigation
A key usability constraint identified during needs finding is that boxers cannot reliably operate a touchscreen while actively training. Research on touch input shows that even moderate hand coverage significantly reduces accuracy on targets below 48px (Parhi, Karlson and Myers, 2006). The GUI is therefore designed for normal touchscreen use with bare hands, while the IMU pads provide the training-time control path.
This feature exists because the training product has to work under movement and fast session changes. The navigation model was chosen to keep the boxer focused on the drill instead of on the screen.
The four pads double as navigation controls outside of training sessions. Left pad moves to the previous item, right pad moves to the next, centre pad confirms a selection, and head pad navigates back. This mapping follows the directional convention familiar from physical four-button controllers, which reduces the need for users to learn new interaction patterns (Norman, 2013).
One edge case is the home screen, which has no parent to return to. On the home screen, the head pad opens a quick-access preset overlay instead of attempting a back navigation with nowhere to go.
During active training, all pad navigation is disabled. Without this, punch impacts on the pads would trigger accidental page changes mid-session. The disable state activates during the countdown and active phases of every session and restores automatically during rest and after session completion.
Session Orchestration
The GUI is the session lifecycle controller for every training mode: technique drills, sparring, free training, and performance tests. Every session begins with an explicit start request from the GUI and ends with an explicit end request that retrieves the session summary.
From the product point of view, this is the core training loop. The user configures a drill, starts it, receives live state feedback, and ends with a summary that supports the next training decision.
The sequence on a typical session is as follows. The user configures the session and taps Start. The GUI sends a request to the backend with the training mode, difficulty, and username, and receives a session ID in return. Throughout the session, state changes arrive from the backend: countdown, active round, rest period, and next round. The GUI uses these to drive the on-screen timer, round counter, and screen transitions. When the final round ends or the user exits early, the GUI sends an end request with the session ID. The backend returns a summary containing punch counts, accuracy scores, and performance metrics, which the results page then displays.
This separation means Section 5.3 (Robot Intelligence) handles scoring and data collection logic, while Section 5.1 (GUI) handles all presentation and user flow logic. The GUI does not need to know how punch scoring is calculated, and the backend does not need to know how results are displayed.
Home Dashboard
The home dashboard is the first screen a registered user reaches after authentication. It consolidates the user's training status and provides direct access to every training mode. The screen has four zones: a header bar showing the user's display name, current rank, and active streak; a gamification row with XP total and rank tier; a mode selection grid with four large buttons (Training, Sparring, Free Training, Performance Tests); and a recent sessions list showing the five most recent completed sessions with mode, date, and key metric.
Preset Quick-Start
Below the mode grid, the three most recently used presets are displayed as quick-start cards. Tapping a preset card bypasses the configuration page entirely and launches the session with the saved parameters. This reduces the number of taps required to start a repeat session from five to two, which matters at the start of a training block when the user already knows what they want to do. The full preset library is accessible via a separate Presets page linked from the header.
Recent Sessions
The recent sessions list queries the database sorted by completion time and shows the five most recent entries. Each entry displays the session mode, the date, and one summary metric: accuracy percentage for training sessions and defense rate for sparring sessions. Tapping an entry navigates to the corresponding results page with the full breakdown. This gives returning users a quick reference for their last session without navigating to the history page.
Coach Station View
Users with a coach account see an alternative home screen. Instead of personal stats, the coach dashboard shows a grid of active stations. Each station card displays the assigned user's name, the current training mode, elapsed session time, and a live accuracy or defense rate reading. A coach can stop any active session from this screen or assign a new drill to an idle station. This view was designed for a gym context where one coach manages several simultaneous users on separate BoxBunny units.
Training Mode Screens
Training mode executes a predetermined punch combination at a configured speed across a set number of rounds. The user selects a combination from the 50-combo library, configures the session parameters, then works through the rounds with live feedback. Three screens make up the active training flow: the live session HUD, the rest screen between rounds, and the results screen after the final round.
Custom Combo Builder
Before entering the configuration page, users can optionally build a custom combination using the self-select screen. Six buttons represent the six punch types (jab, cross, left hook, right hook, left uppercut, right uppercut). Tapping a button appends that punch to the sequence, which is displayed as a row of removable badges. The sequence is capped at ten punches. A user who wants to drill a specific exchange that does not appear in the preset library can construct it here and proceed directly to configuration. The custom combination is held in memory for the session and is not persisted unless the user explicitly saves it as a preset.
Live Session HUD
During an active round the screen shows the current round number and total rounds, a countdown timer with a progress bar, the active combination displayed as a numbered punch sequence with the current punch highlighted, a running accuracy counter, and an AI coaching tip refreshed approximately every ten seconds. The combination display advances in step with the session timer so the user can track where they are in the sequence without counting manually. Accuracy is updated each time the CV subsystem confirms or rejects a detected punch against the expected punch at that position in the sequence.
Two control buttons are present throughout the round: Pause and Stop Session. Pausing freezes the round timer and suspends the combination advance. Stopping ends the session early and navigates to the results screen with the data collected up to that point.
Rest Screen
Between rounds the application transitions to a rest screen showing the remaining rest time as a countdown and a progress bar, the upcoming round number, and the combination that will be drilled next. Three seconds before the rest period ends, the screen displays a "Get Ready" prompt. The user can tap Skip Rest to advance immediately. The rest screen serves as a deliberate pause point, giving the user time to recover and mentally prepare for the next round without requiring any interaction unless they choose to skip.
Training Results Screen
After the final round, the results screen presents the session summary. The top section shows overall accuracy, the combination drilled, total session duration, and the number of rounds completed. A punch-type breakdown table lists accuracy for each punch type that appeared in the combination. Below the breakdown, the XP earned for the session is displayed with a line showing the base award, the accuracy bonus, and the difficulty multiplier. An AI-generated coaching note appears at the bottom, highlighting the weakest punch type and suggesting one specific improvement. The user can save the session to their history, restart the same session, or return to the home dashboard.
Sparring Mode Screens
Sparring mode positions the user as the defender and counter-puncher against an AI-controlled robot opponent. The robot generates attack sequences according to one of five selectable styles, each producing a distinct pattern of punches that the user must read and respond to. The GUI's role in sparring is to present each incoming attack clearly, accept the user's defensive response, and display the exchange outcome in real time.
AI Opponent Styles
The five opponent styles available at the configuration screen are: Boxer, Brawler, Counter-Puncher, Pressure, and Switch. Each style produces a different attack rhythm and punch distribution, which changes the feel of the sparring session for the user. The Boxer style mixes all punch types with balanced frequency, creating a technically varied opponent. The Brawler concentrates on hooks and power punches and attacks in short bursts. The Counter-Puncher attacks infrequently but responds immediately after the user lands a punch, making sessions feel reactive rather than relentless. The Pressure style attacks continuously with minimal gaps, testing defensive endurance. The Switch style rotates between the other four styles at unpredictable intervals, preventing the user from settling into a single defensive pattern.
The attack sequences produced by each style are not random. Each style uses a Markov chain transition model, meaning the probability of each next punch depends on what punch was thrown immediately before. This produces sequences that feel stylistically coherent rather than arbitrary. For example, the Boxer style is more likely to follow a jab with a cross than with an uppercut, mirroring the 1-2 combination common in technical boxing. The Robot Intelligence subsystem manages the transition probabilities and generates the attack commands. The GUI receives each incoming attack as an event and presents it to the user. The Markov chain internals are documented in Section 5.3.
Live Sparring HUD
The sparring session screen shows the current round and timer at the top, followed by an incoming attack panel in the centre. When the robot is about to throw a punch, the panel displays the punch type and a short countdown giving the user time to respond. Three defence buttons appear below the panel: Block, Slip Left, and Slip Right. The user taps the appropriate button or performs a physical defensive movement detected by the CV subsystem. After each exchange, the outcome is appended to a scrolling log below the defence buttons, showing what the robot threw, what the user did, and whether the defence succeeded.
When the user successfully defends an attack, a counter-punch window opens for a brief period. During this window the user can throw a punch at the pads to register a counter. A visual indicator shows the window is open. The window duration decreases at higher difficulty settings, requiring faster reactions. After the window closes, the exchange log updates with the counter outcome.
A round statistics bar at the bottom of the screen shows punches landed, punches thrown, and defense rate for the current round. These update live after each exchange.
Sparring Results Screen
The post-match summary shows the opponent style selected, difficulty level, total duration, and a round-by-round exchange count. The defence breakdown table lists defense rate for each of the six punch types. Punch types where the user's defense rate fell below a threshold are flagged, identifying the specific attacks the user struggled to respond to. This information feeds into the opponent's bias in future sessions: the Robot Intelligence subsystem reads the stored weakness profile and increases the probability of those punch types appearing in the next sparring session, creating an adaptive training loop. The GUI surfaces the outcome of this loop to the user by showing which punch types are flagged and noting that the opponent will target those areas. The XP earned is shown with the defense rate bonus and difficulty multiplier applied. An AI coaching note summarises the session and suggests a specific defensive adjustment. Details of the weakness profile update and the bias mechanism are covered in Section 5.3.
Performance Test Screens
The performance test module offers three standalone tests: Power, Stamina, and Reaction. Each test follows the same three-screen structure: an instructions screen, a live test screen, and a results screen. Tests are accessible from the home dashboard under Performance Tests and can be run independently of any training session.
Power Test
The instructions screen explains that the user should throw five maximum-force punches at the designated pad with five seconds of rest between each punch. The live test screen counts down between punches and updates a list of recorded strikes as each one is detected. After five punches are recorded, or after a sixty-second timeout, the test ends automatically. The results screen shows the peak force reading, the average across all five punches, a consistency rating based on the spread of readings, and the user's all-time personal best for comparison. Force readings are sourced from the IMU subsystem. The GUI displays the values it receives without performing its own force calculations.
Stamina Test
The instructions screen asks the user to throw punches continuously at maximum sustainable rate for a configurable duration, with sixty seconds as the default. The live test screen shows elapsed time, a progress bar, the running punch count, and the current punches-per-minute rate. A prompt in the centre of the screen updates with encouragement at regular intervals. The results screen shows total punches thrown, average rate, peak rate with the timestamp at which it occurred, and a fatigue indicator comparing the punch rate in the first half of the test against the second half. A declining rate in the second half is flagged as an indicator of stamina drop-off.
Reaction Test
The instructions screen explains that the user should respond as quickly as possible to a visual and audio stimulus by tapping the screen or striking a pad. The live test screen presents a series of ten trials. Each trial begins with a blank waiting period of random duration, after which the screen flashes and a tone plays. The time between the stimulus and the user's response is recorded. The results screen shows average reaction time, best and worst single trials, consistency as the standard deviation across all trials, and a percentile comparison against the population baseline stored in the database. Reaction times below 200ms are rated excellent, 200-300ms good, 300-400ms average, and above 400ms are flagged as slow (Kosinski, 2008).
Gamification System
Gamification elements are surfaced across multiple screens rather than isolated to a single page. The design intent is for progression to feel like a natural part of the training record, not a separate reward system bolted on (Hamari et al., 2014). The rank and badge system gives users visible progress after a session, which helps keep training feeling rewarding instead of repetitive. The detailed scoring and data model are covered in Section 5.3.
Rank Tiers and XP Display
The home dashboard header shows the user's current rank title and XP total. Six rank tiers are defined: Novice, Contender, Fighter, Warrior, Champion, and Elite, each requiring progressively higher cumulative XP. The header displays the current tier name and a small progress indicator showing how far through the current tier the user is. When a session results screen awards XP that crosses a tier boundary, a rank-up notification is shown before the standard results view.
Session XP Breakdown
Every results screen shows an XP breakdown with three components: a base award determined by the training mode, an accuracy or defense rate bonus scaled by session performance, and a difficulty multiplier. Showing the breakdown rather than just the total makes the reward legible. A user who wants more XP can see that improving accuracy or raising the difficulty setting has a direct numerical effect.
Streak Tracking
The home dashboard displays the user's active training streak in days. A streak increments when the user completes at least one session on a given calendar day. Streaks reset to zero if a day is missed. The streak value is also one of the inputs to the XP calculation at session end, providing an incentive for consistent daily training.
Phone Dashboard
A companion phone dashboard gives users a quick way to check progress and make light training adjustments without walking back to the robot. It is most useful between rounds or after a session, when the boxer wants a fast summary rather than a full touchscreen interaction. More detailed integration notes are in Section 5.3.
Key Engineering Decisions
Navigation Stack
The application contains over 40 pages managed by a central QStackedWidget.
Rather than coding back button destinations manually on each page, a navigation stack
records the current page index before every transition. The diagram below illustrates
how the stack operates as a user navigates through a typical training flow.
Proficiency Assessment
On signup, new users complete a six-question checklist. Each question has three answer options scored 0, 1, or 2. The total score (0 to 12) maps the user to a proficiency level, with the option to override the suggestion before confirming.
| Question | Option 1 (0) | Option 2 (1) | Option 3 (2) |
|---|---|---|---|
| Have you trained boxing before? | Never | A few times | Regularly |
| Do you know the basic punches? | No | Somewhat | Yes |
| Can you throw a basic 1-2-3 combo? | No | With help | Yes |
| Have you done any sparring before? | Never | Once or twice | Yes, regularly |
| How would you describe your fitness level? | Low | Moderate | High |
| Have you used boxing equipment before? | Never | A few times | Regularly |
Table 5.1.2-3: Proficiency Assessment Questions
| Total Score | Suggested Level |
|---|---|
| 0 to 4 | Beginner |
| 5 to 8 | Intermediate |
| 9 to 12 | Advanced |
Table 5.1.2-4: Proficiency Assessment Scoring
The user can accept or override the suggestion on the result page before confirming. This classification determines the default combo difficulty tier shown on the training page.
Combo Curriculum and Mastery Algorithm
The curriculum contains 50 combinations: 15 Beginner, 20 Intermediate, and 15 Advanced. Each combo uses a notation system where numbers 1 through 6 represent punch types (Jab, Cross, Lead Hook, Rear Hook, Lead Uppercut, Rear Uppercut), with a "b" suffix for body shots and text labels for defensive movements (slip, block, roll). A combo is considered mastered when the user has completed at least five sessions with an average score of 3.0 out of 5.0 or above. This threshold-based progression model draws on mastery learning theory, which holds that learners should demonstrate competence at one level before advancing to the next (Bloom, 1984). Progress is tracked per-user in the SQLite database and persists across sessions. The self-select sequence builder interface is shown in Appendix 3.
Sparring Mode: Markov Chain Generation
Sparring mode generates punch sequences using a first-order Markov chain. A first-order Markov chain is a probabilistic sequence model in which the probability of each next state depends only on the current state (Norris, 1997). This property makes it suitable for real-time punch sequence generation within the Jetson Nano's compute budget, as no sequence history needs to be stored or evaluated. Each boxing style (Pressure Fighter, Counter Puncher, Infighter, Out-Boxer, Random) defines a transition probability matrix over punch types. Starting from a "start" state, the system picks the next punch based on weighted probabilities, continuing until an "end" state is reached or a safety limit of six punches per combo is hit. Sparring is available to all proficiency levels. The style selection interface is shown in Appendix 3.
Below is the transition matrix for the Counter Puncher style as an example. Each row shows the current state, and the columns show the probability of transitioning to each next punch (or ending the combo).
| From State | 1 (Jab) | 2 (Cross) | 3 (L.Hook) | 4 (R.Hook) | 5 (L.Upper) | 6 (R.Upper) | End |
|---|---|---|---|---|---|---|---|
| start | 0.30 | 0.30 | 0.40 | ||||
| 1 (Jab) | 0.40 | 0.60 | |||||
| 2 (Cross) | 0.30 | 0.20 | 0.50 | ||||
| 3 (L.Hook) | 0.30 | 0.70 | |||||
| 4 (R.Hook) | 0.20 | 0.80 | |||||
| 5 (L.Upper) | 0.10 | 0.90 | |||||
| 6 (R.Upper) | 1.00 |
Table 5.1.2-6: Counter Puncher Markov Transition Matrix
1. start: Roll probabilities. Jab (0.30), Cross (0.30), End (0.40). Suppose the roll picks Jab.
2. After Jab: Cross (0.40), End (0.60). Suppose the roll picks Cross.
3. After Cross: Lead Hook (0.30), Rear Hook (0.20), End (0.50). Suppose the roll picks End.
Result: the generated combo is 1-2 (Jab, Cross). The Counter Puncher style has high "end" probabilities, so it naturally produces short, precise combinations. Contrast this with the Pressure Fighter, whose low "end" probabilities generate longer, more aggressive sequences.
When a user's weakness profile is available (from previous sparring sessions), the transition weights are blended with a bias multiplier. The blending factor alpha increases gradually with session count (capped at 0.4), so the adaptation strengthens over time without fully overriding the style's character.
Formal Definition of the Adaptation Mechanism
The adaptation mechanism has six components. Each is defined below with its purpose stated in plain terms before the formal expression.
Adaptation strength. The parameter \(\alpha\) controls how much weight the system gives to the user's recent history versus the base style matrix. It grows by 0.05 per completed sparring session and is capped at 0.4, meaning the robot's style character is always preserved by at least 60 percent.
\[ \alpha = \min(0.4,\; n \times 0.05) \] where \(n\) is the number of completed sparring sessions.
Session frequency normalisation. After each session, the CV system returns raw counts of each punch type the user threw. These are converted to proportions so that sessions of different lengths are comparable. Each count \(c_i\) for punch type \(i\) is divided by the total number of punches thrown in that session.
\[ f_i = \frac{c_i}{\displaystyle\sum_{j} c_j} \]
Rolling weighted average (weakness profile update). The stored weakness profile is updated after each session using an exponential moving average. The old profile is weighted by \(1 - \alpha\) and the current session frequencies are weighted by \(\alpha\). Because \(\alpha\) is small early on, a single unusual session does not distort the profile. As \(\alpha\) grows toward 0.4 with more sessions, recent performance carries increasing influence.
\[ f_i^{\,\text{new}} = (1 - \alpha)\, f_i^{\,\text{old}} + \alpha\, f_i^{\,\text{current}} \]
Weakness multiplier. The weakness multiplier \(w_p\) for a given robot punch \(p\) is derived from the user's opposite-hand punch frequencies. The reasoning is that a boxer who frequently throws left-hand punches is likely to leave their left side exposed, making them susceptible to right-hand counters from the robot, and vice versa.
\[ w_p = \begin{cases} f_{\text{cross}} + f_{\text{rear hook}} + f_{\text{rear upper}} & \text{if } p \in \{1,\, 3,\, 5\} \text{ (left-side robot punch)} \\[8pt] f_{\text{jab}} + f_{\text{lead hook}} + f_{\text{lead upper}} & \text{if } p \in \{2,\, 4,\, 6\} \text{ (right-side robot punch)} \end{cases} \]
Blended transition weight. Each cell \(m_{s,p}\) in the transition matrix represents the base probability of moving from state \(s\) to punch \(p\) under the chosen style. The blended weight \(\tilde{m}_{s,p}\) is formed by mixing this base probability with the weakness multiplier using \(\alpha\) as the blend factor. At \(\alpha = 0\) the output is the pure base style. At the cap of \(\alpha = 0.4\) the output is 60 percent base style and 40 percent weakness bias.
\[ \tilde{m}_{s,p} = (1 - \alpha)\, m_{s,p} + \alpha\, w_p \]
Row normalisation. After blending, the weights in each row of the modified matrix no longer necessarily sum to 1.0. The final step rescales every weight in a row by the row total so that each row forms a valid probability distribution. This is required for the weighted random draw that selects the next punch to operate correctly.
\[ m_{s,p}^{\,\text{final}} = \frac{\tilde{m}_{s,p}}{\displaystyle\sum_{p'} \tilde{m}_{s,p'}} \]
End-to-End Worked Example
The following example traces one complete session cycle from raw punch counts through to a modified transition matrix and a generated combo. The Counter Puncher style is used throughout, as its matrix is shown in the table above. All numbers are carried to two decimal places.
Setup. The user has completed 4 previous sparring sessions. Their stored weakness profile after those sessions is:
| Punch type | Stored frequency |
|---|---|
| Jab | 0.40 |
| Cross | 0.30 |
| Lead Hook | 0.15 |
| Rear Hook | 0.10 |
| Lead Upper | 0.03 |
| Rear Upper | 0.02 |
This profile shows a jab-heavy user who rarely uses uppercuts.
Phase 1: Compute alpha. The user has completed \(n = 4\) sessions.
\[ \alpha = \min(0.4,\; 4 \times 0.05) = \min(0.4,\; 0.20) = 0.20 \]
Phase 2: Normalise the current session's punch counts. The CV system reports the following raw counts from the session just completed:
| Punch type | Count \(c_i\) |
|---|---|
| Jab | 24 |
| Cross | 16 |
| Lead Hook | 8 |
| Rear Hook | 8 |
| Lead Upper | 2 |
| Rear Upper | 2 |
Total punches: \(\sum_j c_j = 24 + 16 + 8 + 8 + 2 + 2 = 60\). Applying equation (2):
\[ f_{\text{jab}} = \frac{24}{60} = 0.40, \quad f_{\text{cross}} = \frac{16}{60} = 0.27, \quad f_{\text{lead hook}} = \frac{8}{60} = 0.13 \] \[ f_{\text{rear hook}} = \frac{8}{60} = 0.13, \quad f_{\text{lead upper}} = \frac{2}{60} = 0.03, \quad f_{\text{rear upper}} = \frac{2}{60} = 0.03 \]
Phase 3: Update the weakness profile. Applying equation (3) with \(\alpha = 0.20\) to each punch type. Shown for jab and cross; the same calculation applies to all six types.
\[ f_{\text{jab}}^{\,\text{new}} = (1 - 0.20) \times 0.40 + 0.20 \times 0.40 = 0.32 + 0.08 = 0.40 \] \[ f_{\text{cross}}^{\,\text{new}} = (1 - 0.20) \times 0.30 + 0.20 \times 0.27 = 0.24 + 0.054 = 0.29 \]
The jab frequency is unchanged because the current session matches the stored value exactly. The cross frequency nudges slightly downward from 0.30 to 0.29 because the current session cross rate (0.27) is marginally lower than the stored value.
Phase 4: Compute weakness multipliers. Using the updated profile values and equation (4).
For left-side robot punches (punch types 1, 3, 5 — Jab, Lead Hook, Lead Uppercut), the multiplier is the sum of the user's right-hand frequencies, because a frequent right-hand puncher tends to leave their right side open:
\[ w_{1,3,5} = f_{\text{cross}} + f_{\text{rear hook}} + f_{\text{rear upper}} = 0.29 + 0.10 + 0.02 = 0.41 \]
For right-side robot punches (punch types 2, 4, 6 — Cross, Rear Hook, Rear Uppercut), the multiplier is the sum of the user's left-hand frequencies:
\[ w_{2,4,6} = f_{\text{jab}} + f_{\text{lead hook}} + f_{\text{lead upper}} = 0.40 + 0.13 + 0.03 = 0.56 \]
The right-side multiplier (0.56) is higher than the left-side multiplier (0.41) because the user throws more left-hand punches overall, exposing their right side more often.
Phase 5: Blend the transition matrix. Applying equation (5) to the start row of the Counter Puncher matrix. The base weights from the table above are: Jab = 0.30, Cross = 0.30, End = 0.40 (all other cells in this row are zero).
\[ \tilde{m}_{\text{start},\,1} = (1 - 0.20) \times 0.30 + 0.20 \times 0.41 = 0.24 + 0.082 = 0.322 \] \[ \tilde{m}_{\text{start},\,2} = (1 - 0.20) \times 0.30 + 0.20 \times 0.56 = 0.24 + 0.112 = 0.352 \] \[ \tilde{m}_{\text{start},\,\text{end}} = (1 - 0.20) \times 0.40 + 0.20 \times 0 = 0.32 + 0 = 0.320 \]
The end state has no weakness multiplier because it is not a punch type, so it receives only the scaled base weight.
Phase 6: Normalise the blended row. The blended weights sum to \(0.322 + 0.352 + 0.320 = 0.994\), which is not exactly 1.0. Applying equation (6):
\[ m_{\text{start},\,1}^{\,\text{final}} = \frac{0.322}{0.994} = 0.324 \] \[ m_{\text{start},\,2}^{\,\text{final}} = \frac{0.352}{0.994} = 0.354 \] \[ m_{\text{start},\,\text{end}}^{\,\text{final}} = \frac{0.320}{0.994} = 0.322 \]
The three values now sum to \(0.324 + 0.354 + 0.322 = 1.000\). Compared to the original Counter Puncher start row (Jab 0.30, Cross 0.30, End 0.40), the cross probability has increased most because the user's left-hand dominance makes them more susceptible to right-hand counters, and the end probability has decreased slightly, meaning the robot is marginally more likely to begin a combo at all.
Phase 7: Generate a combo from the modified matrix. With the normalised start row (Jab 0.324, Cross 0.354, End 0.322), the system performs a weighted random draw. Suppose the draw selects Cross. Moving to the Cross row of the (now blended) matrix, a second draw selects Lead Hook. A third draw from the Lead Hook row selects End. The generated combo is 2–3 (Cross, Lead Hook). This two-punch combo reflects the Counter Puncher style's tendency toward short, precise combinations, while the elevated cross probability in the start row reflects the system's adaptation to this user's left-hand dominance.
AI Coaching Integration
Users benefit from feedback that appears when it is most useful: quick prompts during training and a more reflective chat view after a session. That keeps the coaching feel light and readable while still giving the boxer a clear next step. More detail on the AI coaching pipeline is in Section 5.3.
Sound System
Audio feedback reinforces task events without requiring the user's visual attention, which is useful during active training when the user is focused on the pads rather than the screen (Gaver, 1989). The GUI uses 18 WAV sound effects, all preloaded at startup for zero-latency playback.
A priority tier system prevents lower-priority sounds from masking higher-priority ones. Round start and end bells carry the highest priority among session sounds. Countdown ticks sit below bells, hit confirmation sounds sit below ticks, and UI navigation clicks sit at the lowest priority. A navigation click cannot interrupt a bell, but a bell will always cut through regardless of what else is playing. Volume and per-sound toggles are available from the Settings page.
Feature Set
The complete feature set delivered across all seven iterations is summarised below.
Performance-Oriented Design Decisions
The benchmark results presented in the Testing and Evaluation section are a direct consequence of specific data structure and architectural choices made during implementation. Five decisions are identified below, each with its theoretical basis and measurable effect.
Hash Table Page Routing
The PageRouter stores registered pages in a Python dictionary
(self._pages: Dict[str, QWidget]), which is implemented as a hash
table. Page existence checks and widget retrieval are therefore O(1) average-case
operations regardless of how many pages are registered (Cormen et al., 2009).
With 25 pages registered at startup, any navigation call resolves the target widget
in constant time. This is the primary reason page transition times are independent
of application size.
Stack-Based Navigation History
Back navigation is implemented using a Python list as a stack
(self._history.append to push, self._history.pop() to
return). Python list append is amortised O(1) due to dynamic array doubling
(Cormen et al., 2009). This gives the back-navigation system constant-time cost
at any navigation depth, avoiding the need to traverse or rebuild a navigation
tree on each back press.
Lazy Module Loading
Pages are loaded via importlib.import_module inside
_try_load_page at registration time rather than at package import
time. All page package __init__.py files are intentionally empty,
and many pages use TYPE_CHECKING-only imports and function-local
imports for heavy or optional dependencies such as OpenCV and database helpers.
This implements the lazy initialisation pattern (Gamma et al., 1994), deferring
import cost from the startup critical path to first feature activation. The
result is that startup time reflects only the cost of constructing the active
page, not the cumulative import cost of all 25 page modules.
Connection-Per-Call Database Pattern
The database helper (db_helper._conn()) creates a new SQLite
connection per call via a context manager rather than maintaining a shared
long-lived connection. This follows the connection factory pattern (Fowler,
2002), which avoids idle memory retention from open cursors and prevents
connection state corruption across sequential operations. The trade-off is a
small per-query setup cost, which is acceptable given SQLite's sub-millisecond
connection overhead on local storage.
Bounded History Materialisation
Session history retrieval is capped at 50 rows at the query level. This makes memory consumption and parse time O(k) where k is fixed at 50, rather than O(n) where n grows unboundedly with user history. Bounding query results at the data layer is a standard technique for preventing unbounded memory growth in interactive applications (Fowler, 2002) and directly contributes to the stable memory footprint observed across all three checkpoints in the memory benchmark.
References
- Bloom, B.S. (1984). The 2 Sigma Problem: The Search for Methods of Group Instruction as Effective as One-to-One Tutoring. Educational Researcher, 13(6), 4-16.
- Cormen, T.H., Leiserson, C.E., Rivest, R.L. and Stein, C. (2009). Introduction to Algorithms (3rd ed.). MIT Press.
- Fowler, M. (2002). Patterns of Enterprise Application Architecture. Addison-Wesley.
- Gamma, E., Helm, R., Johnson, R. and Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.
- Gaver, W.W. (1989). The SonicFinder: An interface that uses auditory icons. Human-Computer Interaction, 4(1), 67-94.
- Hamari, J., Koivisto, J. and Sarsa, H. (2014). Does gamification work? A literature review of empirical studies on gamification. Proceedings of the 47th Hawaii International Conference on System Sciences, 3025-3034.
- Kosinski, R.J. (2008). A literature review on reaction time. Clemson University, 10, 1-19.
- Norman, D.A. (2013). The Design of Everyday Things: Revised and Expanded Edition. Basic Books.
- Norris, J.R. (1997). Markov Chains. Cambridge University Press.
- Parhi, P., Karlson, A.K. and Myers, B.A. (2006). Target size study for one-handed thumb use on small touchscreen devices. In Proceedings of the 8th Conference on Human-Computer Interaction with Mobile Devices and Services (MobileHCI 2006), pp. 203-210.
- Schmidt, R.A. and Lee, T.D. (2011). Motor Control and Learning: A Behavioral Emphasis (5th ed.). Human Kinetics.