repetier / Repetier-Firmware

Firmware for Arduino based RepRap 3D printer.
811 stars 734 forks source link

Delta calculations overflow possible with large printer dimensions #104

Open extin opened 11 years ago

extin commented 11 years ago

I have a delta printer that has DELTA_DIAGONAL_ROD of 470 mm and I'm using 400 step/rev steppers. Delta calculations overflow if I set microstepping to 16. I'm using filament drive with 18 mm pulley.

https://github.com/repetier/Repetier-Firmware/blob/master/Repetier/motion.cpp#L964 calculate_delta uses signed long which gives a max of +-2,147,483,647. Calculating DELTA_DIAGONAL_ROD_STEP_SQUARED gives ((400 * 16)/(18 * 3.1415927) * 470)^2 = 2,829,507,803 -> which overflows a signed long.

repetier commented 11 years ago

These are bad news. For that function you are absolutely right and it must get rewritten using floats to prevent such problems, which makes it hopefully not too slow.

The other question that arises is, if there are other places that might overflow as well. I will have a look at it when I rewrite the 0.90 code. I let you know when I think the version should work with your distances, so you could verify it works in practice.

polygonhell commented 11 years ago

If you rewrite that with floats you'll likely lose more precision than just dropping down to 8x micro stepping. Floats can only accurately represent 24 bits of mantissa, so you'd be losing 8 bits of precision on a printer of that size. I haven't looked at the code in question to see how it's used, but you'd probably be better off scaling the computation and trying to lose the minimum number of bits.

kyrreaa commented 11 years ago

Filament drive with that kind of attempted accuracy is a bit over the top isn't it? The slop in the filament will be many many times the microstep precision and then there's the whole rod-linkage thing.

Anyway, new compiler support for int64_t is in isn't it? So, why not make a config param for LARGE_MACHINE or something and if defined, use "long long" in calculations. (You'd probably have to be a tad clever if you need to take sqrt or such on the long long...)

Untill it's in I'd just drop to 8 microsteps, you won't notice the difference.

extin commented 11 years ago

Resolution vise it's not a problem to use 8x microstepping. I'm happy with the current resolution as it is. Just thought I'd report the issue should someone else have the issue and not understand what is happening.

Using double for the delta calculations would be over the top for most users and would possibly slow things down too much. Perhaps the calculations can be made in a different order without losing precision.

kyrreaa commented 11 years ago

Turns out I too get into this piccle. My new machine is only scaled up to 200mm radius instead of 175mm but the stepper drivers are A4982 and only full/half/quarter and 1/16 microsteps is available. The fact that I moved to 400 step/turn motors did not make things better.

The step speed is clearly being influenced by serial communications and it seems to do some odd moves now and then too.

Smoothly working machine had 1/8 microstep and 200 steps/turn so in essence this machine has 4x the apparant step resolution. That, coupled with attempts of running at 350mm/s makes for awfull performance.

repetier commented 11 years ago

Ok, I have put a new development version with a fix for large deltas. It detects the size of the diagonal rod in steps and decides on the version to use. If the rod has max. 46000 steps length it will use fast integer solution with the new and even faster integer square method I added. If it larger it will convert anything in floats and do the position computations. Testing with enforced float version worked so I hope it also works if the values are higher. The other problem might be speed. high stepper rates can consume quite some cpu power and the float computations surely do not make it faster. Also the original solution also used the float sqrt function, so I guess the difference here is not that high.

kyrreaa commented 10 years ago

I run 0.91 with 300mm delta rods, 400mm tall tower travel and 400 steps/turn+16microstep and at some points in my calibration I get odd behaviour. I run a gcode file with pauses that position the head at 140mm radius circle points for X,Y,Z,L,R,F and C points. It sometimes stops short of move to L and starts creeping to it very slowly. It appears to get there but velocity is being influenced in a very odd way. Changing the delta rod length +/- 0.5 may be all I need to do to make the problem come and go. Makes calibration hard...

kyrreaa commented 10 years ago

I just verified that Y height is corrupted when the slowdown occurs on move to L. This was what was screwing up my calibration. By dropping move to L I get proper readings for the others and am close now to calibrating well.

0.91 definitely has a issue here. Is there any printout I can add to identify what is happening?

repetier commented 10 years ago

Not really. You can add

define DEBUG_QUEUE_MOVE

then with echo enabled you get many infos on the computation but these are mainly the cartesian part, not the transformed parts.

One thing you could check if you are treated as large machine because of potential overflows.

uint8_t transformCartesianStepsToDeltaSteps(long cartesianPosSteps[], long deltaPosSteps[]) { if(Printer::isLargeMachine()) {

My guess is that the error i sin that routine a sit is the only one computing delta coordinates.

I've seen the creeping you describe, but only when I had some error in the firmware. Not sure what then happens, but it always disappeared when I solved the error without changing any dimensions.

You should also check if your free ram is still sufficient. A heap overflow could perhaps also cause this and ram is rare on delta printers.

kyrreaa commented 10 years ago

Thanks. I will look into it.