Wallacoloo / printipi

3d printing directly through the Raspberry Pi's GPIO pins
MIT License
141 stars 43 forks source link

Consider per-axis acceleration scheme #87

Open Wallacoloo opened 9 years ago

Wallacoloo commented 9 years ago

Currently, acceleration / velocity planning is done in cartesian space, as this is an easy way to keep the axes synchronized. As the motion planning system is altered to support corner rounding, this also presents a good opportunity to approach acceleration from a per-axis point of view instead (which would take care of #50 as well).

The current scheme for planning (linear) motion is as follows:

  1. Describe a unit velocity vector in cartesian space.
  2. Send this velocity vector to each AxisStepper and ask at what time it should be +1 step from its current location, +2 steps, +3, ...
  3. Apply a function that transforms the times planned under unit-velocity into a trapezoidal velocity function (i.e. constant acceleration).

And then of course, schedule the step event. Arcs are basically the same, just with sending different info to the AxisSteppers in step 2.

The benefits of this system lie in that acceleration is abstracted from the individual coordinate system mathematics, which means that one could implement a constant acceleration system, a jerk system, or any other acceleration system without having to implement it individually for each coordinate system and all coordinate system-specific functions can pretend they're operating at constant velocity.

The downside is that most of the time, the quantity that should be limited is the acceleration of the stepper motors, not the acceleration of the end effector.

There are probably a few ways in which we could introduce axis-based acceleration.

(1) Use the first 2 steps as-is, but modify the 3rd step. For each axis, we ask the coordinate system for the maximum cartesian velocity and acceleration along this curve that will meet the axis limits. We calculate this for each axis and then take the min of each parameter. Finally, construct a trapezoidal cartesian velocity curve and use that to transform the step times in the way that we normally do. Essentially, this is still constant cartesian acceleration for each segment, but computing that acceleration (and maximum velocity value) such that axis acceleration and velocity limits are never violated.

While this should always obey the set limitations, it will at times plan motions at a slower velocity than is strictly necessary. This can actually be mitigated by subdividing each cartesian line into smaller segments (and similarly with subdividing cartesian arcs into shorter arcs) - no path accuracy is lost in this form of subdividing, and the more the segment is subdivided, the more the velocity function converges to the maximum possible velocity. It also requires separate implementations for lines and arcs and assumes a constant-acceleration system. It does provide some insight into the maximum exit velocity of each segment by looking at the maximum velocity along the arc that connects it to the next segment and so forth.