mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-13 19:01:21 +00:00
Fix duplicate G29 preparation time (#15274)
The time estimate added 260 s for every G29 on non-Bambu printers. Prusa MK4, MK4S and CORE One start G-code splits bed leveling across six G29 commands, so those printers showed about 26 extra minutes. The 260 s is now added once per G-code processing run. Bambu printers still only count a G29 inside an M622 J1 block, and their estimates are unchanged. Fixes #15088
This commit is contained in:
@@ -3730,6 +3730,7 @@ void GCodeProcessor::reset()
|
||||
m_detect_layer_based_on_tag = false;
|
||||
|
||||
m_seams_count = 0;
|
||||
m_g29_time_added = false;
|
||||
m_preheat_time = 0.f;
|
||||
m_preheat_steps = 1;
|
||||
}
|
||||
@@ -6131,15 +6132,12 @@ void GCodeProcessor::process_G4(const GCodeReader::GCodeLine& line)
|
||||
//BBS
|
||||
void GCodeProcessor::process_G29(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
//BBS: hardcode 260 seconds for G29
|
||||
//Todo: use a machine related setting when we have second kind of BBL printer
|
||||
const float value_s = 260.0;
|
||||
if (s_IsBBLPrinter){
|
||||
if(m_measure_g29_time)
|
||||
simulate_st_synchronize(value_s);
|
||||
}
|
||||
else{
|
||||
simulate_st_synchronize(value_s);
|
||||
// Firmware may split one bed-leveling sequence across multiple G29 subcommands.
|
||||
constexpr float g29_time = 260.0f;
|
||||
const bool should_add_time = !s_IsBBLPrinter || m_measure_g29_time;
|
||||
if (should_add_time && !m_g29_time_added) {
|
||||
simulate_st_synchronize(g29_time);
|
||||
m_g29_time_added = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1280,6 +1280,7 @@ inline constexpr float DEFAULT_FILAMENT_DENSITY = 1.245f;
|
||||
bool m_detect_layer_based_on_tag {false};
|
||||
int m_seams_count;
|
||||
bool m_measure_g29_time {false};
|
||||
bool m_g29_time_added {false};
|
||||
bool m_single_extruder_multi_material;
|
||||
float m_preheat_time;
|
||||
int m_preheat_steps;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "libslic3r/GCode/GCodeProcessor.hpp"
|
||||
#include "libslic3r/MultiNozzleUtils.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
#include "test_utils.hpp"
|
||||
|
||||
@@ -21,6 +22,7 @@
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "libslic3r/Config.hpp"
|
||||
|
||||
@@ -52,12 +54,16 @@ FullPrintConfig make_config(double load_time, double unload_time, double tool_ch
|
||||
return config;
|
||||
}
|
||||
|
||||
void run_processor(GCodeProcessor& proc, const FullPrintConfig& config, const char* gcode)
|
||||
void run_processor(GCodeProcessor& proc, const FullPrintConfig& config, const char* gcode, bool is_bbl_printer = true)
|
||||
{
|
||||
// reserved_tag() selects between two tag tables based on this shared static, and
|
||||
// other tests in the binary mutate it -- pin it so our "; FEATURE:" role tags are
|
||||
// parsed deterministically regardless of test execution order.
|
||||
GCodeProcessor::s_IsBBLPrinter = true;
|
||||
// other tests in the binary mutate it -- pin it so role tags are parsed
|
||||
// deterministically regardless of test execution order.
|
||||
const bool previous_is_bbl_printer = GCodeProcessor::s_IsBBLPrinter;
|
||||
GCodeProcessor::s_IsBBLPrinter = is_bbl_printer;
|
||||
const ScopeGuard restore_flag([previous_is_bbl_printer] {
|
||||
GCodeProcessor::s_IsBBLPrinter = previous_is_bbl_printer;
|
||||
});
|
||||
ScopedTemporaryFile temp(".gcode");
|
||||
{
|
||||
std::ofstream os(temp.string());
|
||||
@@ -99,6 +105,45 @@ double filament_change_delay(const GCodeProcessorResult& r)
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("G29 preparation time is added only once", "[GCodeTiming][Regression]")
|
||||
{
|
||||
const FullPrintConfig config = make_config(0.0, 0.0, 0.0);
|
||||
auto estimate = [&config](bool is_bbl_printer, const char* commands) {
|
||||
const auto mode = PrintEstimatedStatistics::ETimeMode::Normal;
|
||||
std::string gcode = is_bbl_printer ? "; FEATURE: Custom\n" : ";TYPE:Custom\n";
|
||||
gcode += "G1 X10 Y10 Z0.2 F600\nG1 X20 Y10 F600\n";
|
||||
if (is_bbl_printer)
|
||||
gcode += "M622 J1\n";
|
||||
gcode += commands;
|
||||
if (is_bbl_printer)
|
||||
gcode += "M623\n";
|
||||
gcode += "G1 X20 Y20 F600\nG1 X10 Y20 F600\n";
|
||||
|
||||
GCodeProcessor processor;
|
||||
run_processor(processor, config, gcode.c_str(), is_bbl_printer);
|
||||
return std::make_pair(processor.get_time(mode), processor.get_prepare_time(mode));
|
||||
};
|
||||
|
||||
const auto [baseline_time, baseline_prepare] = estimate(false, "G4 S0\n");
|
||||
const auto [one_time, one_prepare] = estimate(false, "G29\n");
|
||||
const auto [repeated_time, repeated_prepare] = estimate(false,
|
||||
"G29 P9 X10 Y-4 W32 H4\nG29 P1\nG29 P1 X0 Y0 W50 H20 C\nG29 P3.2\nG29 P3.13\nG29 A\n");
|
||||
|
||||
REQUIRE_THAT(one_time - baseline_time, WithinAbs(260.0, 1e-2));
|
||||
REQUIRE_THAT(one_prepare - baseline_prepare, WithinAbs(260.0, 1e-2));
|
||||
REQUIRE_THAT(repeated_time, WithinAbs(one_time, 1e-2));
|
||||
REQUIRE_THAT(repeated_prepare, WithinAbs(one_prepare, 1e-2));
|
||||
|
||||
const auto [baseline_bbl_time, baseline_bbl_prepare] = estimate(true, "G4 S0\n");
|
||||
const auto [one_bbl_time, one_bbl_prepare] = estimate(true, "G29\n");
|
||||
const auto [repeated_bbl_time, repeated_bbl_prepare] = estimate(true, "G29\nG29\n");
|
||||
|
||||
REQUIRE_THAT(one_bbl_time - baseline_bbl_time, WithinAbs(260.0, 1e-2));
|
||||
REQUIRE_THAT(one_bbl_prepare - baseline_bbl_prepare, WithinAbs(260.0, 1e-2));
|
||||
REQUIRE_THAT(repeated_bbl_time, WithinAbs(one_bbl_time, 1e-2));
|
||||
REQUIRE_THAT(repeated_bbl_prepare, WithinAbs(one_bbl_prepare, 1e-2));
|
||||
}
|
||||
|
||||
TEST_CASE("Filament-change time is attributed to tool-change moves, not extrusion roles", "[GCodeTiming]")
|
||||
{
|
||||
// Relative extrusion (M83) so every "E5" is a real 5mm extrusion move rather
|
||||
|
||||
Reference in New Issue
Block a user