Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CURA-6410 buggy fan speed interpolation #2111

Merged
merged 8 commits into from
Jul 5, 2024
29 changes: 7 additions & 22 deletions src/LayerPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1881,7 +1881,8 @@ TimeMaterialEstimates ExtruderPlan::computeNaiveTimeEstimates(Point2LL starting_

void ExtruderPlan::processFanSpeedForMinimalLayerTime(Duration minTime, double time_other_extr_plans)
{
/*
/* interpolate fan speed

min layer time
:
: min layer time fan speed min
Expand All @@ -1892,28 +1893,12 @@ void ExtruderPlan::processFanSpeedForMinimalLayerTime(Duration minTime, double t
speed min..|... \:___________
|________________
layer time >


*/
// interpolate fan speed (for cool_fan_full_layer and for cool_min_layer_time_fan_speed_max)
double totalLayerTime = estimates_.getTotalTime() + time_other_extr_plans;
if (totalLayerTime < minTime)
{
fan_speed = fan_speed_layer_time_settings_.cool_fan_speed_max;
}
else if (minTime >= fan_speed_layer_time_settings_.cool_min_layer_time_fan_speed_max)
{
// ignore gradual increase of fan speed
return;
}
else if (totalLayerTime < fan_speed_layer_time_settings_.cool_min_layer_time_fan_speed_max)
{
// when forceMinimalLayerTime didn't change the extrusionSpeedFactor, we adjust the fan speed
double fan_speed_diff = fan_speed_layer_time_settings_.cool_fan_speed_max - fan_speed;
double layer_time_diff = fan_speed_layer_time_settings_.cool_min_layer_time_fan_speed_max - minTime;
double fraction_of_slope = (totalLayerTime - minTime) / layer_time_diff;
fan_speed = fan_speed_layer_time_settings_.cool_fan_speed_max - fan_speed_diff * fraction_of_slope;
}

const double total_layer_time = estimates_.getTotalTime() + time_other_extr_plans;
const double layer_time_diff = fan_speed_layer_time_settings_.cool_min_layer_time_fan_speed_max - minTime;
const double fraction_of_slope = std::clamp((total_layer_time - minTime) / layer_time_diff, 0.0, 1.0);
fan_speed = std::lerp(fan_speed_layer_time_settings_.cool_fan_speed_max, fan_speed, fraction_of_slope);
}

void ExtruderPlan::processFanSpeedForFirstLayers()
Expand Down
77 changes: 53 additions & 24 deletions src/gcodeExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1434,44 +1434,73 @@ void GCodeExport::writeFanCommand(double speed, std::optional<size_t> extruder)

void GCodeExport::writeSpecificFanCommand(double speed, size_t fan_number)
{
auto iterator = current_fans_speeds_.find(fan_number);

if (iterator != current_fans_speeds_.end() && std::abs(iterator->second - speed) < 0.1)
{
return;
}
const auto iterator = current_fans_speeds_.find(fan_number);
const std::optional<double> current_fan_speed = (iterator != current_fans_speeds_.end()) ? std::optional<double>(iterator->second) : std::nullopt;

if (flavor_ == EGCodeFlavor::MAKERBOT)
{
if (speed >= 50)
// Makerbot cannot PWM the fan speed, only turn it on or off

bool write_value = true;
const bool new_on = speed >= 50;
if (current_fan_speed.has_value())
{
*output_stream_ << "M126 T0" << new_line_; // Makerbot cannot PWM the fan speed...
const bool old_on = current_fan_speed.value() >= 50;
write_value = new_on != old_on;
}
else

if (write_value)
{
*output_stream_ << "M127 T0" << new_line_;
if (new_on)
{
*output_stream_ << "M126 T0" << new_line_;
}
else
{
*output_stream_ << "M127 T0" << new_line_;
}
}
}
else if (speed > 0)
else
{
const bool should_scale_zero_to_one = Application::getInstance().current_slice_->scene.settings.get<bool>("machine_scale_fan_speed_zero_to_one");
*output_stream_ << "M106 S"
<< PrecisionedDouble{ (should_scale_zero_to_one ? static_cast<uint8_t>(2) : static_cast<uint8_t>(1)),
(should_scale_zero_to_one ? speed : speed * 255) / 100 };
if (fan_number)
bool write_value = true;
std::ostringstream new_value;
new_value << PrecisionedDouble{ (should_scale_zero_to_one ? static_cast<uint8_t>(2) : static_cast<uint8_t>(1)), (should_scale_zero_to_one ? speed : speed * 255) / 100 };
const std::string new_value_str = new_value.str();
if (current_fan_speed.has_value())
{
*output_stream_ << " P" << fan_number;
std::ostringstream old_value;
old_value << PrecisionedDouble{ (should_scale_zero_to_one ? static_cast<uint8_t>(2) : static_cast<uint8_t>(1)),
(should_scale_zero_to_one ? current_fan_speed.value() : current_fan_speed.value() * 255) / 100 };
wawanbreton marked this conversation as resolved.
Show resolved Hide resolved

write_value = new_value_str != old_value.str();
}
*output_stream_ << new_line_;
}
else
{
*output_stream_ << "M107";
if (fan_number)

if (write_value)
{
*output_stream_ << " P" << fan_number;
// Check if the value to be written is only made with zeroes, in which case it is actually a turn off
std::string new_value_str_reduced = new_value_str;
std::erase(new_value_str_reduced, '0');
std::erase(new_value_str_reduced, '.');
wawanbreton marked this conversation as resolved.
Show resolved Hide resolved
const bool turn_off = new_value_str_reduced.empty();

if (turn_off)
{
*output_stream_ << "M107";
}
else
{
*output_stream_ << "M106 S" << new_value_str;
}

if (fan_number)
{
*output_stream_ << " P" << fan_number;
}

*output_stream_ << new_line_;
}
*output_stream_ << new_line_;
}

current_fans_speeds_[fan_number] = speed;
Expand Down
Loading