Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/CuraEngine.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemco Burema <41987080+rburema@users.noreply.github.com>2022-11-01 22:09:51 +0300
committerGitHub <noreply@github.com>2022-11-01 22:09:51 +0300
commitd98c06b6a987f36b78b19f7119067f0cca89eae2 (patch)
tree74a82cabeb4bb82d6c246b1be666859ab75596a1
parent4585a7d3294aa49549de7f6f83ea30d0bcda2944 (diff)
parenta09f6118682f6e25577679b0c570a123f36f1f3d (diff)
Merge pull request #1742 from Ultimaker/CURA-7271_slow_lines_individually_minimum_layer_time
Cura 7271 slow lines individually minimum layer time
-rw-r--r--include/LayerPlan.h20
-rw-r--r--include/pathPlanning/TimeMaterialEstimates.h2
-rw-r--r--src/LayerPlan.cpp171
3 files changed, 107 insertions, 86 deletions
diff --git a/include/LayerPlan.h b/include/LayerPlan.h
index 5c1290bd6..1c5e2f322 100644
--- a/include/LayerPlan.h
+++ b/include/LayerPlan.h
@@ -72,6 +72,7 @@ protected:
std::optional<double> prev_extruder_standby_temp; //!< The temperature to which to set the previous extruder. Not used if the previous extruder plan was the same extruder.
TimeMaterialEstimates estimates; //!< Accumulated time and material estimates for all planned paths within this extruder plan.
+ double slowest_path_speed;
public:
size_t extruder_nr; //!< The extruder used for this paths in the current plan.
@@ -129,22 +130,6 @@ public:
void processFanSpeedAndMinimalLayerTime(bool force_minimal_layer_time, Point starting_position);
/*!
- * Set the extrude speed factor. This is used for printing slower than normal.
- *
- * Leaves the extrusion speed as is for values of 1.0
- *
- * \param speedFactor The factor by which to alter the extrusion move speed
- */
- void setExtrudeSpeedFactor(const Ratio speed_factor);
-
- /*!
- * Get the extrude speed factor. This is used for printing slower than normal.
- *
- * \return The factor by which to alter the extrusion move speed
- */
- double getExtrudeSpeedFactor();
-
- /*!
* Get the fan speed computed for this extruder plan
*
* \warning assumes ExtruderPlan::processFanSpeedAndMinimalLayerTime has already been called
@@ -175,10 +160,7 @@ protected:
const RetractionConfig& retraction_config; //!< The retraction settings for the extruder of this plan
- Ratio extrudeSpeedFactor; //!< The factor by which to alter the extrusion move speed
-
double extraTime; //!< Extra waiting time at the and of this extruder plan, so that the filament can cool
- double totalPrintTime; //!< The total naive time estimate for this extruder plan
double fan_speed; //!< The fan speed to be used during this extruder plan
diff --git a/include/pathPlanning/TimeMaterialEstimates.h b/include/pathPlanning/TimeMaterialEstimates.h
index a425dcedc..4a0052655 100644
--- a/include/pathPlanning/TimeMaterialEstimates.h
+++ b/include/pathPlanning/TimeMaterialEstimates.h
@@ -17,6 +17,8 @@ class TimeMaterialEstimates
friend class ExtruderPlan; // cause there the naive estimates are calculated
private:
double extrude_time; //!< Time in seconds occupied by extrusion
+ double extrude_time_at_slowest_path_speed; //!< Time in seconds occupied by extrusion assuming paths are printed at slowest path speed, usually the outer wall speed
+ double extrude_time_at_minimum_speed; //!< Time in seconds occupied by extrusion assuming paths are printed at the user specified Minimum Speed
double unretracted_travel_time; //!< Time in seconds occupied by non-retracted travel (non-extrusion)
double retracted_travel_time; //!< Time in seconds occupied by retracted travel (non-extrusion)
double material; //!< Material used (in mm^3)
diff --git a/src/LayerPlan.cpp b/src/LayerPlan.cpp
index ecc67cdb4..5de685cfa 100644
--- a/src/LayerPlan.cpp
+++ b/src/LayerPlan.cpp
@@ -1,7 +1,9 @@
// Copyright (c) 2022 Ultimaker B.V.
// CuraEngine is released under the terms of the AGPLv3 or higher
+#include <algorithm>
#include <cstring>
+#include <numeric>
#include <optional>
#include <spdlog/spdlog.h>
@@ -28,25 +30,27 @@ namespace cura
constexpr int MINIMUM_LINE_LENGTH = 5; // in uM. Generated lines shorter than this may be discarded
constexpr int MINIMUM_SQUARED_LINE_LENGTH = MINIMUM_LINE_LENGTH * MINIMUM_LINE_LENGTH;
-ExtruderPlan::ExtruderPlan(const size_t extruder,
- const LayerIndex layer_nr,
- const bool is_initial_layer,
- const bool is_raft_layer,
- const coord_t layer_thickness,
- const FanSpeedLayerTimeSettings& fan_speed_layer_time_settings,
- const RetractionConfig& retraction_config)
- : heated_pre_travel_time(0)
- , required_start_temperature(-1)
- , extruder_nr(extruder)
- , layer_nr(layer_nr)
- , is_initial_layer(is_initial_layer)
- , is_raft_layer(is_raft_layer)
- , layer_thickness(layer_thickness)
- , fan_speed_layer_time_settings(fan_speed_layer_time_settings)
- , retraction_config(retraction_config)
- , extrudeSpeedFactor(1.0)
- , extraTime(0.0)
- , totalPrintTime(0)
+ExtruderPlan::ExtruderPlan
+(
+ const size_t extruder,
+ const LayerIndex layer_nr,
+ const bool is_initial_layer,
+ const bool is_raft_layer,
+ const coord_t layer_thickness,
+ const FanSpeedLayerTimeSettings& fan_speed_layer_time_settings,
+ const RetractionConfig& retraction_config
+) :
+ heated_pre_travel_time(0),
+ required_start_temperature(-1),
+ extruder_nr(extruder),
+ layer_nr(layer_nr),
+ is_initial_layer(is_initial_layer),
+ is_raft_layer(is_raft_layer),
+ layer_thickness(layer_thickness),
+ fan_speed_layer_time_settings(fan_speed_layer_time_settings),
+ retraction_config(retraction_config),
+ extraTime(0.0),
+ slowest_path_speed(0.0)
{
}
@@ -70,16 +74,6 @@ void ExtruderPlan::handleAllRemainingInserts(GCodeExport& gcode)
}
}
-void ExtruderPlan::setExtrudeSpeedFactor(const Ratio speed_factor)
-{
- extrudeSpeedFactor = speed_factor;
-}
-
-double ExtruderPlan::getExtrudeSpeedFactor()
-{
- return extrudeSpeedFactor;
-}
-
void ExtruderPlan::setFanSpeed(double _fan_speed)
{
fan_speed = _fan_speed;
@@ -1466,61 +1460,105 @@ void LayerPlan::spiralizeWallSlice(const GCodePathConfig& config, ConstPolygonRe
void ExtruderPlan::forceMinimalLayerTime(double minTime, double minimalSpeed, double travelTime, double extrudeTime)
{
- double totalTime = travelTime + extrudeTime;
- if (totalTime < minTime && extrudeTime > 0.0)
+ const double totalTime = travelTime + extrudeTime;
+ constexpr double epsilon = 0.01;
+
+ double total_extrude_time_at_minimum_speed = 0.0;
+ double total_extrude_time_at_slowest_speed = 0.0;
+ for (GCodePath& path : paths)
{
- double minExtrudeTime = minTime - travelTime;
- if (minExtrudeTime < 1)
- minExtrudeTime = 1;
- double factor = extrudeTime / minExtrudeTime;
- for (GCodePath& path : paths)
+ total_extrude_time_at_minimum_speed += path.estimates.extrude_time_at_minimum_speed;
+ total_extrude_time_at_slowest_speed += path.estimates.extrude_time_at_slowest_path_speed;
+ }
+
+ if (totalTime < minTime - epsilon && extrudeTime > 0.0)
+ {
+ const double minExtrudeTime = minTime - travelTime;
+
+ double factor = 0.0;
+ double target_speed = 0.0;
+ std::function<double(const GCodePath&)> slow_down_func
{
- if (path.isTravelPath())
- continue;
- double speed = path.config->getSpeed() * path.speed_factor * factor;
- if (speed < minimalSpeed)
- factor = minimalSpeed / (path.config->getSpeed() * path.speed_factor);
- }
+ [&target_speed](const GCodePath& path) { return target_speed / (path.config->getSpeed() * path.speed_factor); }
+ };
- // Only slow down for the minimal time if that will be slower.
- assert(getExtrudeSpeedFactor() == 1.0); // The extrude speed factor is assumed not to be changed yet
- if (factor < 1.0)
+ if (minExtrudeTime >= total_extrude_time_at_minimum_speed)
{
- setExtrudeSpeedFactor(factor);
+ // Even at cool min speed extrusion is not taken enough time. So speed is set to cool min speed.
+ target_speed = minimalSpeed;
+
+ // Update stored naive time estimates
+ estimates.extrude_time = total_extrude_time_at_minimum_speed;
+ if (minTime - total_extrude_time_at_minimum_speed - travelTime > epsilon)
+ {
+ extraTime = minTime - total_extrude_time_at_minimum_speed - travelTime;
+ }
}
- else
+ else if (minExtrudeTime >= total_extrude_time_at_slowest_speed && std::abs(total_extrude_time_at_minimum_speed - total_extrude_time_at_slowest_speed) >= epsilon)
{
- factor = 1.0;
- }
-
- double inv_factor = 1.0 / factor; // cause multiplication is faster than division
+ // Slowing down to the slowest path speed is not sufficient, need to slow down further to the minimum speed.
+ // Linear interpolate between total_extrude_time_at_slowest_speed and total_extrude_time_at_minimum_speed
+ const double factor = (total_extrude_time_at_minimum_speed - minExtrudeTime) / (total_extrude_time_at_minimum_speed - total_extrude_time_at_slowest_speed);
+ target_speed = minimalSpeed * (1.0-factor) + slowest_path_speed * factor;
- // Adjust stored naive time estimates
- estimates.extrude_time *= inv_factor;
- for (GCodePath& path : paths)
+ // Update stored naive time estimates
+ estimates.extrude_time = minExtrudeTime;
+ }
+ else
{
- path.estimates.extrude_time *= inv_factor;
+ // Slowing down to the slowest_speed is sufficient to respect the minimum layer time.
+ // Linear interpolate between extrudeTime and total_extrude_time_at_slowest_speed
+ factor = (total_extrude_time_at_slowest_speed - minExtrudeTime) / (total_extrude_time_at_slowest_speed - extrudeTime);
+ slow_down_func =
+ [&slowest_path_speed = slowest_path_speed, &factor](const GCodePath& path)
+ {
+ const double target_speed = slowest_path_speed * (1.0 - factor) + (path.config->getSpeed() * path.speed_factor) * factor;
+ return target_speed / (path.config->getSpeed() * path.speed_factor);
+ };
+
+ // Update stored naive time estimates
+ estimates.extrude_time = minExtrudeTime;
}
- if (minTime - (extrudeTime * inv_factor) - travelTime > 0.1)
+ for (GCodePath& path : paths)
{
- extraTime = minTime - (extrudeTime * inv_factor) - travelTime;
+ if (path.isTravelPath())
+ {
+ continue;
+ }
+ path.speed_factor = slow_down_func(path);
+ path.estimates.extrude_time /= path.speed_factor;
}
- totalPrintTime = (extrudeTime * inv_factor) + travelTime;
}
}
TimeMaterialEstimates ExtruderPlan::computeNaiveTimeEstimates(Point starting_position)
{
- TimeMaterialEstimates ret;
Point p0 = starting_position;
+ const double min_path_speed = fan_speed_layer_time_settings.cool_min_speed;
+ slowest_path_speed =
+ std::accumulate
+ (
+ paths.begin(),
+ paths.end(),
+ std::numeric_limits<double>::max(),
+ [](double value, const GCodePath& path)
+ {
+ return path.isTravelPath() ? value : std::min(value, path.config->getSpeed().value * path.speed_factor);
+ }
+ );
+
bool was_retracted = false; // wrong assumption; won't matter that much. (TODO)
for (GCodePath& path : paths)
{
bool is_extrusion_path = false;
double* path_time_estimate;
double& material_estimate = path.estimates.material;
+
+ path.estimates.extrude_time_at_minimum_speed = 0.0;
+ path.estimates.extrude_time_at_slowest_path_speed = 0.0;
+
if (! path.isTravelPath())
{
is_extrusion_path = true;
@@ -1556,6 +1594,11 @@ TimeMaterialEstimates ExtruderPlan::computeNaiveTimeEstimates(Point starting_pos
double length = vSizeMM(p0 - p1);
if (is_extrusion_path)
{
+ if (length > 0)
+ {
+ path.estimates.extrude_time_at_minimum_speed += length / min_path_speed;
+ path.estimates.extrude_time_at_slowest_path_speed += length / slowest_path_speed;
+ }
material_estimate += length * INT2MM(layer_thickness) * INT2MM(path.config->getLineWidth());
}
double thisTime = length / (path.config->getSpeed() * path.speed_factor);
@@ -1570,7 +1613,6 @@ TimeMaterialEstimates ExtruderPlan::computeNaiveTimeEstimates(Point starting_pos
void ExtruderPlan::processFanSpeedAndMinimalLayerTime(bool force_minimal_layer_time, Point starting_position)
{
TimeMaterialEstimates estimates = computeNaiveTimeEstimates(starting_position);
- totalPrintTime = estimates.getTotalTime();
if (force_minimal_layer_time)
{
forceMinimalLayerTime(fan_speed_layer_time_settings.cool_min_layer_time, fan_speed_layer_time_settings.cool_min_speed, estimates.getTravelTime(), estimates.getExtrudeTime());
@@ -1865,11 +1907,6 @@ void LayerPlan::writeGCode(GCodeExport& gcode)
// for some movements such as prime tower purge, the speed may get changed by this factor
speed *= path.speed_factor;
- // Apply the extrusion speed factor if it's an extrusion move.
- if (! path.config->isTravelPath())
- {
- speed *= extruder_plan.getExtrudeSpeedFactor();
- }
// This seems to be the best location to place this, but still not ideal.
if (path.mesh_id != current_mesh)
{
@@ -2052,7 +2089,7 @@ bool LayerPlan::writePathWithCoasting(GCodeExport& gcode, const size_t extruder_
coord_t coasting_min_dist_considered = MM2INT(0.1); // hardcoded setting for when to not perform coasting
- const double extrude_speed = path.config->getSpeed() * extruder_plan.getExtrudeSpeedFactor() * path.speed_factor * path.speed_back_pressure_factor;
+ const double extrude_speed = path.config->getSpeed() * path.speed_factor * path.speed_back_pressure_factor;
const coord_t coasting_dist = MM2INT(MM2_2INT(coasting_volume) / layer_thickness) / path.config->getLineWidth(); // closing brackets of MM2INT at weird places for precision issues
const double coasting_min_volume = extruder.settings.get<double>("coasting_min_volume");
@@ -2140,7 +2177,7 @@ bool LayerPlan::writePathWithCoasting(GCodeExport& gcode, const size_t extruder_
for (size_t point_idx = point_idx_before_start + 1; point_idx < path.points.size(); point_idx++)
{
const Ratio coasting_speed_modifier = extruder.settings.get<Ratio>("coasting_speed");
- const Velocity speed = Velocity(coasting_speed_modifier * path.config->getSpeed() * extruder_plan.getExtrudeSpeedFactor());
+ const Velocity speed = Velocity(coasting_speed_modifier * path.config->getSpeed());
gcode.writeTravel(path.points[point_idx], speed);
}
return true;