Git Product home page Git Product logo

Comments (13)

repetier avatar repetier commented on June 28, 2024

Great analysis of your problem.
I don't think the first step takes too long, also it does some extra work. What I think is, you reduced your jerk value too much and created a overflow for the first step.
You already islolated

printer_state.interval = CPUDivU2((int)v);

which computes the intervall. Your first speed v is StepsPerMM_MaxJerk/2.
The result of the above command is F_CPU/v < 65536
From this we get v_min = F_CPU/56636 = 245 for 16MHz.
From this we get
MinJerk = v_min_2/stepsPerMM
For 40 Steps per mm we get MinJerk = 12.25 mm/s
For 80 Steps per mm we get MinJerk = 6.125 mm/s

Please let me know, if my analysis is right.

from repetier-firmware.

repetier avatar repetier commented on June 28, 2024

Forget what I wrote at first. The interval is a long so no overflow here. The problem is explicit integration. The computation neglects the speed increase during the step computed. Normally no big error, but starting with no speed at all increases the error significantly. The inital speed is Jerk/2 so higher jerks reduce the error. See the example

v = speed in steps/mm i = timer step size

Jerk = 7, 80 Steps per mm
11:16:12.824 : v:280i:57142
11:16:12.890 : v:2278i:7024
11:16:12.890 : v:2519i:6352
11:16:12.890 : v:2743i:5833
11:16:12.890 : v:2950i:5424
11:16:12.890 : v:3138i:5099
11:16:12.890 : v:3317i:4824

Jerk = 40

11:17:36.137 : v:1600i:10000
11:17:36.137 : v:1949i:8209
11:17:36.137 : v:2236i:7155
11:17:36.195 : v:2487i:6434
11:17:36.195 : v:2711i:5902
11:17:36.195 : v:2917i:5485
11:17:36.195 : v:3105i:5153
11:17:36.195 : v:3284i:4872
11:17:36.195 : v:3454i:4632
11:17:36.195 : v:3615i:4426
11:17:36.195 : v:3777i:4236

so higher jerk values reduce the error (but increase the jerk which may be a problem with your repstrap)
The correct timing need the solution of a quadratic equation every step or an iterative solution, so they are too slow for an ordinary avr.
A simple solulution for your problem would be the following:

    printer_state.interval = CPUDivU2(v);

if(printer_state.interval>11200) printer_state.interval=11200; // Reduce step size to 0.7 ms
printer_state.timer+=printer_state.interval;

you just correct the high step duration if it occurs. This of couse eleminates the possebility of slow speeds if really needed. So perhaps you should just increase maxJerk after all.

from repetier-firmware.

alainm avatar alainm commented on June 28, 2024

My machine has a very high inertia, so increasing jerk in not an option :( We have group here in Brazil studying how to convert CNC milling machines into 3Dprinters. My step rate is also very high 315 steps/mm, speed=50mm/s, max acceleration=500mm/s/s

So, increasing jerk is not possible, neither is limiting slow speed. But it could be possible to calculate that first step interval separetly and include a simple test in the ISR...

Alain

Nossa lista: http://groups.google.com/group/microsdiy-br/about?hl=pt-BR

repetier [email protected] escreveu:

Forget what I wrote at first. The interval is a long so no overflow here. The problem is explicit integration. The computation neglects the speed increase during the step computed. Normally no big error, but starting with no speed at all increases the error significantly. The inital speed is Jerk/2 so higher jerks reduce the error. See the example

v = speed in steps/mm i = timer step size

Jerk = 7, 80 Steps per mm
11:16:12.824 : v:280i:57142
11:16:12.890 : v:2278i:7024
11:16:12.890 : v:2519i:6352
11:16:12.890 : v:2743i:5833
11:16:12.890 : v:2950i:5424
11:16:12.890 : v:3138i:5099
11:16:12.890 : v:3317i:4824

Jerk = 40

11:17:36.137 : v:1600i:10000
11:17:36.137 : v:1949i:8209
11:17:36.137 : v:2236i:7155
11:17:36.195 : v:2487i:6434
11:17:36.195 : v:2711i:5902
11:17:36.195 : v:2917i:5485
11:17:36.195 : v:3105i:5153
11:17:36.195 : v:3284i:4872
11:17:36.195 : v:3454i:4632
11:17:36.195 : v:3615i:4426
11:17:36.195 : v:3777i:4236

so higher jerk values reduce the error (but increase the jerk which may be a problem with your repstrap)
The correct timing need the solution of a quadratic equation every step or an iterative solution, so they are too slow for an ordinary avr.
A simple solulution for your problem would be the following:

printer_state.interval = CPUDivU2(v);
if(printer_state.interval>11200) printer_state.interval=11200; // Reduce step size to 0.7 ms
printer_state.timer+=printer_state.interval;

you just correct the high step duration if it occurs. This of couse eleminates the possebility of slow speeds if really needed. So perhaps you should just increase maxJerk after all.


Reply to this email directly or view it on GitHub:
#11 (comment)

from repetier-firmware.

repetier avatar repetier commented on June 28, 2024

Ok, here an alternative. Not sure if it works or is good enough. Change

   unsigned int v = ComputeV(printer_state.timer,cur->facceleration)+cur->vStart;
    if(v>cur->vMax) v = cur->vMax;
    printer_state.interval = CPUDivU2(v);
    printer_state.timer+=printer_state.interval;

into

   unsigned int v = ComputeV(printer_state.timer,cur->facceleration)+cur->vStart;
    if(v>cur->vMax) v = cur->vMax;
    unsigned long timer2 = printer_state.timer+(CPUDivU2(v)>>1);
    v = ComputeV(timer2,cur->facceleration)+cur->vStart;
    printer_state.interval = CPUDivU2(v);
    printer_state.timer+=printer_state.interval;

This would nearly double computation time but it is much more accurate over the complete acceleration/deceleration way. It simply uses the speed computed at the middle of the first iteration time. You still need some jerk to get it started but it will correct the computation in the second iteration considerably.
Don't forget you have to do it for acceleration and deceleration!

from repetier-firmware.

alainm avatar alainm commented on June 28, 2024

Sorry, that did not work, in fact the first delay went from 2.0 to 2.5 ms. And it also caused an error in the steps (not allways, could be from the extra work), see this: https://picasaweb.google.com/lh/photo/NoPH_GIB8pswaOreS2mS49MTjNZETYmyPJy0liipFm0?feat=directlink

I believe that the acceleration is quite good, I plotted it it is a nice ramp, look at it (I will make a propper plotting program...): https://picasaweb.google.com/lh/photo/xDDDFz-lvWHLXx6PzRNrtNMTjNZETYmyPJy0liipFm0?feat=directlink

The problem is not getting a better acceleration but computing the first step in a different way... I couldn't understand it so far because, if printer_state.timer==0, then ComputeV() should return 0 and I would get cur->vStart which should be right! So I made this change:

  if (printer_state.stepNumber==0) { // beginning acceleration
    printer_state.interval = CPUDivU2(cur->vStart);
    printer_state.timer+=printer_state.interval;
  }else if (printer_state.stepNumber <= cur->accelSteps) { // we are accelerating

but the first step only went from 2.0 to 1.5ms.

Ah, I got some new info: if I make two movemnts only 180ms apart, the extra delay disapears, but if I wait a little more (370ms) it comes back... (using Pronterface)

from repetier-firmware.

repetier avatar repetier commented on June 28, 2024

You must watch the context.

printer_state.stepNumber==0

tells only it is the first step of a new move. The firmware uses path planning, so if you have two moves coming fast, it will concatenate them and only ramp down as much as needed to avoid exceeding jerk. So in this case the second move does not start at the same speed, but a higher speed reducing the error.
To prefill the move queue, the firmware adds 3 dummy moves at the beginning of the first move. So it has some time to concatenate to the second move, which happens with your 180ms apart moves. If you wait longer, the first move starts and the firmware never changes a started move, so it begins at new.

What you try is finding a better solution for the first time step. The correct formula is:

2_timeStep^2=2_v_cur+acceleration*timeStep

What the firmware does is

v_cur = timeAccelerating*acceleration+v_start

Then it assumes constant speed over the next step to comute the time needed for the step
timeStep_approx = F_CPU/v_cur

what you need is a better approximation for v_cur<treshhold

My idea was an iterative solution, but as you said it doesn't converge or not fast enough. A second way could be to write down the correct solutions over a critical speed area and interpolate over this table. For higher speed values use the old computation.

from repetier-firmware.

alainm avatar alainm commented on June 28, 2024

Well, I tried to use that formula, but I probably got it wrong, if

2_timeStep^2=2_v_cur+acceleration*timeStep

then

timeStep= (acceleration+sqrt(acceleration^2+16*v_cur))/4

so I used this

  if (printer_state.stepNumber==0) { // beginning acceleration
    printer_state.interval = (cur->facceleration>>2)+sqrt((cur->facceleration*cur->facceleration)>>4+cur->vStart);
    printer_state.timer+=printer_state.interval;
  }else if (printer_state.stepNumber <= cur->accelSteps) { // we are accelerating

And the first step got even bigger, it went to 3.5ms.

Please help understand what should be the initial speed, apparently it is not cur->vStart...

The second step is allways right, so I tried to make a double iteration for step-0, like this:

  if (printer_state.stepNumber==0) { // beginning acceleration
    unsigned int v = ComputeV(printer_state.timer,cur->facceleration)+cur->vStart;
    printer_state.interval = CPUDivU2(v);
    v = ComputeV(printer_state.interval,cur->facceleration)+cur->vStart;
    printer_state.interval = CPUDivU2(v);
    printer_state.timer+=printer_state.interval;

but it got me 2.2ms so the problem it probably elsewhere...

from repetier-firmware.

alainm avatar alainm commented on June 28, 2024

I made something that works...

line 1455 I replaced this

if(cur->stepsRemaining) {
  cli();

with this, the intention being to remove the first step

if(cur->stepsRemaining) {
  cli();
  if (printer_state.stepNumber){  
  //....
  }//closing after all steps

and compensated it by adding a test to not decrease de first non-issued sttep

if (printer_state.stepNumber)
  cur->stepsRemaining--;

This is justa a proof of concept, but it shows that the problem is probably that something is happening between interrupts...

from repetier-firmware.

alainm avatar alainm commented on June 28, 2024

More news (I had help from a friend in US to rig that)...
I am setting one bit when in the ISR and another in the Besenham function, end reseting them at every exit. This is what is happening: https://picasaweb.google.com/lh/photo/efpMw4blaBsw5NjQ_Z6-1dMTjNZETYmyPJy0liipFm0?feat=directlink

The timing from the end of the ISR to the next ISR is correct 0,7ms. But a lot of things are happening before the ISR exits. I removed the call to sei() in line 1495 and the time between pulses went from 2.0 to 1.1ms.

This never happens in other parts of the movements, in this simple test that I am doing.

So I believe that the problem is ISR related. What could be done? Are some lenghty calculations somehere? Is there some place where a delay may exist? or is there some way of setting this ISR's priority higher?

Any suggestion would be wellcome :)

from repetier-firmware.

repetier avatar repetier commented on June 28, 2024

Ok, spend an other hour doing the math.

My problem is I don't know your parameter. What I need is your jerk value because v_start is jerk/2 for the first move. So i don't know if it's just the math approximation. I did a simple computation with excel for different start speeds, so you can see how large the error can get.

t_exact = 16000000_(sqrt(v_steps^2+2_faccel)-v_steps)/faccel ; correct formula, last one was not correct
t_approx = 16000000/v_steps
stepspermm 315 0,003174603
acceleration 500mm/s^2 faccel=157500steps/s^2

v (mm/s) v (steps/mm) t approx t exact
0 0 #DIV/0! 57015,73161
1 315 50793,65079 33381,90614
2 630 25396,8254 21713,43915
3 945 16931,21693 15654,79681
4 1260 12698,4127 12124,20794
5 1575 10158,73016 9855,213787
6 1890 8465,608466 8286,778522
7 2205 7256,235828 7142,366629
8 2520 6349,206349 6272,365397
9 2835 5643,738977 5589,498536
10 3150 5079,365079 5039,680117
11 3465 4617,604618 4587,708216
12 3780 4232,804233 4209,728949
13 4095 3907,203907 3889,025399
14 4410 3628,117914 3613,544583
15 4725 3386,243386 3374,382493
0,1 31,5 507936,5079 53905,46078
0,2 63 253968,254 50973,80631
0,3 94,5 169312,1693 48218,28129
0,4 126 126984,127 45634,86674
0,5 157,5 101587,3016 43218,18682
0,6 189 84656,08466 40961,72912
0,7 220,5 72562,35828 38858,09049
0,8 252 63492,06349 36899,2292
0,9 283,5 56437,38977 35076,70664

You see depending on start speed the difference between computed ticks per step and correct ticks per step can get quite large.
If you try to add the above formula like you did the last time consider the value range. Only with float calculations you can get the correct value but with floats this needs perhaps 10000 Ticks. The sqrt alone takes 5000 ticks.

from repetier-firmware.

alainm avatar alainm commented on June 28, 2024

Nice! I am trying to put that back into a spreadsheat, I cannot exactly figure what is v_steps, and the formulas. Could you please upload this to google doc, or send it to me (amlistas27_at_fastmail_dot_fm).

I would like to have a closer look at those calculations, using more realistic parameter for various situations could be very instructive.

As it may (or not) be of interest, my parameters are here: http://snipt.org/ufyg3

from repetier-firmware.

alainm avatar alainm commented on June 28, 2024

The last version is working perfectly :)
I tested many different situations without finding any problems...

I uploaded 2 new images here :
https://picasaweb.google.com/alainm789/SharedImages?authuser=0&feat=directlink

The only thing that I find odd is that now do_odd is even and do_even is odd ;-)

from repetier-firmware.

repetier avatar repetier commented on June 28, 2024

Thanks alainm.

Comparing the software with your logic analyzer really helped improving the timings. The improvements will be available in version 0.52.

from repetier-firmware.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.