Merged PR #4553: New gcode flavor (RepRapFirmware) using G10 temperature gcode (thanks @ardenpm)

Old RepRap/Sprinter remains for compatibility with older firmwares, new gcode flavor RepRapFirmware was
introduced so PS supports new versions of RRF (which deprecate M104 for temperature changes)
This commit is contained in:
Lukas Matena 2020-10-23 13:30:46 +02:00
commit 41b3af7599
8 changed files with 81 additions and 27 deletions

View file

@ -1642,9 +1642,9 @@ std::string GCode::placeholder_parser_process(const std::string &name, const std
}
}
// Parse the custom G-code, try to find mcode_set_temp_dont_wait and mcode_set_temp_and_wait inside the custom G-code.
// Parse the custom G-code, try to find mcode_set_temp_dont_wait and mcode_set_temp_and_wait or optionally G10 with temperature inside the custom G-code.
// Returns true if one of the temp commands are found, and try to parse the target temperature value into temp_out.
static bool custom_gcode_sets_temperature(const std::string &gcode, const int mcode_set_temp_dont_wait, const int mcode_set_temp_and_wait, int &temp_out)
static bool custom_gcode_sets_temperature(const std::string &gcode, const int mcode_set_temp_dont_wait, const int mcode_set_temp_and_wait, const bool include_g10, int &temp_out)
{
temp_out = -1;
if (gcode.empty())
@ -1687,6 +1687,40 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc
}
}
}
} else if (*ptr == 'G' && include_g10) { // Only check for G10 if requested
// Line starts with 'G'.
++ ptr;
// Parse the G code value.
char *endptr = nullptr;
int gcode = int(strtol(ptr, &endptr, 10));
if (endptr != nullptr && endptr != ptr && gcode == 10 /* G10 */) {
// G10 code found
ptr = endptr;
// Now try to parse the temperature value.
// While not at the end of the line:
while (strchr(";\r\n\0", *ptr) == nullptr) {
// Skip whitespaces.
for (; *ptr == ' ' || *ptr == '\t'; ++ ptr);
if (*ptr == 'S') {
// Skip whitespaces.
for (++ ptr; *ptr == ' ' || *ptr == '\t'; ++ ptr);
// Parse an int.
endptr = nullptr;
long temp_parsed = strtol(ptr, &endptr, 10);
if (endptr > ptr) {
ptr = endptr;
temp_out = temp_parsed;
// Let the caller know that the custom G-code sets the temperature
// Only do this after successfully parsing temperature since G10
// can be used for other reasons
temp_set_by_gcode = true;
}
} else {
// Skip this word.
for (; strchr(" \t;\r\n\0", *ptr) == nullptr; ++ ptr);
}
}
}
}
// Skip the rest of the line.
for (; *ptr != 0 && *ptr != '\r' && *ptr != '\n'; ++ ptr);
@ -1736,7 +1770,7 @@ void GCode::_print_first_layer_bed_temperature(FILE *file, Print &print, const s
int temp = print.config().first_layer_bed_temperature.get_at(first_printing_extruder_id);
// Is the bed temperature set by the provided custom G-code?
int temp_by_gcode = -1;
bool temp_set_by_gcode = custom_gcode_sets_temperature(gcode, 140, 190, temp_by_gcode);
bool temp_set_by_gcode = custom_gcode_sets_temperature(gcode, 140, 190, false, temp_by_gcode);
if (temp_set_by_gcode && temp_by_gcode >= 0 && temp_by_gcode < 1000)
temp = temp_by_gcode;
// Always call m_writer.set_bed_temperature() so it will set the internal "current" state of the bed temp as if
@ -1754,7 +1788,8 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c
{
// Is the bed temperature set by the provided custom G-code?
int temp_by_gcode = -1;
if (custom_gcode_sets_temperature(gcode, 104, 109, temp_by_gcode)) {
bool include_g10 = (print.config().gcode_flavor == gcfRepRapFirmware);
if (custom_gcode_sets_temperature(gcode, 104, 109, include_g10, temp_by_gcode)) {
// Set the extruder temperature at m_writer, but throw away the generated G-code as it will be written with the custom G-code.
int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id);
if (temp_by_gcode >= 0 && temp_by_gcode < 1000)

View file

@ -689,7 +689,7 @@ void GCodeProcessor::reset()
m_global_positioning_type = EPositioningType::Absolute;
m_e_local_positioning_type = EPositioningType::Absolute;
m_extruder_offsets = std::vector<Vec3f>(Min_Extruder_Count, Vec3f::Zero());
m_flavor = gcfRepRap;
m_flavor = gcfRepRapSprinter;
m_start_position = { 0.0f, 0.0f, 0.0f, 0.0f };
m_end_position = { 0.0f, 0.0f, 0.0f, 0.0f };
@ -1109,7 +1109,7 @@ bool GCodeProcessor::process_cura_tags(const std::string& comment)
else if (flavor == "Repetier")
m_flavor = gcfRepetier;
else if (flavor == "RepRap")
m_flavor = gcfRepRap;
m_flavor = gcfRepRapFirmware;
else if (flavor == "Marlin")
m_flavor = gcfMarlin;
else
@ -1801,7 +1801,7 @@ void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line)
return;
// see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration
float factor = (m_flavor != gcfRepRap && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f;
float factor = ((m_flavor != gcfRepRapSprinter && m_flavor != gcfRepRapFirmware) && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f;
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
if (line.has_x())

View file

@ -126,7 +126,7 @@ public:
}
WipeTowerWriter& disable_linear_advance() {
m_gcode += (m_gcode_flavor == gcfRepRap
m_gcode += (m_gcode_flavor == gcfRepRapSprinter || m_gcode_flavor == gcfRepRapFirmware
? (std::string("M572 D") + std::to_string(m_current_tool) + " S0\n")
: std::string("M900 K0\n"));
return *this;
@ -386,7 +386,7 @@ public:
// Set digital trimpot motor
WipeTowerWriter& set_extruder_trimpot(int current)
{
if (m_gcode_flavor == gcfRepRap)
if (m_gcode_flavor == gcfRepRapSprinter || m_gcode_flavor == gcfRepRapFirmware)
m_gcode += "M906 E";
else
m_gcode += "M907 E";

View file

@ -625,7 +625,7 @@ namespace Slic3r {
void GCodeTimeEstimator::set_default()
{
set_units(Millimeters);
set_dialect(gcfRepRap);
set_dialect(gcfRepRapSprinter);
set_global_positioning_type(Absolute);
set_e_local_positioning_type(Absolute);
@ -1204,7 +1204,8 @@ namespace Slic3r {
if ((dialect == gcfRepetier) ||
(dialect == gcfMarlin) ||
(dialect == gcfSmoothie) ||
(dialect == gcfRepRap))
(dialect == gcfRepRapSprinter) ||
(dialect == gcfRepRapFirmware))
{
if (line.has_value('S', value))
extra_time += value;
@ -1316,7 +1317,7 @@ namespace Slic3r {
GCodeFlavor dialect = get_dialect();
// see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration
float factor = ((dialect != gcfRepRap) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f;
float factor = ((dialect != gcfRepRapSprinter && dialect != gcfRepRapFirmware) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f;
if (line.has_x())
set_axis_max_acceleration(X, line.x() * factor);

View file

@ -46,7 +46,13 @@ std::string GCodeWriter::preamble()
gcode << "G21 ; set units to millimeters\n";
gcode << "G90 ; use absolute coordinates\n";
}
if (FLAVOR_IS(gcfRepRap) || FLAVOR_IS(gcfMarlin) || FLAVOR_IS(gcfTeacup) || FLAVOR_IS(gcfRepetier) || FLAVOR_IS(gcfSmoothie)) {
if (FLAVOR_IS(gcfRepRapSprinter) ||
FLAVOR_IS(gcfRepRapFirmware) ||
FLAVOR_IS(gcfMarlin) ||
FLAVOR_IS(gcfTeacup) ||
FLAVOR_IS(gcfRepetier) ||
FLAVOR_IS(gcfSmoothie))
{
if (this->config.use_relative_e_distances) {
gcode << "M83 ; use relative distances for extrusion\n";
} else {
@ -72,11 +78,15 @@ std::string GCodeWriter::set_temperature(unsigned int temperature, bool wait, in
return "";
std::string code, comment;
if (wait && FLAVOR_IS_NOT(gcfTeacup)) {
if (wait && FLAVOR_IS_NOT(gcfTeacup) && FLAVOR_IS_NOT(gcfRepRapFirmware)) {
code = "M109";
comment = "set temperature and wait for it to be reached";
} else {
code = "M104";
if (FLAVOR_IS(gcfRepRapFirmware)) { // M104 is deprecated on RepRapFirmware
code = "G10";
} else {
code = "M104";
}
comment = "set temperature";
}
@ -88,14 +98,17 @@ std::string GCodeWriter::set_temperature(unsigned int temperature, bool wait, in
gcode << "S";
}
gcode << temperature;
if (tool != -1 &&
( (this->multiple_extruders && ! m_single_extruder_multi_material) ||
FLAVOR_IS(gcfMakerWare) || FLAVOR_IS(gcfSailfish)) ) {
gcode << " T" << tool;
bool multiple_tools = this->multiple_extruders && ! m_single_extruder_multi_material;
if (tool != -1 && (multiple_tools || FLAVOR_IS(gcfMakerWare) || FLAVOR_IS(gcfSailfish)) ) {
if (FLAVOR_IS(gcfRepRapFirmware)) {
gcode << " P" << tool;
} else {
gcode << " T" << tool;
}
}
gcode << " ; " << comment << "\n";
if (FLAVOR_IS(gcfTeacup) && wait)
if ((FLAVOR_IS(gcfTeacup) || FLAVOR_IS(gcfRepRapFirmware)) && wait)
gcode << "M116 ; wait for temperature to be reached\n";
return gcode.str();

View file

@ -1285,8 +1285,9 @@ std::string Print::validate() const
"and use filaments of the same diameter.");
}
if (m_config.gcode_flavor != gcfRepRap && m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlin)
return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter and Repetier G-code flavors.");
if (m_config.gcode_flavor != gcfRepRapSprinter && m_config.gcode_flavor != gcfRepRapFirmware &&
m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlin)
return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter, RepRapFirmware and Repetier G-code flavors.");
if (! m_config.use_relative_e_distances)
return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).");
if (m_config.ooze_prevention)

View file

@ -983,6 +983,7 @@ void PrintConfigDef::init_fff_params()
"The \"No extrusion\" flavor prevents PrusaSlicer from exporting any extrusion value at all.");
def->enum_keys_map = &ConfigOptionEnum<GCodeFlavor>::get_enum_values();
def->enum_values.push_back("reprap");
def->enum_values.push_back("reprapfirmware");
def->enum_values.push_back("repetier");
def->enum_values.push_back("teacup");
def->enum_values.push_back("makerware");
@ -993,6 +994,7 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("smoothie");
def->enum_values.push_back("no-extrusion");
def->enum_labels.push_back("RepRap/Sprinter");
def->enum_labels.push_back("RepRapFirmware");
def->enum_labels.push_back("Repetier");
def->enum_labels.push_back("Teacup");
def->enum_labels.push_back("MakerWare (MakerBot)");
@ -1003,7 +1005,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back("Smoothie");
def->enum_labels.push_back(L("No extrusion"));
def->mode = comExpert;
def->set_default_value(new ConfigOptionEnum<GCodeFlavor>(gcfRepRap));
def->set_default_value(new ConfigOptionEnum<GCodeFlavor>(gcfRepRapSprinter));
def = this->add("gcode_label_objects", coBool);
def->label = L("Label objects");
@ -3352,11 +3354,12 @@ std::string FullPrintConfig::validate()
if (this->use_firmware_retraction.value &&
this->gcode_flavor.value != gcfSmoothie &&
this->gcode_flavor.value != gcfRepRap &&
this->gcode_flavor.value != gcfRepRapSprinter &&
this->gcode_flavor.value != gcfRepRapFirmware &&
this->gcode_flavor.value != gcfMarlin &&
this->gcode_flavor.value != gcfMachinekit &&
this->gcode_flavor.value != gcfRepetier)
return "--use-firmware-retraction is only supported by Marlin, Smoothie, Repetier and Machinekit firmware";
return "--use-firmware-retraction is only supported by Marlin, Smoothie, RepRapFirmware, Repetier and Machinekit firmware";
if (this->use_firmware_retraction.value)
for (unsigned char wipe : this->wipe.values)

View file

@ -25,7 +25,7 @@
namespace Slic3r {
enum GCodeFlavor : unsigned char {
gcfRepRap, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit,
gcfRepRapSprinter, gcfRepRapFirmware, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit,
gcfSmoothie, gcfNoExtrusion,
};
@ -95,7 +95,8 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology
template<> inline const t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["reprap"] = gcfRepRap;
keys_map["reprap"] = gcfRepRapSprinter;
keys_map["reprapfirmware"] = gcfRepRapFirmware;
keys_map["repetier"] = gcfRepetier;
keys_map["teacup"] = gcfTeacup;
keys_map["makerware"] = gcfMakerWare;