Implement M82/M83 and handle relative movements entirely different.

Instead of converting them to absolute first, then back to
relative and having all the fuzz with working on the queue's
start vs. working at the queue's end, mark a movement as relative
and use this directly.
This commit is contained in:
Markus Hitter 2012-03-04 21:23:50 +01:00
parent 34ab76fe6e
commit 5f9ae5b087
7 changed files with 146 additions and 74 deletions

71
dda.c
View File

@ -222,28 +222,55 @@ void dda_create(DDA *dda, TARGET *target) {
// we end at the passed target
memcpy(&(dda->endpoint), target, sizeof(TARGET));
x_delta_um = (uint32_t)labs(target->X - startpoint.X);
y_delta_um = (uint32_t)labs(target->Y - startpoint.Y);
z_delta_um = (uint32_t)labs(target->Z - startpoint.Z);
e_delta_um = (uint32_t)labs(target->E - startpoint.E);
// TODO TODO: We should really make up a loop for all axes.
// Think of what happens when a sixth axis (multi colour extruder)
// appears?
if (target->all_relative) {
x_delta_um = labs(target->X);
um_to_steps_x(dda->x_delta, x_delta_um);
dda->x_direction = (target->X < 0)?1:0;
um_to_steps_x(steps, target->X);
dda->x_delta = labs(steps - startpoint_steps.X);
startpoint_steps.X = steps;
um_to_steps_y(steps, target->Y);
dda->y_delta = labs(steps - startpoint_steps.Y);
startpoint_steps.Y = steps;
um_to_steps_z(steps, target->Z);
dda->z_delta = labs(steps - startpoint_steps.Z);
startpoint_steps.Z = steps;
um_to_steps_e(steps, target->E);
dda->e_delta = labs(steps - startpoint_steps.E);
startpoint_steps.E = steps;
y_delta_um = labs(target->Y);
um_to_steps_y(dda->y_delta, y_delta_um);
dda->y_direction = (target->Y < 0)?1:0;
dda->x_direction = (target->X >= startpoint.X)?1:0;
dda->y_direction = (target->Y >= startpoint.Y)?1:0;
dda->z_direction = (target->Z >= startpoint.Z)?1:0;
dda->e_direction = (target->E >= startpoint.E)?1:0;
z_delta_um = labs(target->Z);
um_to_steps_z(dda->z_delta, z_delta_um);
dda->z_direction = (target->Z < 0)?1:0;
}
else {
x_delta_um = (uint32_t)labs(target->X - startpoint.X);
y_delta_um = (uint32_t)labs(target->Y - startpoint.Y);
z_delta_um = (uint32_t)labs(target->Z - startpoint.Z);
um_to_steps_x(steps, target->X);
dda->x_delta = labs(steps - startpoint_steps.X);
startpoint_steps.X = steps;
um_to_steps_y(steps, target->Y);
dda->y_delta = labs(steps - startpoint_steps.Y);
startpoint_steps.Y = steps;
um_to_steps_z(steps, target->Z);
dda->z_delta = labs(steps - startpoint_steps.Z);
startpoint_steps.Z = steps;
dda->x_direction = (target->X >= startpoint.X)?1:0;
dda->y_direction = (target->Y >= startpoint.Y)?1:0;
dda->z_direction = (target->Z >= startpoint.Z)?1:0;
}
// This if() matches Sprinter's behaviour as of March 2012.
if (target->all_relative || target->e_relative) {
e_delta_um = labs(target->E);
um_to_steps_e(dda->e_delta, e_delta_um);
dda->e_direction = (target->E < 0)?1:0;
}
else {
e_delta_um = (uint32_t)labs(target->E - startpoint.E);
um_to_steps_e(steps, target->E);
dda->e_delta = labs(steps - startpoint_steps.E);
startpoint_steps.E = steps;
dda->e_direction = (target->E >= startpoint.E)?1:0;
}
if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
sersendf_P(PSTR("%ld,%ld,%ld,%ld] ["), target->X - startpoint.X, target->Y - startpoint.Y, target->Z - startpoint.Z, target->E - startpoint.E);
@ -455,10 +482,6 @@ void dda_create(DDA *dda, TARGET *target) {
// next dda starts where we finish
memcpy(&startpoint, target, sizeof(TARGET));
// if E is relative, reset it here
#ifndef E_ABSOLUTE
startpoint.E = startpoint_steps.E = 0;
#endif
}
/*! Start a prepared DDA

6
dda.h
View File

@ -97,11 +97,17 @@
X, Y, Z and E are in micrometers unless explcitely stated. F is in mm/min.
*/
typedef struct {
// TODO TODO: We should really make up a loop for all axes.
// Think of what happens when a sixth axis (multi colour extruder)
// appears?
int32_t X;
int32_t Y;
int32_t Z;
int32_t E;
uint32_t F;
uint8_t all_relative :1; ///< bool: relative coordinates?
uint8_t e_relative :1; ///< bool: e axis relative? Overrides all_relative
} TARGET;
/**

View File

@ -75,6 +75,8 @@ static int32_t decfloat_to_int(decfloat *df, uint32_t multiplicand) {
return df->sign ? -(int32_t)r : (int32_t)r;
}
// TODO TODO: write a gcode_init(), next_target is used uninitialised. For a hint on what to do, see line 340ff.
/// Character Received - add it to our command
/// \param c the next character to process
void gcode_parse_char(uint8_t c) {
@ -344,16 +346,12 @@ void gcode_parse_char(uint8_t c) {
next_target.seen_G = 1;
next_target.G = 1;
if (next_target.option_relative) {
if (next_target.target.all_relative) {
next_target.target.X = next_target.target.Y = next_target.target.Z = 0;
#ifdef E_ABSOLUTE
next_target.target.E = 0;
#endif
}
#ifndef E_ABSOLUTE
// E always relative
if (next_target.target.all_relative || next_target.target.e_relative) {
next_target.target.E = 0;
#endif
}
}
}

View File

@ -40,7 +40,6 @@ typedef struct {
uint8_t seen_checksum :1; ///< seen a checksum?
uint8_t seen_semi_comment :1; ///< seen a semicolon?
uint8_t seen_parens_comment :1; ///< seen an open parenthesis
uint8_t option_relative :1; ///< relative or absolute coordinates?
uint8_t option_inches :1; ///< inches or millimeters?
};
uint16_t flags;

View File

@ -41,9 +41,7 @@ uint8_t next_tool;
#if E_STARTSTOP_STEPS > 0
/// move E by a certain amount at a certain speed
static void SpecialMoveE(int32_t e, uint32_t f) {
TARGET t = startpoint;
t.E += e;
t.F = f;
TARGET t = { 0L, 0L, 0L, e, f, 1, 1 };
enqueue(&t);
}
#endif /* E_STARTSTOP_STEPS > 0 */
@ -61,45 +59,66 @@ static void SpecialMoveE(int32_t e, uint32_t f) {
void process_gcode_command() {
uint32_t backup_f;
// convert relative to absolute
if (next_target.option_relative) {
next_target.target.X += startpoint.X;
next_target.target.Y += startpoint.Y;
next_target.target.Z += startpoint.Z;
#ifdef E_ABSOLUTE
next_target.target.E += startpoint.E;
#endif
}
// E ALWAYS relative, otherwise we overflow our registers after only a few layers
// next_target.target.E += startpoint.E;
// easier way to do this
// startpoint.E = 0;
// moved to dda.c, end of dda_create() and dda_queue.c, next_move()
// implement axis limits
#ifdef X_MIN
if (next_target.target.X < X_MIN * 1000.)
next_target.target.X = X_MIN * 1000.;
if (next_target.target.all_relative) {
if (next_target.target.X += startpoint.X < X_MIN * 1000.)
next_target.target.X = X_MIN * 1000. + startpoint.X;
}
else {
if (next_target.target.X < X_MIN * 1000.)
next_target.target.X = X_MIN * 1000.;
}
#endif
#ifdef X_MAX
if (next_target.target.X > X_MAX * 1000.)
next_target.target.X = X_MAX * 1000.;
if (next_target.target.all_relative) {
if (next_target.target.X += startpoint.X > X_MAX * 1000.)
next_target.target.X = X_MIN * 1000. - startpoint.X;
}
else {
if (next_target.target.X > X_MAX * 1000.)
next_target.target.X = X_MAX * 1000.;
}
#endif
#ifdef Y_MIN
if (next_target.target.Y < Y_MIN * 1000.)
next_target.target.Y = Y_MIN * 1000.;
if (next_target.target.all_relative) {
if (next_target.target.Y += startpoint.Y < Y_MIN * 1000.)
next_target.target.Y = Y_MIN * 1000. + startpoint.Y;
}
else {
if (next_target.target.Y < Y_MIN * 1000.)
next_target.target.Y = Y_MIN * 1000.;
}
#endif
#ifdef Y_MAX
if (next_target.target.Y > Y_MAX * 1000.)
next_target.target.Y = Y_MAX * 1000.;
if (next_target.target.all_relative) {
if (next_target.target.Y += startpoint.Y > Y_MAX * 1000.)
next_target.target.Y = Y_MIN * 1000. - startpoint.Y;
}
else {
if (next_target.target.Y > Y_MAX * 1000.)
next_target.target.Y = Y_MAX * 1000.;
}
#endif
#ifdef Z_MIN
if (next_target.target.Z < Z_MIN * 1000.)
next_target.target.Z = Z_MIN * 1000.;
if (next_target.target.all_relative) {
if (next_target.target.Z += startpoint.Z < Z_MIN * 1000.)
next_target.target.Z = Z_MIN * 1000. + startpoint.Z;
}
else {
if (next_target.target.Z < Z_MIN * 1000.)
next_target.target.Z = Z_MIN * 1000.;
}
#endif
#ifdef Z_MAX
if (next_target.target.Z > Z_MAX * 1000.)
next_target.target.Z = Z_MAX * 1000.;
if (next_target.target.all_relative) {
if (next_target.target.Z += startpoint.Z > Z_MAX * 1000.)
next_target.target.Z = Z_MIN * 1000. - startpoint.Z;
}
else {
if (next_target.target.Z > Z_MAX * 1000.)
next_target.target.Z = Z_MAX * 1000.;
}
#endif
@ -115,6 +134,7 @@ void process_gcode_command() {
next_tool = next_target.T;
}
// TODO TODO: really?
// if we didn't see an axis word, set it to startpoint. this fixes incorrect moves after homing
if (next_target.seen_X == 0)
next_target.target.X = startpoint.X;
@ -253,9 +273,15 @@ void process_gcode_command() {
//?
//? Example: G90
//?
//? All coordinates from now on are absolute relative to the origin of the machine. (This is the RepRap default.)
//? All coordinates from now on are absolute relative to the origin
//? of the machine. This is the RepRap default.
//?
next_target.option_relative = 0;
// No queue_wait() needed.
next_target.target.all_relative = 0;
// TODO: What's about startpoint, next_target an friends?
// What should a machine do when returning from relative
// to absolute mode?
break;
case 91:
@ -265,7 +291,9 @@ void process_gcode_command() {
//?
//? All coordinates from now on are relative to the last position.
//?
next_target.option_relative = 1;
// No queue_wait() needed.
next_target.target.all_relative = 1;
break;
case 92:
@ -393,11 +421,25 @@ void process_gcode_command() {
tool = next_tool;
break;
// M82 - Set E codes absolute (default)
// not implemented
case 82:
//? --- M82 - Set E codes absolute ---
//?
//? This is the default. M82/M82 is not documented in the
//? RepRap wiki, behaviours was taken from Strinter as of March 2012.
// No wait_queue() needed.
next_target.target.e_relative = 0;
break;
// M83 - Set E codes relative while in Absolute Coordinates (G90) mode
// not implemented
case 83:
//? --- M83 - Set E codes relative ---
//?
//? Counterpart to M82.
// No wait_queue() needed.
next_target.target.e_relative = 1;
break;
// M84- stop idle hold
case 84:
@ -407,6 +449,7 @@ void process_gcode_command() {
z_disable();
e_disable();
break;
// M3/M101- extruder on
case 3:
case 101:

12
home.c
View File

@ -34,7 +34,7 @@ void home() {
/// find X MIN endstop
void home_x_negative() {
#if defined X_MIN_PIN
TARGET t = startpoint;
TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 };
t.X = -1000000;
#ifdef SLOW_HOMING
@ -70,7 +70,7 @@ void home_x_positive() {
#warning X_MAX_PIN defined, but not X_MAX. home_x_positive() disabled.
#endif
#if defined X_MAX_PIN && defined X_MAX
TARGET t = startpoint;
TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 };
t.X = +1000000;
#ifdef SLOW_HOMING
@ -104,7 +104,7 @@ void home_x_positive() {
/// fund Y MIN endstop
void home_y_negative() {
#if defined Y_MIN_PIN
TARGET t = startpoint;
TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 };
t.Y = -1000000;
#ifdef SLOW_HOMING
@ -140,7 +140,7 @@ void home_y_positive() {
#warning Y_MAX_PIN defined, but not Y_MAX. home_y_positive() disabled.
#endif
#if defined Y_MAX_PIN && defined Y_MAX
TARGET t = startpoint;
TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 };
t.Y = +1000000;
#ifdef SLOW_HOMING
@ -174,7 +174,7 @@ void home_y_positive() {
/// find Z MIN endstop
void home_z_negative() {
#if defined Z_MIN_PIN
TARGET t = startpoint;
TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 };
t.Z = -1000000;
#ifdef SLOW_HOMING
@ -211,7 +211,7 @@ void home_z_positive() {
#warning Z_MAX_PIN defined, but not Z_MAX. home_z_positive() disabled.
#endif
#if defined Z_MAX_PIN && defined Z_MAX
TARGET t = startpoint;
TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 };
t.Z = +1000000;
#ifdef SLOW_HOMING

View File

@ -274,6 +274,9 @@ void init(void) {
// set up serial
serial_init();
// set up G-code parsing
// gcode_init();
// set up inputs and outputs
io_init();