#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "hal.h"
#include "nuts_bolts.h"
#include "protocol.h"
#include "machine_limits.h"
#include "state_machine.h"
#include "motion_control.h"
#include "tool_change.h"
Functions | |
bool | mc_line (float *target, plan_line_data_t *pl_data) |
void | mc_arc (float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius, plane_t plane, int32_t turns) |
void | mc_cubic_b_spline (float *target, plan_line_data_t *pl_data, float *position, float *first, float *second) |
void | mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_data, float *position, plane_t plane, uint32_t repeats, gc_canned_t *canned) |
void | mc_thread (plan_line_data_t *pl_data, float *position, gc_thread_data *thread, bool feed_hold_disabled) |
status_code_t | mc_jog_execute (plan_line_data_t *pl_data, parser_block_t *gc_block, float *position) |
void | mc_dwell (float seconds) |
status_code_t | mc_homing_cycle (axes_signals_t cycle) |
gc_probe_t | mc_probe_cycle (float *target, plan_line_data_t *pl_data, gc_parser_flags_t parser_flags) |
bool | mc_parking_motion (float *parking_target, plan_line_data_t *pl_data) |
void | mc_override_ctrl_update (gc_override_flags_t override_state) |
ISR_CODE void ISR_FUNC() | mc_reset (void) |
void mc_arc | ( | float * | target, |
plan_line_data_t * | pl_data, | ||
float * | position, | ||
float * | offset, | ||
float | radius, | ||
plane_t | plane, | ||
int32_t | turns | ||
) |
void mc_canned_drill | ( | motion_mode_t | motion, |
float * | target, | ||
plan_line_data_t * | pl_data, | ||
float * | position, | ||
plane_t | plane, | ||
uint32_t | repeats, | ||
gc_canned_t * | canned | ||
) |
void mc_cubic_b_spline | ( | float * | target, |
plan_line_data_t * | pl_data, | ||
float * | position, | ||
float * | first, | ||
float * | second | ||
) |
The algorithm for computing the step is loosely based on the one in Kig (See https://sources.debian.net/src/kig/4:15.08.3-1/misc/kigpainter.cpp/#L759) However, we do not use the stack.
The algorithm goes as it follows: the parameters t runs from 0.0 to 1.0 describing the curve, which is evaluated by eval_bezier(). At each iteration we have to choose a step, i.e., the increment of the t variable. By default the step of the previous iteration is taken, and then it is enlarged or reduced depending on how straight the curve locally is. The step is always clamped between MIN_STEP/2 and 2*MAX_STEP. MAX_STEP is taken at the first iteration.
For some t, the step value is considered acceptable if the curve in the interval [t, t+step] is sufficiently straight, i.e., sufficiently close to linear interpolation. In practice the following test is performed: the distance between eval_bezier(..., t+step/2) is evaluated and compared with 0.5*(eval_bezier(..., t)+eval_bezier(..., t+step)). If it is smaller than SIGMA, then the step value is considered acceptable, otherwise it is not. The code seeks to find the larger step value which is considered acceptable.
At every iteration the recorded step value is considered and then iteratively halved until it becomes acceptable. If it was already acceptable in the beginning (i.e., no halving were done), then maybe it was necessary to enlarge it; then it is iteratively doubled while it remains acceptable. The last acceptable value found is taken, provided that it is between MIN_STEP and MAX_STEP and does not bring t over 1.0.
Caveat: this algorithm is not perfect, since it can happen that a step is considered acceptable even when the curve is not linear at all in the interval [t, t+step] (but its mid point coincides "by chance" with the midpoint according to the parametrization). This kind of glitches can be eliminated with proper first derivative estimates; however, given the improbability of such configurations, the mitigation offered by MIN_STEP and the small computational power available on Arduino, I think it is not wise to implement it.
void mc_dwell | ( | float | seconds | ) |
status_code_t mc_homing_cycle | ( | axes_signals_t | cycle | ) |
status_code_t mc_jog_execute | ( | plan_line_data_t * | pl_data, |
parser_block_t * | gc_block, | ||
float * | position | ||
) |
bool mc_line | ( | float * | target, |
plan_line_data_t * | pl_data | ||
) |
void mc_override_ctrl_update | ( | gc_override_flags_t | override_state | ) |
bool mc_parking_motion | ( | float * | parking_target, |
plan_line_data_t * | pl_data | ||
) |
gc_probe_t mc_probe_cycle | ( | float * | target, |
plan_line_data_t * | pl_data, | ||
gc_parser_flags_t | parser_flags | ||
) |
void mc_thread | ( | plan_line_data_t * | pl_data, |
float * | position, | ||
gc_thread_data * | thread, | ||
bool | feed_hold_disabled | ||
) |