Browse Source

Fixed some arc bugs

Erik van der Zalm 13 years ago
parent
commit
5cf349a24a
2 changed files with 12 additions and 114 deletions
  1. 5
    108
      Marlin/Marlin.pde
  2. 7
    6
      Marlin/motion_control.cpp

+ 5
- 108
Marlin/Marlin.pde View File

1139
 inline void get_arc_coordinates()
1139
 inline void get_arc_coordinates()
1140
 {
1140
 {
1141
    get_coordinates();
1141
    get_coordinates();
1142
-   if(code_seen("I")) offset[0] = code_value();
1143
-   if(code_seen("J")) offset[1] = code_value();
1142
+   if(code_seen('I')) offset[0] = code_value();
1143
+   if(code_seen('J')) offset[1] = code_value();
1144
 }
1144
 }
1145
 
1145
 
1146
 void prepare_move()
1146
 void prepare_move()
1152
 }
1152
 }
1153
 
1153
 
1154
 void prepare_arc_move(char isclockwise) {
1154
 void prepare_arc_move(char isclockwise) {
1155
-#if 0
1156
-  if (radius_mode) {
1157
-    /* 
1158
-      We need to calculate the center of the circle that has the designated radius and passes
1159
-      through both the current position and the target position. This method calculates the following
1160
-      set of equations where [x,y] is the vector from current to target position, d == magnitude of 
1161
-      that vector, h == hypotenuse of the triangle formed by the radius of the circle, the distance to
1162
-      the center of the travel vector. A vector perpendicular to the travel vector [-y,x] is scaled to the 
1163
-      length of h [-y/d*h, x/d*h] and added to the center of the travel vector [x/2,y/2] to form the new point 
1164
-      [i,j] at [x/2-y/d*h, y/2+x/d*h] which will be the center of our arc.
1165
-      
1166
-      d^2 == x^2 + y^2
1167
-      h^2 == r^2 - (d/2)^2
1168
-      i == x/2 - y/d*h
1169
-      j == y/2 + x/d*h
1170
-      
1171
-                                                           O <- [i,j]
1172
-                                                        -  |
1173
-                                              r      -     |
1174
-                                                  -        |
1175
-                                               -           | h
1176
-                                            -              |
1177
-                              [0,0] ->  C -----------------+--------------- T  <- [x,y]
1178
-                                        | <------ d/2 ---->|
1179
-                
1180
-      C - Current position
1181
-      T - Target position
1182
-      O - center of circle that pass through both C and T
1183
-      d - distance from C to T
1184
-      r - designated radius
1185
-      h - distance from center of CT to O
1186
-      
1187
-      Expanding the equations:
1188
-
1189
-      d -> sqrt(x^2 + y^2)
1190
-      h -> sqrt(4 * r^2 - x^2 - y^2)/2
1191
-      i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 
1192
-      j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2
1193
-     
1194
-      Which can be written:
1195
-      
1196
-      i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2
1197
-      j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2
1198
-      
1199
-      Which we for size and speed reasons optimize to:
1200
-
1201
-      h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2)
1202
-      i = (x - (y * h_x2_div_d))/2
1203
-      j = (y + (x * h_x2_div_d))/2
1204
-      
1205
-    */
1206
-    
1207
-    // Calculate the change in position along each selected axis
1208
-    double x = target[gc.plane_axis_0]-gc.position[gc.plane_axis_0];
1209
-    double y = target[gc.plane_axis_1]-gc.position[gc.plane_axis_1];
1210
-    
1211
-    clear_vector(offset);
1212
-    double h_x2_div_d = -sqrt(4 * r*r - x*x - y*y)/hypot(x,y); // == -(h * 2 / d)
1213
-    // If r is smaller than d, the arc is now traversing the complex plane beyond the reach of any
1214
-    // real CNC, and thus - for practical reasons - we will terminate promptly:
1215
-    if(isnan(h_x2_div_d)) { FAIL(STATUS_FLOATING_POINT_ERROR); return(gc.status_code); }
1216
-    // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below)
1217
-    if (gc.motion_mode == MOTION_MODE_CCW_ARC) { h_x2_div_d = -h_x2_div_d; }
1218
-    
1219
-    /* The counter clockwise circle lies to the left of the target direction. When offset is positive,
1220
-       the left hand circle will be generated - when it is negative the right hand circle is generated.
1221
-       
1222
-       
1223
-                                                         T  <-- Target position
1224
-                                                         
1225
-                                                         ^ 
1226
-              Clockwise circles with this center         |          Clockwise circles with this center will have
1227
-              will have > 180 deg of angular travel      |          < 180 deg of angular travel, which is a good thing!
1228
-                                               \         |          /   
1229
-  center of arc when h_x2_div_d is positive ->  x <----- | -----> x <- center of arc when h_x2_div_d is negative
1230
-                                                         |
1231
-                                                         |
1232
-                                                         
1233
-                                                         C  <-- Current position                                 */
1234
-                
1235
-
1236
-    // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!), 
1237
-    // even though it is advised against ever generating such circles in a single line of g-code. By 
1238
-    // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of
1239
-    // travel and thus we get the unadvisably long arcs as prescribed.
1240
-    if (r < 0) { 
1241
-        h_x2_div_d = -h_x2_div_d; 
1242
-        r = -r; // Finished with r. Set to positive for mc_arc
1243
-    }        
1244
-    // Complete the operation by calculating the actual center of the arc
1245
-    offset[gc.plane_axis_0] = 0.5*(x-(y*h_x2_div_d));
1246
-    offset[gc.plane_axis_1] = 0.5*(y+(x*h_x2_div_d));
1247
-
1248
-  } else { // Offset mode specific computations
1249
-#endif
1250
-    float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc
1251
-
1252
-//  }
1253
-  
1254
-  // Set clockwise/counter-clockwise sign for mc_arc computations
1255
-//  uint8_t isclockwise = false;
1256
-//  if (gc.motion_mode == MOTION_MODE_CW_ARC) { isclockwise = true; }
1155
+  float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc
1257
 
1156
 
1258
   // Trace the arc
1157
   // Trace the arc
1259
   mc_arc(current_position, destination, offset, X_AXIS, Y_AXIS, Z_AXIS, feedrate*feedmultiply/60.0/100.0, r, isclockwise);
1158
   mc_arc(current_position, destination, offset, X_AXIS, Y_AXIS, Z_AXIS, feedrate*feedmultiply/60.0/100.0, r, isclockwise);
1260
-    
1261
-//  }
1262
   
1159
   
1263
   // As far as the parser is concerned, the position is now == target. In reality the
1160
   // As far as the parser is concerned, the position is now == target. In reality the
1264
   // motion control system might still be processing the action and the real tool position
1161
   // motion control system might still be processing the action and the real tool position
1265
   // in any intermediate location.
1162
   // in any intermediate location.
1266
-  for(int ii=0; ii < NUM_AXIS; ii++) {
1267
-    current_position[ii] = destination[ii];
1163
+  for(int i=0; i < NUM_AXIS; i++) {
1164
+    current_position[i] = destination[i];
1268
   }
1165
   }
1269
 }
1166
 }
1270
 
1167
 

+ 7
- 6
Marlin/motion_control.cpp View File

19
   along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
19
   along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
20
 */
20
 */
21
 
21
 
22
-//#include "motion_control.h"
23
 #include "Configuration.h"
22
 #include "Configuration.h"
24
 #include "Marlin.h"
23
 #include "Marlin.h"
25
-//#include <util/delay.h>
26
-//#include <math.h>
27
-//#include <stdlib.h>
28
 #include "stepper.h"
24
 #include "stepper.h"
29
 #include "planner.h"
25
 #include "planner.h"
30
 
26
 
35
 {      
31
 {      
36
   //   int acceleration_manager_was_enabled = plan_is_acceleration_manager_enabled();
32
   //   int acceleration_manager_was_enabled = plan_is_acceleration_manager_enabled();
37
   //   plan_set_acceleration_manager_enabled(false); // disable acceleration management for the duration of the arc
33
   //   plan_set_acceleration_manager_enabled(false); // disable acceleration management for the duration of the arc
38
-  SERIAL_ECHOLN("mc_arc.");
39
   float center_axis0 = position[axis_0] + offset[axis_0];
34
   float center_axis0 = position[axis_0] + offset[axis_0];
40
   float center_axis1 = position[axis_1] + offset[axis_1];
35
   float center_axis1 = position[axis_1] + offset[axis_1];
41
   float linear_travel = target[axis_linear] - position[axis_linear];
36
   float linear_travel = target[axis_linear] - position[axis_linear];
37
+  float extruder_travel = target[E_AXIS] - position[E_AXIS];
42
   float r_axis0 = -offset[axis_0];  // Radius vector from center to current location
38
   float r_axis0 = -offset[axis_0];  // Radius vector from center to current location
43
   float r_axis1 = -offset[axis_1];
39
   float r_axis1 = -offset[axis_1];
44
   float rt_axis0 = target[axis_0] - center_axis0;
40
   float rt_axis0 = target[axis_0] - center_axis0;
60
   */
56
   */
61
   float theta_per_segment = angular_travel/segments;
57
   float theta_per_segment = angular_travel/segments;
62
   float linear_per_segment = linear_travel/segments;
58
   float linear_per_segment = linear_travel/segments;
59
+  float extruder_per_segment = extruder_travel/segments;
63
   
60
   
64
   /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
61
   /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
65
      and phi is the angle of rotation. Based on the solution approach by Jens Geisler.
62
      and phi is the angle of rotation. Based on the solution approach by Jens Geisler.
90
   float cos_T = 1-0.5*theta_per_segment*theta_per_segment; // Small angle approximation
87
   float cos_T = 1-0.5*theta_per_segment*theta_per_segment; // Small angle approximation
91
   float sin_T = theta_per_segment;
88
   float sin_T = theta_per_segment;
92
   
89
   
93
-  float arc_target[3];
90
+  float arc_target[4];
94
   float sin_Ti;
91
   float sin_Ti;
95
   float cos_Ti;
92
   float cos_Ti;
96
   float r_axisi;
93
   float r_axisi;
99
 
96
 
100
   // Initialize the linear axis
97
   // Initialize the linear axis
101
   arc_target[axis_linear] = position[axis_linear];
98
   arc_target[axis_linear] = position[axis_linear];
99
+  
100
+  // Initialize the extruder axis
101
+  arc_target[E_AXIS] = position[E_AXIS];
102
 
102
 
103
   for (i = 1; i<segments; i++) { // Increment (segments-1)
103
   for (i = 1; i<segments; i++) { // Increment (segments-1)
104
     
104
     
122
     arc_target[axis_0] = center_axis0 + r_axis0;
122
     arc_target[axis_0] = center_axis0 + r_axis0;
123
     arc_target[axis_1] = center_axis1 + r_axis1;
123
     arc_target[axis_1] = center_axis1 + r_axis1;
124
     arc_target[axis_linear] += linear_per_segment;
124
     arc_target[axis_linear] += linear_per_segment;
125
+    arc_target[E_AXIS] += extruder_per_segment;
125
     plan_buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], target[E_AXIS], feed_rate);
126
     plan_buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], target[E_AXIS], feed_rate);
126
     
127
     
127
   }
128
   }

Loading…
Cancel
Save