Saturday, February 11, 2017

The math behind the vertical plotter

Many people are asking after the math behind the rope plotter. I used only second grade high school math to do it. Here's how it works. 

Target motor positions

For all calculations I am using a coordinate system with the top left of the door as (0,0) and with cm as units. So the top right of the door is (90,0). The positive y-axis is pointing down so I have only positive numbers. The first goal is now to calculate the correct lengths of the ropes L and R in terms of the coordinates (x,y) of the target location for the robot. For this you can use Pythagoras. The left rope is the easiest: there is a triangle with sides x,y and L where `L = (x**2 + y**2)**0.5` (In python the double asterisk means a power). The right rope is also part of a triangle. This triangle has y, 90-x and R as sides. Therefore `R = ( (90-x)**2 + y**2 )**0.5`. Now that we have the target lengths we have to calculate the degrees the motor has to rotate to reach our desired coordinate. The diameter of the bush is about 0,9 cm. A complete 360 degree rotation results therefore in a 0,6 cm * 3,14 change in length. That is about 170 degrees of rotation to move one centimeter. I mounted the motors so that forward rotation is upwards. Therefore the motor target for the left motor is L * -170, the right target is R * -170. 

Navigating the drawing canvas

Now we have a formula to navigate the complete door. But what we really want is to navigate a piece of paper in the middle of the door. I wanted the robot to be usable independently of the space between the attachment points or the size of the paper. Therefore I defined a second coordinate system that has (0,0) in the top left of the paper and is normalised. This means all coordinates are between 0 and 1. This coordinate system is easy to scale on different plotting surfaces and paper sizes. It works like this: let m be the margin left of the paper, n be the margin on top and C the with of the canvas. The coordinates (x,y) in terms of the normalised coordinates (u,v) become simply: `x = C * u + m` and `y = C * v + n`.

At this point it's simply a matter of reading two files, x.rtf and y.rtf with normalised coordinates and moving the robot towards each of these coordinates. 

Ev3 program

You can also download the Lego Mindstorms Ev3 program to see the details. The ev3 main program expects 2 rtf files (robot text files), on named x.rtf and the other y.rtf. Both contain target coordinates. x.rtf has the number of coordinates as it's first line. Note that you can't open these files with a Rich Text File editor!

All the stupid mistakes I made when building 3nsor, the vertical plotter

After long nights of hard work I finally have vertical plotter that makes recognisable illustrations! In this article I'm sharing all the trouble I ran into. There's als an LDD file, 3nsor.lxf, for this 5th generation.

Mistake 1: the wrong spindle

My first hunch was to use a large spindle, so the relative increase in diameter with a layer of cord would be minimal. A varying diameter makes the math a lot more complicated.  The second spindle looked best because it had the smoothest surface. The others had all kinds of ribs. I made several generations with the second spindle. The problem was, though that the motor had to push a really big load. Because, with the spindle diameter, the lever length and thus the torque increases. So I had to add two gears to increase the force. Also, when just using the large spindles without the gears, the internal motor inertia is not enough to keep the robot in place on the vertical surface. It would slowly uncoil and descend. Another problem with that spindle was, that it wasn't part of the original 31313 set. So I went and looked for a smaller spindle. The simple red bush proved to be the solution, but only after I found the right thread...

Mistake 2: the wrong cord

I tried many different cords. I was looking for thin and strong, because a thick thread makes the diameter of the spool change a lot when it's rolled up. As I was counting degrees for movement, this would mean a bad distortion of the drawing. The first thread (the brown) was nice and thin, but broke after 3 drawings. It nearly cost me my brick. The second one, thick white was stronger, but so hard that it dented the soft lego parts and so thick that I had to use a big spool to avoid the change in diameter. This in turn required a gearbox which was imprecise and lossy. Only after a year of failed experiments I had the idea of using dental flos. Thin, strong, cheap, and not all too elastic. A little elastic is ok, as the increased length of the thread, due to stretch would compensate for the increased diameter on the spool.

Mistake 3: running the program from the command line

During development I was coding on my laptop while the robot was drawing. After some time, though, when the robot was running stable I closed my laptop and went to other stuff while the robot was drawing. That was a bad idea. Because I was coding on ev3dev, I ran the program from the command line. And Linux terminates programs run from the command line if the command line gets a time-out. The result was that the program stopped in the middle of a drawing. And when an ev3dev program stops, the motors keep running at the speed they are set to, they don't stop automatically. This resulted in the robot driving all the way up to the top right corner of the door, making a hard-to-clean sharpie stain and then being catapulted all the way to the left on the floor. I was really lucky that it landed on relatively thick rug...

Mistake 4: Putting the pen way below the point where the cords meet

I thought gravity would keep the pen in position but I forgot about impulse. A pen down below gave really imprecise and wobbly lines. That was cool for the very first experiment. It even made my beard look better. But ultimately it was a bad idea.