Technical skills
Hover a card to see what each tool is for
Robotics middleware. I use it to architect communication between sensors, planning and actuators through nodes, topics and services.
My main language for prototyping, vision and control, with NumPy, OpenCV, PyTorch and rclpy.
Open-source PCB design, from schematics to routing and DRC checks. Every board I build goes through it.
Parametric CAD. I model parts, assemblies and drawings before printing or machining.
Multi-material additive manufacturing with soluble supports and mixed flexible/rigid parts. I go from model to working part in a day.
Motion planning under ROS 2, inverse kinematics and collision avoidance. Used to drive and simulate manipulator arms.
Real-time object detection. I train it on my own image sets for robotic vision.
Reprogrammable logic in VHDL, for parallel processing too fast for a standard microcontroller.
Component selection, trace routing, signal and power constraints. My Illumine board was routed end to end.
3D modelling, tolerances and assemblies. The foundation of every mechanical project before manufacturing starts.
Finite element analysis in Abaqus or Inventor Nastran. I validate a part's strength and study mesh convergence before producing it.
Real-time embedded programming on microcontrollers, when Python is too slow or too indirect.
Design
CAD, 3D modelling and structural optimisation
Prototyping
Multi-material 3D printing and rapid manufacturing
Development
Embedded code and robotics
The lab corner
Seven physics and AI simulations, written for the pleasure of watching equations move. Pull the sliders and watch.
Opens in a new tab, more comfortable on a computer.
Fluid in a paraboloid
A liquid simulated in real time inside a parabolic glass. Stir it with the mouse, click to splash, and tweak everything in the panel: viscosity (from water to honey), gravity, colour, particle count…
Under the hood
Under the surface, ~900 particles run an SPH simulation (Smoothed Particle Hydrodynamics, the “double density relaxation” scheme by Clavet et al., 2005): gravity, pairwise viscosity impulses, density relaxation with a dual pressure term (anti-clustering), all accelerated by a spatial hash grid, plus collisions projected onto the wall y = kx². Rendering then turns the particles into a continuous surface: a Gaussian density field (metaballs) thresholded in a GLSL shader that derives normals, refraction, specular highlights and Fresnel directly on the GPU.
Closed-loop magnetic levitation
A steel ball held in mid-air by a feedback-controlled electromagnet. Tune Kp, Ki and Kd live, poke the ball, change its mass or add sensor noise, and watch the response curve: the system settles, oscillates… or drops out.
Under the hood
A genuine mechatronics problem: the plant is open-loop unstable (the magnetic force F = C·(i/x)² grows as the ball gets closer). The simulation integrates m·ẍ = m·g − F at 480 Hz, with a first-order coil lag (L/R), current saturation, measurement noise and a filtered derivative. The PID controller works around the equilibrium current i_eq = x·√(mg/C), with integral-clamping anti-windup. The linearised analysis (stable iff Kp > i_eq/x₀ and Kd > 0) can be checked live with the presets.
Rayleigh-Bénard convection
A fluid layer heated from below and cooled from above: watch it organise into cells, then turbulent plumes. Heat or cool locally with the mouse, play with viscosity and heating power, and follow the dust carried along by the flow.
Under the hood
Two coupled lattice-Boltzmann grids: D2Q9 for the flow (BGK collision, no-slip top/bottom walls, periodic sides) and D2Q5 for temperature (advection-diffusion, fixed-temperature plates). The Boussinesq coupling injects a vertical buoyancy gβ·(T−T₀) into the collision equilibrium: beyond the critical threshold, pure conduction becomes unstable and convection cells appear. Tracers are advected by bilinear interpolation of the velocity field.
Mass-spring cloth in the wind
A flag flapping in turbulent wind. Grab it, pull on it (too hard and it tears), tune wind strength and direction, gravity, stiffness… and orbit around the 3D scene.
Under the hood
The cloth is a grid of particles linked by distance constraints (warp, weft, shear), integrated with Verlet then projected Position-Based-Dynamics style. The wind applies to each triangle an aerodynamic force F = n·(n·v_rel)·|v_rel|·k, where v_rel accounts for the cloth velocity, the flag flutter emerges by itself from this coupling. A constraint stretched beyond the threshold breaks and the adjacent triangles disappear: tears propagate naturally. Three.js rendering with per-frame recomputed normals.
Quarter-car suspension
One wheel, a spring, a damper and a quarter of a car body on a scrolling road. Tune stiffness and damping, switch road surface, throw in a pothole, and read the verdict: does the body filter the road? The “dead damper” preset is worth a try.
Under the hood
The classic 2-DOF quarter-car model: sprung mass (body) on spring ks + damper cs, unsprung mass (wheel) on tyre stiffness kt, equations written around static equilibrium and integrated semi-implicitly at 960 Hz (the tyre is stiff). The road profile scrolls under the wheel at the chosen speed: sinusoidal cobblestones, filtered value noise, Gaussian speed bumps, half-cosine potholes. Indicators are computed live: natural frequency f₀ = √(ks/ms)/2π, damping ratio ζ = cs/2√(ks·ms), and body-acceleration RMS as the comfort criterion.
Chaotic double pendulum
Two linked bars released together, plus a swarm of pale pendulums started a hair apart. Watch them stay merged, then diverge all at once. Grab the masses with the mouse, change lengths, masses and gravity, slow down time.
Under the hood
The double pendulum follows its full Lagrangian equations, integrated with a fourth-order Runge-Kutta scheme at 480 Hz. With no friction the energy is conserved, which the readout checks live (near-zero drift). It is a nonlinear Hamiltonian system, deterministic yet chaotic. About fifteen copies start less than a thousandth of a radian apart, and the gap between them grows exponentially, the signature of a positive Lyapunov exponent. The bottom graph plots that gap on a logarithmic scale, a rising straight line until the chaos has decorrelated everything.
Metronomes that synchronize
Five metronomes started at random rates on one board resting on rollers. Without touching anything, they end up ticking together. Lock the board and they go independent again, detune them and the synchronization breaks.
Under the hood
Each metronome is a pendulum kept going by an escapement, modelled Pantaleone-style with a Van der Pol term that sets the tick amplitude. The only coupling runs through the moving board: when one arm pushes one way, the board recoils and drags all the others along. The N arms and the board form one system of equations solved explicitly, then integrated with Runge-Kutta 4 at 480 Hz. From arbitrary phases, the whole set converges to a common beat, measured by the Kuramoto order parameter r (from 0, disorder, to 1, synchronization), plotted live.