From cdf84fd100775df63b2bf25d9f7dd2886b6ca109 Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Thu, 20 Jul 2017 16:09:39 -0700 Subject: [PATCH] Buffer overflow bug fix and related changes --- avr/src/axis.c | 4 ++-- avr/src/plan/exec.c | 2 +- avr/src/plan/line.c | 4 +++- avr/src/plan/planner.c | 33 ++++++++++++++++++++------------- avr/src/plan/planner.h | 2 ++ avr/src/vars.c | 5 +++-- src/js/main.js | 2 +- 7 files changed, 32 insertions(+), 20 deletions(-) diff --git a/avr/src/axis.c b/avr/src/axis.c index 6b8f63a..8953882 100644 --- a/avr/src/axis.c +++ b/avr/src/axis.c @@ -43,7 +43,7 @@ typedef struct { float travel_max; // max work envelope for soft limits float travel_min; // min work envelope for soft limits float jerk_max; // max jerk (Jm) in km/min^3 - float recip_jerk; // reciprocal of current jerk in min^3/mm + float recip_jerk; // reciprocal of current jerk in min^3/km float radius; // radius in mm for rotary axes float search_velocity; // homing search velocity float latch_velocity; // homing latch velocity @@ -143,7 +143,7 @@ AXIS_GET(jerk_max, float, 0) /// Sets jerk and its reciprocal for axis void axis_set_jerk_max(int axis, float jerk) { axes[axis].jerk_max = jerk; - axes[axis].recip_jerk = 1 / (jerk * JERK_MULTIPLIER); + axes[axis].recip_jerk = 1.0 / jerk; } diff --git a/avr/src/plan/exec.c b/avr/src/plan/exec.c index 2814275..ec1cff3 100644 --- a/avr/src/plan/exec.c +++ b/avr/src/plan/exec.c @@ -87,7 +87,7 @@ static stat_t _exec_aline_section(float length, float Vi, float Vt) { // len / avg. velocity const float move_time = 2 * length / (Vi + Vt); // in mins - const float segments = round(move_time / SEGMENT_TIME); + const float segments = ceil(move_time / SEGMENT_TIME); ex.segment_count = segments; ex.segment_time = move_time / segments; // in mins ex.segment = 0; diff --git a/avr/src/plan/line.c b/avr/src/plan/line.c index 2156e76..8cb845d 100644 --- a/avr/src/plan/line.c +++ b/avr/src/plan/line.c @@ -200,7 +200,7 @@ int mp_find_jerk_axis(const float axis_square[]) { for (int axis = 0; axis < AXES; axis++) if (axis_square[axis]) { // Do not use fp_ZERO here // Squaring axis_length ensures it's positive - C = axis_square[axis] * axis_get_recip_jerk(axis); + C = axis_square[axis] / axis_get_jerk_max(axis); if (maxC < C) { maxC = C; @@ -216,6 +216,8 @@ int mp_find_jerk_axis(const float axis_square[]) { static float _calc_jerk(const float axis_square[], const float unit[]) { int axis = mp_find_jerk_axis(axis_square); + ASSERT(isfinite(unit[axis]) && unit[axis]); + // Finally, the selected jerk term needs to be scaled by the // reciprocal of the absolute value of the axis's unit // vector term. This way when the move is finally decomposed into diff --git a/avr/src/plan/planner.c b/avr/src/plan/planner.c index ac2ca10..d8da7d9 100644 --- a/avr/src/plan/planner.c +++ b/avr/src/plan/planner.c @@ -239,7 +239,7 @@ void mp_calculate_trapezoid(mp_buffer_t *bf) { float naive_move_time = 2 * bf->length / (bf->entry_velocity + bf->exit_velocity); // average - if (naive_move_time < SEGMENT_TIME) { + if (isfinite(naive_move_time) && naive_move_time < SEGMENT_TIME) { bf->cruise_velocity = bf->length / SEGMENT_TIME; bf->exit_velocity = max(0, min(bf->cruise_velocity, (bf->entry_velocity - bf->delta_vmax))); @@ -252,7 +252,7 @@ void mp_calculate_trapezoid(mp_buffer_t *bf) { } // B" case: Block is short, but fits into a single body segment - if (naive_move_time <= SEGMENT_TIME) { + if (isfinite(naive_move_time) && naive_move_time <= SEGMENT_TIME) { bf->entry_velocity = mp_buffer_prev(bf)->exit_velocity; if (!fp_ZERO(bf->entry_velocity)) { @@ -385,8 +385,9 @@ void mp_calculate_trapezoid(mp_buffer_t *bf) { } else break; - } while ((fabs(bf->cruise_velocity - computed_velocity) / - computed_velocity) > TRAPEZOID_ITERATION_ERROR_PERCENT); + } while (TRAPEZOID_ITERATION_ERROR_PERCENT < + (fabs(bf->cruise_velocity - computed_velocity) / + computed_velocity)); // set velocity and clean up any parts that are too short bf->cruise_velocity = computed_velocity; @@ -435,15 +436,21 @@ void mp_calculate_trapezoid(mp_buffer_t *bf) { #if 0 void mp_print_buffer(mp_buffer_t *bp) { - printf_P(PSTR("{\"msg\":\"%d,0x%04lx," - "%0.2f,%0.2f,%0.2f,%0.2f," - "%0.2f,%0.2f,%0.2f,%0.2f," - "%0.2f,%0.2f,%0.2f\"}\n"), - bp->flags & BUFFER_REPLANNABLE, (intptr_t)bp->cb, - bp->length, bp->head_length, bp->body_length, bp->tail_length, - bp->entry_velocity, bp->cruise_velocity, bp->exit_velocity, - bp->braking_velocity, - bp->entry_vmax, bp->cruise_vmax, bp->exit_vmax); + printf_P(PSTR("{\"msg\":\"")); + printf_P(PSTR("%d,"), bp->flags & BUFFER_REPLANNABLE); + printf_P(PSTR("0x%04lx,"), (intptr_t)bp->cb); + printf_P(PSTR("%0.2f,"), bp->length); + printf_P(PSTR("%0.2f,"), bp->head_length); + printf_P(PSTR("%0.2f,"), bp->body_length); + printf_P(PSTR("%0.2f,"), bp->tail_length); + printf_P(PSTR("%0.2f,"), bp->entry_velocity); + printf_P(PSTR("%0.2f,"), bp->cruise_velocity); + printf_P(PSTR("%0.2f,"), bp->exit_velocity); + printf_P(PSTR("%0.2f,"), bp->braking_velocity); + printf_P(PSTR("%0.2f,"), bp->entry_vmax); + printf_P(PSTR("%0.2f,"), bp->cruise_vmax); + printf_P(PSTR("%0.2f"), bp->exit_vmax); + printf_P(PSTR("\"}\n")); while (!usart_tx_empty()) continue; } diff --git a/avr/src/plan/planner.h b/avr/src/plan/planner.h index 60c7476..bdc2c35 100644 --- a/avr/src/plan/planner.h +++ b/avr/src/plan/planner.h @@ -75,6 +75,8 @@ void mp_set_plan_steps(bool plan_steps); void mp_flush_planner(); void mp_kinematics(const float travel[], float steps[]); +void mp_print_buffer(mp_buffer_t *bp); + void mp_plan(mp_buffer_t *bf); void mp_replan_all(); diff --git a/avr/src/vars.c b/avr/src/vars.c index 70d6762..815bcc1 100644 --- a/avr/src/vars.c +++ b/avr/src/vars.c @@ -312,8 +312,9 @@ static char *_resolve_name(const char *_name) { if (!len || 4 < len) return 0; - static char name[4]; - strcpy(name, _name); + static char name[5]; + strncpy(name, _name, 4); + name[4] = 0; // Handle axis to motor mapping if (2 < len && name[1] == '.') { diff --git a/src/js/main.js b/src/js/main.js index c2b5de9..eca6d06 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -15,7 +15,7 @@ $(function() { Vue.filter('fixed', function (value, precision) { if (typeof value == 'undefined') return ''; - return value.toFixed(precision) + return parseFloat(value).toFixed(precision) }); Vue.filter('upper', function (value) { -- 2.27.0