Back to 5.1 User Interface (GUI)

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.

Seven-Iteration Build Timeline Each iteration adds one layer of training flow, integration, or polish. 1 Shell PySide6, nav, Jetson 2 Curriculum combos, session UI 3 Sparring Markov, assessment 4 Performance tests, sensors 5 Navigation stack, AI coaching 6 User mgmt login, validation 7 Dashboard ROS 2, phone, design

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.

Interactive IMU Navigation Cue Click a pad to preview the direction label and the active state. Press a pad to preview the navigation response GUI training-time control path Up / Head Right Left Confirm

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.

Typical Session Flow A training session moves from setup to live control to results review. Configure mode, level, duration Start session ID issued Run countdown, active, rest Finish summary returned Review results, next-session choice

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.

Training Mode Screen Flow Configuration Live SessionHUD (Round N) Rest Screen Results Loop until final round After 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.

Sparring Exchange Loop Robot Attack(style-driven) User DefenceBlock / Slip Defence OK Hit Logged Counter Windowuser punches pad Exchange Log Loop continues for each attack until round timer expires

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.

Performance Test Module Structure Power Test 5 max-force punches 5s rest between Outputs Peak · Average · Consistency Personal best comparison Stamina Test Sustained punching 60s default duration Outputs Total · Avg rate · Peak rate Fatigue indicator Reaction Test 10 visual/audio trials random stimulus delay Outputs Avg · Best · Worst · StDev Percentile vs baseline

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.

Rank Tier Progression Novice 0 Contender 500 Fighter 1,500 Warrior 3,500 Champion 7,000 Elite 12,000 Cumulative XP thresholds (indicative; exact values set in Section 5.3)

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.

Session XP Composition Base Award per mode + Performance Bonus accuracy / defense rate × Difficulty Mult. selected level = Session XP awarded Each results screen surfaces these three components alongside the final total.

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.

Navigation Stack: Push on Forward, Pop on Back Forward Navigation (push) Login Main Menu Training Combo Select Session Stack after arriving at Session: Bottom ← [ Login, Main Menu, Training, Combo Select ] → Top Back Navigation (pop) Session Combo Select pop: Combo Select Training pop: Training Main Menu pop: Main Menu When the stack is empty, pressing Back falls back safely to the Main Menu. This eliminates manual per-page back button wiring across all 40+ pages.

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 4Beginner
5 to 8Intermediate
9 to 12Advanced

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
start0.300.300.40
1 (Jab)0.400.60
2 (Cross)0.300.200.50
3 (L.Hook)0.300.70
4 (R.Hook)0.200.80
5 (L.Upper)0.100.90
6 (R.Upper)1.00

Table 5.1.2-6: Counter Puncher Markov Transition Matrix

Worked example (Counter Puncher):

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
Jab0.40
Cross0.30
Lead Hook0.15
Rear Hook0.10
Lead Upper0.03
Rear Upper0.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\)
Jab24
Cross16
Lead Hook8
Rear Hook8
Lead Upper2
Rear Upper2

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.

Hash Table Page Routing Navigation Call page_id string dict hash lookup self._pages[page_id] Target QWidget immediate resolution Average-case lookup cost remains O(1) as page count grows.

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.

Lazy Loading Reduces Startup Critical Path Eager import path Import all page modules Heavy dependencies Construct first page Lazy import path Register routes Render active page Import other pages on first use Startup cost is shifted from global import time to feature activation time.

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.

Bounded History Materialisation Unbounded O(n) Bounded O(50) Row cap at query time keeps memory and parse cost stable across long-term usage.

References