I made two small circuits today for temperature control of the extruder head on a reprap type 3D printer. The idea is to control the temperature, which needs to be somewhere between 200 and 240 C I think, using EMC2 and two parallel port pins.
The first circuit is based on the 555 and produces a square waveform with variable frequency depending on the resistance of a thermistor. At room temperature the thermistor resistance is 100 kOhms and the output frequency is below 1 Hz, and when the temperature is suitable for extrusion the thermistor resistance is about 200 Ohms which produces an output frequency of around 25-30 Hz. If the EMC2 base-thread runs with a 50 us period then it should be possible to record the frequency of this square wave using an input pin on the parallel port with an accuracy of roughly 1/500 (half a degree C?), which should suffice.
Testing the heating side of things, a wire with about 6 ohms of resistance wrapped around the extruding head, showed that a suitable DC voltage is around 8 V and produces a current of 1.3 A. The idea is to use a HAL PWM-generator to drive the base of a 337 transistor which drives the gate of an IRF610 FET that controls the current through the heating wire. By adjusting the PWM duty cycle it should be possible to control the temperature using a PID controller based on the temperature measurement.
The algorithm works by incrementally constructing the diagram while adding the point-generators one by one. This initial configuration is used at the beginning:
The diagram will be correct if new generator points are placed inside the orange circle (this way we avoid edges that extend to infinity). Once about 500 randomly chosen points are added the diagram looks like this:
Because of floating-point errors it gets harder to construct the correct diagram when more and more points are added. My code now crashes at slightly more than 500 generators (due to an assert() that fails, not a segfault - yay!). It boils down to calculating the sign of a 4-by-4 determinant, which due to floating-point error goes wrong at some point. That's why the Sugihara-Iri algorithm is based on strictly preserving the correct topology of the diagram, and in fact they show in their papers that their algorithm doesn't crash when a random error is added to the determinant-calculations, and it even works (in some sense) when the determinant calculation is completely replaced by a random number generator. Their 1992 paper constructs the diagram for one million generators using 32-bit float
numbers, while my naive attempt using double here crashes after 535 points... some work to do still then!
Note how within one voronoi-region the offset is determined by the associated generator (a line, point, or arc). It's very easy to figure out the offset within one region: points and arcs have circular offsets, while lines have line offsets. The complete offset path is a result of connecting the offset from one region with the next region.
I've run actively this year from week 13, which means 34 weeks of running/jogging so far. Or an average of 29.56km per week. Weeks 15, 19, and 37 were the low points with only 5-6 km completed (week 37 I had a fever). Week 29 (55k total) is one of the most active with a 24k long run(in central park, IIRC) in the beginning of the week, some short runs in the middle, and the Jakob half-marathon on the weekend.
At 30km/week the total should land on roughly 1200 km for this year.
There's some peer pressure on signing up for the Finlandia langlauf in February... we'll see if that happens or not.
Legs still feel a bit heavy from Sunday. This week is supposed to be a lot easier than last week, and next week is just light jogging before the D-day...
There was an uphill about 2/3rds into the last repeat which causes a jump in the HR-trace.
Previously the flat() predicate looked only at the number of intervals contained in a fiber when deciding where to insert new fibers in the adaptive waterline algorithm. Here I've borrowed the same flat() function used in adaptive drop-cutter which computes the angle between subsequent line-segments(yellow), and inserts a new fiber(cyan) if the angle exceeds some pre-set threshold.
This works on the larger Tux model also. However, there's no free lunch: the uniformly sampled waterline (yellow) runs in about 2 s (using OpenMP on a dual-core machine), while the adaptively sampled waterline takes around 30s to compute (no OpenMP).
The difference between the adaptive (red) and the uniformly sampled (yellow) waterlines is really only visible when zooming in on sharp corners or other details. Compare this to adaptive drop-cutter.
I've upgraded Ubuntu and EMC2 on the Atom 330 machine I have for controlling the lathe. The Atom 330 is a dual-core chip, but with Hyper Threading the OS can see four cores. That's not good for real-time performance, so the first thing I did was turn off HT from the BIOS. Next I did a distribution upgrade to 10.04LTS which downloaded about 1 Gig in an estimated 9 minutes (2Mb/s is OK I guess...). I then used the emc2-install script which installs the real-time kernel and emc2, and finally I edited /boot/grub/menu.lst by adding "isolcpus=1" on the kernel line. This reserves one cpu core for real-time and the other for non-real-time tasks. Without "isolcpus=1" the latency-test jitter values were easily 10k and more with a light load on the machine. With one core dedicated to real-time the jitter numbers start out at around 4k at light load and double to 7-8k under heavy load.
Here are some selected screenshots:
Next stop is getting the X and Z servos moving, as well as the hefty 2 kW spindle servo.
With finite precision numbers, if you take a small number eps, there comes a point when x == x + eps. Here's some code that figures out when that happens:
double epsD(double x){double r;
r =1000.0;while( x <(x + r))
r = r /2.0;return(2.0* r );}
double epsD(double x) {
double r;
r = 1000.0;
while ( x < (x + r) )
r = r / 2.0;
return ( 2.0 * r );
}
With x around one the resolution limit is roughly at 1e-16 for doubles, and 1e-7 for floats. The top data points show how the relative accuracy stays constant, so at x=1e7 the resolution is only about eps=1 for floats.
Thinking about CAD/CAM related stuff, if you have a fancy top of the line CNC-machine with the longest axis x=1000mm and a theoretical accuracy of one micron, or 0.001mm, then we're at the point where we really should use doubles (which are slower, but how much slower?).
I was trying to work on a new adaptive waterline feature, but ended up uncovering an old existing problem/bug with waterline. I think it has to be a problem in either building the weave from the fibers, or constructing the planar embedding of the weave.
The yellow waterline should obviously be a smooth loop around the outside of the weave (red/green fibers) and not a zigzag journey back and forth... 🙁
Update: this is better now:
Update2: here's a figure where new fibers (red and green) are inserted adaptively where the shape of the waterline changes most. There's something wrong with building the planar embedding for this weave, so no yellow adaptive waterline path yet...
Update3: some progress at last (fixed a bug in adaptive drop-cutter at the same time):