Self-Leveling Table: MkII

I finally got around to starting on a new version of the self-leveling table. This version is a much better design off the bat (more similar to other designs that are out there).  There are quite a few difference between this table and the last one, so it’s pretty much a new design, but it follows pretty much the same idea of the last table: Keep the table top level.

For this table, I’m using almost all 3D printed parts (with threaded inserts) and an Arduino 101 instead of an Uno+Accelerometer.  The 101 is nice because it’s faster than an Uno and has a built-in IMU to give me table position data.

This is “Part 1” of the table, where it only uses 3 servos and the “feet” need to slide along the table to actuate.  “Part 2” of the table will have 3 more motors connecting the first 3 legs to a fixed base.  Part 1 is to work out a lot of the kinks and see if anything needs to be changed for Part 2.

For the control loop on the table for now, I’m using only accelerometer data from the 101’s IMU and a median filter to try to sooth the noise.  Unfortunately, the servos are being pretty jittery and introducing a lot of noise into my accelerometer reading, so I’m going to need to start experimenting with some different filtering options.  I’m running pretty much an “I” controller, where I just add the accelerometer data multiplied by a scaling factor (kI) to the current commanded angle of the servo.  I also have an interesting second loop where I have a desired steady-state position of each servo.  If I don’t add the state-feedback of the current position of each leg, the table will level itself, but the motors will be spread very far.  Including the state-feedback and desired steady-state angle of the table legs makes the table stand up nice and tall once it’s leveled

I’ve converted my coordinate system to a sort of “Hexagonal” coordinate system with 4 axes: “e1, e2, e3, and z.”  e1 acts along Cartesian x, e2 and e3 are 120° rotated from e1, in order to have 3 unit vectors spanning a flat plane, with each vector lined up with a motor on the table, and then z acts along Cartesian z.  I was hoping that this would simplify the control loop a bit.  Right now, each servo only acts on one axis of the new coordinate system as if the 3 different axes are independent.  The 3 axes aren’t actually fully independent, but for initial testing, it works well enough.

Cartesian Coordinates:

“Hexagonal” Coordinates:

Eventually, I want to do full forward-kinematics of the table, but not at the moment.

I ran some tests holding two motors steady while sweeping the third.  Here’s a quick video of that:

I logged the acceleration along the three axes: e1, e2, and e3.  As you can see, the three axes are not fully independent (I’m using 4 axes to plot a 3-dimensional space, so this is expected)

I also added a basic low-pass filter: where is the acceleration of each axis, and is a filtering constant (set to 0.075 for these tests).


I’m not really happy with how noisy the signal is, even after this major filtering.  Something else you can notice in the video is how stutter-y the sweeping motor is as it extends out.  This can be seen in the accelerometer data plot, as well.

My next plan of action will be to complete the full 6-motor design so the table does not need to rely on sliding to level itself


I think I’ve finished the full 6-motor design.


The main question I have right now is how I’m going to make the ball and socket joints with the 3D printer. I’m worried that they won’t slide nicely in each other.

Also, I need some sort of split-cup in order to be able to pop the ball into the socket, and I’m worried about that edge catching on the ball. I made the ball and socket parts modular, so I can quickly print multiple options without needing to re-design the table.

At the moment, my 3D printer is not working, so I won’t be able to do much work until I get that working again.