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

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/GCodes/GCodes.cpp')
-rw-r--r--src/GCodes/GCodes.cpp366
1 files changed, 207 insertions, 159 deletions
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 3fb29110..81f59e43 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -84,7 +84,6 @@ void GCodes::Init()
eofStringCounter = 0;
eofStringLength = strlen(eofString);
offSetSet = false;
- zProbesSet = false;
active = true;
longWait = platform->Time();
dwellTime = longWait;
@@ -158,8 +157,6 @@ void GCodes::Reset()
{
resourceOwners[i] = nullptr;
}
-
- lastProbedTime = millis();
}
float GCodes::FractionOfFilePrinted() const
@@ -175,8 +172,8 @@ bool GCodes::RunConfigFile(const char* fileName)
return DoFileMacro(*daemonGCode, fileName, false);
}
-// Are we still running the config file?
-bool GCodes::IsRunningConfigFile() const
+// Return true if the daemon is busy running config.g or a trigger file
+bool GCodes::IsDaemonBusy() const
{
return daemonGCode->MachineState().fileState.IsLive();
}
@@ -229,7 +226,7 @@ void GCodes::Spin()
if ((toBeHomed & (1u << axis)) != 0 && (axis != Z_AXIS || toBeHomed == (1u << Z_AXIS)))
{
toBeHomed &= ~(1u << axis);
- DoFileMacro(gb, HomingFileNames[axis]);
+ DoFileMacro(gb, HomingFileNames[axis], true);
break;
}
}
@@ -250,7 +247,6 @@ void GCodes::Spin()
probeCount++;
if (probeCount >= numProbePoints)
{
- zProbesSet = true;
reprap.GetMove()->FinishedBedProbing(0, reply);
gb.SetState(GCodeState::normal);
}
@@ -304,7 +300,7 @@ void GCodes::Spin()
if (LockMovementAndWaitForStandstill(gb))
{
gb.SetState(GCodeState::pausing2);
- DoFileMacro(gb, PAUSE_G);
+ DoFileMacro(gb, PAUSE_G, true);
}
break;
@@ -445,13 +441,13 @@ void GCodes::Spin()
moveBuffer.endStopsToCheck = 0;
moveBuffer.usePressureAdvance = false;
moveBuffer.filePos = noFilePosition;
- moveBuffer.coords[X_AXIS] = x - platform->GetZProbeParameters().xOffset;
- moveBuffer.coords[Y_AXIS] = y - platform->GetZProbeParameters().yOffset;
- moveBuffer.coords[Z_AXIS] = platform->GetZProbeDiveHeight();
+ moveBuffer.coords[X_AXIS] = x - platform->GetCurrentZProbeParameters().xOffset;
+ moveBuffer.coords[Y_AXIS] = y - platform->GetCurrentZProbeParameters().yOffset;
+ moveBuffer.coords[Z_AXIS] = platform->GetZProbeStartingHeight();
moveBuffer.feedRate = platform->GetZProbeTravelSpeed();
moveBuffer.xAxes = 0;
segmentsLeft = 1;
- gb.SetState(GCodeState::gridProbing2);
+ gb.AdvanceState();
}
else
{
@@ -461,9 +457,15 @@ void GCodes::Spin()
break;
case GCodeState::gridProbing2: // ready to probe the current grid probe point
- if (LockMovementAndWaitForStandstill(gb)
- && millis() - lastProbedTime >= (uint32_t)(reprap.GetPlatform()->GetZProbeParameters().recoveryTime * SecondsToMillis)
- )
+ if (LockMovementAndWaitForStandstill(gb))
+ {
+ lastProbedTime = millis();
+ gb.AdvanceState();
+ }
+ break;
+
+ case GCodeState::gridProbing2a: // ready to probe the current grid probe point
+ if (millis() - lastProbedTime >= (uint32_t)(reprap.GetPlatform()->GetCurrentZProbeParameters().recoveryTime * SecondsToMillis))
{
// Probe the bed at the current XY coordinates
// Check for probe already triggered at start
@@ -481,7 +483,7 @@ void GCodes::Spin()
moveBuffer.usePressureAdvance = false;
moveBuffer.filePos = noFilePosition;
moveBuffer.coords[Z_AXIS] = -platform->GetZProbeDiveHeight();
- moveBuffer.feedRate = platform->GetZProbeParameters().probeSpeed;
+ moveBuffer.feedRate = platform->GetCurrentZProbeParameters().probeSpeed;
moveBuffer.xAxes = 0;
segmentsLeft = 1;
gb.SetState(GCodeState::gridProbing3);
@@ -499,19 +501,15 @@ void GCodes::Spin()
break;
}
- lastProbedTime = millis();
const float heightError = moveBuffer.coords[Z_AXIS] - platform->ZProbeStopHeight();
reprap.GetMove()->AccessBedProbeGrid().SetGridHeight(gridXindex, gridYindex, heightError);
- ++numPointsProbed;
- heightSum += (double)heightError;
- heightSquaredSum += (double)heightError * (double)heightError;
// Move back up to the dive height
moveBuffer.moveType = 0;
moveBuffer.endStopsToCheck = 0;
moveBuffer.usePressureAdvance = false;
moveBuffer.filePos = noFilePosition;
- moveBuffer.coords[Z_AXIS] = platform->GetZProbeDiveHeight();
+ moveBuffer.coords[Z_AXIS] = platform->GetZProbeStartingHeight();
moveBuffer.feedRate = platform->GetZProbeTravelSpeed();
moveBuffer.xAxes = 0;
segmentsLeft = 1;
@@ -550,13 +548,13 @@ void GCodes::Spin()
if (gridYindex == grid.NumYpoints())
{
// Finished probing the grid
+ float mean, deviation;
+ const uint32_t numPointsProbed = reprap.GetMove()->AccessBedProbeGrid().GetStatistics(mean, deviation);
if (numPointsProbed >= 4)
{
- error = SaveHeightMapToFile(reply);
- const double mean = heightSum/numPointsProbed;
- const double deviation = sqrt(((heightSquaredSum * numPointsProbed) - (heightSum * heightSum)))/numPointsProbed;
- reply.catf(" - %u points probed, mean error %.2f, deviation %.2f", numPointsProbed, mean, deviation);
- reprap.GetMove()->UseHeightMap(true);
+ reply.printf("%u points probed, mean error %.2f, deviation %.2f\n", numPointsProbed, mean, deviation);
+ error = SaveHeightMap(gb, reply);
+ reprap.GetMove()->AccessBedProbeGrid().UseHeightMap(true);
}
else
{
@@ -783,7 +781,7 @@ void GCodes::CheckTriggers()
DoEmergencyStop();
}
else if (lowestTriggerPending < MaxTriggers // if a trigger is pending
- && !daemonGCode->MachineState().fileState.IsLive()
+ && !IsDaemonBusy()
&& daemonGCode->GetState() == GCodeState::normal // and we are not already executing a trigger or config.g
)
{
@@ -1061,9 +1059,10 @@ unsigned int GCodes::LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType)
{
mappedMoveArg -= currentTool->GetOffset()[mappedAxis]; // adjust requested position to compensate for tool offset
}
- if (reprap.GetMove()->UsingHeightMap())
+ const HeightMap& heightMap = reprap.GetMove()->AccessBedProbeGrid();
+ if (heightMap.UsingHeightMap())
{
- const unsigned int minSegments = reprap.GetMove()->AccessBedProbeGrid().GetMinimumSegments(fabs(mappedMoveArg - moveBuffer.coords[mappedAxis]));
+ const unsigned int minSegments = heightMap.GetMinimumSegments(fabs(mappedMoveArg - moveBuffer.coords[mappedAxis]));
if (minSegments > numSegments)
{
numSegments = minSegments;
@@ -1084,12 +1083,16 @@ unsigned int GCodes::LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType)
moveArg -= currentTool->GetOffset()[axis]; // adjust requested position to compensate for tool offset
}
- if (axis < Z_AXIS && moveType == 0 && reprap.GetMove()->UsingHeightMap())
+ if (axis < Z_AXIS && moveType == 0)
{
- const unsigned int minSegments = reprap.GetMove()->AccessBedProbeGrid().GetMinimumSegments(fabs(moveArg - moveBuffer.coords[axis]));
- if (minSegments > numSegments)
+ const HeightMap& heightMap = reprap.GetMove()->AccessBedProbeGrid();
+ if (heightMap.UsingHeightMap())
{
- numSegments = minSegments;
+ const unsigned int minSegments = reprap.GetMove()->AccessBedProbeGrid().GetMinimumSegments(fabs(moveArg - moveBuffer.coords[axis]));
+ if (minSegments > numSegments)
+ {
+ numSegments = minSegments;
+ }
}
}
moveBuffer.coords[axis] = moveArg;
@@ -1296,7 +1299,7 @@ void GCodes::ClearMove()
// Run a file macro. Prior to calling this, 'state' must be set to the state we want to enter when the macro has been completed.
// Return true if the file was found or it wasn't and we were asked to report that fact.
-bool GCodes::DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissing)
+bool GCodes::DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissing, bool runningM502)
{
FileStore * const f = platform->GetFileStore(platform->GetSysDir(), fileName, false);
if (f == nullptr)
@@ -1316,6 +1319,7 @@ bool GCodes::DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissi
}
gb.MachineState().fileState.Set(f);
gb.MachineState().doingFileMacro = true;
+ gb.MachineState().runningM502 = runningM502;
gb.SetState(GCodeState::normal);
gb.Init();
return true;
@@ -1524,7 +1528,7 @@ bool GCodes::DoHome(GCodeBuffer& gb, StringRef& reply, bool& error)
if (reprap.GetMove()->IsDeltaMode())
{
SetAllAxesNotHomed();
- DoFileMacro(gb, HOME_DELTA_G);
+ DoFileMacro(gb, HOME_DELTA_G, true);
}
else
{
@@ -1542,7 +1546,7 @@ bool GCodes::DoHome(GCodeBuffer& gb, StringRef& reply, bool& error)
{
// Homing everything
SetAllAxesNotHomed();
- DoFileMacro(gb, HOME_ALL_G);
+ DoFileMacro(gb, HOME_ALL_G, true);
}
else if ( platform->MustHomeXYBeforeZ()
&& ((toBeHomed & (1u << Z_AXIS)) != 0)
@@ -1577,7 +1581,7 @@ bool GCodes::DoSingleZProbeAtPoint(GCodeBuffer& gb, int probePointIndex, float h
switch (cannedCycleMoveCount)
{
case 0: // Move Z to the dive height. This only does anything on the first move; on all the others Z is already there
- cannedMoveCoords[Z_AXIS] = platform->GetZProbeDiveHeight() + max<float>(platform->ZProbeStopHeight(), 0.0);
+ cannedMoveCoords[Z_AXIS] = platform->GetZProbeStartingHeight();
cannedMoveType[Z_AXIS] = CannedMoveType::absolute;
cannedFeedRate = platform->GetZProbeTravelSpeed();
if (DoCannedCycleMove(gb, 0))
@@ -1587,19 +1591,20 @@ bool GCodes::DoSingleZProbeAtPoint(GCodeBuffer& gb, int probePointIndex, float h
return false;
case 1: // Move to the correct XY coordinates
- GetProbeCoordinates(probePointIndex, cannedMoveCoords[X_AXIS], cannedMoveCoords[Y_AXIS], cannedMoveCoords[Z_AXIS]);
+ (void)reprap.GetMove()->GetProbeCoordinates(probePointIndex, cannedMoveCoords[X_AXIS], cannedMoveCoords[Y_AXIS], true);
cannedMoveType[X_AXIS] = CannedMoveType::absolute;
cannedMoveType[Y_AXIS] = CannedMoveType::absolute;
// NB - we don't use the Z value
cannedFeedRate = platform->GetZProbeTravelSpeed();
if (DoCannedCycleMove(gb, 0))
{
+ lastProbedTime = millis();
cannedCycleMoveCount++;
}
return false;
case 2: // Probe the bed
- if (millis() - lastProbedTime >= (uint32_t)(platform->GetZProbeParameters().recoveryTime * SecondsToMillis))
+ if (millis() - lastProbedTime >= (uint32_t)(platform->GetCurrentZProbeParameters().recoveryTime * SecondsToMillis))
{
const float height = (GetAxisIsHomed(Z_AXIS))
? 2 * platform->GetZProbeDiveHeight() // Z axis has been homed, so no point in going very far
@@ -1622,7 +1627,6 @@ bool GCodes::DoSingleZProbeAtPoint(GCodeBuffer& gb, int probePointIndex, float h
case 2:
// Successful probing
- lastProbedTime = millis();
if (GetAxisIsHomed(Z_AXIS))
{
lastProbedZ = moveBuffer.coords[Z_AXIS] - (platform->ZProbeStopHeight() + heightAdjust);
@@ -1646,7 +1650,7 @@ bool GCodes::DoSingleZProbeAtPoint(GCodeBuffer& gb, int probePointIndex, float h
return false;
case 3: // Raise the head back up to the dive height
- cannedMoveCoords[Z_AXIS] = platform->GetZProbeDiveHeight() + max<float>(platform->ZProbeStopHeight(), 0.0);
+ cannedMoveCoords[Z_AXIS] = platform->GetZProbeStartingHeight();
cannedMoveType[Z_AXIS] = CannedMoveType::absolute;
cannedFeedRate = platform->GetZProbeTravelSpeed();
if (DoCannedCycleMove(gb, 0))
@@ -1664,7 +1668,7 @@ bool GCodes::DoSingleZProbeAtPoint(GCodeBuffer& gb, int probePointIndex, float h
// This simply moves down till the Z probe/switch is triggered. Call it repeatedly until it returns true.
// Called when we do a G30 with no P parameter.
-bool GCodes::DoSingleZProbe(GCodeBuffer& gb, bool reportOnly, float heightAdjust)
+bool GCodes::DoSingleZProbe(GCodeBuffer& gb, StringRef& reply, bool reportOnly, float heightAdjust)
{
switch (DoZProbe(gb, 1.1 * platform->AxisTotalLength(Z_AXIS)))
{
@@ -1677,7 +1681,13 @@ bool GCodes::DoSingleZProbe(GCodeBuffer& gb, bool reportOnly, float heightAdjust
return true;
case 2: // success
- if (!reportOnly)
+ if (reportOnly)
+ {
+ float m[DRIVES];
+ reprap.GetMove()->GetCurrentMachinePosition(m, false);
+ reply.printf("Stopped at height %.3f mm", m[Z_AXIS]);
+ }
+ else
{
moveBuffer.coords[Z_AXIS] = platform->ZProbeStopHeight() + heightAdjust;
SetPositions(moveBuffer.coords);
@@ -1700,7 +1710,7 @@ int GCodes::DoZProbe(GCodeBuffer& gb, float distance)
{
if (platform->GetZProbeType() == ZProbeTypeDelta)
{
- const ZProbeParameters& params = platform->GetZProbeParameters();
+ const ZProbeParameters& params = platform->GetCurrentZProbeParameters();
return reprap.GetMove()->DoDeltaProbe(params.extraParam, 1.0, params.probeSpeed, distance); //TODO second parameter
}
else
@@ -1723,7 +1733,7 @@ int GCodes::DoZProbe(GCodeBuffer& gb, float distance)
cannedMoveCoords[Z_AXIS] = -distance;
cannedMoveType[Z_AXIS] = CannedMoveType::relative;
- cannedFeedRate = platform->GetZProbeParameters().probeSpeed;
+ cannedFeedRate = platform->GetCurrentZProbeParameters().probeSpeed;
if (DoCannedCycleMove(gb, ZProbeActive))
{
@@ -1756,24 +1766,20 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer& gb, StringRef& reply)
if (!gb.Seen('P'))
{
- bool reportOnly = false;
- if (gb.Seen('S') && gb.GetIValue() < 0)
- {
- reportOnly = true;
- }
- return DoSingleZProbe(gb, reportOnly, heightAdjust);
+ const bool reportOnly = (gb.Seen('S') && gb.GetIValue() < 0);
+ return DoSingleZProbe(gb, reply, reportOnly, heightAdjust);
}
- int probePointIndex = gb.GetIValue();
+ const int probePointIndex = gb.GetIValue();
if (probePointIndex < 0 || (unsigned int)probePointIndex >= MaxProbePoints)
{
reprap.GetPlatform()->Message(GENERIC_MESSAGE, "Z probe point index out of range.\n");
return true;
}
- float x = (gb.Seen(axisLetters[X_AXIS])) ? gb.GetFValue() : moveBuffer.coords[X_AXIS];
- float y = (gb.Seen(axisLetters[Y_AXIS])) ? gb.GetFValue() : moveBuffer.coords[Y_AXIS];
- float z = (gb.Seen(axisLetters[Z_AXIS])) ? gb.GetFValue() : moveBuffer.coords[Z_AXIS];
+ const float x = (gb.Seen(axisLetters[X_AXIS])) ? gb.GetFValue() : moveBuffer.coords[X_AXIS];
+ const float y = (gb.Seen(axisLetters[Y_AXIS])) ? gb.GetFValue() : moveBuffer.coords[Y_AXIS];
+ const float z = (gb.Seen(axisLetters[Z_AXIS])) ? gb.GetFValue() : moveBuffer.coords[Z_AXIS];
reprap.GetMove()->SetXBedProbePoint(probePointIndex, x);
reprap.GetMove()->SetYBedProbePoint(probePointIndex, y);
@@ -1783,7 +1789,6 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer& gb, StringRef& reply)
reprap.GetMove()->SetZBedProbePoint(probePointIndex, z, false, false);
if (gb.Seen('S'))
{
- zProbesSet = true;
reprap.GetMove()->FinishedBedProbing(gb.GetIValue(), reply);
}
return true;
@@ -1794,8 +1799,7 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer& gb, StringRef& reply)
{
if (gb.Seen('S'))
{
- zProbesSet = true;
- int sParam = gb.GetIValue();
+ const int sParam = gb.GetIValue();
if (sParam == 1)
{
// G30 with a silly Z value and S=1 is equivalent to G30 with no parameters in that it sets the current Z height
@@ -1816,20 +1820,18 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer& gb, StringRef& reply)
return false;
}
-// This returns the (X, Y) points to probe the bed at probe point count. When probing, it returns false.
-// If called after probing has ended it returns true, and the Z coordinate probed is also returned.
-bool GCodes::GetProbeCoordinates(int count, float& x, float& y, float& z) const
-{
- const ZProbeParameters& rp = platform->GetZProbeParameters();
- x = reprap.GetMove()->XBedProbePoint(count) - rp.xOffset;
- y = reprap.GetMove()->YBedProbePoint(count) - rp.yOffset;
- z = reprap.GetMove()->ZBedProbePoint(count);
- return zProbesSet;
-}
-
+// Set or print the Z probe. Called by G31.
+// Note that G31 P or G31 P0 prints the parameters of the currently-selected Z probe.
bool GCodes::SetPrintZProbe(GCodeBuffer& gb, StringRef& reply)
{
- ZProbeParameters params = platform->GetZProbeParameters();
+ int32_t zProbeType = 0;
+ bool seenT = false;
+ gb.TryGetIValue('T',zProbeType, seenT);
+ if (zProbeType == 0)
+ {
+ zProbeType = platform->GetZProbeType();
+ }
+ ZProbeParameters params = platform->GetZProbeParameters(zProbeType);
bool seen = false;
gb.TryGetFValue(axisLetters[X_AXIS], params.xOffset, seen);
gb.TryGetFValue(axisLetters[Y_AXIS], params.yOffset, seen);
@@ -1853,11 +1855,20 @@ bool GCodes::SetPrintZProbe(GCodeBuffer& gb, StringRef& reply)
if (seen)
{
- platform->SetZProbeParameters(params);
+ if (!LockMovementAndWaitForStandstill(gb))
+ {
+ return false;
+ }
+ platform->SetZProbeParameters(zProbeType, params);
+ }
+ else if (seenT)
+ {
+ // Don't bother printing temperature coefficient and calibration temperature because we will probably remove them soon
+ reply.printf("Threshold %d, trigger height %.2f, offsets X%.1f Y%.1f", params.adcValue, params.height, params.xOffset, params.yOffset);
}
else
{
- const int v0 = platform->ZProbe();
+ const int v0 = platform->GetZProbeReading();
int v1, v2;
switch (platform->GetZProbeSecondaryValues(v1, v2))
{
@@ -1879,8 +1890,6 @@ bool GCodes::SetPrintZProbe(GCodeBuffer& gb, StringRef& reply)
// Called when we see an M557 command with no P parameter
bool GCodes::DefineGrid(GCodeBuffer& gb, StringRef &reply)
{
- reprap.GetMove()->UseHeightMap(false);
-
bool seenX = false, seenY = false, seenR = false, seenS = false;
float xValues[2];
float yValues[2];
@@ -1963,7 +1972,7 @@ bool GCodes::DefineGrid(GCodeBuffer& gb, StringRef &reply)
return true;
}
}
- GridDefinition newGrid(xValues, yValues, radius, spacing); // create a new grid
+ GridDefinition newGrid(xValues, yValues, radius, spacing); // create a new grid
if (newGrid.IsValid())
{
reprap.GetMove()->AccessBedProbeGrid().SetGrid(newGrid);
@@ -1981,100 +1990,90 @@ bool GCodes::DefineGrid(GCodeBuffer& gb, StringRef &reply)
// Prior to calling this the movement system must be locked.
bool GCodes::ProbeGrid(GCodeBuffer& gb, StringRef& reply)
{
- int32_t sParam = 0;
- bool dummy;
- gb.TryGetIValue('S', sParam, dummy);
+ Move * const move = reprap.GetMove();
+ if (!move->AccessBedProbeGrid().GetGrid().IsValid())
+ {
+ reply.copy("No valid grid defined for G29 bed probing");
+ return true;
+ }
+
+ if (!AllAxesAreHomed())
+ {
+ reply.copy("Must home printer before G29 bed probing");
+ return true;
+ }
+ gridXindex = gridYindex = 0;
+
+ HeightMap& heightMap = move->AccessBedProbeGrid();
+ heightMap.UseHeightMap(false);
+ heightMap.ClearGridHeights();
+ move->SetIdentityTransform();
+ gb.SetState(GCodeState::gridProbing1);
+ return false;
+}
+
+bool GCodes::LoadHeightMap(GCodeBuffer& gb, StringRef& reply) const
+{
+ const char* heightMapFileName;
if (gb.Seen('P'))
{
- heightMapFile = gb.GetString();
+ heightMapFileName = gb.GetString();
}
else
{
- heightMapFile = DefaultHeightMapFile;
+ heightMapFileName = DefaultHeightMapFile;
}
+ FileStore * const f = platform->GetFileStore(platform->GetSysDir(), heightMapFileName, false);
- Move * const move = reprap.GetMove();
- switch(sParam)
+ if (f == nullptr)
{
- case 0: // Probe the bed and save to file
- if (!move->AccessBedProbeGrid().GetGrid().IsValid())
- {
- reply.copy("No valid grid defined for G29 bed probing");
- return true;
- }
-
- if (!AllAxesAreHomed())
- {
- reply.copy("Must home printer before G29 bed probing");
- return true;
- }
+ reply.printf("Height map file %s not found", heightMapFileName);
+ return true;
+ }
- gridXindex = gridYindex = 0;
- numPointsProbed = 0;
- heightSum = heightSquaredSum = 0.0;
+ reply.printf("Failed to load height map from file %s: ", heightMapFileName); // set up error message to append to
+ HeightMap& heightMap = reprap.GetMove()->AccessBedProbeGrid();
+ const bool err = heightMap.LoadFromFile(f, reply);
+ f->Close();
+ if (err)
+ {
+ heightMap.ClearGridHeights(); // make sure we don't end up with a partial height map
+ }
+ else
+ {
+ reply.Clear(); // wipe the error message
+ }
- move->AccessBedProbeGrid().ClearGridHeights();
- move->UseHeightMap(false);
- move->SetIdentityTransform();
- gb.SetState(GCodeState::gridProbing1);
- return false;
+ heightMap.UseHeightMap(!err);
+ return err;
+}
- case 1: // Load height map from file
+// Save the height map and append the success or error message to 'reply', returning true if an error occurred
+// Called by G29 and M374. Both use the P parameter to provide the filename.
+bool GCodes::SaveHeightMap(GCodeBuffer& gb, StringRef& reply) const
+{
+ const char* heightMapFileName;
+ if (gb.Seen('P'))
+ {
+ heightMapFileName = gb.GetString();
+ if (heightMapFileName[0] == 0)
{
- const char* locHeightMapFileName;
- if (gb.Seen('P'))
- {
- locHeightMapFileName = gb.GetString();
- }
- else
- {
- locHeightMapFileName = DefaultHeightMapFile;
- }
- FileStore * const f = platform->GetFileStore(platform->GetSysDir(), locHeightMapFileName, false);
-
- if (f == nullptr)
- {
- reply.printf("Height map file %s not found", locHeightMapFileName);
- return true;
- }
-
- reply.printf("Failed to load height map from file %s: ", heightMapFile); // set up error message to append to
- const bool err = move->AccessBedProbeGrid().LoadFromFile(f, reply);
- f->Close();
- if (err)
- {
- move->AccessBedProbeGrid().ClearGridHeights(); // make sure we don't end up with a partial height map
- }
- else
- {
- reply.Clear(); // wipe the error message
- }
-
- move->UseHeightMap(!err);
- return err;
+ reply.cat("No height map file name provided");
+ return false; // no file name provided, which is legitimate for G29
}
-
- case 2: // Clear height map
- move->AccessBedProbeGrid().ClearGridHeights();
- move->UseHeightMap(false);
- return false;
-
- default:
- reply.copy("Invalid S parameter in G29 command");
- return true;
}
-}
+ else
+ {
+ heightMapFileName = DefaultHeightMapFile;
+ }
-// Save the height map and write the success or error message to 'reply', returning true if an error occurred
-bool GCodes::SaveHeightMapToFile(StringRef& reply) const
-{
- Platform *platform = reprap.GetPlatform();
- FileStore * const f = platform->GetFileStore(platform->GetSysDir(), heightMapFile, true);
+ Platform * const platform = reprap.GetPlatform();
+ FileStore * const f = platform->GetFileStore(platform->GetSysDir(), heightMapFileName, true);
bool err;
if (f == nullptr)
{
- reply.printf("Failed to create height map file %s", heightMapFile);
+ reply.catf("Failed to create height map file %s", heightMapFileName);
err = true;
}
else
@@ -2083,17 +2082,25 @@ bool GCodes::SaveHeightMapToFile(StringRef& reply) const
f->Close();
if (err)
{
- platform->GetMassStorage()->Delete(platform->GetSysDir(), heightMapFile);
- reply.printf("Failed to save height map to file %s", heightMapFile);
+ platform->GetMassStorage()->Delete(platform->GetSysDir(), heightMapFileName);
+ reply.catf("Failed to save height map to file %s", heightMapFileName);
}
else
{
- reply.printf("Height map saved to file %s", heightMapFile);
+ reply.catf("Height map saved to file %s", heightMapFileName);
}
}
return err;
}
+// Clear the height map
+void GCodes::ClearHeightMap() const
+{
+ HeightMap& heightMap = reprap.GetMove()->AccessBedProbeGrid();
+ heightMap.ClearGridHeights();
+ heightMap.UseHeightMap(false);
+}
+
// Return the current coordinates as a printable string.
// Coordinates are updated at the end of each movement, so this won't tell you where you are mid-movement.
void GCodes::GetCurrentCoordinates(StringRef& s) const
@@ -2868,22 +2875,28 @@ void GCodes::SetPidParameters(GCodeBuffer& gb, int heater, StringRef& reply)
if (heater >= 0 && heater < HEATERS)
{
- PidParameters pp = platform->GetPidParameters(heater);
+ const FopDt& model = reprap.GetHeat()->GetHeaterModel(heater);
+ M301PidParameters pp = model.GetM301PidParameters(false);
bool seen = false;
gb.TryGetFValue('P', pp.kP, seen);
gb.TryGetFValue('I', pp.kI, seen);
gb.TryGetFValue('D', pp.kD, seen);
- gb.TryGetFValue('T', pp.kT, seen);
- gb.TryGetFValue('S', pp.kS, seen);
if (seen)
{
- platform->SetPidParameters(heater, pp);
- reprap.GetHeat()->UseModel(heater, false);
+ reprap.GetHeat()->SetM301PidParameters(heater, pp);
+ }
+ else if (!model.UsePid())
+ {
+ reply.printf("Heater %d is in bang-bang mode", heater);
+ }
+ else if (model.ArePidParametersOverridden())
+ {
+ reply.printf("Heater %d P:%.1f I:%.3f D:%.1f", heater, pp.kP, pp.kI, pp.kD);
}
else
{
- reply.printf("Heater %d P:%.2f I:%.3f D:%.2f T:%.2f S:%.2f", heater, pp.kP, pp.kI, pp.kD, pp.kT, pp.kS);
+ reply.printf("Heater %d uses model-derived PID parameters. Use M307 H%d to view them", heater, heater);
}
}
}
@@ -3217,6 +3230,41 @@ void GCodes::SetAllAxesNotHomed()
axesHomed = 0;
}
+// Write the config-override file returning true if an error occurred
+bool GCodes::WriteConfigOverrideFile(StringRef& reply, const char *fileName) const
+{
+ FileStore * const f = platform->GetFileStore(platform->GetSysDir(), fileName, true);
+ if (f == nullptr)
+ {
+ reply.printf("Failed to create file %s", fileName);
+ return true;
+ }
+
+ bool ok = f->Write("; This is a system-generated file - do not edit\n");
+ if (ok)
+ {
+ ok = reprap.GetMove()->GetDeltaParams().WriteParameters(f);
+ }
+ if (ok)
+ {
+ ok = reprap.GetHeat()->WriteModelParameters(f);
+ }
+ if (ok)
+ {
+ ok = platform->WriteZProbeParameters(f);
+ }
+ if (!f->Close())
+ {
+ ok = false;
+ }
+ if (!ok)
+ {
+ reply.printf("Failed to write file %s", fileName);
+ platform->GetMassStorage()->Delete(platform->GetSysDir(), fileName);
+ }
+ return !ok;
+}
+
// Resource locking/unlocking
// Lock the resource, returning true if success.