repetier / Repetier-Firmware

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

Moves towards/from points close to printer perimiter runs too fast/slow #247

Open kyrreaa opened 10 years ago

kyrreaa commented 10 years ago

It appears there is something wonky with the speed limits when printer closes in on horizontal delta rod angles. Around 25-30 degrees or lower causes odd issues where vertical movement on axis are run at far higher speeds than printer max speed defines.

Maby a cheap (computational wise) way of limiting this would be to make the vertical max speeds relative to coordinate position in printer radius? I think this radius is already calculated to be used in the delta transform so maby a ratio on that can be used to control speed. Right now there is a bug that can make a move towards the edge creep ultra slowly and then the return move goes blistering fast.

The effect of error seems related to printer geometry and resolution. One of my printers with only 200 steps/turn and 8 microsteps has no such issues while the 400 steps/turn 16 microstep one gets into these issues all the time.

Trying to make gcode that can demonstrate it so we can see what internal calculations are made and make it repeat the error.

repetier commented 10 years ago

Speeds/accelerations are calculated for the extruder not for the depending axis. For that reason your motors must cope with the most negative conditions at max. speed, which is for deltas near the border where you are most horizontal. Here the horizontal axis gets the highest speeds/accelerations and you have the highest nonlinearity as well. If they can not handle it, you need longer rods or a smaller printer radius or a slower max. speed. Speed limiting must be done in the path planner which is completely unaware of the delta transformations.

For that reason, the nonlinearity should be thought of during delta design to prevent angles < ~40°.

kyrreaa commented 10 years ago

40 degrees max, (assuming a initial delta angle of around 30 degrees off vertical), makes the useable print area for a 300mm rod delta only a radius of 80mm or a diameter of 160. Going to 30 degrees gives around 110mm radius (220mm dia). This is a major difference all things considered. The delta radius in that situation is 150mm. A rod length of 300 with a delta radius of 150 seems quite common.

Anyway, the problem still exist at 40 degrees. Suddently a far reaching move run very fast. At 40 degrees the relative speed of the z vs the x/y movement is only 1.17 so with my max of 600 mm/s real performance and a limit of 300mm/s it should have been fine, but it is not.

I tried moves all the way out to 120mm radius with max speed of 200mm/s and I see the same sudden highspeed moves after doing multiple nice perimiters at this angle (120mm radius equates to around 26 degrees with a ratio of movement of 2:1 still below my limit of 600mm/s.)

repetier commented 10 years ago

No, i meant the other 40°, so 300mm rod can use 230mm diameter. But most important is the speed ratio between the columns, which should stay within 1:3 i guess.

Have you already included the latest github version where I limit the max. speed entered to the one allowed in eeprom settings? If not using too high speeds gives you too less segments which can cause odd behaviour.

kyrreaa commented 10 years ago

I will test that tonight, but I think I have latest changes synched. I have a spreadsheet showing the relative speed vs the angle of the delta. It should have been safe and indeed it seems fine for normal printing untill it suddenly does a bobo.

I'll do a slow speed video of it so we can see what it does :)

repetier commented 10 years ago

Ok, let me know if it helped. I will check myself as soon as my delta is functional again.

kyrreaa commented 10 years ago

motion.cpp line 1264: float seconds = cartesianDistance / feedrate; This has no check for validity. It is multiplied with the segmentcount per second to generate the number of segments used. I am not sure this is a problem as the segmentcount is min(1, sps*seconds) so it is limited from being 0 there.

Feedrate calculated in printer.cpp could be clamped though. Only rates equal to or below the limit should be allowed. To reduce overhead any non-change in feedrate with F parameter could be stripped by Repetier Host. Negative feedrates should be discarded.

Don't think this is the problem though...

kyrreaa commented 10 years ago

Could #246 be directly related to this issue? If a move is split into too few segments it will be very vulnerable out in the perimiter of the print area due to the higher non-linearity.

kyrreaa commented 10 years ago

I've been trying to come up wioth some gcode that triggers the behavior I see and finally I caught it in the act. http://www.youtube.com/watch?v=0x1_sADmYt4

Please read the video description for details. Sufficient to say, there definately is a bug here and I believe it's either in path-planner or in the math...

repetier commented 10 years ago

Agreed. That did not look correct. Like it was missing the subsegments or so. Hope I can reproduce it somehow. I have 160 steps per mm and 445mm diagonal rods. But it's running on a ARM so lets hope it more a computational problem, then it should happen on both systems.

kyrreaa commented 10 years ago

Great to hear you now have a highrez printer to test on! That helps a lot.

If I were to make mine bigger it would have been with 393mm rods (ball2ball) as the rods at hobbyking are 750mm long.

repetier commented 10 years ago

I get a similar behaviour with 9000 mm/min. A move takes 2.4s and with 200 segments per second I normally get 480 segments. When it is ok, I get this output:

19:18:57.144 : Seconds:2.40 19:18:57.144 : Segments:480 19:18:57.147 : Num lines:5 19:18:57.148 : segments_per_line:96 19:18:57.164 : Max DS:199 19:18:57.164 : Steps Per Segment:199 19:18:57.168 : Virtual axis steps:19104 19:18:57.185 : Max DS:114 19:18:57.185 : Steps Per Segment:114 19:18:57.188 : Virtual axis steps:10944 19:18:57.205 : Max DS:74 19:18:57.209 : Steps Per Segment:74 19:18:57.209 : Virtual axis steps:7104 19:18:57.230 : Max DS:102 19:18:57.230 : Steps Per Segment:102 19:18:57.234 : Virtual axis steps:9792 19:18:57.254 : Max DS:165 19:18:57.254 : Steps Per Segment:165 19:18:57.258 : Virtual axis steps:15840

Now from time to time the same code decides we need only 1 segment:

19:18:57.258 : Seconds:2.40 19:18:57.262 : New max. segment length:360.00 19:18:57.262 : Segments:1 19:18:57.262 : Num lines:1 19:18:57.266 : segments_per_line:1 19:18:57.266 : Max DS:33367 19:18:57.271 : Steps Per Segment:33367 19:18:57.271 : Virtual axis steps:33367

As you see the debug shows it knows it takes as well 2.4 seconds. And here is the code for the computation (motion.cpp 1288):

    segmentCount = RMath::max(1, int(float((cartesianDir & 136)==136 ? EEPROM::deltaSegmentsPerSecondPrint() : EEPROM::deltaSegmentsPerSecondMove()) * seconds));

in my case print and travel both are set to 200 so even if it would select the wrong version we still have 200_2.4. With integer rounding it would still be 200_2 but we get 1 from this.

That makes no sense at all. Any ides?

repetier commented 10 years ago

Ok, I see the value is always read from eeprom, which is not good anyway, so I will replace the code to use printer storage instead. The result was the segments per mov returned sometime -32768 so the max condition did go to 1. Can you confirm with this changes:

    float sps = (cartesianDir & 136)==136 ? EEPROM::deltaSegmentsPerSecondPrint() : EEPROM::deltaSegmentsPerSecondMove();
    segmentCount = RMath::max(1, static_cast<int>(sps * seconds));

ifdef DEBUG_SEGMENT_LENGTH

Com::printFLN(PSTR("sps:"),sps);

that you get the same problem with AVR. Maybe it only me with an I2C eeprom getting wrong values from time to time.

Best is to compile with

define DEBUG_SPLIT

define DEBUG_SEGMENT_LENGTH

so you see how the wrong split gets assembled.

kyrreaa commented 10 years ago

I have seen this issue on avr as I am running mega2560 in the video. I have yet to run actual control via due.

Also, fetching from eeprom every time is a big mistake in my eyes. It definitely needs to be cached by memory. The actual option to use should always be in memory, and only during the read from eeprom and write to eeprom should these values ever be exchanged with the eeprom. The eeprom-routine should not be used on flagrant access to options, system mem variables should.

kyrreaa commented 10 years ago

In case you were wondering, calculating sps and fetching the values from eeprom takes 390 cycles. Doing the same with values in ram takes 314 cycles. Fetching each of the eeprom values thus cost 38 cycles.

Edit: Some more math! Assuming you are printing a high-rez object with very many tiny short segments. Let's say around 0.5mm long segments and you print at 50mm/s. Then you need to fetch both the variables for each line of gcode and there are 50/0.5 = 100 of em every second. At 38 cycles per fetch and two fetches that's 100_2_38 = 7600 cycles every second wasted. I am very glad we can remove this as this will improve the number of cycles available for the stepper ISR. (Albeit with 0.05% hehe.)

repetier commented 10 years ago

I've already updated it for the next update to ram usage, so the problem is now gone for me. The question was more if you have the same read error in avr or if that was caused by an other problem. So if you add the debug options and modifications, will it show a 1 segment move with negative sps?

kyrreaa commented 10 years ago

Will check tonight when I get home. (a few hours...)

kyrreaa commented 10 years ago

I tried doing the mods on the due platform and apply the patch on the avr platform as well. I noticed it being very complicated doing so. Now that the due may start to diverge more from avr due to hardware being used more efficiently (I know we need to focus on making the hal layer the only difference, but still...) I wonder if it would be better to use two trees one for avr and one for sam. That way you can cherrypick patches and apply them cross-project. You can pull updates from a different repo and cherrypick and even merge the trees into your projects just like you can fork it. Would make it a lot easier I think to work on the common and separate files. Better than a batchfile just copying everything over at least.

repetier commented 10 years ago

As soon as we stop modifying only the hal layer we start getting 2 versions which get more and more incompatible. Users only make changes for their system, so it stays on me to make the modifications and test if nothing gets broken. With my little time I have no time to do so and at some point it is a complete different firmware. And then someone comes with a new HAL for lets say a smoothieboard and we have a third version we need to keep up to date. So please not two version. The maximum is sime #if contitions for different hardware solutions if it can not be solved by the hal.

kyrreaa commented 10 years ago

I understand. The solution is probably to merge the two folders. Then make the right Hal be included based on board selection. The incompatible code can be prevented from being compiled with ifdefs.

Pins can be moved to pins_sam and pins_avr and a pins.h will be the abstraction between em based on the board selection. Hal_sam and Hal_avr can again be the specific layers with Hal.h as abstraction. I think this would make it easier to work with the multiple hardware platforms especially as it would make it easier to see where we should not change in order not to break the other platform.

repetier commented 10 years ago

Well my preferred solution would be to have a subfolder for each HAL structure. But that stupid Arduino IDE only supports flat file structures. So I had your solution and mine. With your solutions it is easier to keep everything in sync while the per architecture solution has less files in the ide (and still too much). But I already hate that I always have to switch between directories, so I really need a better solution soon. Perhaps even find a Arduino-less solution that works for all.

kyrreaa commented 10 years ago

I suggest you select to use external editor in arduino. Then it will load the files automatically on compile and only show grayed out uneditable windows for files.

My idea to protect c-files (cpp too) that are for specific hardware from being compiled on wrong board is simply to have em check that they are on right board, otherwise ifdef their content out of existence. Empty cpp files compile fast :)

Download Atmel Studio 6.1 or 6.2 and use that as editor. You can simply pull a file into it to edit and if you do contextual lookups and such it will open additional files in same folder as it finds references. You can also search and refactor for all open files so simply dragging the files needed to the editor is enough. Further, you could define blank projects and add include folders for the Arduino systems, core and libs. Then you can even have automatic code completion and function-call use description popups for the external calls. You will find your life a lot easier. Studio uses Visual studio from microsoft as a base so it's really good on syntax and such. And you can add on a-style and have all code be compatible with that with a keystroke.

Maby a studio project file could be included in the project folder too so you only click on that to open. Two files would allow studio to see only the relevant files for the architechture you edit or it can organize files in folders without moving em by using links.

I'll see if i can export my setup, that's how I work. I also use Studio and a ICE3 or J-Link to debug the firmware live. Much easier than print statements hehe.

repetier commented 10 years ago

I like the external editor trick. Didn't know it existed. I also like the Arduino Studio. I use it already for non-Arduino projects. SO I think I know where we are going to soon:-)

repetier commented 10 years ago

Back to our initial problem. I just found out some things I really do not like.

If I go above 14000 mm/min with my tests I start getting the speed changes you also see. To my surprise I saw vMax >65535 which is even more a problem on avr where it is a 16 bit uint. So for AVR we need to limit speed to 65535 steps per second. Now I have to find out where this gets converted to 16bit in arm as that must be the place causing my speed change. I hope there is no need to extend speed variables to 32 bit for avr.

What I do not understand is why it works for you with 300mm/s and not with 110mm/s which is slower and should be safe, you get that problem. Or did you mean 310mm/s in the video?

Since you need more speed on the towers if you are at the ends the overflow will happen there first.

kyrreaa commented 10 years ago

266 Has been added so you can get going faster.

(I know a few tricks to get studio to accept folders and such so i did it for you.)

kyrreaa commented 10 years ago

The values for my speeds are correct and i copy-pasted the gcode so there were to be no errors. Video description has it. I was running on avr when this happened as mentioned. I will be rigging up a full working stepper setup with the due board soon, but first it needs some heaters and such...

kyrreaa commented 10 years ago

By the way, seeing that high a vMax is normal. 14000mm/min = 233.3 mm/s and with 160 steps/mm on the axis you get 37328 steps/sec. To get beyond 65k you need a ratio of 65000/37328 = 1.74 which means you are out in the 30 degrees or lower range.at 25 degrees you reach 2.1:1 ratio which could still be fine. I am working on a simple way to change the speeds based on the outer perimiters so that we can print further out without going over the max speed set on towers (instead of in cartesian mode).

The difference between 30 and 25 degrees is by the way 20mm diameter if delta arms are 300mm long.

kyrreaa commented 10 years ago

Here's the output of the end of my test, which is crashing horribly by suddently jumping in speed: (Sorry I borked the first attempt by editing wrong file so no sps. This time it's there.)

18:47:36.271 : Seconds:0.37 18:47:36.271 : sps:100.00 18:47:36.272 : New max. segment length:3.06 18:47:36.272 : Segments:36 18:47:36.272 : Num lines:2 18:47:36.272 : segments_per_line:18 18:47:36.272 : Max DS:388 18:47:36.272 : Steps Per Segment:388 18:47:36.272 : Virtual axis steps:6984 18:47:36.272 : Max DS:764 18:47:36.272 : Steps Per Segment:764 18:47:36.272 : Virtual axis steps:13752

18:47:36.272 : Seconds:0.73 18:47:36.272 : sps:100.00 18:47:36.272 : Segments:73 18:47:36.272 : Num lines:4 18:47:36.272 : segments_per_line:18 18:47:36.272 : Max DS:762 18:47:36.272 : Steps Per Segment:762 18:47:36.272 : Virtual axis steps:13716 18:47:36.278 : Max DS:387 18:47:36.278 : Steps Per Segment:387 18:47:36.278 : Virtual axis steps:6966 18:47:36.286 : Max DS:379 18:47:36.289 : Steps Per Segment:379 18:47:36.289 : Virtual axis steps:6822 18:47:36.297 : Max DS:730 18:47:36.297 : Steps Per Segment:730 18:47:36.297 : Virtual axis steps:13140

18:47:36.304 : Seconds:0.73 18:47:36.304 : sps:100.00 18:47:36.304 : Segments:73 18:47:36.304 : Num lines:4 18:47:36.304 : segments_per_line:18 18:47:36.313 : Max DS:729 18:47:36.313 : Steps Per Segment:729 18:47:36.313 : Virtual axis steps:13122 18:47:36.327 : Max DS:378 18:47:36.327 : Steps Per Segment:378 18:47:36.327 : Virtual axis steps:6804 18:47:36.355 : Max DS:388 18:47:36.355 : Steps Per Segment:388 18:47:36.355 : Virtual axis steps:6984 18:47:36.380 : Max DS:764 18:47:36.380 : Steps Per Segment:764 18:47:36.381 : Virtual axis steps:13752

18:47:36.394 : Seconds:0.73 18:47:36.397 : sps:100.00 18:47:36.401 : Segments:73 18:47:36.401 : Num lines:4 18:47:36.401 : segments_per_line:18 18:47:36.419 : Max DS:762 18:47:36.423 : Steps Per Segment:762 18:47:36.424 : Virtual axis steps:13716 18:47:36.457 : Max DS:387 18:47:36.457 : Steps Per Segment:387 18:47:36.457 : Virtual axis steps:6966 18:47:36.474 : Max DS:379 18:47:36.474 : Steps Per Segment:379 18:47:36.474 : Virtual axis steps:6822 18:47:36.487 : Max DS:730 18:47:36.487 : Steps Per Segment:730 18:47:36.487 : Virtual axis steps:13140

18:47:36.494 : Seconds:0.37 18:47:36.494 : sps:100.00 18:47:36.494 : Segments:36 18:47:36.494 : Num lines:2 18:47:36.494 : segments_per_line:18 18:47:36.504 : Max DS:729 18:47:36.504 : Steps Per Segment:729 18:47:36.504 : Virtual axis steps:13122 18:47:36.513 : Max DS:378 18:47:36.513 : Steps Per Segment:378 18:47:36.513 : Virtual axis steps:6804

I note there is no segment issues? Interesting that the virtual axis steps is not the same both ways though... I thought it had to be?

repetier commented 10 years ago

Ok, no segment issues. Can you repeat with

define DEBUG_QUEUE_MOVE

compiled in and echo enabled. That log would give some infos on speed calculations. Of special interest would be if LimitInterval:240 stays > 306 which is the limit for 20MHz (245 for 16MHz)

That is the error I currently see and which I try to solve. For AVR I know I can limit it in motion.cpp with fullInterval = limitInterval>LIMIT_INTERVAL ? limitInterval : LIMIT_INTERVAL; // This is our target speed

and LIMIT_INTERVAL set to the correct limit. Currently there stands 200 which is too low. That would help but for arm I'd like to go higher, so I need to find the overflow which results from this.

What was your speed for that example?

kyrreaa commented 10 years ago

Same script: G0 X-110 F18000 G0 X110 G0 X-110 G0 X110 G0 X0

kyrreaa commented 10 years ago

Here's a full log of the movement with DEBUG_QUEUE_MOVE.

19:06:46.213 : ID:3247 19:06:46.213 : vStart/End:3809/3809 19:06:46.213 : accel/decel steps:1887/1887/6984 19:06:46.213 : st./end speed:30.0/30.0 19:06:46.213 : Flags:146 19:06:46.213 : joinFlags:5 19:06:46.213 : ID:3247 19:06:46.214 : Delta 7699 0 0 0 19:06:46.214 : Dir:30 19:06:46.214 : Flags:18 19:06:46.214 : fullSpeed:300.00 19:06:46.214 : vMax:38095 19:06:46.214 : Acceleration:329829.15 19:06:46.214 : Acceleration Prim:380751 19:06:46.214 : Remaining steps:6984 19:06:46.214 : LimitInterval:525 19:06:46.214 : Move distance on the XYZ space:55.00 19:06:46.214 : Commanded feedrate:300.00 19:06:46.215 : Constant full speed move time:3666600.00 19:06:46.215 : ID:3524 19:06:46.215 : vStart/End:962/962 19:06:46.215 : accel/decel steps:62/62/13752 19:06:46.215 : st./end speed:30.0/30.0 19:06:46.215 : Flags:146 19:06:46.215 : joinFlags:5 19:06:46.215 : ID:3524 19:06:46.238 : Delta 7699 0 0 0 19:06:46.239 : Dir:30 19:06:46.239 : Flags:18 19:06:46.239 : fullSpeed:300.71 19:06:46.239 : vMax:9651 19:06:46.239 : Acceleration:329907.15 19:06:46.239 : Acceleration Prim:749905 19:06:46.239 : Remaining steps:13752 19:06:46.239 : LimitInterval:266 19:06:46.239 : Move distance on the XYZ space:55.00 19:06:46.239 : Commanded feedrate:300.00 19:06:46.239 : Constant full speed move time:3658032.00 19:06:46.240 : Echo:G0 X-110.00 F18000.00 19:06:46.272 : ID:3801 19:06:46.273 : vStart/End:935/935 19:06:46.273 : accel/decel steps:59/59/13716 19:06:46.273 : st./end speed:30.0/30.0 19:06:46.273 : Flags:146 19:06:46.273 : joinFlags:5 19:06:46.273 : ID:3801 19:06:46.273 : Delta 7699 0 0 0 19:06:46.273 : Dir:31 19:06:46.273 : Flags:18 19:06:46.273 : fullSpeed:300.37 19:06:46.273 : vMax:9370 19:06:46.273 : Acceleration:329534.18 19:06:46.273 : Acceleration Prim:747096 19:06:46.273 : Remaining steps:13716 19:06:46.274 : LimitInterval:267 19:06:46.274 : Move distance on the XYZ space:55.00 19:06:46.274 : Commanded feedrate:300.00 19:06:46.274 : Constant full speed move time:3662172.00 19:06:46.319 : ID:3801 19:06:46.319 : vStart/End:935/9365 19:06:46.319 : accel/decel steps:59/1/13716 19:06:46.319 : st./end speed:30.0/300.2 19:06:46.319 : Flags:146 19:06:46.319 : joinFlags:7 19:06:46.319 : ID:4078 19:06:46.319 : vStart/End:38022/3799 19:06:46.319 : accel/decel steps:1/1888/6966 19:06:46.319 : st./end speed:300.2/30.0 19:06:46.319 : Flags:146 19:06:46.319 : joinFlags:5 19:06:46.319 : ID:4078 19:06:46.319 : Delta 7699 0 0 0 19:06:46.319 : Dir:31 19:06:46.319 : Flags:18 19:06:46.319 : fullSpeed:300.21 19:06:46.319 : vMax:38022 19:06:46.319 : Acceleration:329359.40 19:06:46.319 : Acceleration Prim:379229 19:06:46.319 : Remaining steps:6966 19:06:46.319 : LimitInterval:526 19:06:46.320 : Move distance on the XYZ space:55.00 19:06:46.320 : Commanded feedrate:300.00 19:06:46.321 : Constant full speed move time:3664116.00 19:06:46.346 : ID:4078 19:06:46.349 : vStart/End:38022/38022 19:06:46.351 : accel/decel steps:1/1/6966 19:06:46.356 : st./end speed:300.2/300.2 19:06:46.357 : Flags:146 19:06:46.357 : joinFlags:7 19:06:46.360 : ID:4355 19:06:46.363 : vStart/End:37235/3721 19:06:46.367 : accel/decel steps:1/1849/6822 19:06:46.371 : st./end speed:300.2/30.0 19:06:46.373 : Flags:146 19:06:46.373 : joinFlags:5 19:06:46.378 : ID:4355 19:06:46.379 : Delta 7699 0 0 0 19:06:46.379 : Dir:31 19:06:46.380 : Flags:18 19:06:46.383 : fullSpeed:300.26 19:06:46.385 : vMax:37243 19:06:46.390 : Acceleration:329422.46 19:06:46.393 : Acceleration Prim:371461 19:06:46.394 : Remaining steps:6822 19:06:46.398 : LimitInterval:537 19:06:46.400 : Move distance on the XYZ space:55.00 19:06:46.405 : Commanded feedrate:300.00 19:06:46.409 : Constant full speed move time:3663414.00 19:06:46.436 : ID:4355 19:06:46.480 : vStart/End:37235/37216 19:06:46.480 : accel/decel steps:1/3/6822 19:06:46.481 : st./end speed:300.2/300.0 19:06:46.481 : Flags:146 19:06:46.481 : joinFlags:7 19:06:46.481 : ID:4632 19:06:46.481 : vStart/End:6147/614 19:06:46.481 : accel/decel steps:1/27/13140 19:06:46.481 : st./end speed:300.0/30.0 19:06:46.481 : Flags:146 19:06:46.481 : joinFlags:5 19:06:46.481 : ID:4632 19:06:46.481 : Delta 7699 0 0 0 19:06:46.481 : Dir:31 19:06:46.481 : Flags:18 19:06:46.481 : fullSpeed:300.05 19:06:46.481 : vMax:6148 19:06:46.481 : Acceleration:329877.75 19:06:46.481 : Acceleration Prim:716468 19:06:46.481 : Remaining steps:13140 19:06:46.481 : LimitInterval:279 19:06:46.481 : Move distance on the XYZ space:55.00 19:06:46.481 : Commanded feedrate:300.00 19:06:46.482 : Constant full speed move time:3666060.00 19:06:46.482 : Echo:G0 X110.00 19:06:46.527 : ID:4632 MJ:29.98 19:06:46.527 : ID:4632 19:06:46.528 : vStart/End:6147/614 19:06:46.528 : accel/decel steps:1/27/13140 19:06:46.528 : st./end speed:300.0/30.0 19:06:46.528 : Flags:146 19:06:46.528 : joinFlags:5 19:06:46.528 : ID:4909 19:06:46.528 : vStart/End:613/613 19:06:46.528 : accel/decel steps:27/27/13122 19:06:46.528 : st./end speed:30.0/30.0 19:06:46.528 : Flags:146 19:06:46.528 : joinFlags:1 19:06:46.528 : ID:4909 19:06:46.528 : Delta 7699 0 0 0 19:06:46.528 : Dir:30 19:06:46.528 : Flags:18 19:06:46.528 : fullSpeed:300.46 19:06:46.528 : vMax:6148 19:06:46.528 : Acceleration:329636.31 19:06:46.528 : Acceleration Prim:714963 19:06:46.528 : Remaining steps:13122 19:06:46.528 : LimitInterval:279 19:06:46.528 : Move distance on the XYZ space:55.00 19:06:46.528 : Commanded feedrate:300.00 19:06:46.528 : Constant full speed move time:3661038.00 19:06:46.573 : ID:4632 19:06:46.573 : vStart/End:6147/614 19:06:46.573 : accel/decel steps:1/27/13140 19:06:46.573 : st./end speed:300.0/30.0 19:06:46.573 : Flags:146 19:06:46.573 : joinFlags:5 19:06:46.573 : ID:4909 19:06:46.573 : vStart/End:613/6148 19:06:46.573 : accel/decel steps:27/1/13122 19:06:46.573 : st./end speed:30.0/300.5 19:06:46.573 : Flags:146 19:06:46.573 : joinFlags:3 19:06:46.573 : ID:5186 19:06:46.573 : vStart/End:37169/3711 19:06:46.573 : accel/decel steps:1/1845/6804 19:06:46.573 : st./end speed:300.5/30.0 19:06:46.573 : Flags:146 19:06:46.573 : joinFlags:5 19:06:46.573 : ID:5186 19:06:46.573 : Delta 7699 0 0 0 19:06:46.574 : Dir:30 19:06:46.574 : Flags:18 19:06:46.574 : fullSpeed:300.50 19:06:46.574 : vMax:37174 19:06:46.574 : Acceleration:329680.06 19:06:46.574 : Acceleration Prim:370771 19:06:46.574 : Remaining steps:6804 19:06:46.574 : LimitInterval:538 19:06:46.581 : Move distance on the XYZ space:55.00 19:06:46.581 : Commanded feedrate:300.00 19:06:46.581 : Constant full speed move time:3660552.00 19:06:46.625 : ID:5186 19:06:46.625 : vStart/End:37169/37112 19:06:46.625 : accel/decel steps:1/7/6804 19:06:46.625 : st./end speed:300.5/300.0 19:06:46.625 : Flags:146 19:06:46.625 : joinFlags:7 19:06:46.625 : ID:5463 19:06:46.625 : vStart/End:38095/3809 19:06:46.625 : accel/decel steps:1/1887/6984 19:06:46.625 : st./end speed:300.0/30.0 19:06:46.625 : Flags:146 19:06:46.625 : joinFlags:5 19:06:46.625 : ID:5463 19:06:46.626 : Delta 7699 0 0 0 19:06:46.626 : Dir:30 19:06:46.626 : Flags:18 19:06:46.626 : fullSpeed:300.00 19:06:46.626 : vMax:38095 19:06:46.626 : Acceleration:329829.15 19:06:46.626 : Acceleration Prim:380751 19:06:46.626 : Remaining steps:6984 19:06:46.626 : LimitInterval:525 19:06:46.626 : Move distance on the XYZ space:55.00 19:06:46.626 : Commanded feedrate:300.00 19:06:46.626 : Constant full speed move time:3666600.00 19:06:46.672 : ID:5463 19:06:46.672 : vStart/End:38095/38095 19:06:46.672 : accel/decel steps:1/1/6984 19:06:46.672 : st./end speed:300.0/300.0 19:06:46.672 : Flags:146 19:06:46.672 : joinFlags:7 19:06:46.672 : ID:1308 19:06:46.677 : vStart/End:9628/962 19:06:46.677 : accel/decel steps:1/62/13752 19:06:46.677 : st./end speed:300.0/30.0 19:06:46.677 : Flags:146 19:06:46.677 : joinFlags:5 19:06:46.677 : ID:1308 19:06:46.677 : Delta 7699 0 0 0 19:06:46.677 : Dir:30 19:06:46.677 : Flags:18 19:06:46.677 : fullSpeed:300.71 19:06:46.677 : vMax:9651 19:06:46.677 : Acceleration:329907.15 19:06:46.677 : Acceleration Prim:749905 19:06:46.677 : Remaining steps:13752 19:06:46.678 : LimitInterval:266 19:06:46.678 : Move distance on the XYZ space:55.00 19:06:46.678 : Commanded feedrate:300.00 19:06:46.678 : Constant full speed move time:3658032.00 19:06:46.679 : Echo:G0 X-110.00 19:06:46.718 : ID:1308 MJ:30.02 19:06:46.718 : ID:1308 19:06:46.718 : vStart/End:9628/963 19:06:46.718 : accel/decel steps:1/62/13752 19:06:46.718 : st./end speed:300.0/30.0 19:06:46.718 : Flags:146 19:06:46.718 : joinFlags:7 19:06:46.718 : ID:1585 19:06:46.718 : vStart/End:936/935 19:06:46.718 : accel/decel steps:59/59/13716 19:06:46.719 : st./end speed:30.0/30.0 19:06:46.719 : Flags:146 19:06:46.719 : joinFlags:5 19:06:46.719 : ID:1585 19:06:46.719 : Delta 7699 0 0 0 19:06:46.719 : Dir:31 19:06:46.719 : Flags:18 19:06:46.719 : fullSpeed:300.37 19:06:46.719 : vMax:9370 19:06:46.719 : Acceleration:329534.18 19:06:46.719 : Acceleration Prim:747096 19:06:46.719 : Remaining steps:13716 19:06:46.719 : LimitInterval:267 19:06:46.719 : Move distance on the XYZ space:55.00 19:06:46.719 : Commanded feedrate:300.00 19:06:46.719 : Constant full speed move time:3662172.00 19:06:46.763 : ID:1585 19:06:46.763 : vStart/End:936/9365 19:06:46.763 : accel/decel steps:59/1/13716 19:06:46.763 : st./end speed:30.0/300.2 19:06:46.763 : Flags:146 19:06:46.763 : joinFlags:7 19:06:46.763 : ID:1862 19:06:46.763 : vStart/End:38022/3799 19:06:46.763 : accel/decel steps:1/1888/6966 19:06:46.764 : st./end speed:300.2/30.0 19:06:46.764 : Flags:146 19:06:46.764 : joinFlags:5 19:06:46.764 : ID:1862 19:06:46.764 : Delta 7699 0 0 0 19:06:46.764 : Dir:31 19:06:46.764 : Flags:18 19:06:46.764 : fullSpeed:300.21 19:06:46.764 : vMax:38022 19:06:46.764 : Acceleration:329359.40 19:06:46.764 : Acceleration Prim:379229 19:06:46.764 : Remaining steps:6966 19:06:46.764 : LimitInterval:526 19:06:46.764 : Move distance on the XYZ space:55.00 19:06:46.764 : Commanded feedrate:300.00 19:06:46.764 : Constant full speed move time:3664116.00 19:06:46.807 : ID:1862 19:06:46.807 : vStart/End:38022/38022 19:06:46.807 : accel/decel steps:1/1/6966 19:06:46.807 : st./end speed:300.2/300.2 19:06:46.807 : Flags:146 19:06:46.807 : joinFlags:7 19:06:46.807 : ID:2139 19:06:46.808 : vStart/End:37235/3721 19:06:46.808 : accel/decel steps:1/1849/6822 19:06:46.808 : st./end speed:300.2/30.0 19:06:46.808 : Flags:146 19:06:46.808 : joinFlags:5 19:06:46.808 : ID:2139 19:06:46.808 : Delta 7699 0 0 0 19:06:46.808 : Dir:31 19:06:46.808 : Flags:18 19:06:46.808 : fullSpeed:300.26 19:06:46.808 : vMax:37243 19:06:46.808 : Acceleration:329422.46 19:06:46.808 : Acceleration Prim:371461 19:06:46.808 : Remaining steps:6822 19:06:46.808 : LimitInterval:537 19:06:46.808 : Move distance on the XYZ space:55.00 19:06:46.808 : Commanded feedrate:300.00 19:06:46.808 : Constant full speed move time:3663414.00 19:06:46.854 : ID:2139 19:06:46.854 : vStart/End:37235/37216 19:06:46.854 : accel/decel steps:1/3/6822 19:06:46.855 : st./end speed:300.2/300.0 19:06:46.855 : Flags:146 19:06:46.855 : joinFlags:7 19:06:46.855 : ID:2416 19:06:46.855 : vStart/End:6147/614 19:06:46.855 : accel/decel steps:1/27/13140 19:06:46.855 : st./end speed:300.0/30.0 19:06:46.855 : Flags:146 19:06:46.855 : joinFlags:5 19:06:46.855 : ID:2416 19:06:46.855 : Delta 7699 0 0 0 19:06:46.855 : Dir:31 19:06:46.855 : Flags:18 19:06:46.855 : fullSpeed:300.05 19:06:46.855 : vMax:6148 19:06:46.855 : Acceleration:329877.75 19:06:46.855 : Acceleration Prim:716468 19:06:46.855 : Remaining steps:13140 19:06:46.855 : LimitInterval:279 19:06:46.855 : Move distance on the XYZ space:55.00 19:06:46.856 : Commanded feedrate:300.00 19:06:46.856 : Constant full speed move time:3666060.00 19:06:46.856 : Echo:G0 X110.00 19:06:46.900 : ID:2416 MJ:29.98 19:06:46.900 : ID:2416 19:06:46.900 : vStart/End:6147/614 19:06:46.901 : accel/decel steps:1/27/13140 19:06:46.901 : st./end speed:300.0/30.0 19:06:46.901 : Flags:146 19:06:46.901 : joinFlags:5 19:06:46.901 : ID:2693 19:06:46.901 : vStart/End:613/613 19:06:46.901 : accel/decel steps:27/27/13122 19:06:46.901 : st./end speed:30.0/30.0 19:06:46.901 : Flags:146 19:06:46.901 : joinFlags:1 19:06:46.901 : ID:2693 19:06:46.901 : Delta 7699 0 0 0 19:06:46.901 : Dir:30 19:06:46.901 : Flags:18 19:06:46.901 : fullSpeed:300.46 19:06:46.901 : vMax:6148 19:06:46.901 : Acceleration:329636.31 19:06:46.901 : Acceleration Prim:714963 19:06:46.901 : Remaining steps:13122 19:06:46.901 : LimitInterval:279 19:06:46.902 : Move distance on the XYZ space:55.00 19:06:46.902 : Commanded feedrate:300.00 19:06:46.902 : Constant full speed move time:3661038.00 19:06:46.947 : ID:2416 19:06:46.947 : vStart/End:6147/614 19:06:46.947 : accel/decel steps:1/27/13140 19:06:46.947 : st./end speed:300.0/30.0 19:06:46.947 : Flags:146 19:06:46.947 : joinFlags:5 19:06:46.947 : ID:2693 19:06:46.947 : vStart/End:613/6148 19:06:46.947 : accel/decel steps:27/1/13122 19:06:46.947 : st./end speed:30.0/300.5 19:06:46.947 : Flags:146 19:06:46.947 : joinFlags:3 19:06:46.947 : ID:2970 19:06:46.947 : vStart/End:37169/3711 19:06:46.947 : accel/decel steps:1/1845/6804 19:06:46.947 : st./end speed:300.5/30.0 19:06:46.947 : Flags:146 19:06:46.947 : joinFlags:5 19:06:46.947 : ID:2970 19:06:46.947 : Delta 7699 0 0 0 19:06:46.947 : Dir:30 19:06:46.948 : Flags:18 19:06:46.948 : fullSpeed:300.50 19:06:46.948 : vMax:37174 19:06:46.948 : Acceleration:329680.06 19:06:46.948 : Acceleration Prim:370771 19:06:46.948 : Remaining steps:6804 19:06:46.948 : LimitInterval:538 19:06:46.957 : Move distance on the XYZ space:55.00 19:06:46.957 : Commanded feedrate:300.00 19:06:46.957 : Constant full speed move time:3660552.00 19:06:46.957 : Echo:G0 X0.00 19:07:02.475 : Echo:M104 T0 S0 19:07:02.475 : Echo:M140 S0 19:07:02.475 : Echo:G1 X0.00 Y0.00 F15000.00 (Hmm, how do I make it do a small textbox with scrollbars?)

kyrreaa commented 10 years ago

The start and end speeds doesn't add up to me. I thought the whole point was to go 30-300, 300-300, 300-30, 30-30 etc. So the start speed of the next matches the end speed of the last. Some places here we go from end speed of 30 to start speed of 300 on next.

On my test now the failing/skipping segments are in the middle of the bed, moving accross 0,0. The move starts from either -110 to 110, or from 110 to -110 and the segment that would pass 0 is the one skipping due to speed going from 30 to 300.

Changing speed to F12000 makes it run a tad jerky the first pass but no skips or errors. It completes the test with position intact.

At F6000 it runs smooth through entire movement.

What I find even more odd is how it lists larger vMax many times on teh 100mm/s runs than the 300mm/s. I think it overflows vMax...

repetier commented 10 years ago

Ok, you got the same problem, see this part: 19:06:46.239 : vMax:9651 19:06:46.239 : Acceleration:329907.15 19:06:46.239 : Acceleration Prim:749905 19:06:46.239 : Remaining steps:13752 19:06:46.239 : LimitInterval:266 LimitInterval 266 would give vMax = 75187 but you have 9651 which is 75187-65536. So my limiting would have helped here (i guess). At least it would have prevented the overflow resulting in wrong vMax.

The start/end speeds are hard to read as it is not sequential order. With each new line the pathplanner updates and returnes the new changed parts, so output is a bit mixed and you have to order by ascending id to read it correctly.

kyrreaa commented 10 years ago

I'll fire up the debugger with a break on vMax != vMax32 (making an extra one)

kyrreaa commented 10 years ago

Damnit! My tuning got blasted! I had forgotten to save the eeprom after my last round of calibrating the printer. Somehow after synching with master for these tests it lost something and blasted the eeprom even with eeprom save flag on. Must be firmware who dunnit.

Edit: It was the debugger who lost the preserve eeprom flag. Think I recreated it now. And backed up.

kyrreaa commented 10 years ago

Breakthrough! I added code to calculate an extra vMax with 32 bit by first adding it in the line under where vMax was declared as volatile uint32_t vMax32; (to allow better debugging) and then adding: vMax32 = F_CPU / fullInterval; // maximum steps per second, we can reach if (vMax32!= vMax) { vMax = 65535; } Result is slower movement, but no indication of glitching... Either the path planner doesn't have time to get to grips with the speed or the issue is a ISR vs app domain thing where something is read before it's ready or such. The test for vMax vs vMax32 never triggers and by commenting out the code but leaving in the variable, it still crashes as before.

Edit: The missing glitches was a result of eradicated eeprom settings on programming.

kyrreaa commented 10 years ago

Trying to limit fullInterval does not help. I run 20 MHz so I tried 20 M / 65535 = 305 and limited to 306 minimum. Result is horrible jumping eben though the value would not go abowe 65359.

kyrreaa commented 10 years ago

I added limiting code modifying the 200 limit and using F_CPU/65000 as limit. This worked making it not crash but I still heat it doing erronous speed changes on straight paths. There is something else wrong. This is a symptom not the cause.

kyrreaa commented 10 years ago

Is anyone getting anywhere with this bug? I have debugger ready, please tell if there is anything I can do.

What I would like is a description of how this part of the code works as it's quite hard to grasp.

repetier commented 10 years ago

Strange thing that 65535 works and limiting it through limit does not. and Limiting to F_CPU/65000 again does.

Just found another thing that might be a problem. In void PrintLine::calculateMove(float axis_diff[],uint8_t pathOptimize)

it should be

if NONLINEAR_SYSTEM

axisInterval[VIRTUAL_AXIS] = fabs(axis_diff[VIRTUAL_AXIS])_F_CPU/(Printer::maxFeedrate[Z_AXIS]_stepsRemaining);
limitInterval = RMath::max(axisInterval[VIRTUAL_AXIS],limitInterval); // NEW LINE

endif

fullInterval = limitInterval>LIMIT_INTERVAL ? limitInterval : LIMIT_INTERVAL; // This is our target speed

The virtual axis is always the fastest for nonlinear systems, that is what it was made for. Will now test if that makes a difference for me.

With what part of code do you have problems to understand how it works?

repetier commented 10 years ago

Thinking about my latest comment. If virtual axis is the fastest it can not be larger then the other 4 axis, so the line makes no sense :-(

kyrreaa commented 10 years ago

Hmm, we already calculate the distance from each tower do we not ? Can we not use this vs the delta rod length to find the sin/cos type ratio and limit speed based on that ? That would allow moves all the way down to horizontal rods without overspeed. Close to a tower the accuracy will be reduced for that tower ofcource.

I'd still like a description of the code and thoughts around it as I am having a hard time understanding what all the extra complexity does. In essence it splits a move into multiple segments and/or lines? It determines the delta rod positions for each of the towers for each end of the segments along the move and the path planner handles the speeds vs the segments to join em smoothly.

I assume each point is only calculated once as the next segment need to have a common start with the end of previous segment. That leaves all the vMax stuff and how the pulse timer actually works. It baffles me. I think it changes the timer intervall all the time, but I am having a hard time seeing where the actual steps are being performed.

repetier commented 10 years ago

Looks like I had a breakthrough. Found several problems with my logic analyzer. Now I can go left/right with 600mm/s and acceleration 4000 on the due. Peak frequency is more then 100KHz, but that is near the limit what is possible. Before that I got wrong sounds from 250mm/s so it is a real improvement. I need to add some changes and some more tests as I had changes quite some parts. I think the main problem is in bresenham. There the timing computation for full speed should look like if(!cur->accelSteps) { if(cur->vMax>STEP_DOUBLER_FREQUENCY) {

if ALLOW_QUADSTEPPING

                    if(cur->vMax>STEP_DOUBLER_FREQUENCY*2)
                    {
                        Printer::stepsPerTimerCall = 4;
                        Printer::interval = cur->fullInterval<<2;
                    }
                    else
                    {
                        Printer::stepsPerTimerCall = 2;
                        Printer::interval = cur->fullInterval<<1;
                    }

else

                    Printer::stepsPerTimerCall = 2;
                    Printer::interval = cur->fullInterval<<1;

endif

                }
                else
                {
                    Printer::stepsPerTimerCall = 1;
                    Printer::interval = cur->fullInterval;
                }
            }

see << which were >> so the opposite of what we need. Cartesian version was correct:-(

kyrreaa commented 10 years ago

You should use tags or it eats the << and >>. as well as a lot of stuff inbetween. I tried to do your mod but it did not work. It still runs away on avr.

kyrreaa commented 10 years ago

I found something but I don't know if it's relevant. I am experimenting with alternative ways to compile which gives me some more output and when I decided to run the old c-code for setTimer instead of the embedded asm I got errors. Turns out "long stepperWait = 0;" is placed below the asm routine so technically it has no idea where stepperWait is...

kyrreaa commented 10 years ago

This looks finky to me: fullInterval = limitInterval>200 ? limitInterval : 200; // This is our target speed // new time at full speed = limitIntervalp->stepsRemaining [ticks] timeForMove = (float)limitInterval \ (float)stepsRemaining; // for large z-distance this overflows with long computation Why do we bother to limit fullInterval to minimum 200 and then go on and use the unlimited version to recalculate timeForMove?

kyrreaa commented 10 years ago

Fixed! (possibly)

267 should do it. Please try it out.

repetier commented 10 years ago

Ok, the code is a good idea also it still removes some chars when embedded:-(

As I've written I have found several parts which were wrong. The limiting is still needed for avrs to limit to allowed range and not create overflows. That is the only reason for that limit then in the hope no one tries that frequency with single stepping. With a due relevant parts are rewritten so it accepts 32 bit values allowing 100khz and a bit more with quad stepping. On my logic analyser I saw that around that value a limit is reached and the stepper interrupt uses 95% of computation time. Quite some time simply waiting for the delays needed to help stepper drivers recognize the signals.

The other part has to do with the part you also modified. That needs a different approach for the delta printer. It needs the distance in VIRTUAL_AXIS and only use that step frequency for calculation. Except E is leading then we need the E distance and steps there. That is the part that still needs testing. And then I need to see if it prints well.

With some luck I get finished this weekend or monday so I can commit it.

Just for your information how nonlinear systems work.

  1. For each line we have, we split it into subsegments stored with the line. Each subsegment stores the delta move needed to reach that position on the line. So all subsegments added give the line move. That way the path planner only needs to calculate over the much longer lines reducing computation power. Here we use the delta transformation to get the delta column positions for each segment and build differences for the delta values.
  2. XYZ delta are nonlinear and differ from segment to segment. For that reason we introduced a virtual linear axis. It is determined by the subsegment with the largest delta and the same for all subsegments. So moving along this axis results in a move that removes the nonlinearities for speed calculations.

Well thats all which makes it different from normal cartesian calculations.

kyrreaa commented 10 years ago

When I reach the limit after my patch it only stutters smoothly and can't go faster. Before it missed steps and crashed badly.

I still notice a slight stutter or speed variation as it passes center of the bed in my test. Probably computational.

repetier commented 10 years ago

Here a short video with my current solution:

https://dl.dropboxusercontent.com/u/74036902/delta_moves_600mmps.mov

one move left/right is 360mm. Speed is 600mm//s with 160steps per mm. Run on a due. You see no stuttering or interrupts at all. One important thing is to find out which frequencies the interrupt can safely handle. As soon as your frequency is shorter then allowed or your buffer runs out you get at least some slow downs or real stuttering if timing gets imperfect. But I think best is to wait for the release then we can speak about the same modifications. Will also test my new version on a naked board with analyser on a avr. Hope that gives some more insight.

kyrreaa commented 10 years ago

The analyser you talk about slow down the print though. It is outputting signals on ports using the horrible routines for arduino... Lots of lookups and single bit settings all over.

By the way, I will be opening up another issue... Found a problem with the queuing or code interpreter. Getting format errors on obviously correct code. (It relates to lines with comments in them.)