Marlin: Acceleration Issue in RC6

Created on 16 Sep 2016  Â·  5Comments  Â·  Source: MarlinFirmware/Marlin

I'm not sure if this is fixed in RC7 jet, but this faulty behaviour is not mentioned in the changes-log.

It is described as followed: (I always used 2mm/s^2 for testing)
If i change the max Acceleration with the M201 (for Example the X-Axis) Command, and i move that Axis by Hand with G0 X100 for Example, its behaviour changes between Accelerate from STOP to 100mm with the in M201 defined Value and stops immediately, and Fullspeed (i dont know what acceleration Value this is, its pretty fast) decelerate to 100mm with the in M201 defined Value.

  • so it don't accelerate and decelerate in one move
  • sometimes it wont decelerate or accelerate at all, there is no behaviour recognizable
  • if it accelerate or decelerate seems to depend on the distance the Axis have to travel, if the distances are the same, for example: G0 X10; G0 X20; G0 X30 it wont change its behaviour in accelerating or decelerating. But most of the Time it just decelerate from Fullspeed.

I also played with the other Acceleration Settings via G-Codes, nothing changes...

any ideas?

Potential ? Discussion More Data Testing Work

All 5 comments

First, check with RCBugFix in case we fixed this since RC6 and RC7 were tagged.

If it still shows the same problem, then I suggest trying the old (supposedly incorrect) acceleration code from before we updated it (based on Ultimaker's code) and see if it helps. To do that, replace this block in planner.cpp around line 1010…

block->acceleration_steps_per_s2 = ceil((block->steps[E_AXIS] ? acceleration : travel_acceleration) * steps_per_mm);
if (max_acceleration_steps_per_s2[X_AXIS] < (block->acceleration_steps_per_s2 * block->steps[X_AXIS]) / block->step_event_count)
  block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[X_AXIS] * block->step_event_count) / block->steps[X_AXIS];
if (max_acceleration_steps_per_s2[Y_AXIS] < (block->acceleration_steps_per_s2 * block->steps[Y_AXIS]) / block->step_event_count)
  block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[Y_AXIS] * block->step_event_count) / block->steps[Y_AXIS];
if (max_acceleration_steps_per_s2[Z_AXIS] < (block->acceleration_steps_per_s2 * block->steps[Z_AXIS]) / block->step_event_count)
  block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[Z_AXIS] * block->step_event_count) / block->steps[Z_AXIS];
if (max_acceleration_steps_per_s2[E_AXIS] < (block->acceleration_steps_per_s2 * block->steps[E_AXIS]) / block->step_event_count)
  block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[E_AXIS] * block->step_event_count) / block->steps[E_AXIS];

…with this block of code…

block->acceleration_steps_per_s2 = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
if(((float)block->acceleration_steps_per_s2 * (float)block->steps[X_AXIS] / (float)block->step_event_count) > max_acceleration_steps_per_s2[X_AXIS])
  block->acceleration_steps_per_s2 = max_acceleration_steps_per_s2[X_AXIS];
if(((float)block->acceleration_steps_per_s2 * (float)block->steps[Y_AXIS] / (float)block->step_event_count) > max_acceleration_steps_per_s2[Y_AXIS])
  block->acceleration_steps_per_s2 = max_acceleration_steps_per_s2[Y_AXIS];
if(((float)block->acceleration_steps_per_s2 * (float)block->steps[E_AXIS] / (float)block->step_event_count) > max_acceleration_steps_per_s2[E_AXIS])
  block->acceleration_steps_per_s2 = max_acceleration_steps_per_s2[E_AXIS];
if(((float)block->acceleration_steps_per_s2 * (float)block->steps[Z_AXIS] / (float)block->step_event_count) > max_acceleration_steps_per_s2[Z_AXIS])
  block->acceleration_steps_per_s2 = max_acceleration_steps_per_s2[Z_AXIS];

And, just to see if it makes any difference, you should also try this block of code, which is the same as the current code, but does some extra casting that might, possibly, have some effect....

block->acceleration_steps_per_s2 = ceil((block->steps[E_AXIS] ? acceleration : travel_acceleration) * steps_per_mm);
if (max_acceleration_steps_per_s2[X_AXIS] < ((float)block->acceleration_steps_per_s2 * (float)block->steps[X_AXIS]) / (float)block->step_event_count)
  block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[X_AXIS] * (float)block->step_event_count) / (float)block->steps[X_AXIS];
if (max_acceleration_steps_per_s2[Y_AXIS] < ((float)block->acceleration_steps_per_s2 * (float)block->steps[Y_AXIS]) / (float)block->step_event_count)
  block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[Y_AXIS] * (float)block->step_event_count) / (float)block->steps[Y_AXIS];
if (max_acceleration_steps_per_s2[Z_AXIS] < ((float)block->acceleration_steps_per_s2 * (float)block->steps[Z_AXIS]) / (float)block->step_event_count)
  block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[Z_AXIS] * (float)block->step_event_count) / (float)block->steps[Z_AXIS];
if (max_acceleration_steps_per_s2[E_AXIS] < ((float)block->acceleration_steps_per_s2 * (float)block->steps[E_AXIS]) / (float)block->step_event_count)
  block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[E_AXIS] * (float)block->step_event_count) / (float)block->steps[E_AXIS];

Also there's this variant, which might be a little bit faster, because it does less float math:

block->acceleration_steps_per_s2 = ceil((block->steps[E_AXIS] ? acceleration : travel_acceleration) * steps_per_mm);
if (max_acceleration_steps_per_s2[X_AXIS] < float(block->acceleration_steps_per_s2 * block->steps[X_AXIS]) / (float)block->step_event_count)
  block->acceleration_steps_per_s2 = (uint32_t)(float(max_acceleration_steps_per_s2[X_AXIS] * block->step_event_count) / (float)block->steps[X_AXIS]);
if (max_acceleration_steps_per_s2[Y_AXIS] < float(block->acceleration_steps_per_s2 * block->steps[Y_AXIS]) / (float)block->step_event_count)
  block->acceleration_steps_per_s2 = (uint32_t)(float(max_acceleration_steps_per_s2[Y_AXIS] * block->step_event_count) / (float)block->steps[Y_AXIS]);
if (max_acceleration_steps_per_s2[Z_AXIS] < float(block->acceleration_steps_per_s2 * block->steps[Z_AXIS]) / (float)block->step_event_count)
  block->acceleration_steps_per_s2 = (uint32_t)(float(max_acceleration_steps_per_s2[Z_AXIS] * block->step_event_count) / (float)block->steps[Z_AXIS]);
if (max_acceleration_steps_per_s2[E_AXIS] < float(block->acceleration_steps_per_s2 * block->steps[E_AXIS]) / (float)block->step_event_count)
  block->acceleration_steps_per_s2 = (uint32_t)(float(max_acceleration_steps_per_s2[E_AXIS] * block->step_event_count) / (float)block->steps[E_AXIS]);

I'd really like to make sure we truly understand the acceleration behavior so it's totally predictable and deterministic, and gets the right result, especially when combining X and Y movement.

P.S. I presume you are using a Cartesian printer and not a Delta. With a Delta we have to consider moves being split up into much smaller lines, and then kinematically transformed, and all that extra detail.

Yes its a Cartesian "Printer" (Actually its a printed Saw),
img_20160914_154455

But it just got Cops with a pitch of 2mm, by 1/8 micro-stepping on the Drivers and 1,8° Engines it need 800 steps for 1mm at each axis.

I will report after checking and trying out, thanks thinkyhead

That is one crazy looking robot!

Hihi you're right, on interest, i will show you the source if its done

I tested with RC7 now, and it works perfectly, should have tryed this first... sorry for this unnecessary bug-report :-(

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ahsnuet09 picture ahsnuet09  Â·  3Comments

Ciev picture Ciev  Â·  3Comments

Kaibob2 picture Kaibob2  Â·  4Comments

W8KDB picture W8KDB  Â·  4Comments

manianac picture manianac  Â·  4Comments