Hi, I’m trying to implement an input shaper for stepper linear motion to compensate fullstep/microsteps vibration. I already looked at how the current input shaper works—proxy kinematic and alter movement/position in time before iter solver. But I’m not sure it is possible to do what I want here. For example, there are several motors moving, and I want to do pulses for each one based on their phase. And because I have CoreXY, it simplifies nothing for me.
I currently want tight coupling with a specific stepper and stepper phase, so I added hooks to step compress code, specifically to queue_flush(), because I want to modify step timings a little before compressing. Here they are mapped one to one with steps.
For now, I am working on phase tracking for this, the basic idea looks like this:
static int
queue_flush(struct stepcompress *sc, uint64_t move_clock)
{
if (sc->queue_pos >= sc->queue_next)
return 0;
stepper_shaper(sc->oid, sc->queue_pos, sc->queue_next, sc->last_step_clock, move_clock, sc->sdir);
while (sc->last_step_clock < move_clock) {
struct step_move move = compress_bisect_add(sc);
int ret = check_line(sc, move);
if (ret)
return ret;
add_move(sc, sc->last_step_clock + move.interval, &move);
if (sc->queue_pos + move.count >= sc->queue_next) {
uint32_t diff = sc->queue_pos + move.count - sc->queue_next;
while (diff--)
stepper_shaper_far(sc->oid, sc->sdir);
sc->queue_pos = sc->queue_next = sc->queue;
break;
}
sc->queue_pos += move.count;
}
calc_last_step_print_time(sc);
return 0;
}
....
uint32_t diff(uint32_t a, uint32_t b) {
return (a >= b) ? (a - b) : (UINT32_MAX - b + a + 1);
}
void stepper_shaper(uint32_t oid, uint32_t *queue_pos, uint32_t *queue_next, uint64_t last_step_clock, uint64_t move_clock, int sdir)
{
uint32_t *qlast = queue_next;
uint32_t *pos = queue_pos;
struct tracker *stepper = &steppers[oid];
int msteps = (sdir) ? -stepper->msteps : stepper->msteps;
while (pos < qlast && last_step_clock < move_clock) {
stepper->mscnt = (stepper->mscnt + msteps) % 1024;
last_step_clock += diff(*(pos+1), *pos);
pos++;
}
}
void stepper_shaper_far(uint32_t oid, int sdir) {
struct tracker *stepper = &steppers[oid];
int msteps = (sdir) ? -stepper->msteps : stepper->msteps;
stepper->mscnt = (stepper->mscnt + msteps) % 1024;
}
But there is something off (it works for short moves and doesn’t for long), it does not work for long movements and I think I misunderstood some crucial parts of the code here, like time conversion, to track flushed steps reliably.
I would appreciate it if anyone had any ideas on what I’m doing wrong or maybe how to do it properly.
Thanks.