The goal here was basically to turn an off the shelf head massager into an automated device that would massage my head for me. The very initial concept was just to use a linear actuator or a single stepper motor with threaded rod to create an up and down motion. However, I got carried away and wanted the device to move in all directions. For that reason I chose to use a Stewart-Gough Platform offering 6DOF.
- Is this over-engineered? YES!
- Was this expensive? YES!
- Am I an idiot? YES!
All software and hardware files are available on GitHub:
A simple idea to take an existing head scratcher that can be bought for £10 or less from pretty much anywhere and turn it into an automated device that could move freely in any direction…
Inspirations and examples.
Shown here are some of the sources which proved most helpful when learning to implement a Stewart Platform.
Inverse kinematics notes.
Below is essentially a collection of notes and diagrams I made to understand the basic concepts of using inverse kinematics to control different types of robotic platforms. These platforms have been around for decades and used in many different applications (industrial robots, aerospace simulators, theme-park rides, etc.). I opted not to use linear actuators to build a Stewart Platform since small linear actuators pretty much don’t exist, instead using the slightly more convoluted method of using motors to convert rotary motion into linear motion.
Based on the first couple of inspirations I also decided to use some addressable servo motors from Robotis – the Dynamixel AX-12A. These servos can be daisy-chained together, meaning that multiple motors can be controlled with only 3 wires from the MCU (data, power & ground). There are also a number of existing libraries available which meant getting up and running would be quick and painless.
The AX-12A servos talk over UART but I needed to keep the serial debug port open during development. So I bought a simple, cheap UART converter to connect between my PC and spare UART pins of a spare Mega2560 (which has 4 serial ports).
Each individual motor can be programmed with a unique ID number. Then, when multiple motors are daisy-chained together, we can talk to each specific motor using only a single UART TX pin. The required data packets are relatively small frames so if using a high baud rate latencies are decent even when talking to 6 motors using the same serial line.
Basic physical design.
Using MS Visio I drew out the basic layout for all 6 servo motors required for a Stewart Platform. After several iterations I settled on the measurements shown in the accompanying image, with each servo using an arm of 32mm in length which is not shown. This version allowed for a relatively compact form factor with enough space to realise great range of motion.
In order to determine the correct values to be used within the Forward Kinematics formula the angles must be ascertained for each servo arm position, as well as the overall base measurements. At this stage all values are still theoretical within MS Visio, with real values being measured from the actual HW once built. For now though this is enough to construct a working model and simulator.
Using Processing Software and starting with the base provided by Radames Ajna & Thiago Hersan I was able to generate a working mathematical model for all of the moving parts and joints.
As part of the Processing application I also added a serial connection between the model and the MCU. This would allow me to use the sim model to control the real platform. When the simulated model moves, the platform moves to match.
Lastly, I added some function buttons which would run the platform in various different modes of operation.
Servo arm design.
Very basic design made in Fusion 360 based on simple measurements taken from the servo chassis. The multiple M3 holes are simply to reduce material but also offer some scope for trying different rod mounting positions. Very quick and easy to print multiple of these.
Base design – CAD to real.
After I understood the math and was happy with the basic layout I proceeded with CAD design.
Thankfully there are ready-made 3D models for all of the Dynamixel motors provided by Robotis which can be taken from here.
It was then a case of importing the servo models, recreating the initial base from MS Visio inside of Fusion 360 and mounting each servo based on the initially calculated angles as best as possible.
Thankfully each AX-12A motor comes with their own individual mounting bracket (FP04-03) which I simply screwed directly into the base. The files for these brackets are public so more can be 3D printed if/when needed.
Angles from real hardware.
To program the algorithm with the correct values required based on the actual hardware, the first step was to find the exact centre point of the base platform. Easily done with a ruler and pencil.
The next step is just as simple; taking a protractor and determining the precise angle from the centre point of the base platform to the centre point of each servo’s rotation point.
Unless all hardware has been placed by a machine, the angles will not be a perfect match with the initial theoretical values so this is an important step to ensure accurate control.
Connecting base to platform.
Rod bearings were added, providing a strong connection between the bottom base plate and the top platform – linked via a metal rod. The bearings also allow for flexible movements so that the platform can move freely. At the extreme end, the rod can move inwards by around 40 degrees.
Basic top platform.
To begin testing a real working platform I put together an upper platform for the rods to connect to – very simple design to save material and is ~33% smaller than the bottom base in diameter. It includes some protruded stilts for attaching the other end of the rod bearings as shown. Also important here to note the angles from the centre to each connection point.
To properly control daisy-chained DYNAMIXEL AX-12A motors, the MCU needs to convert its UART signals to half duplex. To enable correct TTL communications I followed the suggested circuit provided by Robotis, which adds a tri-state buffer and some passive components.
The full working prototype hardware setup is ultimately very simple.
Putting everything together and running some of the basic test modes I created.
Visible from the gif here you can see that the control is being done from within the Processing window where the simulation is running. Commands are then passed to the Mega2560 which is controlling the 6 servo motors to mimic exactly what is seen on the screen.
The correlation is not a 100% perfect match but all of the movements are extremely fluid and smooth.
(I had moved back to breadboard here so that I could probe some extra signal paths)
The first image at the top shows basically an extreme worst case scenario which is important to consider. This is using vertical SHM and everything is set to maximum speed. With this, the platform has maximum momentum at the top and bottom hence the motors are working at max effort to change direction every time. This results in current draw exceeding 4A during each “loop”, with RMS being around 1.2A.
The second image is showing a more realistic current draw from the system from a normal use-case. The initial movement of the six stationary motors peaks at around 2A then settles to around ~1A peak during the vertical SHM test loop running at slower speed. The RMS is actually 800mA which is great.
I wanted the option to move away from my bench power supply, whilst also ensuring that this build would be portable – so I opted for battery power rather than adding a plug for the mains.
For this I connected up a Sunpadow 11.1V, 2250mAh LiPo. It supplies the peak current for normal use-cases when required and is small enough that it could be contained within the current size of the platform’s frame.
Note: when fully charged a 11.1V LiPo will actually be 12.6V which exceeds the voltage range given by Robotis for the AX-12A motors. However, looking deeper is seems the max voltage is actually more like 16V according to some registers, so I didn’t bother to add any regulators.
As always a basic initial test was done on a breadboard, then the veroboard shown previously was used for the majority of the development and testing of the system. Moving forward though, the veroboard was too messy and I needed a cleaner board to reduce noise and allow allow me to easily connect the battery supply. For this I decided just to make a custom PCB shield for the Mega2560. All design work was done using KiCAD and I ordered 5 boards from JLCPCB for just $2!!! (not including shipment from China to UK). Everything was pretty standard here with the exception of a custom made part and footprint for the DC-DC converter I wanted to use.
Mistakes were made.
I knew that the clearance above the USB and power connectors of the Mega2560 below would be very tight, since I placed the battery connector, switch and motor connector right above them. However I just assumed that the shield stacking pins would allow enough space – without even checking! Woops. Some pins were even touching the outer USB casing so I had to fix this.
In an attempt to make-do with the existing PCBs and workaround this, I took the power connector off as shown in the images, then was about to take the USB connector off (and wire it back to the board…) before I took the lazy way out and double-stacked the shield stacking pins 😅 which will do for now!
Mount and bracket.
With a working prototype and working PCBs, it was time to further develop the existing base design, creating a suitable mount and bracket for the final prototype.
This consisted of a) build out the “underside” of the base to include a holder for the battery and PCBs, and b) create a slide-able bracket which could easily connect to the base, was able to screw to any wall and was strong enough to take the weight of all the entire build.
The blue and yellow bodies shown were printed with a nominal 20%. The red body on the other hand was printed with 60% cubic infill for a blend of strength and flexibility.
Printed off six new brackets (FP04-F3) using the same coloured filament as the base and attached them with some M2 screws.
I then re-connected all of the AX-12A motors to this new base – again using M2 screws to fix all of the motors into a bracket. At this stage everything is now connected firmly in place and the build can operate upside down when attached to the mounting bracket.
Here the mount has been placed on some 3mm MDF wood and the base has been slid into position on the mount. Everything is connected together and ready for final prototype testing, showing the Mega2560 screwed into the base with the custom PCBs attached on top.
Since the build was not moving from my desk I opted not to waste time charging batteries and shown here I am connected back to the bench power supply. I am also still connecting the Mega2560 back to the PC for debug.
Most important piece.
I designed another simple platform attachment, this time with some added spokes which hold a through-hole for my existing head massager. There’s also a small insert for a screw which will hold the massager in place once set.
These platform attachments are extremely easy to make and take very little time to print. The idea is that new versions can be created for a variety of different attachments…
They are also light and thin enough that you can hold them on with clips, rather than having to unscrew and re-screw all of the rod attachments each time.
Fully mounted with the head-massager platform connected! Shown here with my lovely assistant Baldy Barbra. I used Barbra as a test vehicle for developing various modes to ensure that everything was comfortable and safe for use. Some of those modes are show in the gif gallery below!
If you would rather see these within a short video, you can watch here.
(Note that the USB cable was still connected during these tests for debug purposes)
Most things were cheap, with the prominent exception of the servo motors. Since the time of purchase the price has also increased by almost 50%. Thankfully the plan was always to re-use these motors for prototyping other projects. Nevertheless, I wouldn’t recommend buying until they come back down in price.
|Item||Single Cost||Quantity||Links||Total Cost|
|Dynamixel AX-12A Servo Motor||£43.60||6||LINK||£261.60|
|Rod Ball Bearings Pack||£3.91||2||LINK||£7.82|
|Custom PCBs from JLCPCB||£2||1||LINK||£2|
Potential future improvements…
If I was ever to create a revision 2.0 here are some things that I would address:
- Smaller form factor. The motors could be placed much closer together with shorter arms, losing some range of motion but creating a smaller device which takes up less space and is lighter
- Smaller MCU. I would probably move from the Mega2560 to an ESP32. Which would have the following benefits; smaller, faster processor, inherently enables WiFi (or Bluetooth), more memory, and is cheaper.
- Run all math on MCU. Right now, I kept all math is running on PC! The Mega2560 is currently not doing much at all. The plan would be to completely remove the need for PC and instead run everything on the MCU. The thought is that I would also run a small web server on the MCU so that I could control the device with only my phone – not use UART like is done above.
- Different motors. The daisy-chain operation of the AX-12A servos was too good to pass up and saved a lot of time. However servos in general are very noisy and the AX-12As are no exception here. They are also very pricey and overkill for this specific application. Ideally I’d find cheaper alternatives, at the cost of more complex HW & SW.
- Build full enclosure. Sticking with servos means doing anything possible to reduce the noise. A simple way it so create an enclosure which contains the bodies of the motors – also creating a much cleaner looking final product.
- Proper power circuitry. Circuitry used on the PCBs was just done the lazy way – I would need update design with fuses and regulators for a “final” version.
- Add “find head” function. Picturing this device placed permanently on a wall, it would be greatly improved if able to move into the correct position based on a person’s height. Some rails, a small stepper motor and an ultrasonic sensor would do the trick.
- Test with other hairstyles!
3 responses to “Stewart Platform Head Massager”
[…] Those cheap wire-arm head massagers are great at giving your scalp a nice, relaxing rub. But they’re handheld implements that force the user to either manipulate the massager themselves or talk a partner into performing the task. David McDaid decided that the experience would be much more pleasant if a robot took care of the hard work, so he built this Stewart platform head massager. […]
LikeLiked by 1 person
Bravo! I’ve benefited from self administered scalp massages forever. If this well engineered machine delivers an invigorating massage-AND without pulling out any hair regardless of hair shaft lengths-it may have great commercial value. Good luck!
LikeLiked by 1 person
Thank you! And excellent point – I would certainly need to test this out with varying hairstyles – something else for me to add to the future work list.