grblHAL core  20241107
motion_control.c File Reference
#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)
 

Function Documentation

◆ mc_arc()

void mc_arc ( float *  target,
plan_line_data_t pl_data,
float *  position,
float *  offset,
float  radius,
plane_t  plane,
int32_t  turns 
)

◆ mc_canned_drill()

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 
)

◆ mc_cubic_b_spline()

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.

◆ mc_dwell()

void mc_dwell ( float  seconds)

◆ mc_homing_cycle()

status_code_t mc_homing_cycle ( axes_signals_t  cycle)

◆ mc_jog_execute()

status_code_t mc_jog_execute ( plan_line_data_t pl_data,
parser_block_t gc_block,
float *  position 
)

◆ mc_line()

bool mc_line ( float *  target,
plan_line_data_t pl_data 
)

◆ mc_override_ctrl_update()

void mc_override_ctrl_update ( gc_override_flags_t  override_state)

◆ mc_parking_motion()

bool mc_parking_motion ( float *  parking_target,
plan_line_data_t pl_data 
)

◆ mc_probe_cycle()

gc_probe_t mc_probe_cycle ( float *  target,
plan_line_data_t pl_data,
gc_parser_flags_t  parser_flags 
)

◆ mc_reset()

ISR_CODE void ISR_FUNC() mc_reset ( void  )

◆ mc_thread()

void mc_thread ( plan_line_data_t pl_data,
float *  position,
gc_thread_data thread,
bool  feed_hold_disabled 
)