Fixed occasional step correction induced stutter.
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Wed, 21 Sep 2016 20:13:12 +0000 (13:13 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Wed, 21 Sep 2016 20:13:12 +0000 (13:13 -0700)
src/motor.c
src/plan/exec.c
src/plan/planner.c
src/plan/runtime.c
src/util.c

index a39be7d3e8ba5ab438c1dbf61ef75203d3f63bb5..61a64cdc8b12982ead19a70c64b827d1fe6014ae 100644 (file)
@@ -82,6 +82,7 @@ typedef struct {
   bool wasEnabled;
   int32_t error;
   bool last_negative;            // Last step sign
+  bool reading;
 
   // Move prep
   uint8_t timer_clock;           // clock divisor setting or zero for off
@@ -233,15 +234,25 @@ int32_t motor_get_encoder(int motor) {return motors[motor].encoder;}
 
 
 void motor_set_encoder(int motor, float encoder) {
+  if (st_is_busy()) ALARM(STAT_INTERNAL_ERROR);
+
   motor_t *m = &motors[motor];
-  cli();
   m->encoder = m->position = m->commanded = round(encoder);
   m->error = 0;
-  sei();
 }
 
 
-int32_t motor_get_error(int motor) {return motors[motor].error;}
+int32_t motor_get_error(int motor) {
+  motor_t *m = &motors[motor];
+
+  m->reading = true;
+  int32_t error = motors[motor].error;
+  m->reading = false;
+
+  return error;
+}
+
+
 int32_t motor_get_position(int motor) {return motors[motor].position;}
 
 
@@ -381,7 +392,7 @@ void motor_load_move(int motor) {
   m->last_negative = m->negative;
 
   // Compute error
-  m->error = m->commanded - m->encoder;
+  if (!m->reading) m->error = m->commanded - m->encoder;
   m->commanded = m->position;
 }
 
index 887aab45fb6b3d311bb29920421b9110836f0f13..a4c75ce4e1262510ffdbcd6a816e29ef1e777613 100644 (file)
@@ -58,7 +58,6 @@ typedef struct {
   float cruise_velocity;
   float exit_velocity;
 
-  float segments;           // number of segments in line
   uint32_t segment_count;   // count of running segments
   float segment_velocity;   // computed velocity for segment
   float segment_time;       // actual time increment per segment
@@ -105,13 +104,13 @@ static stat_t _exec_aline_section(float length, float vin, float vout) {
 
     // len / avg. velocity
     float move_time = 2 * length / (vin + vout);
-    ex.segments = ceil(move_time / NOM_SEGMENT_TIME);
-    ex.segment_time = move_time / ex.segments;
-    ex.segment_count = (uint32_t)ex.segments;
+    float segments = ceil(move_time / NOM_SEGMENT_TIME);
+    ex.segment_time = move_time / segments;
+    ex.segment_count = round(segments);
 
     if (vin == vout) ex.segment_velocity = vin;
     else ex.segment_velocity =
-           mp_init_forward_dif(ex.fdif, vin, vout, ex.segments);
+           mp_init_forward_dif(ex.fdif, vin, vout, segments);
 
     if (ex.segment_time < MIN_SEGMENT_TIME)
       return STAT_MINIMUM_TIME_MOVE; // exit /wo advancing position
index d10b677c54fe7025478fdd68b6168aa2262d36d4..e83c63ebb7b5a1ced61292573b72bf1dd7b385a4 100644 (file)
@@ -676,7 +676,7 @@ void mp_queue_push_nonstop(buffer_cb_t cb, uint32_t line) {
  *     PLANNER_VELOCITY_TOLERANCE necessitating the introduction of fabs()
  */
 float mp_get_target_length(float Vi, float Vf, float jerk) {
-  return fabs(Vi - Vf) * invsqrt(jerk / fabs(Vi - Vf));
+  return fp_EQ(Vi, Vf) ? 0 : fabs(Vi - Vf) * invsqrt(jerk / fabs(Vi - Vf));
 }
 
 
index 333f367ede9f59bb0956cfa161784960fd89145b..01de3267c0cd936e7ee35bde62436b602dbe467e 100644 (file)
@@ -64,8 +64,7 @@ typedef struct {
   distance_mode_t distance_mode;
   distance_mode_t arc_distance_mode;
 
-  float previousP[MOTORS];
-  float previousI[MOTORS];
+  float previous_error[MOTORS];
 } mp_runtime_t;
 
 static mp_runtime_t rt = {0};
@@ -175,38 +174,33 @@ stat_t mp_runtime_move_to_target(float target[], float time) {
       motor[error] = 0;
     }
 
-    float P = error[motor] - rt.previousI[motor];
-    float I = error[motor];
-    float D = P - rt.previousP[motor];
+    error[motor] = 0.5 * (error[motor] - rt.previous_error[motor]);
+    rt.previous_error[motor] = error[motor];
 
-    rt.previousP[motor] = P;
-    rt.previousI[motor] = I;
-
-    error[motor] = 0.5 * P + 0.5 * I + 0.15 * D;
-
-#if 0
     if (error[motor] < -MAX_STEP_CORRECTION)
       error[motor] = -MAX_STEP_CORRECTION;
     else if (MAX_STEP_CORRECTION < error[motor])
       error[motor] = MAX_STEP_CORRECTION;
-#endif
 
     old_length_sqr += square(travel[motor]);
     new_length_sqr += square(travel[motor] - error[motor]);
   }
 
   bool use_error = false;
-  if (!fp_ZERO(old_length_sqr)) {
+  if (!fp_ZERO(new_length_sqr)) {
     float new_time = time * invsqrt(old_length_sqr / new_length_sqr);
 
-    if (EPSILON <= new_time && new_time <= MAX_SEGMENT_TIME) {
+    if (!isnan(new_time) && !isinf(new_time) &&
+        EPSILON <= new_time && new_time <= MAX_SEGMENT_TIME) {
       time = new_time;
       use_error = true;
     }
   }
 
-  if (!use_error)
-    for (int motor = 0; motor < MOTORS; motor++) error[motor] = 0;
+  if (!use_error) memset(error, 0, sizeof(error));
+
+#else
+  const int32_t error[MOTORS] = {0};
 #endif
 
   // Call the stepper prep function
index e5e8341592f373c7fbdb119409845a49e76822d8..f30feb6e9bceb788004df17480d5c10bf9793fc0 100644 (file)
@@ -50,5 +50,5 @@ float invsqrt(float number) {
   y = y * (threehalfs - x2 * y * y);   // 1st iteration
   y = y * (threehalfs - x2 * y * y);   // 2nd iteration, this can be removed
 
-  return y;
+  return y; //isnan(y) ? 1.0 / sqrt(number) : y;
 }