this is just a quick update on the Bezier-motor-control engine. I worked the last days pretty much all of my free time on the new “core” system and can say that it is more or less done. I now can define moves based one Bézier curves – or in other words by defining 4 points (2-dimensional: time; position) per curve. The engine is then processing the data to a list of linear segments (based on linear functions). So every curve becomes 200 linear segments. To get a smooth move, I developed an algorithm, that uses a finer granularity where the curve bends the most. In the picture below you can see the segmentation (in this case 100 segments):
Every motor-movement in the next version will be based on this new methodology as it allows detailed planning of the motors position in time. I even allows to get information about the speed of the motors at any time. On top of that is the motor movement much smoother as it was with the old delay-based engine. It also allows much greater speeds. I was able to move my dolly along my 100 cm (4 foot) track (this one) in 6 seconds with nice speed-ramping on both sides.
Because the DUE is fast enough and the motor position calculation is based on an easy linear function, there should be plenty of processing power for doing all this for 2 motors simultaneously. Right now there are approx. 0.05 motors steps done per processing loop. This means that the DUE only needs to step the motor every 20 processing loops. [Edit: Running 2 different curves with 2 motors simultaneously is tested and working perfectly.]
The only drawback is that this new control-methodology is making extensive use of the 96kb RAM that that the Arduino DUE has to offer. One of the curves with its 200 linear sub-segments is taking 2400 bytes of RAM. That means that in theory 40 of these curves can be stored in the DUE’s memory. Because the systems itself needs some of the memory too, lets say that 20-25 curves can be stored. I think that this is a good amount to design some pretty complex video-moves. Here is another example of how such a move can look like:
It consists of 3 curves and here is the actual source-code to define such a move by hand:
// x coordinate = time in ms
// y coordinate = motor position in cm
curve.p0 = Point( 0, 0);
curve.p1 = Point( 6000, 0);
curve.p2 = Point( 10000, 50);
curve.p3 = Point( 20000, 50);
curve.p0 = Point( 20000, 50);
curve.p1 = Point( 30000, 50);
curve.p2 = Point( 31000, 35);
curve.p3 = Point( 40000, 35);
curve.p0 = Point( 40000, 35);
curve.p1 = Point( 51000, 35);
curve.p2 = Point( 51000, 100);
curve.p3 = Point( 70000, 100);
The cool thing is that I can read the motor position for any time I want. This will end up in a feature to kind of fast preview the programmed move – for example with 16x speed.
I guess I need a good user interface for editing these curves on the system now!