Fork of Smoothie to port to mbed non-LPC targets.
Fork of Smoothie by
Gcode.cpp
00001 /* 00002 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl). 00003 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 00004 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00005 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>. 00006 */ 00007 00008 00009 #include <string> 00010 using std::string; 00011 #include "Gcode.h" 00012 #include "libs/StreamOutput.h" 00013 #include "utils.h" 00014 00015 #include <stdlib.h> 00016 00017 // This is a gcode object. It reprensents a GCode string/command, an caches some important values about that command for the sake of performance. 00018 // It gets passed around in events, and attached to the queue ( that'll change ) 00019 Gcode::Gcode(const string& command, StreamOutput* stream) : command(command), m(0), g(0), add_nl(false), stream(stream) { 00020 prepare_cached_values(); 00021 this->millimeters_of_travel = 0.0F; 00022 this->accepted_by_module=false; 00023 } 00024 00025 Gcode::Gcode(const Gcode& to_copy){ 00026 this->command.assign( to_copy.command ); 00027 this->millimeters_of_travel = to_copy.millimeters_of_travel; 00028 this->has_m = to_copy.has_m; 00029 this->has_g = to_copy.has_g; 00030 this->m = to_copy.m; 00031 this->g = to_copy.g; 00032 this->add_nl = to_copy.add_nl; 00033 this->stream = to_copy.stream; 00034 this->accepted_by_module=false; 00035 this->txt_after_ok.assign( to_copy.txt_after_ok ); 00036 } 00037 00038 Gcode& Gcode::operator= (const Gcode& to_copy){ 00039 if( this != &to_copy ){ 00040 this->command.assign( to_copy.command ); 00041 this->millimeters_of_travel = to_copy.millimeters_of_travel; 00042 this->has_m = to_copy.has_m; 00043 this->has_g = to_copy.has_g; 00044 this->m = to_copy.m; 00045 this->g = to_copy.g; 00046 this->add_nl = to_copy.add_nl; 00047 this->stream = to_copy.stream; 00048 this->txt_after_ok.assign( to_copy.txt_after_ok ); 00049 } 00050 this->accepted_by_module=false; 00051 return *this; 00052 } 00053 00054 00055 // Whether or not a Gcode has a letter 00056 bool Gcode::has_letter( char letter ){ 00057 //return ( this->command->find( letter ) != string::npos ); 00058 for (std::string::const_iterator c = this->command.cbegin(); c != this->command.cend(); c++) { 00059 if( *c == letter ){ 00060 return true; 00061 } 00062 } 00063 return false; 00064 } 00065 00066 // Retrieve the value for a given letter 00067 // We don't use the high-level methods of std::string because they call malloc and it's very bad to do that inside of interrupts 00068 float Gcode::get_value( char letter ){ 00069 //__disable_irq(); 00070 const char* cs = command.c_str(); 00071 char* cn = NULL; 00072 for (; *cs; cs++){ 00073 if( letter == *cs ){ 00074 cs++; 00075 float r = strtof(cs, &cn); 00076 if (cn > cs) 00077 return r; 00078 } 00079 } 00080 //__enable_irq(); 00081 return 0; 00082 } 00083 00084 int Gcode::get_int( char letter ) 00085 { 00086 const char* cs = command.c_str(); 00087 char* cn = NULL; 00088 for (; *cs; cs++){ 00089 if( letter == *cs ){ 00090 cs++; 00091 int r = strtol(cs, &cn, 10); 00092 if (cn > cs) 00093 return r; 00094 } 00095 } 00096 return 0; 00097 } 00098 00099 int Gcode::get_num_args(){ 00100 int count = 0; 00101 for(size_t i=1; i<this->command.length(); i++){ 00102 if( this->command.at(i) >= 'A' && this->command.at(i) <= 'Z' ){ 00103 count++; 00104 } 00105 } 00106 return count; 00107 } 00108 00109 // Cache some of this command's properties, so we don't have to parse the string every time we want to look at them 00110 void Gcode::prepare_cached_values(){ 00111 if( this->has_letter('G') ){ 00112 this->has_g = true; 00113 this->g = this->get_int('G'); 00114 }else{ 00115 this->has_g = false; 00116 } 00117 if( this->has_letter('M') ){ 00118 this->has_m = true; 00119 this->m = this->get_int('M'); 00120 }else{ 00121 this->has_m = false; 00122 } 00123 } 00124 00125 void Gcode::mark_as_taken(){ 00126 this->accepted_by_module = true; 00127 }
Generated on Tue Jul 12 2022 20:09:01 by 1.7.2