008.02 refactored gcode normalizer to include octal stripping

This commit is contained in:
alden.hart
2013-04-28 22:12:15 -04:00
parent 44cf6a891e
commit 6b7e3585bf
8 changed files with 68 additions and 71 deletions
+1 -1
View File
@@ -30,7 +30,7 @@
<ToolNumber>000028011884</ToolNumber>
<Channel>
<host>127.0.0.1</host>
<port>4114</port>
<port>4123</port>
<ssl>False</ssl>
</Channel>
<ToolOptions>
+3
View File
@@ -168,6 +168,7 @@ uint8_t cm_get_distance_mode() { return gm.distance_mode;}
uint8_t cm_get_inverse_feed_rate_mode() { return gm.inverse_feed_rate_mode;}
uint8_t cm_get_spindle_mode() { return gm.spindle_mode;}
uint32_t cm_get_model_linenum() { return gm.linenum;}
uint8_t cm_get_block_delete_switch() { return gm.block_delete_switch;}
uint8_t cm_isbusy() { return (mp_isbusy());}
// set parameters in gm struct
@@ -560,6 +561,8 @@ void canonical_machine_init()
cm_set_path_control(cfg.path_control);
cm_set_distance_mode(cfg.distance_mode);
gm.block_delete_switch = true;
// never start a machine in a motion mode
gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE;
+7 -3
View File
@@ -94,11 +94,11 @@ typedef struct GCodeModel { // Gcode dynamic model
float g28_position[AXES]; // XYZABC stored machine position for G28
float g30_position[AXES]; // XYZABC stored machine position for G30
float min_time; // minimum time possible for the move given axis constraints
float min_time; // minimum time possible for the move given axis constraints
float feed_rate; // F - normalized to millimeters/minute
float inverse_feed_rate; // ignored if inverse_feed_rate not active
float feed_rate_override_factor; // 1.0000 x F feed rate. Go up or down from there
float traverse_override_factor; // 1.0000 x traverse rate. Go down from there
float traverse_override_factor; // 1.0000 x traverse rate. Go down from there
uint8_t inverse_feed_rate_mode; // G93 TRUE = inverse, FALSE = normal (G94)
uint8_t feed_rate_override_enable; // TRUE = overrides enabled (M48), F=(M49)
uint8_t traverse_override_enable; // TRUE = traverse override enabled
@@ -124,9 +124,11 @@ typedef struct GCodeModel { // Gcode dynamic model
uint8_t spindle_mode; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4)
float spindle_speed; // in RPM
float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there
float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there
uint8_t spindle_override_enable; // TRUE = override enabled
uint8_t block_delete_switch; // set true to enable block deletes (true is default)
// unimplemented gcode parameters
// float cutter_radius; // D - cutter radius compensation (0 is off)
// float cutter_length; // H - cutter length compensation (0 is off)
@@ -443,6 +445,8 @@ uint8_t cm_get_distance_mode(void);
uint8_t cm_get_inverse_feed_rate_mode(void);
uint8_t cm_get_spindle_mode(void);
uint32_t cm_get_model_linenum(void);
uint8_t cm_get_block_delete_switch(void);
uint8_t cm_isbusy(void);
void cm_set_motion_mode(uint8_t motion_mode);
+1
View File
@@ -196,6 +196,7 @@ static stat_t _command_dispatch()
} else if (cs.state == CONTROLLER_STARTUP) {
// strcpy(cs.in_buf, "$x");
// strcpy(cs.in_buf, "g1f400x100");
strcpy(cs.in_buf, "?");
cs.state = CONTROLLER_READY;
} else {
return (STAT_OK);
+50 -60
View File
@@ -78,82 +78,72 @@ stat_t gc_gcode_parser(char_t *block)
* chars < 0x20 (control characters)
* ! $ % , ; ; ? @ ^ _ ~ " ' <DEL>
*
* Valid characters in a Gcode block are (see RS274NGC_3 Appendix E)
* digits all digits are passed to interpreter
* lower case alpha all alpha is passed
* upper case alpha all alpha is passed
* + - . / * < = > chars passed to interpreter
* | % # ( ) [ ] { } chars passed to interpreter
* <sp> <tab> chars are legal but are not passed
* / if first, block delete char - omits the block
* Valid characters in a Gcode block are a sub-set of those in RS274NGC_3 Appendix E:
* - alphanumeric plus '-' and '.'
*
* Block delete: Blocks starting with '/' are ignored if block delete switch is on,
* otherwise they are processed as usual.
*
* Octal stripping: Leading zeros in number fields are stripped unless followed by a period
*
* Comment handling:
*
* - Comments are not normalized - they are left alone
* - Comments always terminate the block (i.e. embedded comments are not supported)
* - Messages in comments are sent to console
* - The 'MSG' specifier in comment can have mixed case but cannot cannot have embedded white spaces
* - Normalization returns true if there was a message to display, false otherwise
* - Processing splits string into command and comment portions - cases:
* supported: COMMAND
* supported: comment
* supported: COMMAND comment
*
* unsupported: COMMAND COMMAND
* unsupported: comment COMMAND
* unsupported: COMMAND comment COMMAND
*
* ++++ todo: Support leading and trailing spaces around the MSG specifier
* ++++ todo: Refactor to reject Octal numbers (leading 0's)
* - Processing splits string into command and comment portions - supported cases are:
* COMMAND
* (comment)
* COMMAND (comment)
*/
static uint8_t _normalize_gcode_block(char_t *block)
static uint8_t _normalize_gcode_block(char_t *str)
{
char_t c;
char_t *comment=0; // comment pointer - first char past opening paren
uint8_t i=0; // index for incoming characters
uint8_t j=0; // index for normalized characters
char_t *rd = str; // read pointer
char_t *wr = str; // pointer to write normalized characters
char_t *cp = NUL; // comment pointer - first char past opening paren
if (block[0] == '/') { // discard deleted blocks
block[0] = NUL;
return (false);
}
if (block[0] == '?') { // trap and return ? command
return (false);
if (*rd == '?') { return (false); } // trap and return ? command
if (*rd == '/') { // handle block deletes
rd++;
if (cm_get_block_delete_switch() == true) {
*wr = NUL;
return (false);
}
}
// normalize the command block & mark the comment(if any)
while ((c = toupper(block[i++])) != NUL) {
if ((isupper(c)) || (isdigit(c))) { // capture common chars
block[j++] = c;
do {
if (*rd == NUL) { *wr = NUL; }
else if (*rd == '(') { *wr = NUL; cp = rd+1; }
else if ((isalnum((char)*rd)) || (strchr("-.", *rd))) { // all valid characters
*(wr++) = (char_t)toupper((char)*(rd));
}
rd++;
} while (*wr != NUL);
// Perform Octal stripping - remove invalid leading zeros in number strings
rd = str;
while (*rd != NUL) {
if ((!isdigit(*rd)) && (*(rd+1) == '0') && (isdigit(*(rd+2)))) {
wr = rd+1;
while (*wr != NUL) { *wr = *(wr+1); wr++;}
// while (*wr != NUL) { *(wr++) = *(wr+1); }
continue;
}
if (c == '(') { // detect & handle comments
block[j] = NUL;
comment = &block[i];
break;
}
if (c <= ' ') continue; // toss controls & whitespace
if (c == DEL) continue; // toss DELETE (0x7F)
if (strchr("!$%,;:?@^_~`\'\"", c)) // toss invalid punctuation
continue;
block[j++] = c;
rd++;
}
block[j] = NUL; // terminate the command
if (comment != 0) {
if ((toupper(comment[0]) == 'M') &&
(toupper(comment[1]) == 'S') &&
(toupper(comment[2]) == 'G')) {
i=0;
comment +=3; // skip past the leading chars
while ((c = comment[i++]) != NUL) {// remove trailing parenthesis
if (c == ')') {
comment[--i] = NUL;
break;
}
}
(void)cm_message(comment);
// process a comment with a message, otherwise ignore it
rd = cp;
if (cp != NUL) {
if ((tolower(*(rd++)) == 'm') && (toupper(*(rd++)) == 's') && (toupper(*(rd++)) == 'g')) {
do {
if (*rd == ')') *rd = NUL; // remove trailing parenthesis, if any
rd++;
} while (*rd != NUL);
(void)cm_message(cp);
return (true);
}
}
}
return (false);
}
+1 -2
View File
@@ -236,7 +236,7 @@ void rpt_print_system_ready_message(void)
/*
* rpt_init_status_report()
*
* Call this function to completely re-initialze the status report
* Call this function to completely re-initialize the status report
* Sets SR list to hard-coded defaults and re-initializes sr values in NVM
*/
@@ -248,7 +248,6 @@ void rpt_init_status_report()
cmdObj_t *cmd = cmd_reset_list(); // used for status report persistence locations
cs.status_report_counter = (cfg.status_report_interval / RTC_PERIOD); // RTC fires every 10 ms
// cmd->index = cmd_get_index((const char_t *)"",(const char_t *)"se00"); // set first SR persistence index
cmd->index = cmd_get_index(nul, se00); // set first SR persistence index
for (uint8_t i=0; i < CMD_STATUS_REPORT_LEN ; i++) {
if (sr_defaults[i][0] == NUL) break; // quit on first blank array entry
+4 -4
View File
@@ -49,7 +49,7 @@
// *** motor settings ***
#define M1_MOTOR_MAP AXIS_X // 1ma
#define M1_MOTOR_MAP AXIS_X // 1ma
#define M1_STEP_ANGLE 1.8 // 1sa
#define M1_TRAVEL_PER_REV 1.25 // 1tr
#define M1_MICROSTEPS 8 // 1mi 1,2,4,8
@@ -94,7 +94,7 @@
// *** axis settings ***
#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values
#define X_VELOCITY_MAX 1200 // xvm G0 max velocity in mm/min
#define X_VELOCITY_MAX 800 // xvm G0 max velocity in mm/min
#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min
#define X_TRAVEL_MAX 150 // xtm travel between switches or crashes
#define X_JERK_MAX JERK_MAX // xjm
@@ -108,7 +108,7 @@
#define X_JERK_HOMING X_JERK_MAX // xjh
#define Y_AXIS_MODE AXIS_STANDARD
#define Y_VELOCITY_MAX 1200
#define Y_VELOCITY_MAX 800
#define Y_FEEDRATE_MAX Y_VELOCITY_MAX
#define Y_TRAVEL_MAX 150
#define Y_JERK_MAX JERK_MAX
@@ -122,7 +122,7 @@
#define Y_JERK_HOMING Y_JERK_MAX
#define Z_AXIS_MODE AXIS_STANDARD
#define Z_VELOCITY_MAX 1200
#define Z_VELOCITY_MAX 800
#define Z_FEEDRATE_MAX Z_VELOCITY_MAX
#define Z_TRAVEL_MAX 75
#define Z_JERK_MAX JERK_MAX
+1 -1
View File
@@ -40,7 +40,7 @@
extern "C"{
#endif
#define TINYG2_FIRMWARE_BUILD 008.01 // refining a functioning unit!
#define TINYG2_FIRMWARE_BUILD 008.02 // refining a functioning unit!
#define TINYG2_FIRMWARE_VERSION 0.01 // firmware major version
#define TINYG2_HARDWARE_PLATFORM 1.00 // hardware platform indicator (Native Arduino Due)
#define TINYG2_HARDWARE_VERSION 1.00 // hardware platform revision number