diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-11-12 21:12:06 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-11-12 21:12:06 +0300 |
commit | 18ccfdacdd652db3ad1a91a156b43b3e18d62e33 (patch) | |
tree | 34be93cc2cd51bfdc3dd990d63f3547a78973348 /src | |
parent | 8df2bfbcfa44cb1b5e4e66233f8389fcf99b8a6b (diff) |
Fixes and improvements to new heater model and tuning3.2beta3.2
Heater model defaults to enabled when set up with default parameters
M303 H parameter is optional (but checked) if T parameter is given
Diffstat (limited to 'src')
-rw-r--r-- | src/Heating/FOPDT.cpp | 3 | ||||
-rw-r--r-- | src/Heating/Heat.cpp | 89 | ||||
-rw-r--r-- | src/Heating/Heater.cpp | 18 | ||||
-rw-r--r-- | src/Heating/Heater.h | 2 | ||||
-rw-r--r-- | src/Heating/LocalHeater.cpp | 23 | ||||
-rw-r--r-- | src/Heating/LocalHeater.h | 2 | ||||
-rw-r--r-- | src/Heating/RemoteHeater.cpp | 2 | ||||
-rw-r--r-- | src/Heating/RemoteHeater.h | 2 | ||||
-rw-r--r-- | src/Tools/Tool.h | 2 |
9 files changed, 82 insertions, 61 deletions
diff --git a/src/Heating/FOPDT.cpp b/src/Heating/FOPDT.cpp index 4c5e81fd..be274f17 100644 --- a/src/Heating/FOPDT.cpp +++ b/src/Heating/FOPDT.cpp @@ -60,8 +60,9 @@ FopDt::FopDt() noexcept : heatingRate(DefaultHotEndHeaterHeatingRate), coolingRateFanOff(DefaultHotEndHeaterCoolingRate), coolingRateChangeFanOn(0.0), deadTime(DefaultHotEndHeaterDeadTime), maxPwm(1.0), standardVoltage(0.0), - enabled(false), usePid(true), inverted(false), pidParametersOverridden(false) + enabled(true), usePid(true), inverted(false), pidParametersOverridden(false) { + CalcPidConstants(); } // Check the model parameters are sensible, if they are then save them and return true. diff --git a/src/Heating/Heat.cpp b/src/Heating/Heat.cpp index 2a3d8e94..ce24563c 100644 --- a/src/Heating/Heat.cpp +++ b/src/Heating/Heat.cpp @@ -25,6 +25,7 @@ Licence: GPL #include "RepRap.h" #include "Sensors/TemperatureSensor.h" #include "GCodes/GCodeBuffer/GCodeBuffer.h" +#include <Tools/Tool.h> #include <TaskPriorities.h> #include <General/Portability.h> @@ -822,49 +823,81 @@ GCodeResult Heat::ConfigureHeaterMonitoring(size_t heater, GCodeBuffer& gb, cons // Process M303 GCodeResult Heat::TuneHeater(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) { - if (gb.Seen('H')) + // To tune a heater, a heater number and/or a tool number musty be given + FansBitmap fans; + int heaterNumber; + const bool seenHeater = gb.Seen('H'); + if (seenHeater) { - const unsigned int heater = gb.GetUIValue(); - if (heaterBeingTuned != -1) + heaterNumber = gb.GetIValue(); + } + const bool seenTool = gb.Seen('T'); + if (seenTool) + { + const int toolNumber = gb.GetIValue(); + const auto tool = reprap.GetTool(toolNumber); + if (tool.IsNull()) { - // Trying to start a new auto tune, but we are already tuning a heater - reply.printf("Error: cannot start auto tuning heater %u because heater %d is being tuned", heater, heaterBeingTuned); + reply.printf("tool %d not found", toolNumber); + return GCodeResult::error; } - else + if (seenHeater) { - const auto h = FindHeater(heater); - if (h.IsNotNull()) + if (!tool->UsesHeater(heaterNumber)) { - const GCodeResult rslt = h->StartAutoTune(gb, reply); - if (rslt <= GCodeResult::warning) - { - heaterBeingTuned = (int8_t)heater; - } - return rslt; - } - else - { - reply.printf("Heater %u not found", heater); + reply.printf("tool %d does not use heater %d", toolNumber, heaterNumber); + return GCodeResult::error; } } - return GCodeResult::error; + else if (tool->HeaterCount() == 0) + { + reply.printf("tool %d has no heaters", toolNumber); + return GCodeResult::error; + } + else + { + heaterNumber = tool->Heater(0); + } + fans = tool->GetFanMapping(); } - else + + if (seenHeater || seenTool) { - // Report the auto tune status - const int whichPid = (heaterBeingTuned == -1) ? lastHeaterTuned : heaterBeingTuned; - const auto h = FindHeater(whichPid); + if (heaterBeingTuned != -1) + { + // Trying to start a new auto tune, but we are already tuning a heater + reply.printf("Error: cannot start a new auto tune because heater %d is being tuned", heaterBeingTuned); + return GCodeResult::error; + } - if (h.IsNotNull()) + const auto h = FindHeater(heaterNumber); + if (h.IsNull()) { - h->GetAutoTuneStatus(reply); + reply.printf("Heater %u not found", heaterNumber); + return GCodeResult::error; } - else + + const GCodeResult rslt = h->StartAutoTune(gb, reply, fans); + if (rslt <= GCodeResult::warning) { - reply.copy("No heater has been tuned since startup"); + heaterBeingTuned = (int8_t)heaterNumber; } - return GCodeResult::ok; + return rslt; + } + + // If we get here then neither T nor H was given, so report the auto tune status + const int whichPid = (heaterBeingTuned == -1) ? lastHeaterTuned : heaterBeingTuned; + const auto h = FindHeater(whichPid); + + if (h.IsNotNull()) + { + h->GetAutoTuneStatus(reply); } + else + { + reply.copy("No heater has been tuned since startup"); + } + return GCodeResult::ok; } // Process M308 diff --git a/src/Heating/Heater.cpp b/src/Heating/Heater.cpp index 9a862383..8a3b50b0 100644 --- a/src/Heating/Heater.cpp +++ b/src/Heating/Heater.cpp @@ -152,27 +152,29 @@ GCodeResult Heater::SetOrReportModel(unsigned int heater, GCodeBuffer& gb, const } else if (!model.IsEnabled()) { - reply.printf("Heater %u is disabled", heater); + reply.printf("Heater %u is disabled due to bad model", heater); } else { const char* const mode = (!model.UsePid()) ? "bang-bang" : (model.ArePidParametersOverridden()) ? "custom PID" : "PID"; - reply.printf("Heater %u model: heating rate %.3f, cooling time constant %.1f (fan off) %.1f (fan on), dead time %.2f, max PWM %.2f, calibration voltage %.1f, mode %s", heater, - (double)model.GetHeatingRate(), (double)model.GetTimeConstantFanOff(), (double)model.GetTimeConstantFanOn(), - (double)model.GetDeadTime(), (double)model.GetMaxPwm(), (double)model.GetVoltage(), mode); + reply.printf("Heater %u model: heating rate %.3f, cooling time constant %.1f", heater, (double)model.GetHeatingRate(), (double)model.GetTimeConstantFanOff()); + if (model.GetCoolingRateChangeFanOn() > 0.0) + { + reply.catf("/%.1f", (double)model.GetTimeConstantFanOn()); + } + reply.catf(", dead time %.2f, max PWM %.2f, calibration voltage %.1f, mode %s", (double)model.GetDeadTime(), (double)model.GetMaxPwm(), (double)model.GetVoltage(), mode); if (model.IsInverted()) { - reply.cat(", inverted temperature control"); + reply.cat(", inverted control"); } if (model.UsePid()) { - // When reporting the PID parameters, we scale them by 255 for compatibility with older firmware and other firmware M301PidParameters params = model.GetM301PidParameters(false); - reply.catf("\nComputed PID parameters for setpoint change: P%.1f, I%.3f, D%.1f", (double)params.kP, (double)params.kI, (double)params.kD); + reply.catf("\nComputed PID parameters: setpoint change: P%.1f, I%.3f, D%.1f", (double)params.kP, (double)params.kI, (double)params.kD); params = model.GetM301PidParameters(true); - reply.catf("\nComputed PID parameters for load change: P%.1f, I%.3f, D%.1f", (double)params.kP, (double)params.kI, (double)params.kD); + reply.catf(", load change: P%.1f, I%.3f, D%.1f", (double)params.kP, (double)params.kI, (double)params.kD); } } return GCodeResult::ok; diff --git a/src/Heating/Heater.h b/src/Heating/Heater.h index 8c8231e0..6c34ba9f 100644 --- a/src/Heating/Heater.h +++ b/src/Heating/Heater.h @@ -42,7 +42,7 @@ public: virtual GCodeResult ResetFault(const StringRef& reply) noexcept = 0; // Reset a fault condition - only call this if you know what you are doing virtual void SwitchOff() noexcept = 0; virtual void Spin() noexcept = 0; - virtual GCodeResult StartAutoTune(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) = 0; // Start an auto tune cycle for this heater + virtual GCodeResult StartAutoTune(GCodeBuffer& gb, const StringRef& reply, FansBitmap fans) THROWS(GCodeException) = 0; // Start an auto tune cycle for this heater virtual void GetAutoTuneStatus(const StringRef& reply) const noexcept = 0; // Get the auto tune status or last result virtual void Suspend(bool sus) noexcept = 0; // Suspend the heater to conserve power or while doing Z probing virtual float GetAccumulator() const noexcept = 0; // Get the inertial term accumulator diff --git a/src/Heating/LocalHeater.cpp b/src/Heating/LocalHeater.cpp index 5c2daf76..5cac4954 100644 --- a/src/Heating/LocalHeater.cpp +++ b/src/Heating/LocalHeater.cpp @@ -481,7 +481,7 @@ float LocalHeater::GetExpectedHeatingRate() const noexcept } // Auto tune this heater. The caller has already checked that on other heater is being tuned. -GCodeResult LocalHeater::StartAutoTune(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) +GCodeResult LocalHeater::StartAutoTune(GCodeBuffer& gb, const StringRef& reply, FansBitmap fans) THROWS(GCodeException) { // Get the target temperature (required) gb.MustSee('S'); @@ -495,24 +495,6 @@ GCodeResult LocalHeater::StartAutoTune(GCodeBuffer& gb, const StringRef& reply) return GCodeResult::error; } - // Get the optional tool number - int toolNumber = (gb.Seen('T')) ? gb.GetIValue() : -1; - if (toolNumber >= 0) - { - auto tool = reprap.GetTool(toolNumber); - if (tool.IsNull()) - { - reply.printf("Tool %d not found", toolNumber); - return GCodeResult::error; - } - tuningFans = tool->GetFanMapping(); - reprap.GetFansManager().SetFansValue(tuningFans, 0.0); - } - else - { - tuningFans.Clear(); - } - if (!GetModel().IsEnabled()) { reply.printf("heater %u cannot be auto tuned while it is disabled", GetHeaterNumber()); @@ -549,6 +531,9 @@ GCodeResult LocalHeater::StartAutoTune(GCodeBuffer& gb, const StringRef& reply) reply.printf("Auto tuning heater %u using target temperature %.1f" DEGREE_SYMBOL "C and PWM %.2f - do not leave printer unattended", GetHeaterNumber(), (double)targetTemp, (double)maxPwm); + tuningFans = fans; + reprap.GetFansManager().SetFansValue(tuningFans, 0.0); + tuningPwm = maxPwm; tuningTargetTemp = targetTemp; tuningStartTemp.Clear(); diff --git a/src/Heating/LocalHeater.h b/src/Heating/LocalHeater.h index b1ccdfcb..e21148c7 100644 --- a/src/Heating/LocalHeater.h +++ b/src/Heating/LocalHeater.h @@ -47,7 +47,7 @@ public: float GetTemperature() const noexcept override; // Get the current temperature float GetAveragePWM() const noexcept override; // Return the running average PWM to the heater. Answer is a fraction in [0, 1]. float GetAccumulator() const noexcept override; // Return the integral accumulator - GCodeResult StartAutoTune(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) override; // Start an auto tune cycle for this heater + GCodeResult StartAutoTune(GCodeBuffer& gb, const StringRef& reply, FansBitmap fans) THROWS(GCodeException) override; // Start an auto tune cycle for this heater void GetAutoTuneStatus(const StringRef& reply) const noexcept override; // Get the auto tune status or last result void Suspend(bool sus) noexcept override; // Suspend the heater to conserve power or while doing Z probing void PrintCoolingFanPwmChanged(float pwmChange) noexcept override; diff --git a/src/Heating/RemoteHeater.cpp b/src/Heating/RemoteHeater.cpp index 94e6f377..8bf9e9a0 100644 --- a/src/Heating/RemoteHeater.cpp +++ b/src/Heating/RemoteHeater.cpp @@ -128,7 +128,7 @@ float RemoteHeater::GetAccumulator() const noexcept return 0.0; // not supported } -GCodeResult RemoteHeater::StartAutoTune(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) +GCodeResult RemoteHeater::StartAutoTune(GCodeBuffer& gb, const StringRef& reply, FansBitmap fans) THROWS(GCodeException) { reply.copy("remote heater auto tune not implemented"); return GCodeResult::error; diff --git a/src/Heating/RemoteHeater.h b/src/Heating/RemoteHeater.h index 558b49b4..e82cb695 100644 --- a/src/Heating/RemoteHeater.h +++ b/src/Heating/RemoteHeater.h @@ -28,7 +28,7 @@ public: float GetTemperature() const noexcept override; // Get the current temperature float GetAveragePWM() const noexcept override; // Return the running average PWM to the heater. Answer is a fraction in [0, 1]. float GetAccumulator() const noexcept override; // Return the integral accumulator - GCodeResult StartAutoTune(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) override; // Start an auto tune cycle for this heater + GCodeResult StartAutoTune(GCodeBuffer& gb, const StringRef& reply, FansBitmap fans) THROWS(GCodeException) override; // Start an auto tune cycle for this heater void GetAutoTuneStatus(const StringRef& reply) const noexcept override; // Get the auto tune status or last result void Suspend(bool sus) noexcept override; // Suspend the heater to conserve power or while doing Z probing void PrintCoolingFanPwmChanged(float pwmChange) noexcept override; diff --git a/src/Tools/Tool.h b/src/Tools/Tool.h index b7b7699f..98c87039 100644 --- a/src/Tools/Tool.h +++ b/src/Tools/Tool.h @@ -101,6 +101,7 @@ public: void IterateExtruders(std::function<void(unsigned int)> f) const noexcept; void IterateHeaters(std::function<void(int)> f) const noexcept; + bool UsesHeater(int8_t heater) const noexcept; void SetFansPwm(float f) const noexcept; @@ -127,7 +128,6 @@ private: void SetTemperatureFault(int8_t dudHeater) noexcept; void ResetTemperatureFault(int8_t wasDudHeater) noexcept; bool AllHeatersAtHighTemperature(bool forExtrusion) const noexcept; - bool UsesHeater(int8_t heater) const noexcept; static void ToolUpdated() noexcept { reprap.ToolsUpdated(); } // call this whenever we change a variable that is reported in the OM as non-live |