mike moore
Projects / Inverted pendulum

Inverted pendulum

An arm on my desk that swings itself upright and balances there. One motor, no hands. The next one has two arms and still only one motor.

active Aug 2026 – now simulation and bench
Render
source the rig's CADmotion recorded run
The rig on my desk. Rendered from the CAD and posed from a recorded run. The page follows the theme, day or night.

The problem

Hang a pendulum below its pivot and it looks after itself: push it, and gravity brings it back. Stand the same arm above its pivot and gravity does the opposite — the further it leans, the harder it is pulled over. Only which side of the pivot it is on has changed.

One link, driven at the shoulder — θ measured from hanging

$$I\ddot{\theta} = \tau - b\dot{\theta} - mgL\sin\theta$$

Two places it can sit still — only one of them stays

$$\sin\theta = 0 \;\Rightarrow\; \theta = 0 \;\text{(hanging)} \quad\text{or}\quad \theta = \pi \;\text{(upright)}$$

So the motor has to notice a lean and undo it faster than that runs away. Mine reads the angle and decides 200 times a second. The sensor, the loop rate, the friction I keep re-measuring — all of it serves that race.

In simulation first

I do not know the machine exactly — some numbers are measured, some estimated. So I simulate a few hundred versions of it and ask how many stay up. A controller that only works on the machine I assumed is no use.

Fig. 1
sim 100 machinesbench 10 runs0 hanging · 180 upright
Getting up there. Angle measured from rest, so nothing wraps: 0 is hanging, 180 is straight up. The arm swings a little, comes back further, and on the third try has enough to go over. Blue is a hundred plausible versions of the rig; orange is ten runs of the actual bench. The width of the blue band is what not knowing the machine exactly costs.

Then on the bench

The same app drives the simulator and the real rig, and the corner tells you which. Telling those two apart is most of what I write about.

Film
screen Showsource simseed 20260828
Holding it there, and asking for something else. This is the Show screen — the one between Calm and Health, and the only place the lean and the motor current run live side by side. The arm is balancing; I ask it to sway, the aim line pulls away from the arm, and the current goes to work keeping up. The corner reads SOURCE SIM, so this is the simulator; the same screen drives the rig.

What I wrote about it

Newest last, which is roughly the order the work happened in. More will follow as the second arm gets built and measured.

What’s next: a second arm

Add a second arm, hinged onto the first, with no motor at the new joint. The shoulder must swing both up and hold them there through a joint it cannot push on.

Render
source the rig's CADmotion simulated runelbow 95 µN·m
Two arms, one motor. A simulated run, rendered from the CAD of the rig I am building. The second arm does not exist yet.

Two links, one input — B selects the shoulder alone

$$M(q)\,\ddot{q} + C(q,\dot{q})\,\dot{q} + g(q) = B\,u$$ $$B = \begin{bmatrix} 1 \\ 0 \end{bmatrix}$$

The plan: linearize about upright and solve for the gains

$$A^{\top}P + PA - PBR^{-1}B^{\top}P + Q = 0$$ $$K = R^{-1}B^{\top}P$$

Not built yet

Those gains are only as good as the numbers inside A and B, which come from a plant model I am still calibrating. Solving it now would return confident, plausible, wrong answers.