LevSim is the simulation environment I built so levitation controllers can be designed and tuned against the rig's real magnetic behaviour — not a hand-derived model that falls apart on contact with hardware.
- Role
- CAD · All Software Architecture + Implementation · Ansys work guided by Aditya Matam & Neha Ramachandran
- Timeline
- Nov – Dec 2025
- Stack
- Ansys Electronics Desktop · SciKit-Learn · PyBullet · Gymnasium
- Status
- Functional prototype
The problem
Hybrid electromagnetic suspension (HEMS) is a proven low-power way to levitate, but it's brutally nonlinear — and for a student team there's no clean way to simulate one without re-deriving the magnetic flux through the whole structure (and the air around it) for every design change. At best that's tedious; at worst it's a wall that keeps teams without graduate-level magnetostatics from ever touching the control problem.
After two years on the lev sub-team I'd watched the same gap open again and again: controllers that held rock-steady in our MATLAB sim under any disturbance fell apart on the real rig under near-perfect conditions. We were missing a fundamental piece of the analytical model, and MATLAB wasn't scaling past PID anyway. The fix was to stop hand-calculating forces and root the simulation in empirical data instead — Ansys FEA (verified against load-cell measurements) → a polynomial force model → a PyBullet rigid-body sim.
System overview
Lev_pod_env.py ⇄
PyBullet) queries every step while a controller drives the pod. Redrawn from the project's
dataflow diagram.The pipeline splits in two. Offline, an Ansys magnetostatic model of a single yoke is
swept across the coil currents, gap heights and roll angles the rig actually sees; the resulting
force/torque table is fit to a polynomial (Maglev_Model.pkl) so it can be evaluated
in microseconds. At run time, Lev_pod_env.py is the orchestrator: each step it
pulls the pod's state from PyBullet, converts the controller's analog output into real coil
currents with maglev_coil.py, asks the MagLev Predictor for the per-yoke force and
torque, and feeds those point loads back into PyBullet — all wrapped in a Gymnasium interface so
any controller can drive it.
Decisions & deep dives
Why FEA, not an analytical model?
I first proved FEA was trustworthy: a load-cell setup measured the force on a single small yoke, and Ansys magnetostatic results at the same gaps agreed within ~10%. That made an FEA-derived lookup a reliable replacement for the broken analytical chain.
Why a polynomial on top of FEA?
Running Ansys inside the sim loop is infeasible. A parametric sweep across the rig's working
range of heights, roll angles and coil currents gives a discrete table; fitting it in
SciKit-Learn (lev_sim/Function Fitting.ipynb) turns each step into a cheap
polynomial evaluation — and makes the pipeline plug-and-play for new yoke designs.
Why PyBullet + Gymnasium?
PyBullet handles the rigid-body dynamics; a custom maglev_coil component models
coil current (including inductive impedance) so the force model gets real currents. Our
LUT-fit polynomial model ensures we have FEA-backed force and torque driving our simulation, and
Gymnasium standardizes the interface, so the same environment runs under PID
(lev_PID) or RL (lev_PPO).
How do you reuse it across controllers?
lev_pod_env.py exposes exactly the I/O a controller sees on the real pod —
distance-sensor readings in, motor-controller PWM out — so anything written against the sim
can move straight onto the rig with no interface changes.
Results & honest limits
- A repeatable simulation process that works for complex systems like maglev, grounded in FEA data and tested with both a hand-tuned PID loop and a trained PPO policy.
- The force model is only as good as the swept range — extrapolate far outside it and the polynomial is unreliable.
- It's a functional prototype: the coil model is a simplification, and fully closing the sim-to-real gap still requires tuning runs on the physical rig, though our starting point improves considerably.
The team