Open kyrreaa opened 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°.
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.)
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.
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 :)
Ok, let me know if it helped. I will check myself as soon as my delta is functional again.
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...
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.
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...
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.
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.
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?
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));
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
so you see how the wrong split gets assembled.
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.
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.)
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?
Will check tonight when I get home. (a few hours...)
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.
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.
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.
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.
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.
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:-)
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.
(I know a few tricks to get studio to accept folders and such so i did it for you.)
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...
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.
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?
Ok, no segment issues. Can you repeat with
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?
Same script:
G0 X-110 F18000
G0 X110
G0 X-110
G0 X110
G0 X0
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?)
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...
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.
I'll fire up the debugger with a break on vMax != vMax32 (making an extra one)
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.
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.
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.
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.
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.
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
axisInterval[VIRTUAL_AXIS] = fabs(axis_diff[VIRTUAL_AXIS])_F_CPU/(Printer::maxFeedrate[Z_AXIS]_stepsRemaining);
limitInterval = RMath::max(axisInterval[VIRTUAL_AXIS],limitInterval); // NEW LINE
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?
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 :-(
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.
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(cur->vMax>STEP_DOUBLER_FREQUENCY*2)
{
Printer::stepsPerTimerCall = 4;
Printer::interval = cur->fullInterval<<2;
}
else
{
Printer::stepsPerTimerCall = 2;
Printer::interval = cur->fullInterval<<1;
}
Printer::stepsPerTimerCall = 2;
Printer::interval = cur->fullInterval<<1;
}
else
{
Printer::stepsPerTimerCall = 1;
Printer::interval = cur->fullInterval;
}
}
see << which were >> so the opposite of what we need. Cartesian version was correct:-(
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.
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...
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?
Fixed! (possibly)
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.
Well thats all which makes it different from normal cartesian calculations.
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.
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.
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.)
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.