Giving my 2020 thesis robot the tests it never got — and a 2026 opponent.
In 2020 my master thesis (Control of a Ball-Balancing Robot, Aalborg University) modeled a ballbot — an omnidirectional robot balancing on a single sphere driven by three omniwheels — with quaternion Lagrangian dynamics, unit-norm-preserving Unscented Kalman Filters and a nonlinear feedback-linearization controller. Everything was validated in simulation; the thesis closes with the classic line that "further laboratory tests are to be conducted."
They never were. Five years later, this repository is me conducting them — in the 2026 stack instead of the 2020 lab: a Python/MuJoCo rebuild of the same robot, with the same physical parameters, where my classical controllers (LQR now, the thesis cascade FLC next) will face learned policies (PPO/SAC) on the same tasks the thesis used for its robustness studies. Same honest rules as the thesis, which reported its own negative results (the UKF wasn't worth its complexity over the EKF; FLC ≈ SMC): whichever controller loses, the comparison gets published.
| Piece | State |
|---|---|
| Planar (2-D) nonlinear dynamics, thesis Appendix A parameters | ✅ working, tested |
| Continuous LQR (numpy-only CARE solver, no scipy) | ✅ working, tested |
| Demo: 5° tilt + 20 N mid-run shove, stats + plot | ✅ working |
Gymnasium env (BallbotBalance-v0, optional extra) |
✅ scaffolded, untrained |
MuJoCo model (mujoco/ballbot.xml) |
🚧 drafted — simplified gimbal drive, loads & steps, not a faithful omniwheel port |
| Thesis FLC port, RL training, classical-vs-learned comparison | 🔜 not started — see ROADMAP.md |
No results are claimed beyond what the tests and the demo script reproduce.
Python 3.10+; core dependencies are just numpy and matplotlib.
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
python -m ballbot.demo # 10 s balance demo -> stats + out/demo.png
pytest -q # equilibrium, LQR recovery, energy & CARE checksOptional extras (the package works without them):
pip install -e ".[mujoco]" # MuJoCo
python -m ballbot.check_mjcf # validates mujoco/ballbot.xml loads & steps
pip install -e ".[rl]" # gymnasiumimport gymnasium as gym
import ballbot.envs # registers BallbotBalance-v0
env = gym.make("BallbotBalance-v0")
obs, info = env.reset(seed=0)
obs, reward, terminated, truncated, info = env.step(env.action_space.sample())The planar (sagittal-plane) ballbot: ball rolling without slip, rigid-body
pendulum pivoting about the ball centre, drive torque acting across the
ball–body interface, drivetrain inertia reflected through the wheel/ball
radius ratio. The full derivation (Lagrangian, mass matrix, generalized
forces, linearization) lives in the docstrings of
src/ballbot/planar.py; the LQR gain comes from a
Hamiltonian-eigenvector CARE solver in
src/ballbot/lqr.py — numpy only, verified by residual
in the tests.
Physical parameters are the real ones from thesis Appendix A ("System
parameters", report p. 127), cross-checked against the published
Constants_Kugle.m:
| Symbol | Value | Meaning |
|---|---|---|
M_b |
16.154 kg | body mass (all components) |
l |
0.4213 m | ball centre → body COM |
J_by |
4.161 kg·m² | body pitch inertia about ball centre |
M_k, r_k, J_k |
1.478 kg, 0.129 m, 15.4·10⁻³ kg·m² | ball |
J_w, r_w |
3.19·10⁻³ kg·m², 0.05 m | drivetrain at wheel axle |
τ_wheel,max |
1.9825 N·m | per-wheel torque after 13/3 gearbox |
The planar model collapses the three-omniwheel drive (45° zenith, 120° apart) into one equivalent pitch torque with an approximate ~5.4 N·m limit — the faithful 3-D actuator map is milestone M2.
Six milestones from this scaffold to a published classical-vs-learned comparison and an in-browser demo: ROADMAP.md.
- The thesis (2020, with Cristina Roche): quaternion dynamics, QUKF/VUKF estimators, cascade FLC — full report, MATLAB/Simulink models and our firmware/ROS patches at VBorjaDD/MasterThesis.
- The physical platform is the Kugle robot built at Aalborg University by Thomas Kølbæk Jespersen: Kugle-MATLAB · Kugle-Embedded · Kugle-ROS. All physical parameters used here trace back to that machine.
- ETH Zürich's Rezero and earlier AAU ballbot theses shaped the design space the thesis worked in.
MIT © 2026 Victor Borja. Thesis text and figures remain © 2020 their authors (Aalborg University student report).