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
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;}
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;
}
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
// 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
* 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));
}
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};
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
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;
}