Browse Source

Comment/cleanup of motion code

Scott Lahteine 7 years ago
parent
commit
000b3b3117

+ 12
- 6
Marlin/src/feature/bedlevel/abl/abl.cpp View File

@@ -366,6 +366,7 @@ float bilinear_z_offset(const float raw[XYZ]) {
366 366
    * splitting the move where it crosses grid borders.
367 367
    */
368 368
   void bilinear_line_to_destination(const float fr_mm_s, uint16_t x_splits, uint16_t y_splits) {
369
+    // Get current and destination cells for this line
369 370
     int cx1 = CELL_INDEX(X, current_position[X_AXIS]),
370 371
         cy1 = CELL_INDEX(Y, current_position[Y_AXIS]),
371 372
         cx2 = CELL_INDEX(X, destination[X_AXIS]),
@@ -375,8 +376,8 @@ float bilinear_z_offset(const float raw[XYZ]) {
375 376
     cx2 = constrain(cx2, 0, ABL_BG_POINTS_X - 2);
376 377
     cy2 = constrain(cy2, 0, ABL_BG_POINTS_Y - 2);
377 378
 
379
+    // Start and end in the same cell? No split needed.
378 380
     if (cx1 == cx2 && cy1 == cy2) {
379
-      // Start and end on same mesh square
380 381
       buffer_line_to_destination(fr_mm_s);
381 382
       set_current_from_destination();
382 383
       return;
@@ -385,25 +386,30 @@ float bilinear_z_offset(const float raw[XYZ]) {
385 386
     #define LINE_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist)
386 387
 
387 388
     float normalized_dist, end[XYZE];
388
-
389
-    // Split at the left/front border of the right/top square
390 389
     const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
390
+
391
+    // Crosses on the X and not already split on this X?
392
+    // The x_splits flags are insurance against rounding errors.
391 393
     if (cx2 != cx1 && TEST(x_splits, gcx)) {
394
+      // Split on the X grid line
395
+      CBI(x_splits, gcx);
392 396
       COPY(end, destination);
393 397
       destination[X_AXIS] = bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx;
394 398
       normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
395 399
       destination[Y_AXIS] = LINE_SEGMENT_END(Y);
396
-      CBI(x_splits, gcx);
397 400
     }
401
+    // Crosses on the Y and not already split on this Y?
398 402
     else if (cy2 != cy1 && TEST(y_splits, gcy)) {
403
+      // Split on the Y grid line
404
+      CBI(y_splits, gcy);
399 405
       COPY(end, destination);
400 406
       destination[Y_AXIS] = bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy;
401 407
       normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
402 408
       destination[X_AXIS] = LINE_SEGMENT_END(X);
403
-      CBI(y_splits, gcy);
404 409
     }
405 410
     else {
406
-      // Already split on a border
411
+      // Must already have been split on these border(s)
412
+      // This should be a rare case.
407 413
       buffer_line_to_destination(fr_mm_s);
408 414
       set_current_from_destination();
409 415
       return;

+ 12
- 6
Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp View File

@@ -59,6 +59,7 @@
59 59
      * splitting the move where it crosses mesh borders.
60 60
      */
61 61
     void mesh_line_to_destination(const float fr_mm_s, uint8_t x_splits, uint8_t y_splits) {
62
+      // Get current and destination cells for this line
62 63
       int cx1 = mbl.cell_index_x(current_position[X_AXIS]),
63 64
           cy1 = mbl.cell_index_y(current_position[Y_AXIS]),
64 65
           cx2 = mbl.cell_index_x(destination[X_AXIS]),
@@ -68,8 +69,8 @@
68 69
       NOMORE(cx2, GRID_MAX_POINTS_X - 2);
69 70
       NOMORE(cy2, GRID_MAX_POINTS_Y - 2);
70 71
 
72
+      // Start and end in the same cell? No split needed.
71 73
       if (cx1 == cx2 && cy1 == cy2) {
72
-        // Start and end on same mesh square
73 74
         buffer_line_to_destination(fr_mm_s);
74 75
         set_current_from_destination();
75 76
         return;
@@ -78,25 +79,30 @@
78 79
       #define MBL_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist)
79 80
 
80 81
       float normalized_dist, end[XYZE];
81
-
82
-      // Split at the left/front border of the right/top square
83 82
       const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2);
83
+
84
+      // Crosses on the X and not already split on this X?
85
+      // The x_splits flags are insurance against rounding errors.
84 86
       if (cx2 != cx1 && TEST(x_splits, gcx)) {
87
+        // Split on the X grid line
88
+        CBI(x_splits, gcx);
85 89
         COPY(end, destination);
86 90
         destination[X_AXIS] = mbl.index_to_xpos[gcx];
87 91
         normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
88 92
         destination[Y_AXIS] = MBL_SEGMENT_END(Y);
89
-        CBI(x_splits, gcx);
90 93
       }
94
+      // Crosses on the Y and not already split on this Y?
91 95
       else if (cy2 != cy1 && TEST(y_splits, gcy)) {
96
+        // Split on the Y grid line
97
+        CBI(y_splits, gcy);
92 98
         COPY(end, destination);
93 99
         destination[Y_AXIS] = mbl.index_to_ypos[gcy];
94 100
         normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
95 101
         destination[X_AXIS] = MBL_SEGMENT_END(X);
96
-        CBI(y_splits, gcy);
97 102
       }
98 103
       else {
99
-        // Already split on a border
104
+        // Must already have been split on these border(s)
105
+        // This should be a rare case.
100 106
         buffer_line_to_destination(fr_mm_s);
101 107
         set_current_from_destination();
102 108
         return;

+ 49
- 80
Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp View File

@@ -475,30 +475,17 @@
475 475
     // We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic,
476 476
     // so we call _buffer_line directly here.  Per-segmented leveling and kinematics performed first.
477 477
 
478
-    inline void _O2 ubl_buffer_segment_raw(const float &rx, const float &ry, const float rz, const float &e, const float &fr) {
478
+    inline void _O2 ubl_buffer_segment_raw(const float raw[XYZE], const float &fr) {
479 479
 
480 480
       #if ENABLED(DELTA)  // apply delta inverse_kinematics
481 481
 
482
-        const float delta_A = rz + SQRT( delta_diagonal_rod_2_tower[A_AXIS]
483
-                                         - HYPOT2( delta_tower[A_AXIS][X_AXIS] - rx,
484
-                                                   delta_tower[A_AXIS][Y_AXIS] - ry ));
485
-
486
-        const float delta_B = rz + SQRT( delta_diagonal_rod_2_tower[B_AXIS]
487
-                                         - HYPOT2( delta_tower[B_AXIS][X_AXIS] - rx,
488
-                                                   delta_tower[B_AXIS][Y_AXIS] - ry ));
489
-
490
-        const float delta_C = rz + SQRT( delta_diagonal_rod_2_tower[C_AXIS]
491
-                                         - HYPOT2( delta_tower[C_AXIS][X_AXIS] - rx,
492
-                                                   delta_tower[C_AXIS][Y_AXIS] - ry ));
493
-
494
-        planner._buffer_line(delta_A, delta_B, delta_C, e, fr, active_extruder);
482
+        DELTA_RAW_IK();
483
+        planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], fr, active_extruder);
495 484
 
496 485
       #elif IS_SCARA  // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
497 486
 
498
-        const float lseg[XYZ] = { rx, ry, rz };
499
-
500
-        inverse_kinematics(lseg); // this writes delta[ABC] from lseg[XYZ]
501
-                                  // should move the feedrate scaling to scara inverse_kinematics
487
+        inverse_kinematics(raw); // this writes delta[ABC] from raw[XYZE]
488
+                                 // should move the feedrate scaling to scara inverse_kinematics
502 489
 
503 490
         const float adiff = FABS(delta[A_AXIS] - scara_oldA),
504 491
                     bdiff = FABS(delta[B_AXIS] - scara_oldB);
@@ -506,11 +493,11 @@
506 493
         scara_oldB = delta[B_AXIS];
507 494
         float s_feedrate = max(adiff, bdiff) * scara_feed_factor;
508 495
 
509
-        planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], e, s_feedrate, active_extruder);
496
+        planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], s_feedrate, active_extruder);
510 497
 
511 498
       #else // CARTESIAN
512 499
 
513
-        planner._buffer_line(rx, ry, rz, e, fr, active_extruder);
500
+        planner._buffer_line(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], raw[E_AXIS], fr, active_extruder);
514 501
 
515 502
       #endif
516 503
 
@@ -528,12 +515,14 @@
528 515
       if (!position_is_reachable(rtarget[X_AXIS], rtarget[Y_AXIS]))  // fail if moving outside reachable boundary
529 516
         return true; // did not move, so current_position still accurate
530 517
 
531
-      const float tot_dx = rtarget[X_AXIS] - current_position[X_AXIS],
532
-                  tot_dy = rtarget[Y_AXIS] - current_position[Y_AXIS],
533
-                  tot_dz = rtarget[Z_AXIS] - current_position[Z_AXIS],
534
-                  tot_de = rtarget[E_AXIS] - current_position[E_AXIS];
518
+      const float total[XYZE] = {
519
+        rtarget[X_AXIS] - current_position[X_AXIS],
520
+        rtarget[Y_AXIS] - current_position[Y_AXIS],
521
+        rtarget[Z_AXIS] - current_position[Z_AXIS],
522
+        rtarget[E_AXIS] - current_position[E_AXIS]
523
+      };
535 524
 
536
-      const float cartesian_xy_mm = HYPOT(tot_dx, tot_dy);  // total horizontal xy distance
525
+      const float cartesian_xy_mm = HYPOT(total[X_AXIS], total[Y_AXIS]);  // total horizontal xy distance
537 526
 
538 527
       #if IS_KINEMATIC
539 528
         const float seconds = cartesian_xy_mm / feedrate;                                  // seconds to move xy distance at requested rate
@@ -553,41 +542,30 @@
553 542
         scara_oldB = stepper.get_axis_position_degrees(B_AXIS);
554 543
       #endif
555 544
 
556
-      const float seg_dx = tot_dx * inv_segments,
557
-                  seg_dy = tot_dy * inv_segments,
558
-                  seg_dz = tot_dz * inv_segments,
559
-                  seg_de = tot_de * inv_segments;
545
+      const float diff[XYZE] = {
546
+        total[X_AXIS] * inv_segments,
547
+        total[Y_AXIS] * inv_segments,
548
+        total[Z_AXIS] * inv_segments,
549
+        total[E_AXIS] * inv_segments
550
+      };
560 551
 
561 552
       // Note that E segment distance could vary slightly as z mesh height
562 553
       // changes for each segment, but small enough to ignore.
563 554
 
564
-      float seg_rx = current_position[X_AXIS],
565
-            seg_ry = current_position[Y_AXIS],
566
-            seg_rz = current_position[Z_AXIS],
567
-            seg_le = current_position[E_AXIS];
555
+      float raw[XYZE] = {
556
+        current_position[X_AXIS],
557
+        current_position[Y_AXIS],
558
+        current_position[Z_AXIS],
559
+        current_position[E_AXIS]
560
+      };
568 561
 
569 562
       // Only compute leveling per segment if ubl active and target below z_fade_height.
570
-
571 563
       if (!planner.leveling_active || !planner.leveling_active_at_z(rtarget[Z_AXIS])) {   // no mesh leveling
572
-
573
-        do {
574
-
575
-          if (--segments) {     // not the last segment
576
-            seg_rx += seg_dx;
577
-            seg_ry += seg_dy;
578
-            seg_rz += seg_dz;
579
-            seg_le += seg_de;
580
-          } else {              // last segment, use exact destination
581
-            seg_rx = rtarget[X_AXIS];
582
-            seg_ry = rtarget[Y_AXIS];
583
-            seg_rz = rtarget[Z_AXIS];
584
-            seg_le = rtarget[E_AXIS];
585
-          }
586
-
587
-          ubl_buffer_segment_raw(seg_rx, seg_ry, seg_rz, seg_le, feedrate);
588
-
589
-        } while (segments);
590
-
564
+        while (--segments) {
565
+          LOOP_XYZE(i) raw[i] += diff[i];
566
+          ubl_buffer_segment_raw(raw, feedrate);
567
+        }
568
+        ubl_buffer_segment_raw(rtarget, feedrate);
591 569
         return false; // moved but did not set_current_from_destination();
592 570
       }
593 571
 
@@ -598,10 +576,7 @@
598 576
       #endif
599 577
 
600 578
       // increment to first segment destination
601
-      seg_rx += seg_dx;
602
-      seg_ry += seg_dy;
603
-      seg_rz += seg_dz;
604
-      seg_le += seg_de;
579
+      LOOP_XYZE(i) raw[i] += diff[i];
605 580
 
606 581
       for(;;) {  // for each mesh cell encountered during the move
607 582
 
@@ -612,8 +587,8 @@
612 587
         // in top of loop and again re-find same adjacent cell and use it, just less efficient
613 588
         // for mesh inset area.
614 589
 
615
-        int8_t cell_xi = (seg_rx - (MESH_MIN_X)) * (1.0 / (MESH_X_DIST)),
616
-               cell_yi = (seg_ry - (MESH_MIN_Y)) * (1.0 / (MESH_X_DIST));
590
+        int8_t cell_xi = (raw[X_AXIS] - (MESH_MIN_X)) * (1.0 / (MESH_X_DIST)),
591
+               cell_yi = (raw[Y_AXIS] - (MESH_MIN_Y)) * (1.0 / (MESH_X_DIST));
617 592
 
618 593
         cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
619 594
         cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1);
@@ -631,8 +606,8 @@
631 606
         if (isnan(z_x0y1)) z_x0y1 = 0;              //   in order to avoid isnan tests per cell,
632 607
         if (isnan(z_x1y1)) z_x1y1 = 0;              //   thus guessing zero for undefined points
633 608
 
634
-        float cx = seg_rx - x0,   // cell-relative x and y
635
-              cy = seg_ry - y0;
609
+        float cx = raw[X_AXIS] - x0,   // cell-relative x and y
610
+              cy = raw[Y_AXIS] - y0;
636 611
 
637 612
         const float z_xmy0 = (z_x1y0 - z_x0y0) * (1.0 / (MESH_X_DIST)),   // z slope per x along y0 (lower left to lower right)
638 613
                     z_xmy1 = (z_x1y1 - z_x0y1) * (1.0 / (MESH_X_DIST));   // z slope per x along y1 (upper left to upper right)
@@ -650,40 +625,34 @@
650 625
         // and the z_cxym slope will change, both as a function of cx within the cell, and
651 626
         // each change by a constant for fixed segment lengths.
652 627
 
653
-        const float z_sxy0 = z_xmy0 * seg_dx,                                     // per-segment adjustment to z_cxy0
654
-                    z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * seg_dx;  // per-segment adjustment to z_cxym
628
+        const float z_sxy0 = z_xmy0 * diff[X_AXIS],                                     // per-segment adjustment to z_cxy0
629
+                    z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * diff[X_AXIS];  // per-segment adjustment to z_cxym
655 630
 
656 631
         for(;;) {  // for all segments within this mesh cell
657 632
 
658
-          float z_cxcy = z_cxy0 + z_cxym * cy;      // interpolated mesh z height along cx at cy
633
+          if (--segments == 0)                      // if this is last segment, use rtarget for exact
634
+            COPY(raw, rtarget);
659 635
 
636
+          float z_cxcy = z_cxy0 + z_cxym * cy;      // interpolated mesh z height along cx at cy
660 637
           #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
661 638
             z_cxcy *= fade_scaling_factor;          // apply fade factor to interpolated mesh height
662 639
           #endif
663 640
 
664
-          if (--segments == 0) {                    // if this is last segment, use rtarget for exact
665
-            seg_rx = rtarget[X_AXIS];
666
-            seg_ry = rtarget[Y_AXIS];
667
-            seg_rz = rtarget[Z_AXIS];
668
-            seg_le = rtarget[E_AXIS];
669
-          }
670
-
671
-          ubl_buffer_segment_raw(seg_rx, seg_ry, seg_rz + z_cxcy, seg_le, feedrate);
641
+          const float z = raw[Z_AXIS];
642
+          raw[Z_AXIS] += z_cxcy;
643
+          ubl_buffer_segment_raw(raw, feedrate);
644
+          raw[Z_AXIS] = z;
672 645
 
673 646
           if (segments == 0)                        // done with last segment
674 647
             return false;                           // did not set_current_from_destination()
675 648
 
676
-          seg_rx += seg_dx;
677
-          seg_ry += seg_dy;
678
-          seg_rz += seg_dz;
679
-          seg_le += seg_de;
649
+          LOOP_XYZE(i) raw[i] += diff[i];
680 650
 
681
-          cx += seg_dx;
682
-          cy += seg_dy;
651
+          cx += diff[X_AXIS];
652
+          cy += diff[Y_AXIS];
683 653
 
684
-          if (!WITHIN(cx, 0, MESH_X_DIST) || !WITHIN(cy, 0, MESH_Y_DIST)) {  // done within this cell, break to next
654
+          if (!WITHIN(cx, 0, MESH_X_DIST) || !WITHIN(cy, 0, MESH_Y_DIST))    // done within this cell, break to next
685 655
             break;
686
-          }
687 656
 
688 657
           // Next segment still within same mesh cell, adjust the per-segment
689 658
           // slope and intercept to compute next z height.

+ 2
- 9
Marlin/src/module/motion.cpp View File

@@ -587,12 +587,9 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
587 587
     float raw[XYZE];
588 588
     COPY(raw, current_position);
589 589
 
590
-    // Drop one segment so the last move is to the exact target.
591
-    // If there's only 1 segment, loops will be skipped entirely.
592
-    --segments;
593 590
 
594 591
     // Calculate and execute the segments
595
-    for (uint16_t s = segments + 1; --s;) {
592
+    while (--segments) {
596 593
 
597 594
       static millis_t next_idle_ms = millis() + 200UL;
598 595
       thermalManager.manage_heater();  // This returns immediately if not really needed.
@@ -691,16 +688,12 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
691 688
       // SERIAL_ECHOPAIR("mm=", cartesian_mm);
692 689
       // SERIAL_ECHOLNPAIR(" segments=", segments);
693 690
 
694
-      // Drop one segment so the last move is to the exact target.
695
-      // If there's only 1 segment, loops will be skipped entirely.
696
-      --segments;
697
-
698 691
       // Get the raw current position as starting point
699 692
       float raw[XYZE];
700 693
       COPY(raw, current_position);
701 694
 
702 695
       // Calculate and execute the segments
703
-      for (uint16_t s = segments + 1; --s;) {
696
+      while (--segments) {
704 697
         static millis_t next_idle_ms = millis() + 200UL;
705 698
         thermalManager.manage_heater();  // This returns immediately if not really needed.
706 699
         if (ELAPSED(millis(), next_idle_ms)) {

+ 2
- 2
Marlin/src/module/planner.h View File

@@ -505,8 +505,8 @@ class Planner {
505 505
     /**
506 506
      * Get the index of the next / previous block in the ring buffer
507 507
      */
508
-    static int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); }
509
-    static int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); }
508
+    static int8_t next_block_index(const int8_t block_index) { return BLOCK_MOD(block_index + 1); }
509
+    static int8_t prev_block_index(const int8_t block_index) { return BLOCK_MOD(block_index - 1); }
510 510
 
511 511
     /**
512 512
      * Calculate the distance (not time) it takes to accelerate

+ 1
- 2
Marlin/src/module/stepper.cpp View File

@@ -409,8 +409,7 @@ void Stepper::isr() {
409 409
   // If there is no current block, attempt to pop one from the buffer
410 410
   if (!current_block) {
411 411
     // Anything in the buffer?
412
-    current_block = planner.get_current_block();
413
-    if (current_block) {
412
+    if ((current_block = planner.get_current_block())) {
414 413
       trapezoid_generator_reset();
415 414
 
416 415
       // Initialize Bresenham counters to 1/2 the ceiling

Loading…
Cancel
Save