The MotionPlanner works on a step-by-step basis, only ever processing one stepper motor step at a time. However, each step is internally broken down into a series of OutputEvents (set pin x high, then set pin y low)
The result is that if two steps are scheduled at the same time, and each is composed of multiple OutputEvents, then although those OutputEvents will be scheduled for the right times, an OutputEvent set farther in the future might actually be sent to the scheduler before an event set closer to the present.
Consider the following table of 2 steps that each consist of 2 OutputEvents. Both steps are scheduled to occur at t=1.
The current algorithm will pick one of these steps, schedule it completely, and then repeat with the other step. Since they both begin at the same time, either one could be picked. Let's assume step 1 is scheduled first. Then, the order with which the OutputEvents are sent to the scheduler looks like:
step#1event#1 (t=1)
step#1event#2 (t=2)
step#2event#1 (t=1)
step#2event#2 (t=2)
Notice that step#1event#2, which occurs at t=2, is scheduled before step#2event#1, which should occur at t=1. Really, the events should be ordered like so (swap the 2nd and 3rd ones):
step#1event#1 (t=1)
step#2event#1 (t=1)
step#1event#2 (t=2)
step#2event#2 (t=2)
Although this bug is present everywhere, it only affects the the observable behavior on an unbuffered scheduler. Because an unbuffered scheduler cannot schedule a future event before executing the pending event, scheduling in the first order will cause the 3rd event to occur at t=2 (at best). In the DMA scheduler, which can buffer a few ms in the future, everything works OK.
The MotionPlanner works on a step-by-step basis, only ever processing one stepper motor step at a time. However, each step is internally broken down into a series of OutputEvents (set pin x high, then set pin y low)
The result is that if two steps are scheduled at the same time, and each is composed of multiple OutputEvents, then although those OutputEvents will be scheduled for the right times, an OutputEvent set farther in the future might actually be sent to the scheduler before an event set closer to the present.
Consider the following table of 2 steps that each consist of 2 OutputEvents. Both steps are scheduled to occur at t=1.
The current algorithm will pick one of these steps, schedule it completely, and then repeat with the other step. Since they both begin at the same time, either one could be picked. Let's assume step 1 is scheduled first. Then, the order with which the OutputEvents are sent to the scheduler looks like:
Notice that step#1event#2, which occurs at t=2, is scheduled before step#2event#1, which should occur at t=1. Really, the events should be ordered like so (swap the 2nd and 3rd ones):
Although this bug is present everywhere, it only affects the the observable behavior on an unbuffered scheduler. Because an unbuffered scheduler cannot schedule a future event before executing the pending event, scheduling in the first order will cause the 3rd event to occur at t=2 (at best). In the DMA scheduler, which can buffer a few ms in the future, everything works OK.