All good things › Forums › Morgan Builders forum › SCARA Kinematics and CPU-Performance
- This topic has 75 replies, 3 voices, and was last updated 12 years ago by
cocktailyogi.
-
AuthorPosts
-
-
June 12, 2014 at 20:02 #4625
cocktailyogi
ParticipantHello,
I have finished my Reprap-Morgan with the new Marlin-firmware. It is a nice machine, which has to competite with my last printer, a Prusa I3.
One think I quickly realised is, that the Arduino Mega 2560 8bit-CPU in combination with RAMPS not enough CPU-power to to the transformtion-maths. For slow printing speeds it is okay, but when going faster than 50 mm/s it slows down and does not run smooth any more. The main problem are the atan2() and sqrt() operations in floating-point-math on the function calculate_delta().
Switching over to Arduino DUE would solve the problem, but it is only 3.3V logic. Ramps has to be modified.
Has anybody other suggestions?
For me the Morgan is a hobby project with an intersting concept, but stillnot beating Prusa I3, except the Z-height is better.
Maybe it is also possible to tweak the code?
Yogi
-
June 12, 2014 at 20:52 #4629
Quentin Harley
KeymasterI am going to explore Smoothie… and will post my config files in a fork if I succeed. Smoothie is a 32bit ARM based board as will, with kinematics ready firmware.
The only problem is the choice of driver on board.
-
June 12, 2014 at 20:53 #4633
Quentin Harley
KeymasterTweaking code might be an option. There are lots of places where we can shave off cycles.
-
June 16, 2014 at 18:32 #4673
cocktailyogi
ParticipantHi,
I think, getting the math fast enough is not possible on the 8bit CPU. A CPU with floating-point support or lots of MHZ would be nice.
The Smoothyboard has good specs, if I would have known before…. The price is also good. The onboard drivers also seem to be perfect. Good luck.
During the meantime I will build a XXL-Delta-printer. Maybe I will finish my Morgan with stronger CPU one day.
Have a good time,
Yogi -
June 16, 2014 at 22:49 #4697
Quentin Harley
KeymasterAt what speeds were you testing the machine?
-
June 17, 2014 at 15:10 #4709
RobertKuhlmann
ParticipantHow about using this library:
http://blog.oscarliang.net/enhanced-arduino-c-custom-math-library/He only missed to optimize sqrt – damn.
But maybe we can complete Oscar’s library with the approach shown over here:
http://www-user.tu-chemnitz.de/~heha/Mikrocontroller/Wurzel.htmThe “manual way” is implemented in ATmega8 there already. I didn’t dig into that too deep now but it should be possible to enhance it for our needs.
Maybe even the “reference-table”-approach would do the job, but I didn’t check the table size we’d need for that. But the manual way should be good enough. -
June 17, 2014 at 16:46 #4713
Quentin Harley
KeymasterI like it! Will try it on armlevel soon…
-
June 17, 2014 at 19:02 #4717
RobertKuhlmann
ParticipantI’ve invested some time to transfer the idea to Marlin.
Here are three files, that we can start with:
http://reprap.org/wiki/File:Marlin_mathematics.zipmath_tables.h – holds all conversion-tables for sin, cos, tan, acos
new_mathematic.h and .cpp – new fast functions fsin, fcos, ftan, facos, fatan2 (fsqrt as a dummy)
Oscar Liang obviously used deg-parameters, while Arduino wants rad. So I had to change a few things and I prepared the value-tables, not included in his blog.
I did include the assembler code for fsqrt as a comment but didn’t work on that now.
TODO:
1. fsqrt
2. Exchange trigonometric calls throughout Marlin (no big deal with Visual Studio though).If someone wants to help me finish this work (e.g. test accuracy or impact on printing a.s.o), you’re welcome.
Greetings
Robert -
June 17, 2014 at 23:08 #4749
Quentin Harley
KeymasterCount me in. I will do a fast technical print on my latest morgan, exchange the firmware, and do another print. Of course I will have to make sure that exactly the same calibration factors are used in order to see the effect of the firmware only.
I will need some time to complete this, but will keep you posted.
Q
-
June 17, 2014 at 23:12 #4753
Quentin Harley
KeymasterI will have to devise some code to report the available free cycles on the machine in order to judge the possibility of increasing the calculations per second. This should have a marked quality increase at faster prints.
-
June 17, 2014 at 23:14 #4757
RobertKuhlmann
ParticipantVery good. I’ll do my part and try to transfer the sqrt-assembler code within the next days.
If accuracy becomes a problem, we could try to use larger tables, maybe up to ten times should be possible. -
June 17, 2014 at 23:23 #4761
RobertKuhlmann
ParticipantI’m compiling now and correct some errors. Will send you an update soon.
-
June 17, 2014 at 23:59 #4765
RobertKuhlmann
ParticipantHere’s the complete Marin-armlevel with new_mathematics. It compiles without errors now but is untested:
http://reprap.org/wiki/File:Marlin_armlevel_new_mathematics_beta.zip
That’s all for today. Have to go to bed now.
Bye
Robert -
June 18, 2014 at 09:58 #4785
Quentin Harley
KeymasterThanks. I am going to make a new branch for it on my Git repository, then we can collaborate on the effort. If it makes a marked difference (which it should) I will port it to yogi’s new marlin implementation.
-
June 18, 2014 at 10:04 #4789
RobertKuhlmann
ParticipantGreat.
And one further suggestion:
We should combine both ways. Yogi’s auto-leveling and your armlevel and make it selectable with a symbolic constant.Homing to z=0 or z=max should be selectable with a symbolic constant too.
And I will learn how to use Github for collaboration…
-
June 18, 2014 at 18:28 #4809
Quentin Harley
KeymasterI like it. Auto level is fine, but you need extra sensors and wires, and Morgan does not need constant probing. In my experience it works fine after you taught it where the head moves using the armlevel routines.
-
June 18, 2014 at 19:06 #4813
RobertKuhlmann
ParticipantBy the way: I made very good progresses in merging the armlevel- and the Yogi-branch, together with new-mathematics.
I’m confident to get ready before this weekend (and tomorrow we have a holiday here).I’m done with
cardreader.cpp cardreader.h Configuration.h Configuration_adv.h ConfigurationStore.cpp ConfigurationStore.h fastio.h language.h LiquidCrystalRus.cpp LiquidCrystalRus.h Marlin.h Marlin_main.cpp MarlinSerial.cpp MarlinSerial.h motion_control.cpp motion_control.h
so far, working on “pins.h” which is a lot of work because of several new boards, that are defined in there.With the result it should be very easy to keep Morgan’s Marlin up to date with recent Marlin improvements.
If we are successful with this, the new trigonometrical functions might make it into the official Marlin too.Merging is a good practice for me to get deeper into the Marlin-code and to understand it.
-
June 18, 2014 at 21:25 #4817
Quentin Harley
KeymasterWe can go even more precise by only converting certain functions. Morgan inverse kinematics only use atan2 for instance. (another reason why to improve sqrt…)
Sin and Cos only used for forward kinematics, used only during homing, and calibration routines.
This should enable you to have a larger tan table.
also, cos(a) = sin(a+90)
found this:
-
June 18, 2014 at 22:01 #4841
Quentin Harley
Keymasterand this:
-
June 18, 2014 at 22:57 #4845
Quentin Harley
Keymastersomething weird going on… Arm turned wrong way around
on debugging:
SCARA_psi: atan=1.97 fatan=0.00
SCARA_psi: atan=1.96 fatan=0.00
SCARA_psi: atan=1.95 fatan=0.00
SCARA_psi: atan=1.94 fatan=0.00
SCARA_psi: atan=1.93 fatan=0.00
SCARA_psi: atan=1.91 fatan=0.00
SCARA_psi: atan=1.90 fatan=0.00
SCARA_psi: atan=1.89 fatan=0.00
SCARA_psi: atan=1.88 fatan=0.00
SCARA_psi: atan=1.87 fatan=0.00
SCARA_psi: atan=1.85 fatan=0.00
SCARA_psi: atan=1.84 fatan=0.00
SCARA_psi: atan=1.83 fatan=0.00
SCARA_psi: atan=1.82 fatan=0.00
SCARA_psi: atan=1.80 fatan=0.00Something is not right…
-
June 18, 2014 at 23:50 #4849
Quentin Harley
Keymasterfloat fsqrt(float num)
{
float x1 = num; //start it offx1 = x1-(0.5*(x1 – num/x1));
x1 = x1-(0.5*(x1 – num/x1));
x1 = x1-(0.5*(x1 – num/x1));
x1 = x1-(0.5*(x1 – num/x1)); // Four times should be enough…return x1;
}//float fsqrt(float num)
-
June 18, 2014 at 23:51 #4853
Quentin Harley
Keymasterdon’t know if it is quicker than the standard sqrt though…
-
June 19, 2014 at 15:42 #4857
RobertKuhlmann
ParticipantNews:
Merging goes on very good. I’ve corrected the errors in “new_mathematics”, especially in “math_tables.h” and they should work now. I’ll test them before I send out the next version, using an Arduino simulator.I have to refresh my C-skills. But it’s getting better every day. The arrays where defined wrong and therefor useless. But I’ve fixed that.
I’ll try a more radical approach to speed up sqrt. Take a look at this:
01: float squareRoot(float x) 02: { 03: unsigned int i = *(unsigned int*) &x; 04: 05: // adjust bias 06: i += 127 << 23; 07: // approximation of square root 08: i >>= 1; 09: 10: return *(float*) &i; 11: }It’s extremely fast and maybe it’s accurate enough for our purposes.
(found it over here: http://bits.stephan-brumme.com/squareRoot.html)Thanks go to Stephan Brumme for publishing and documenting this approach.
Similar to this it should be quite easy to use this approach for sq() as well (with no loss of accuracy of course).The new sin for example in new_mathematics.cpp now looks like this:
float rad2deg(float rad) { return (rad*4068)/71; } float fsin(float rad) { return SIN_TABLE[(int)(rad2deg(rad)*10)]; } //float fsin(float rad) -
June 20, 2014 at 12:28 #4881
RobertKuhlmann
ParticipantNext steps done:
I’ve done an array of three columns (one each for fsin(), fcos(), ftan() ) with 7854 rows.
7854 is (2*Pi*10000)/8 (truncated to int). This allows addressing the table this way:float fsin(float rad) { return TRIG_TABLES[rad*1250,0]; } //float fsin(float rad)TRIG_TABLES takes 94248 bytes.
Another table of 10001 rows for facos, consumes 40004 bytes, making facos look like this:
float facos(float num) { //num range is 1 >= num >= -1 //with 10001 rows (max index 10000, starting at 0) return ACOS_TABLE[(int)(5000-(num/2)*10000)]; }//float facos(float num)Merging the armlevel- and Yogi’s branch is completed and compiles with no errors. I’ll check this against the actual Marlin branch, write some math-test routines and speed measurement and put it on my Morgan today.
I’ll post the results as soon as possible.
The new math-routines and tables can be found here in advance:
http://reprap.org/wiki/File:Marlin_mathematics.zipGreetings
Robert -
June 20, 2014 at 13:05 #4885
RobertKuhlmann
ParticipantBaahhh. Arrays are limited to 32K, it seems. Need to work around that…
-> Three arrays instead of multidimensional though. No fundamental problem.
-
June 20, 2014 at 14:37 #4893
RobertKuhlmann
ParticipantMaths compiled now.
http://reprap.org/wiki/File:Marlin_mathematics.zipSize of Marlin now (armlevel+Yogi+new_mathematics):
229996 bytes used of 258048 available bytes. 😀 -
June 20, 2014 at 18:17 #4905
Quentin Harley
KeymasterThat makes it rather specific which electronics to use for Morgan… So glad it fit! Will give it a whirl this weekend!
-
June 20, 2014 at 19:48 #4909
RobertKuhlmann
ParticipantHi Quentin,
I think it will no become too specific.
256k should be available on any platform.Even the code is not ATmega-specific.
But I’ll have to break up the arrays further on, because my Arduino won’t work with this package (fw doesn’t boot). I guess it needs more free memory at startup, than just the few kilobytes I left him.
But even with e.g. 16k-rad-tables the accuracy should be good enough. If not we can use some tricks, because of the symmetries in sinus, cosinus and tangens.
Have a nice weekend, Quentin. And all of you Morgan-fans too, of course. 🙂
-
June 20, 2014 at 22:41 #4921
Quentin Harley
KeymasterI strongly suggest we use the same table for sin and cos, with an offset in the reading position. That will make the single table slightly bigger, but combined will be smaller.
-
June 21, 2014 at 10:19 #4925
RobertKuhlmann
ParticipantYou are so very right. 🙂
I’ll have to break up my work on Marlin between merging and new trig.-functions, because the merge isn’t working as expected.
So I’ll concentrate on finishing the maths first. -
June 21, 2014 at 16:01 #4929
RobertKuhlmann
ParticipantLooks like the “Quake-sqrt” is 7 times slower than ATmega’s sqrt:
2.1 SQRT(float) 10000 times <fast> s;<standard> s 0.71600003 s;0.10400000 s;…
Stephan’s sqrt doesn’t give useful results until now.
-
June 21, 2014 at 16:54 #4933
RobertKuhlmann
ParticipantI’ve got the fast approach running lately:
float fsqrt(float x) { long val_int = *(long*)&x; /* Same bits, but as an int */ val_int -= 127L << 23; /* Subtract 2^m. */ val_int >>= 1; /* Divide by 2. */ val_int += 127L << 23; /* Add ((b + 1) / 2) * 2^m. */ return *(float*)&val_int; /* Interpret again as float */ }//float fsqrt(float x)It’s significantly faster than sqrt(x):
2. Performance 2.1 SQRT(float) 10000 times <fast> s;<standard> s 0.26399998 s;0.68300004 s;I’ll calibrate and take a look if accuracy is good enough…
-
June 21, 2014 at 17:42 #4941
Quentin Harley
KeymasterLooks good so far…
-
June 21, 2014 at 18:10 #4945
Quentin Harley
KeymasterI notice there is a lot of rad – deg conversions going on at the moment.
Then inverse kinematics use degrees as an input because degrees are numerically larger – 360deg vs 2Pi radians
I propose we make the f functions degree based:
something like this perhaps?float fsin(float degf) { int degi = degf * 10; return SIN_TABLE[degi]; } //float fsin(float degf) -
June 21, 2014 at 23:32 #4957
RobertKuhlmann
ParticipantI’ve seen the conversions in Marlin_main.cpp too (e.g. sth. like “sin(f_delta[x_axis]/SCARA_RAD2DEG)” or similar).
In motion_control.cpp the sin-calls gets a rad in function mc_arc, but that isn’t in use in your armlevel-branch. So, yes, we can switch to sin(deg), cos(deg) a.s.o.
-
June 22, 2014 at 00:45 #4961
Quentin Harley
KeymasterI noticed PROGMEM does not support float values.
-
June 22, 2014 at 01:37 #4965
RobertKuhlmann
ParticipantYes. Arduino’s Reference says that. So we have to store the 32-bit representation of our floats and dereference and typecast on read. Unsigned int (is 32-bit long, as float is) is supported by PROGMEM arrays.
Good point. I was just wondering about the results I’ve gotfrom my fsin-tests.
Way to go:
The result values have to be stored in the array as the unsigned integer representation of the 32-bit float values.The function for fsin(deg) should look something like this (assuming only 900 values for 0.0°-90.0° are stored in the array):
float fsin(float deg) { int tmpswitch = 0; int index; if (deg > 270) {tmpswitch = 3;} else {if (deg > 180) {tmpswitch = 2;} else {if (deg > 90) {tmpswitch = 1;}}} switch (tmpswitch){ case 0: {index = (int)deg*10;} break; case 1: {index = 900-(int)deg*10;} break; case 2: {index = -(int)deg*10;} break; case 3: {index= -900-(int)deg*10;} break; }//switch (tmpswitch) return return *(float*)&SIN_TABLE[index]; } //float fsin(float deg)– untested –
That’s what we can learn from the fsqrt-function, that returns the 32-bit memory of an unsigned int as float.
And we need a little function to give us all the unsigned integers we need for the table (I think that’ll be no job excel can do. 😉 ).
-
June 22, 2014 at 12:28 #4969
RobertKuhlmann
ParticipantGood news I’d like to share to all readers here:
The new functions work now. We have a fast replacement for sqrt() and an extremely fast one for sin(), cos() and tan().
I’m looking forward to finish the new math-library today.
To get it to work, I had to take care of teh fact, that PROGMEM can not be addressed like normal memory, but has to be read out by prgm-read-commands (prgm-read-dword in our case).
The value-array can be declared like this:const float SIN_TABLE[901] PROGMEM = { 0.00000000000000000, 0.00174532836589831, 0.00349065141522373, 0.00523596383141958, 0.00698126029796155, ... };Access to the values in the array can be achieved this way:
for (int i=0;i < 900; i++) { union {float flt; unsigned long lng;} cvt; cvt.lng = pgm_read_dword(&SIN_TABLE[i]); ms.printFloat(cvt.flt,8); SERIAL_ECHOLN(""); }One little goody for attentional readers of this thread:
Output of floats with the precision you like can be done with MarlinSerial (include MarlinSerial.h for that), but you need to move the declaration of printFloat from the private to the public section. Usage: Look into the code-snippet above.Another goody. I do speed-measurement the folloewing way:
... SERIAL_ECHOLN(" 2.1 SQRT(float) 10000 times fsqrt s;sqrt s"); float starttime1=millis(); for (int i=0; i <= 10000; i++) { saveresult += fsqrt((i/100)); } float stoptime1=millis(); float starttime2=millis(); for (int i=0; i <= 10000; i++) { saveresult += sqrt((i/100)); } float stoptime2=millis(); SERIAL_ECHO(" "); ms.printFloat((stoptime1-starttime1)/1000,8); SERIAL_ECHO(" s;"); ms.printFloat((stoptime2-starttime2)/1000,8); SERIAL_ECHOLN(" s;"); ms.printFloat(saveresult,8); SERIAL_ECHOLN(""); ...(print saveresult to prevent compiler-optimization)
Greetings from Germany
Robert -
June 23, 2014 at 08:02 #5013
RobertKuhlmann
ParticipantFind me on Github:
https://github.com/RobertKuhlmann/Marlin_mathsI’ve uploaded my results to github. Replacements for sqrt, sin, cos and tan are operational and tested.
Speed is doubled for these.I’ve included an enhancement for Marlin_main.cpp for test-output to the serial monitor with command M998.
-
June 23, 2014 at 17:43 #5017
cocktailyogi
ParticipantHi Robert,
interesting concept nd impressive work, you have done there. Where are you living in Germany? I am german, as well.
At the moment I am not sure, if these optimizations will bring us into to the nessecary performance range with that small CPU, but I decided to do some measurements. I am testing the function calculate_delta() standalone on the hardware. My first results showed, that it needs 750-906µs to execute (from my SCARA-fork). This is far too slow, because we need to do it at least 200 times per second. This, means ca. 20% execution time only for maths-transform. Not much reliable time left for the planner and motion-control.
I wanted to test it also with your new-mathematics, but unfortunately, I am unable to compile it. On Arduino 1.5.6 beta it gives me “expected initialzer before PROGMEM”-error.
Another point to discuss:
We should use more than 900 values for the sine-tables, because this leads roughly to a position accuracy of 0.22-0.25mm. Could be better.Yogi
-
June 23, 2014 at 20:14 #5021
cocktailyogi
Participanthi again,
I found the reason for my compile-error: I did not knoe, that “avr/pgmspace.h” must be included. Now PROGMEM is operational.
By using optimized fsqrt(), execution time only reduced some µs, but is still in the area of 0.75-0.9ms .
The interesting part would be to optimise atan2() and pow(x,2).
Yogi
-
June 23, 2014 at 20:37 #5025
Quentin Harley
Keymasteratan2 is done already… Robert just needs to send me the files for testing.
Since we only use pow() to square the input, pow(x,2) can be replaced by the following:
square(x)
where it is defined as such
#define square(x) ((x)*(x))
-
June 23, 2014 at 20:54 #5029
Quentin Harley
KeymasterRobert, what is the current issue with fatan2 and facos?
-
June 23, 2014 at 21:01 #5033
-
June 23, 2014 at 23:13 #5037
RobertKuhlmann
ParticipantHello Quentin any Yogi,
I was very busy today so please excuse my late answer.
I’m not finished with facos and fatan2. I’m on business travel tomorrow and will work on, inclusive complete integration with the armlevel-branch with conditional defines in Configuration.h a.s.o.@Yogi:
We have some tweaks in the back, that may allow us to reach your requested speeds. I’ll take a look/try on that too.I’ll upload the integration requirements on GitHub as soon as possible, so that you can write test-routines more easy. I’m using M998 (in Marlin_main.cpp) because it is a realistic test-environment for later use in Marlin (especially when it comes to memory usage).
pow(x,2):
My tests with the sqrt-approach transfered to sq() were not better than sq() itself. I didn’t compare it to pow though.atan2:
The optimization-potential seems very good here, as soon as acos is up and running. I will try to finish my work on that tomorrow.@Yogi:
Yes, I’m living in germany. My mail address: github@robertkuhlmann.de (its a fresh address exclusively for dev.-exchange, so if spammed I can change it with only little effort).Greetings
Robert -
June 23, 2014 at 23:19 #5041
Quentin Harley
KeymasterNo Problem!
-
June 24, 2014 at 09:32 #5045
RobertKuhlmann
ParticipantI just finished a successful facos-test:
2.4 facos(num) 10000 times facos s;acos s 0.86300001 s;2.31200003 sMeasurements for fatan2 will follow…
-
June 24, 2014 at 09:46 #5049
RobertKuhlmann
ParticipantSpeed for fatan2:
2.5 fatan2(opp,adj) 10000 times facos s;acos s 1.18900001 s;2.03500008 sCode will be on GitHub during the day.
-
June 24, 2014 at 09:52 #5053
RobertKuhlmann
Participantsq() compared to pow:
2.1a SQ(float) compared to pow(x,2) 10000 times sq s;pow s 0.52300000 s;0.53399996 s -
June 24, 2014 at 12:16 #5057
Quentin Harley
KeymasterWhat is the maximum error in fatan2 with facos and fsqrt?
-
June 24, 2014 at 12:19 #5061
Quentin Harley
KeymasterI tried all the different accurate fast sqrt functions, and none beat the native routine in speed, except at the cost of accuracy…
Facos accuracy is adjustable. Have you done any tests printing?
-
June 24, 2014 at 14:57 #5069
RobertKuhlmann
ParticipantHi Quentin,
it seems to be my karma to be the last one to benefit from my work. I made some calibrations and they all worked well. But I still didn’t find the time to start a print. Well, I changed to your SDS-z-axis at last and it works like charm. My hotend is fixed and works, I just don’t find the time for an armlevel-calibration as the last step before printing. But working on the firmware was more interesting, challenging and, last but not least, time consuming. But that’s okay.GitHub is updated with new versions and additional files:
https://github.com/RobertKuhlmann/Marlin_maths/pulseLooking at the accuracy-tests, facos does a perfect job. I tested with 5000 entries in the acos table.
fsin() and fcos() could be faster with a more effective parameter-handling. I had to check them for their sign and handle deg values over 360 degrees. I didn’t check that, but do you know or can you figure out if we see deg-values outside the 0360 degree-range? If not we could set fsin(), fcos() and ftan() to “unsafe mode” and skip the parameter handling. That would save a lot of CPU-time.
sqrt and accuracy:
If accuracy of fsqrt is not good enough while an accurate sqrt-replacement isn’t faster, maybe a totally new approach is needed.
And with “totally” I also mean “radically”. E.g.: Why don’t we move all trigonometric and other expensive calculations completely from the microcontroller? It should be possible to write a GCODE-postprocesoor that accepts the fundamental parameters (calibration-results) of a Morgan. It could then precalculate all the planning and motion-control prior to printing, resulting in a big GCODE+-file (as I would call it). C would only have to execute the prepared low-level-commands.
The low-level-commands could be realized as an extension to GCODE.Didn’t anyone ever thought about such an approach? Or are there any objective arguments not to give this a try? Doesn’t sound too complicated to me.
-
June 24, 2014 at 15:01 #5073
RobertKuhlmann
ParticipantLost my mind, though. I took my Arduino with me on my business travel, but forgot to take the USB-cable too. 😮
Brain -> working on Marlin/Morgan -> nothing left for other processes -
June 24, 2014 at 16:23 #5077
cocktailyogi
ParticipantHi Robert,
respect, your business travel seems to be less interesting 😉 🙂 hehe
Thanks for your great work. I will start testing with it now and report later.
I have thought about your gcode-postprocessor idea. One technical problem would be communication-speed. 250000baud will not be enough to transfer data in realtime and avoid buffer underrun. We also should keep in mind, that there are two ways to optimize performance: Software-optimization or better CPU. Also code-readability is important and some optimisation-paths reduce this. Actually the Marlin-team seems to prefer better hardware on the roadmap.
If we compare costs of a 32bit ~100Mhz Board (i.e. Arduino DUE/Ramps-FD or Smoothieboard) it is not more expensive than a RAMPS/MEGA-Kit. So we should keep thi soption in mind.
But software-improovement is interesting and makes fun, we also can learn a lot. So lets tune it a little bit:
I did some research, what thinks cost most performane on Atmel 8bit-CPUs:
– floating point maths
(could be worth to move to fixed point, but also much work. Marlin-team seems to keep floating-point and move to faster hardware in future. Maybe we should onl move to FixPoint in reverse-Transform?)
– Division-maths a=b/c
(We have lots of divisions, I will see, what I can do.)
– trigonometric operations
(Robert is already on it.)Specially we have a combination of all 3….
I found some libs, which may be useful, Robert. Maybe it saves you some work?
fixed-point-libs
http://sourceforge.net/projects/avrfix/Trignometric-lookuptable and maths:
http://blog.oscarliang.net/enhanced-arduino-c-custom-math-library/Kind Regards,
Yogi -
June 24, 2014 at 17:13 #5081
RobertKuhlmann
ParticipantHi Yogi,
I think I have to complete the picture I’ve outlined above.I think GCODE+ has to be brought to the micro-controller via SD-card, network or similar. Most boards support SD-cards to enable printing independently of a connected PC.
GCODE+ only would be larger, due to containing printer-dependent commands. But these commands wouldn’t need any further calculations, but could be executed directly on the printer hardware (e.g. containing steps/motor, instead of distances or coordinates).
I want to use the existing hardware (even the older models) instead of waiting or paying for upgrades. That saves ressources, not just money.Lets just unburden the micro-controllers from trigonometry and stuff. They aren’t built for that anyway.
After finishing MATH_SPEED_LEVEL_IV I will try to analyze what has to be done to achieve these goals. I have a strong feeling it may work (usually a good sign).
Another idea I have in my mind is quite similar to yours, regarding fixed point mathematics, instead of floating point. The more radical approach (I like radical approaches, you see? 😉 ) is to only use integer-arithmetic at all. Considered in more detail, the “world” we are thinking about isn’t contingented by rational numbers, but integers. E.g. the building space of any printer has a limited number of points where we can deposit plastic. One layer with e.g. 200mm x 200mm in a resolution of 50 microns effectively has 4000 dot x 4000 dots.
Any connection between two of these dots can be reached by sending a determined amount of step-commands to two stepper motors. In fact nothing we really need trigonometry for. Even arcs in this rastered world are only approximated, where real math would describe them as round.So instead of struggling with sqrt-COU-cycles we would have replace floating point mathematics with algorithms for a determined raster world. Sounds promising to me.
The drawback of this approach might be the memory required, but that’s only a feeling.Greetings from the train
(more from my hotel room)
RobertP.S:: And, yes, the travel is less interesting than Marlin/Morgan/Arduino 😀
Will arrive in Cologne soon… -
June 24, 2014 at 18:00 #5085
cocktailyogi
ParticipantHi Robert,
crasy idea, sounds possible. But we are getting off-topic. Forgive me, my short-term goal is to get my printer ready to print parts for my next printer 🙂
I managed to reduce execution-time of the reverse-tranform by factor of 2 (!!!!) only by killing 2 useless divisions.
Execution time went from 700-900µs to 350-400µs. I will patch the fix and another bugfix into my github-tree later.
At the moment I am plying with your maths-lib, but my Arduino-toolkit alwas complains about “… not declared in this scope”. I cannot find any missing include. You should not forget to give oscarliang some credits in your lib. There is some copy-paste 😉
Yogi
-
June 24, 2014 at 18:39 #5089
cocktailyogi
ParticipantI managed to reduce execution-time of the reverse-tranform by factor of 2 (!!!!) only by killing 2 useless divisions.
Execution time went from 700-900µs to 350-400µs. I will patch the fix and another bugfix into my github-tree later.
It seems, I opened beerbottle too early. Code was patched to death…. forgot a typecast. Now it only saves 10µs… Sorry for that!
-
June 24, 2014 at 21:46 #5093
RobertKuhlmann
ParticipantYou won’t believe that:
They charge 5€/hour for internet in my hotel! They are crazy! I went to my favorite restaurant in cologne and I am online here for free (have a Telekom hotspot flatrate though).@Yogi: I know that feeling soooooo well. 😉
But that’s okay. When measuring performance always keep in mind, that the compiler may optimize.The printer that primarily has to print for me is under construction in parallel (a RepRapPro Mendel, but not bought from them). But Morgan is where my heart beats. I loved the concept from start. Okay, I forgot to print something with it until today, but after seeing the first calibration patterns scratched into my aluminum building platform in best accuracy (my hotend didn’t work that day), I was sure being on the right track to contribute to Quentin’s idea.
I had Oscar Liang in the code-comments but removed him, because he isn’t the original source of this idea, just published and documented it. I thank him for doing so, nevertheless.
By the way: Where did you see copy&paste from Oscar? There’s nothing left, but I admit, he pointed to the right direction.I’ve updated GitHub. Marlin.h was missing. I think you’ll have to merge my files with yours to get a working Marlin.
I’m using WinMerge for that: http://winmerge.org/
Really good tool to compare and merge files and hole directory-trees.And we’re anything but getting off-topic. 😉 (topic is “Scara kinematics and CPU-performance”) Nobody is more ontopic, than we are. 😀
But I can understand that you want quick results. Sometimes I want them too. But then there shows up an interesting problem that waits to be solved and I can’t hold on me any longer, leave my printing plans behind and solve that new problem, that’s blinking and flashing so interesting. 🙂
Since I’ve started to work on software problems in my job again (I paused for several years with that) it’s like a drug again. Thinking new ways and solving problems others didn’t or failed with, is what I like the most. That’s where my sympathy to radical solutions originates.So lets take a look at 3D-printer electronics on a basic level:
The micro-controller combined with driver shields for external devices as stepper motors, endstops and displays needs information on how exactly to drive these units to get the result we want.
On the other hand every slicer software translates 3D-models into a unified language that describes them layer- and coordinate-oriented. So why should the micro-controller do additional translation work? Something it was never designed for? Lacking of fast memory its main purpose is to drive the external I/Os most effectively and precisely.
Whereas your PC has the capabilities to calculate the behavior of whole planetary systems in parallel, but we only let him transform 3D-models to 2D-command-lists.
I think, let the PC do his job and cut the food for the micro-controller in pieces that fit into its (tiny, memory and CPU-power lacking) world.Lets take a more detailed look into the problem:
GCODE says: “Do a move from A to B while a certain extruder is active and do this with a certain speed.”
It reads like this “G1 X12.45 Y11.47 F2500”
Our micro-controller remembers the last coordinates where he thinks the printer head should be, and now “the mc” starts to calculate how to reach the given endposition within the shortest way, and how exactly it has to manage the steppers to achieve that?
Why not let the PC “play” this scenario in its gigantic memory with its overwhelming CPU-power and tell the poor, power and memory lacking MC the result of the PC’s finger exercise?And this for the price of a few extra commands in the Marlin firmware, leaving the rest of it untouched and therefore compatible with existing procedures and software? The longer I think of it, the more i love it.
We only need to transfer the calculation work to the PC and write the results into the GCODE. I’ll definitely work on that for the next days.
Maybe I’ll print something when there’ll be a pause. But lifting Marlin to the next performance level sounds far too interesting to leave it undone.One final statement why I’m so interested in this topic:
I called a folk in Berlin a few days ago to print me some parts for my Morgan (for the SDS-z-axis andmore). He is a very experienced maker of 3D-printers and delivers excellent print-quality.
When I told him I was working on a Morgan he stated, that he does like the concept but thinks it’s to slow and not competitive in speed and accuracy. I’m totally contrary to his opinion and his criticism on Morgan motivated me to intensify my contribution to make Morgan an overall success.
There are details in Morgan’s design, that make it superior to many other printers, even if most of them weren’t noticed in public until now. E.g. the correlation and dependency between building platform an z-axis. Morgan’s printings are much more immune to Morgan’s frame-movements while the print process than any other printer I’ve seen.
The Psi-Theta-arms and their drive allow extreme precision with simplest materials. You can build this printer with almost no experience, getting a precision you’ll have to invest months for, when building a Prusa or Mendel.
Improvements on Quentins’s design can be done with ease and you can freely decide how much oney or ressources you wnat to invest to improve buildspace or precision.
The concept of Morgan is ingenious. So I’m willing to give my 2 cents to help on its success.Of course, GCODE+ will improve any existing 3D-printer, not only the Morgan. But hearing Morgan is inferior, just because its mathematics are a bit more complicated than that of other 3D-printer models, is not acceptable.
Sounds like I’ve got a lot of work to do in the next weeks. 😉
-
June 25, 2014 at 10:10 #5105
Quentin Harley
KeymasterGreat reply Robert!
I also disagree with the critics, perhaps because Morgan is my child, but mostly because there is more going for this design than against.
Go check what people said when they saw Morgan for the first time on Hack-a-day. Yet it is printing, and people with other 3D printers wants to know what I did to get my machine to print intricate pieces to cleanly.
To be frank… I don’t always know the answer to that question.
-
June 25, 2014 at 14:53 #5109
cocktailyogi
ParticipantHi Robert,
nice and interesting discussion. I fully agree with you about Morgan Hardware and design-concepts. But you are wrong, there are other people, which also realised the genius in this concept-design, espeacially the Z-Axis impressed me and motivated me to build one. 😉 hehe
But the weak point here are the nonlinearities and computations. “Weak” means not unsolvable and not worth to do it.
In my opinion the limiting parts of inaccurateness on the Morgan will not be caused by mechanics (it is good!), but it is caused by software.
I have some other projects and ideas also going on. So please forgive me, I do not have the ressources to finish that job completely.As physicist and product-tester I am always open for new concepts. Regarding your GCODE+ idea I am completely on the other side 🙂 So let us have a good discussion 😉
From my point of view it would be a step back because your are putting printer-specific stuff back to the computer. Sure, you would answer, that the slicing process is also machine-specific. Yes, you are right, for me the PC-based slicing is also only a temporary step in printing-development.
To make my vision clear:
If you look at it from the interface-side, it is always good, to standarise interfaces, and this should never happen machine-specific. GCODE are doing this, unfortunately the slicing process is machine-specific, so this is resulting in machine-specific code. My vision is to put the slicing-process also into the printer. Then you could have only STL-files and send them to the machine. The machine will take care of everything else. This make it possible to eleminate all machine-specific from the interfaces. Unfortunately, this will need MORE performance on an embedded-system.The ideal target setup would be a small embedded-board. I.e.: Beagleboard. Even better would be a ZYNQ-Processor, which has buildin FPGA-Unit. Then we could have full realtime-capabilities and fast motion-control with very high precision. This stuff is today already available for 50-120$ and prices are dropping. In future our children will receive STL-files per Smarthone and send it via WIFI to the printing unit. This might be in Supermarket or at home.
Are we still on topic? *smile*
What do you think?
Yogi
-
June 25, 2014 at 16:37 #5113
Quentin Harley
KeymasterHi CY
I am currently working on implementing Morgan kinematics on Smoothieware. That should give it more space to breathe.
Will do a post on it when working.
Q
-
June 26, 2014 at 13:11 #5121
RobertKuhlmann
ParticipantHi Yogi,
(sorry for answering that late, but there was no internet on my train back, yesterday).I’m not with you, when you argue to integrate more computations into the printer-electronics.
Your own PC can easily and with best accuracy calculate the printer commands for many files and several printers (if you own more than one) and still is good enough for its normal PC-tasks.But the printers already out there have a weak micro-controller with a spit of memory, running on frequencies my armclock would be ashamed of.
You’re right: Accuracy is a matter of software, prior to mechanics. Of course the basic concept of a printer limits its abilities, but with good parts and good work the physical basis can be brought to a very good accuracy. What we can do with software, on the other hand, shouldn’t be limited by the investment into the printer.
I’d far more like to build several Morgans with, let’s say, 60$ electronics, where I have to precalculate the printjobs om my notebook first, than to build them with e.g. 100$ electronics, just to let them do a task my notebook would still outperform by any measure.Your argument about standards and interfaces is okay. But even GCODE+ would be a standardized interface, only the content would be machine specific, what is, as you’ve stated yourself, the case even in GCODE today. Even in GCODE you have to specify the nozzle-width, the print-material a.s.o.
My point is to move some specific tasks of the printing process onto a platform that it’s far more suitable for and leave the (mathematically) simple part work to the micro-controller.
Your vision of sending the STL-files to “the machine” is okay. If I built a printer farm, I would invest into one PC that manages all print jobs, precalculates them and delivers the results to the several micro-controllers.
I’d call it the thin-client approach, transformed to the 3D-printer-level. Whereas your fat-printer-client would be interesting, if you need only one single printer, and even then you’d still have you PC for other tasks and just not use it for 3D-print-jobs.I’ll transfer the caculations to a seperate for my PC and publish the results in a few days (it’s not a very complicated task though). And it will be using the most accurate floating point datatypes available on my platform to get the most accurate results. After the concept is proofen in praxis I’ll try to realize it with a special math library that allows (almost) unlimited accuracy.
I can’t follow your point of smart boards being cheap and still keep going down in price. More COU-power and more memory always costs more ressources. And sophisticated printer-electronics are not available everywhere. But especially availability is that central important point with RepRap. Everybody everywhere should be able to build one. And therefor the count and the level of complexity of the required parts should be as low as possible. That’s what makes my concept of outsourcing maths from the micro-controller fit better into the philosophy of RepRap. I think. 🙂
-
June 26, 2014 at 19:36 #5129
cocktailyogi
ParticipantHi Robert,
I can see your point and I think I also made my point clear. More dicussion on this does not make sense to me. We are talking about two complety different user concepts. The crowd will decide in the next few years.
Let us ste back to your Idea. Why GCODE+? If I got it right, you want to recode the GCODE from the slicing-tool?
Maybe you can get easier, what you want. The GCODE in 3Dprinting was designed for cartesian systems. All slicers do GCODEs in XYZ … the Deltas and SCARAs try to transform it in microcontroller (we have discussed this before already), while the XYZ-Printer yust moves.
Yust make an open-source Slicer like SLIC3R SCARA-compatibel. Add a new Gcode “move theta and/or psi in degree” and add kinematics selection to slicing-tool. The Slicer has to be converted to do the optimised for SCARA. Then the slicer could generate standard-gcode and you will not get bigger files than nowadays with a cartesian printer.Yogi
-
June 26, 2014 at 21:28 #5137
RobertKuhlmann
ParticipantHi Yogi,
that would bind the user to that specific slicer or one that is “scara-compatible”, while a post-/pre-processor would be independent from the slicer as well as the actual Marlin-firmware version, as long as it contains the low scara-low-level commands.
But what I like the most: Any Morgan-owner would benefit from GCODE+ without any modification or invest. Just update your Marlin-firmware and use the preprocessor for your GCode-files before printing.
And, yes, it’s not about one concept being superior over another, but different aspects of how to look at specific problems with 3D-printing.
-
June 26, 2014 at 21:28 #5141
Quentin Harley
KeymasterI can see the merit of both schools of thought. Nicholas Seward runs a preprocessor on all of his exotic printers because the uP simply would not have the guns to do the math.
The other side of the coin, is that I see users at house4hack that are very inexperienced with 3D printing, and adding another step would complicate their lives even more. I have set up a machine running Octoprint on a raspberry pi, that automagically slices the STL using a tuned cura profile in order to make printing as easy as possible for them. These guys do not want to learn how to print. They just want the printed item.
I am a different user altogether, and like to fine-tune my settings for each project.
Morgan need to be a machine for all, and printing straight out of software like Cura would be a mandatory feature for a commercial ready system. Not a toy for makers. A tool for people with ideas, regardless of their backgrounds.
I quite like where this tread has taken us, from a point where the firmware is not quite coping at speed, to a point where it is almost possible.
Morgan is a product of this mantra. “Just because it is impossible today it does not mean that it is indeed impossible. If you want a maker to succeed, you need to tell him/her this idea would never work…”
You will excuse me if I remain positive about my project 😉
Q
-
June 27, 2014 at 23:06 #5149
RobertKuhlmann
ParticipantMorgan need to be a machine for all, and printing straight out of software like Cura would be a mandatory feature for a commercial ready system. Not a toy for makers. A tool for people with ideas, regardless of their backgrounds.
I agree with that too. That would mean to my approach to integrate the preprocessor into e.g Cura. First it has to and will be an external tool, but integrating it into the printing-process should be no problem as long as we talk about Open Source projects like Cura.
You will excuse me if I remain positive about my project 😉
Of course not. 😉
By the way: The “Forschungszentrum Juelich” (a scientific institute) will build several Morgans by some of their trainees. They will, if they do as I asked them, put them on the Morgan-world-map, as soon as they have finished the builds.
I support them with infos and links.Hey. Weekend. Time to start a print on my Morgan – finally. 😉
-
-
June 29, 2014 at 19:15 #5165
Quentin Harley
KeymasterHow is the printing going? I am busy with a large print for a customer on my first Morgan while I work on the firmware on the other.
-
June 29, 2014 at 19:29 #5169
RobertKuhlmann
ParticipantHi Quentin,
I’m in on it. In a few minutes I’ll begin some test-prints. Of course I was busy until now (had to help my father with a computer-problem). It seems something always wants to keep me from printing. 😉
Some results on the new math-library so far?
-
June 29, 2014 at 21:00 #5193
Quentin Harley
KeymasterI had to stop tinkering for a while to actually print something for a client. Will get beck into it next week.
I am also making progress in the smoothie firmware – At least I have something that can compile now without spitting out lots of errors…
Untested, and probably not working at all – but a start.
-
July 1, 2014 at 00:21 #5209
Quentin Harley
KeymasterYou want speed… here is speed!
Not completed yet, but at least I have something to show.
Q
-
July 1, 2014 at 12:42 #5213
RobertKuhlmann
ParticipantImpressive. So where can I find Smoothie?
-
July 1, 2014 at 20:17 #5221
-
July 2, 2014 at 10:20 #5249
RobertKuhlmann
ParticipantSounds and looks good. And a competitive price from start (with only relatively small amounts built, I guess). Promising…
With 120MHz speed seems to be no problem.;)
-
July 2, 2014 at 18:54 #5253
Quentin Harley
KeymasterNow it seems they ran out of stock…
Who has been buying?
-
July 21, 2014 at 15:06 #5493
cocktailyogi
ParticipantHi guys,
I did some runtime-comparism of Roberts new math-libs in combination with reverse-transformation-function calculate_delta().
I tested it alone on the Arduio Mega 2560 und ideal circumstances and measured the execution time.
calculate_delta() standard: average execution time: 800 ms
calculate_delta(), tuned with Roberts fatan2(), based on lookup tables:
average execution time: 720 msIt does not save much time. Maybe solving the transformation in integer-maths coul help.
Kind Regards,
Yogi-
July 21, 2014 at 21:00 #5505
cocktailyogi
ParticipantSorry, I have written wrong units.
It should be:
calculate_delta() standard: average execution time: 800 µscalculate_delta(), tuned with Roberts fatan2(), based on lookup tables:
average execution time: 720 µs
-
-
-
AuthorPosts
- You must be logged in to reply to this topic.

