📄 stepper-move.c
字号:
#include <stdio.h>#include <stepper-interrupt.h>#include <stepper-move.h>#include <limits.h>#if 0#define PRINTF(...) printf(__VA_ARGS__)#else#define PRINTF(...) do {} while (0)#endifstatic unsigned intisqrt(unsigned long x){ unsigned int r; unsigned int b2 = 0x40000000; unsigned int b = 0x8000; while(x < b2) { b2 >>= 2; b >>= 1; } if (b == 0) return 0; r = b; b >>= 1; while(b > 0) { r += b; unsigned int t = r*r; if (t > x) { r -= b; } b >>=1; } return r;}#define ACC_FIRST_UP 0#define ACC_K1_UP 1#define ACC_LAST_UP 2#define ACC_TOP 3#define ACC_FIRST_DOWN 4#define ACC_K1_DOWN 5#define ACC_LAST_DOWN 6#define ACC_END 7typedef struct _AccDiff AccDiff;struct _AccDiff{ long diff; unsigned long pos;};static inline longbase_acc(unsigned long t,unsigned long n, unsigned long l, unsigned long a_max){ long a; if (t >= n) { if (t >= n+l) { a = -a_max; } else { a = 0; } } else { a = a_max; } return a;}static AccDiff acc[ACC_END+1];StepperResultstepper_move(unsigned int stepper_index, unsigned long *periodp, unsigned long a_max,unsigned long v_max, long s_end){ unsigned long start_period = *periodp; unsigned long s; unsigned long ds; unsigned long l; unsigned long da0; unsigned long k1 = 0; unsigned long n = (v_max+a_max-1)/a_max; unsigned long a_speed_adj = v_max - (n-1)*a_max; unsigned long s_res; long d; if (s_end >= 0) { s_res = s_end/2; } else { s_res = (-s_end)/2; } d = s_res - (long)a_max*(n*n-1) - (long)a_speed_adj; acc[ACC_END].diff = 0; acc[ACC_END].pos = UINT_MAX; if (d < 0) { l = 0; n = isqrt(s_res/a_max); if (n*(unsigned long long)n*a_max < s_res) n++; a_speed_adj = a_max; acc[ACC_LAST_UP].diff=0; acc[ACC_FIRST_DOWN].diff=0; } else { l = (d+v_max-1)/v_max; acc[ACC_LAST_UP].diff= a_speed_adj - a_max; acc[ACC_FIRST_DOWN].diff= a_max - a_speed_adj; } acc[ACC_LAST_UP].pos = n-1; acc[ACC_FIRST_DOWN].pos = n+l; s = a_max*(n*n-1) + a_speed_adj + l * (a_max*(n-1) + a_speed_adj); ds = s-s_res; da0 = ds/(2*n+l-1); acc[ACC_FIRST_UP].diff = -da0; acc[ACC_LAST_DOWN].diff = da0; acc[ACC_FIRST_UP].pos = 0; acc[ACC_LAST_DOWN].pos = 2*n+l-1; ds -= da0*(2*n+l-1); acc[ACC_K1_UP].diff = 0; acc[ACC_K1_DOWN].diff = 0; acc[ACC_K1_UP].pos = 0; acc[ACC_K1_DOWN].pos = 2*n+l-1; acc[ACC_TOP].diff = 0; acc[ACC_TOP].pos = n; if (ds > 0) { k1 = (2*n+l -ds)/2; if (k1 < n) { acc[ACC_K1_UP].diff = -1; acc[ACC_K1_DOWN].diff = 1; acc[ACC_K1_UP].pos = k1; acc[ACC_K1_DOWN].pos = 2*n+l-1 - k1; ds -= (2*(n-k1)+l-1); } if (ds > 0) { acc[ACC_LAST_UP].diff--; acc[ACC_TOP].diff = 1; acc[ACC_TOP].pos = n+ds-1; } }#if 0 { unsigned int k; PRINTF("n=%ld l=%ld a_max=%ld v_max=%ld s_res=%ld\n", n,l ,a_max, v_max, s_res); for (k = 0; k < 7; k++) { PRINTF(" %ld@%ld", acc[k].diff, acc[k].pos); } PRINTF("\n"); }#endif { StepperResult res; unsigned int k; unsigned long t = 0; long da = 0; long a_prev = ULONG_MAX; for (k = 0; k < ACC_END; k++) { long a; da += acc[k].diff; if (acc[k].pos != acc[k+1].pos) { /* Next position is different */ if (t != acc[k].pos) { a = base_acc(t,n,l,a_max); if (s_end < 0) a = -a; if (a_prev != a) { res = stepper_add_acc(stepper_index, t+start_period, a); if (res != STEPPER_OK) return res; PRINTF("%d: %ld@%ld\n", stepper_index, a, t+start_period); a_prev = a; } t = acc[k].pos; } a = da + base_acc(t,n,l,a_max); if (s_end < 0) a = -a; if (a_prev != a) { res = stepper_add_acc(stepper_index, t+start_period, a); if (res != STEPPER_OK) return res; PRINTF("%d: %ld@%ld\n", stepper_index, a, t+start_period); a_prev = a; } t++; da = 0; } } res = stepper_add_acc(stepper_index, t+start_period, 0); PRINTF("%d: %d@%ld\n", stepper_index, 0, t+start_period); if (res != STEPPER_OK) return res; *periodp += t; } return STEPPER_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -