Parcourir la source

Fix and combine JD condition

Scott Lahteine il y a 4 ans
Parent
révision
c55475e8e7
1 fichiers modifiés avec 79 ajouts et 79 suppressions
  1. 79
    79
      Marlin/src/module/planner.cpp

+ 79
- 79
Marlin/src/module/planner.cpp Voir le fichier

@@ -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
 

Chargement…
Annuler
Enregistrer