|
@@ -2306,87 +2306,87 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
2306
|
2306
|
|
2307
|
2307
|
vmax_junction_sqr = junction_acceleration * junction_deviation_mm * sin_theta_d2 / (1.0f - sin_theta_d2);
|
2308
|
2308
|
|
2309
|
|
- if (block->millimeters < 1) {
|
2310
|
|
- const float neg = junction_cos_theta < 0 ? -1 : 1,
|
2311
|
|
- t = neg * junction_cos_theta;
|
2312
|
|
-
|
2313
|
|
- // If angle is greater than 135 degrees (octagon), find speed for approximate arc
|
2314
|
|
- if (t > 0.7071067812f) {
|
2315
|
|
-
|
2316
|
|
- #if ENABLED(JD_USE_MATH_ACOS)
|
2317
|
|
-
|
2318
|
|
- #error "TODO: Inline maths with the MCU / FPU."
|
2319
|
|
-
|
2320
|
|
- #elif ENABLED(JD_USE_LOOKUP_TABLE)
|
2321
|
|
-
|
2322
|
|
- // Fast acos approximation (max. error +-0.01 rads)
|
2323
|
|
- // Based on LUT table and linear interpolation
|
2324
|
|
-
|
2325
|
|
- /**
|
2326
|
|
- * // Generate the JD Lookup Table
|
2327
|
|
- * constexpr float c = 1.00751317f; // Correction factor to center error around 0
|
2328
|
|
- * for (int i = 0; i < jd_lut_count - 1; ++i) {
|
2329
|
|
- * const float x0 = (sq(i) - 1) / sq(i),
|
2330
|
|
- * y0 = acos(x0) * (i ? c : 1),
|
2331
|
|
- * x1 = 0.5 * x0 + 0.5,
|
2332
|
|
- * y1 = acos(x1) * c;
|
2333
|
|
- * jd_lut_k[i] = (y0 - y1) / (x0 - x1);
|
2334
|
|
- * jd_lut_b[i] = (y1 * x0 - y0 * x1) / (x0 - x1);
|
2335
|
|
- * }
|
2336
|
|
- * jd_lut_k[jd_lut_count - 1] = jd_lut_b[jd_lut_count - 1] = 0;
|
2337
|
|
- *
|
2338
|
|
- * // Compute correction factor (Set c to 1.0f first!)
|
2339
|
|
- * float min = INFINITY, max = -min;
|
2340
|
|
- * for (float t = 0; t <= 1; t += 0.0003f) {
|
2341
|
|
- * const float e = acos(t) / approx(t);
|
2342
|
|
- * if (isfinite(e)) {
|
2343
|
|
- * if (e < min) min = e;
|
2344
|
|
- * if (e > max) max = e;
|
2345
|
|
- * }
|
2346
|
|
- * }
|
2347
|
|
- * fprintf(stderr, "%.9gf, ", (min + max) / 2);
|
2348
|
|
- */
|
2349
|
|
- static constexpr int16_t jd_lut_count = 15;
|
2350
|
|
- static constexpr uint16_t jd_lut_tll = 1 << jd_lut_count;
|
2351
|
|
- static constexpr int16_t jd_lut_tll0 = __builtin_clz(jd_lut_tll) + 1; // i.e., 16 - jd_lut_count
|
2352
|
|
- static constexpr float jd_lut_k[jd_lut_count] PROGMEM = {
|
2353
|
|
- -1.03146219f, -1.30760407f, -1.75205469f, -2.41705418f, -3.37768555f,
|
2354
|
|
- -4.74888229f, -6.69648552f, -9.45659828f, -13.3640289f, -18.8927879f,
|
2355
|
|
- -26.7136307f, -37.7754059f, -53.4200745f, -75.5457306f, 0.0f };
|
2356
|
|
- static constexpr float jd_lut_b[jd_lut_count] PROGMEM = {
|
2357
|
|
- 1.57079637f, 1.70886743f, 2.04220533f, 2.62408018f, 3.52467203f,
|
2358
|
|
- 4.85301876f, 6.77019119f, 9.50873947f, 13.4009094f, 18.9188652f,
|
2359
|
|
- 26.7320709f, 37.7884521f, 53.4292908f, 75.5522461f, 0.0f };
|
2360
|
|
-
|
2361
|
|
- const int16_t idx = (t == 0.0f) ? 0 : __builtin_clz(uint16_t((1.0f - t) * jd_lut_tll)) - jd_lut_tll0;
|
2362
|
|
-
|
2363
|
|
- float junction_theta = t * pgm_read_float(&jd_lut_k[idx]) + pgm_read_float(&jd_lut_b[idx]);
|
2364
|
|
- if (neg > 0) junction_theta = RADIANS(180) - junction_theta;
|
2365
|
|
-
|
2366
|
|
- #else
|
2367
|
|
-
|
2368
|
|
- // Fast acos(-t) approximation (max. error +-0.033rad = 1.89°)
|
2369
|
|
- // Based on MinMax polynomial published by W. Randolph Franklin, see
|
2370
|
|
- // https://wrf.ecse.rpi.edu/Research/Short_Notes/arcsin/onlyelem.html
|
2371
|
|
- // acos( t) = pi / 2 - asin(x)
|
2372
|
|
- // acos(-t) = pi - acos(t) ... pi / 2 + asin(x)
|
2373
|
|
-
|
2374
|
|
- const float asinx = 0.032843707f
|
2375
|
|
- + t * (-1.451838349f
|
2376
|
|
- + t * ( 29.66153956f
|
2377
|
|
- + t * (-131.1123477f
|
2378
|
|
- + t * ( 262.8130562f
|
2379
|
|
- + t * (-242.7199627f
|
2380
|
|
- + t * ( 84.31466202f ) ))))),
|
2381
|
|
- junction_theta = RADIANS(90) + neg * asinx; // acos(-t)
|
2382
|
|
-
|
2383
|
|
- // NOTE: junction_theta bottoms out at 0.033 which avoids divide by 0.
|
|
2309
|
+ // For small moves with >135° junction (octagon) find speed for approximate arc
|
|
2310
|
+ if (block->millimeters < 1 && junction_cos_theta < -0.7071067812f) {
|
|
2311
|
+
|
|
2312
|
+ #if ENABLED(JD_USE_MATH_ACOS)
|
|
2313
|
+
|
|
2314
|
+ #error "TODO: Inline maths with the MCU / FPU."
|
|
2315
|
+
|
|
2316
|
+ #elif ENABLED(JD_USE_LOOKUP_TABLE)
|
|
2317
|
+
|
|
2318
|
+ // Fast acos approximation (max. error +-0.01 rads)
|
|
2319
|
+ // Based on LUT table and linear interpolation
|
|
2320
|
+
|
|
2321
|
+ /**
|
|
2322
|
+ * // Generate the JD Lookup Table
|
|
2323
|
+ * constexpr float c = 1.00751317f; // Correction factor to center error around 0
|
|
2324
|
+ * for (int i = 0; i < jd_lut_count - 1; ++i) {
|
|
2325
|
+ * const float x0 = (sq(i) - 1) / sq(i),
|
|
2326
|
+ * y0 = acos(x0) * (i ? c : 1),
|
|
2327
|
+ * x1 = 0.5 * x0 + 0.5,
|
|
2328
|
+ * y1 = acos(x1) * c;
|
|
2329
|
+ * jd_lut_k[i] = (y0 - y1) / (x0 - x1);
|
|
2330
|
+ * jd_lut_b[i] = (y1 * x0 - y0 * x1) / (x0 - x1);
|
|
2331
|
+ * }
|
|
2332
|
+ * jd_lut_k[jd_lut_count - 1] = jd_lut_b[jd_lut_count - 1] = 0;
|
|
2333
|
+ *
|
|
2334
|
+ * // Compute correction factor (Set c to 1.0f first!)
|
|
2335
|
+ * float min = INFINITY, max = -min;
|
|
2336
|
+ * for (float t = 0; t <= 1; t += 0.0003f) {
|
|
2337
|
+ * const float e = acos(t) / approx(t);
|
|
2338
|
+ * if (isfinite(e)) {
|
|
2339
|
+ * if (e < min) min = e;
|
|
2340
|
+ * if (e > max) max = e;
|
|
2341
|
+ * }
|
|
2342
|
+ * }
|
|
2343
|
+ * fprintf(stderr, "%.9gf, ", (min + max) / 2);
|
|
2344
|
+ */
|
|
2345
|
+ static constexpr int16_t jd_lut_count = 15;
|
|
2346
|
+ static constexpr uint16_t jd_lut_tll = 1 << jd_lut_count;
|
|
2347
|
+ static constexpr int16_t jd_lut_tll0 = __builtin_clz(jd_lut_tll) + 1; // i.e., 16 - jd_lut_count
|
|
2348
|
+ static constexpr float jd_lut_k[jd_lut_count] PROGMEM = {
|
|
2349
|
+ -1.03146219f, -1.30760407f, -1.75205469f, -2.41705418f, -3.37768555f,
|
|
2350
|
+ -4.74888229f, -6.69648552f, -9.45659828f, -13.3640289f, -18.8927879f,
|
|
2351
|
+ -26.7136307f, -37.7754059f, -53.4200745f, -75.5457306f, 0.0f };
|
|
2352
|
+ static constexpr float jd_lut_b[jd_lut_count] PROGMEM = {
|
|
2353
|
+ 1.57079637f, 1.70886743f, 2.04220533f, 2.62408018f, 3.52467203f,
|
|
2354
|
+ 4.85301876f, 6.77019119f, 9.50873947f, 13.4009094f, 18.9188652f,
|
|
2355
|
+ 26.7320709f, 37.7884521f, 53.4292908f, 75.5522461f, 0.0f };
|
|
2356
|
+
|
|
2357
|
+ const float neg = junction_cos_theta < 0 ? -1 : 1,
|
|
2358
|
+ t = neg * junction_cos_theta;
|
|
2359
|
+
|
|
2360
|
+ const int16_t idx = (t == 0.0f) ? 0 : __builtin_clz(uint16_t((1.0f - t) * jd_lut_tll)) - jd_lut_tll0;
|
|
2361
|
+
|
|
2362
|
+ float junction_theta = t * pgm_read_float(&jd_lut_k[idx]) + pgm_read_float(&jd_lut_b[idx]);
|
|
2363
|
+ if (neg > 0) junction_theta = RADIANS(180) - junction_theta; // acos(-t)
|
2384
|
2364
|
|
2385
|
|
- #endif
|
|
2365
|
+ #else
|
2386
|
2366
|
|
2387
|
|
- const float limit_sqr = (block->millimeters * junction_acceleration) / junction_theta;
|
2388
|
|
- NOMORE(vmax_junction_sqr, limit_sqr);
|
2389
|
|
- }
|
|
2367
|
+ // Fast acos(-t) approximation (max. error +-0.033rad = 1.89°)
|
|
2368
|
+ // Based on MinMax polynomial published by W. Randolph Franklin, see
|
|
2369
|
+ // https://wrf.ecse.rpi.edu/Research/Short_Notes/arcsin/onlyelem.html
|
|
2370
|
+ // acos( t) = pi / 2 - asin(x)
|
|
2371
|
+ // acos(-t) = pi - acos(t) ... pi / 2 + asin(x)
|
|
2372
|
+
|
|
2373
|
+ const float neg = junction_cos_theta < 0 ? -1 : 1,
|
|
2374
|
+ t = neg * junction_cos_theta,
|
|
2375
|
+ asinx = 0.032843707f
|
|
2376
|
+ + t * (-1.451838349f
|
|
2377
|
+ + t * ( 29.66153956f
|
|
2378
|
+ + t * (-131.1123477f
|
|
2379
|
+ + t * ( 262.8130562f
|
|
2380
|
+ + t * (-242.7199627f
|
|
2381
|
+ + t * ( 84.31466202f ) ))))),
|
|
2382
|
+ junction_theta = RADIANS(90) + neg * asinx; // acos(-t)
|
|
2383
|
+
|
|
2384
|
+ // NOTE: junction_theta bottoms out at 0.033 which avoids divide by 0.
|
|
2385
|
+
|
|
2386
|
+ #endif
|
|
2387
|
+
|
|
2388
|
+ const float limit_sqr = (block->millimeters * junction_acceleration) / junction_theta;
|
|
2389
|
+ NOMORE(vmax_junction_sqr, limit_sqr);
|
2390
|
2390
|
}
|
2391
|
2391
|
}
|
2392
|
2392
|
|