Added has_independent_z

Added z calibration wizard
Finished probe calibration wizard
This commit is contained in:
Lars Brubaker 2022-04-01 11:28:58 -07:00
parent 68d361c2da
commit b25694f8c3
14 changed files with 213 additions and 577 deletions

View file

@ -99,6 +99,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SettingsKey.bed_remove_part_temperature,
SettingsKey.bed_shape,
SettingsKey.bed_size,
SettingsKey.bed_surface,
SettingsKey.bed_temperature,
SettingsKey.bed_temperature_blue_tape,
SettingsKey.bed_temperature_buildtak,
@ -107,8 +108,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SettingsKey.bed_temperature_kapton,
SettingsKey.bed_temperature_pei,
SettingsKey.bed_temperature_pp,
SettingsKey.has_swappable_bed,
SettingsKey.bed_surface,
SettingsKey.before_toolchange_gcode,
SettingsKey.before_toolchange_gcode_1,
SettingsKey.before_toolchange_gcode_2,
@ -148,8 +147,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SettingsKey.has_fan_per_extruder,
SettingsKey.has_hardware_leveling,
SettingsKey.has_heated_bed,
SettingsKey.has_independent_z_motors,
SettingsKey.has_power_control,
SettingsKey.has_sd_card_reader,
SettingsKey.has_swappable_bed,
SettingsKey.has_z_probe,
SettingsKey.has_z_servo,
SettingsKey.heat_extruder_before_homing,
@ -219,7 +220,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SettingsKey.use_z_probe,
SettingsKey.validate_layer_height,
SettingsKey.validate_leveling,
SettingsKey.validate_probe_offset,
SettingsKey.validation_threshold,
SettingsKey.write_regex,
SettingsKey.xy_offsets_have_been_calibrated,

View file

@ -45,6 +45,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public const string bed_remove_part_temperature = nameof(bed_remove_part_temperature);
public const string bed_shape = nameof(bed_shape);
public const string bed_size = nameof(bed_size);
public const string bed_surface = nameof(bed_surface);
public const string bed_temperature = nameof(bed_temperature);
public const string bed_temperature_blue_tape = nameof(bed_temperature_blue_tape);
public const string bed_temperature_buildtak = nameof(bed_temperature_buildtak);
@ -53,8 +54,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public const string bed_temperature_kapton = nameof(bed_temperature_kapton);
public const string bed_temperature_pei = nameof(bed_temperature_pei);
public const string bed_temperature_pp = nameof(bed_temperature_pp);
public const string has_swappable_bed = nameof(has_swappable_bed);
public const string bed_surface = nameof(bed_surface);
public const string before_toolchange_gcode = nameof(before_toolchange_gcode);
public const string before_toolchange_gcode_1 = nameof(before_toolchange_gcode_1);
public const string before_toolchange_gcode_2 = nameof(before_toolchange_gcode_2);
@ -133,8 +132,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public const string has_fan_per_extruder = nameof(has_fan_per_extruder);
public const string has_hardware_leveling = nameof(has_hardware_leveling);
public const string has_heated_bed = nameof(has_heated_bed);
public const string has_independent_z_motors = nameof(has_independent_z_motors);
public const string has_power_control = nameof(has_power_control);
public const string has_sd_card_reader = nameof(has_sd_card_reader);
public const string has_swappable_bed = nameof(has_swappable_bed);
public const string has_z_probe = nameof(has_z_probe);
public const string has_z_servo = nameof(has_z_servo);
public const string heat_extruder_before_homing = nameof(heat_extruder_before_homing);
@ -306,7 +307,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public const string use_z_probe = nameof(use_z_probe);
public const string validate_layer_height = nameof(validate_layer_height);
public const string validate_leveling = nameof(validate_leveling);
public const string validate_probe_offset = nameof(validate_probe_offset);
public const string validation_threshold = nameof(validation_threshold);
public const string wipe_shield_distance = nameof(wipe_shield_distance);
public const string wipe_tower_perimeters_per_extruder = nameof(wipe_tower_perimeters_per_extruder);

View file

@ -1014,6 +1014,16 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
RebuildGCodeOnChange = false
},
new SliceSettingData()
{
SlicerConfigName = SettingsKey.has_independent_z_motors,
PresentationName = "Has Independent Z Motors".Localize(),
HelpText = "The printer has the ability to move each z motor independently and the firmware has [G34](https://reprap.org/wiki/G-code#G34:_Z_Stepper_Auto-Align) enabled.".Localize(),
DataEditType = DataEditTypes.CHECK_BOX,
ShowAsOverride = true,
DefaultValue = "0",
RebuildGCodeOnChange = false
},
new SliceSettingData()
{
SlicerConfigName = SettingsKey.measure_probe_offset_conductively,
PresentationName = "Measure Probe Offset Conductively".Localize(),
@ -1028,19 +1038,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
RebuildGCodeOnChange = false
},
new SliceSettingData()
{
SlicerConfigName = SettingsKey.validate_probe_offset,
PresentationName = "Validate Probe Offset Automatically".Localize(),
HelpText = "If the printer has a physically touching z probe (like a BLTouch) this will enable automatic validation of the distance between the nozzle and the z probe.".Localize(),
DataEditType = DataEditTypes.CHECK_BOX,
ShowAsOverride = true,
DefaultValue = "0",
Show = (settings) => !settings.GetBool(SettingsKey.has_hardware_leveling)
&& settings.GetBool(SettingsKey.has_z_probe),
UiUpdate = UiUpdateRequired.SliceSettings,
RebuildGCodeOnChange = false
},
new SliceSettingData()
{
SlicerConfigName = SettingsKey.conductive_pad_center,
PresentationName = "Conductive Pad Center".Localize(),

View file

@ -336,9 +336,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SettingsKey.z_servo_depolyed_angle,
SettingsKey.z_servo_retracted_angle,
SettingsKey.measure_probe_offset_conductively,
#if DEBUG
SettingsKey.validate_probe_offset,
#endif
SettingsKey.conductive_pad_center,
SettingsKey.conductive_probe_min_z,
}),
@ -371,6 +368,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SettingsKey.has_fan,
SettingsKey.has_fan_per_extruder,
SettingsKey.has_hardware_leveling,
SettingsKey.has_independent_z_motors,
SettingsKey.has_heated_bed,
SettingsKey.has_swappable_bed,
SettingsKey.has_sd_card_reader,

View file

@ -154,11 +154,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
// Require user confirmation after this point
this.RequireCancelConfirmation = true;
// add in the homing printer page
yield return new HomePrinterPage(
this,
levelingStrings.HomingPageInstructions(true, false));
// start heating so we are closer to temp after homing
if (LevelingPlan.NeedsToBeRun(printer))
{
// start heating up the bed as that will be needed next
@ -176,8 +172,25 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
for (int i = 0; i < extruderCount; i++)
{
temps[i] = printer.Settings.Helpers.ExtruderTargetTemperature(i);
printer.Connection.SetTargetHotendTemperature(i, temps[i]);
}
if (printer.Settings.GetBool(SettingsKey.has_independent_z_motors))
{
var aligingString = "The printer is now aliging the z-axis. It will do the following:".Localize() +
"\n\n • " + "Home the printer".Clone() +
"\n • " + "Probe multiple times on the left and right".Clone() +
"\n • " + "Save the collected data".Clone() +
"\n • " + "Home the printer again".Clone() +
"\n • " + "Move on to the next calibration step".Clone();
// do z alignment procedure
yield return new AligningZAxisPageInstructions(this, aligingString);
}
// add in the homing printer page
yield return new HomePrinterPage(this, levelingStrings.HomingPageInstructions(true, false));
yield return new WaitForTempPage(
this,
"Heating the printer".Localize(),
@ -197,7 +210,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
printer.Connection.QueueLine($"T0");
}
foreach(var page in DoManualOffsetMeasurment(levelingStrings, autoProbePositions, manualProbePositions))
foreach(var page in DoZOffsetMeasurment(levelingStrings, autoProbePositions, manualProbePositions))
{
yield return page;
}
@ -215,34 +228,10 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
babySteppingValue[i] = 0;
}
var allowValidation = false;
#if DEBUG
allowValidation = true;
#endif
if (hotendCount == 1 // this could be improved for dual extrusion calibration in the future. But for now it is single extrusion.
&& printer.Settings.Helpers.ProbeBeingUsed
&& printer.Settings.GetValue<bool>(SettingsKey.validate_probe_offset)
&& allowValidation)
{
// tell them about the automatic part and any settings that should be changed
yield return new ZProbePrintCalibrationPartPage(
this,
printer,
"Validating Z Offset".Localize(),
"We will now measure the probe offset from the top of a printed calibration object.".Localize());
// measure the top of the part we just printed
yield return new ZProbeCalibrateRetrieveTopProbeData(this, PageTitle);
// tell the user we are done and everything should be working
yield return new ZCalibrationValidateComplete(this, PageTitle);
}
else
{
yield return new CalibrateProbeRemovePaperInstructions(this, PageTitle);
}
yield return new CalibrateProbeRemovePaperInstructions(this, PageTitle);
}
private IEnumerable<WizardPage> DoManualOffsetMeasurment(LevelingStrings levelingStrings,
private IEnumerable<WizardPage> DoZOffsetMeasurment(LevelingStrings levelingStrings,
List<PrintLevelingWizard.ProbePosition> autoProbePositions,
List<List<PrintLevelingWizard.ProbePosition>> manualProbePositions)
{

View file

@ -0,0 +1,95 @@
/*
Copyright (c) 2019, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.PrinterCommunication;
using MatterHackers.MatterControl.SlicerConfiguration;
using System;
namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
public class AligningZAxisPageInstructions : WizardPage
{
private bool calibrationComplete;
public AligningZAxisPageInstructions(ISetupWizard setupWizard, string instructionsText)
: base(setupWizard, "Aligning Z Axis".Localize(), instructionsText)
{
}
public override void OnClosed(EventArgs e)
{
calibrationComplete = false;
// Unregister listeners
printer.Connection.LineReceived -= Connection_LineRecieved;
base.OnClosed(e);
}
public override void OnLoad(EventArgs args)
{
// Send the G34 Z Stepper Auto Align (https://reprap.org/wiki/G-code#G34:_Z_Stepper_Auto-Align)
// 7 iterations .1 accuracy for early exit
printer.Connection.QueueLine("G34 I7 T.1");
NextButton.Enabled = false;
// Register listeners
printer.Connection.LineReceived += Connection_LineRecieved;
// Always enable the advance button after 15 seconds
UiThread.RunOnIdle(() =>
{
// Wait 30 seconds then ensure that if we miss the ok event, the user can still continue.
if (!this.HasBeenClosed)
{
NextButton.Enabled = true;
}
}, 30);
base.OnLoad(args);
}
private void Connection_LineRecieved(object sender, string reciviedString)
{
if (reciviedString == "ok")
{
calibrationComplete = true;
printer.Connection.LineReceived -= Connection_LineRecieved;
}
if (calibrationComplete)
{
NextButton.Enabled = true;
UiThread.RunOnIdle(() => NextButton.InvokeClick());
}
}
}
}

View file

@ -27,74 +27,74 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.PrinterCommunication;
using MatterHackers.MatterControl.SlicerConfiguration;
using System;
namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
public class HomePrinterPage : WizardPage
{
private bool homingAxisObserved;
public class HomePrinterPage : WizardPage
{
private bool homingAxisObserved;
public HomePrinterPage(ISetupWizard setupWizard, string instructionsText)
: base(setupWizard, "Homing the printer".Localize(), instructionsText)
{
// Register listeners
printer.Connection.DetailedPrintingStateChanged += Connection_DetailedPrintingStateChanged;
}
public HomePrinterPage(ISetupWizard setupWizard, string instructionsText)
: base(setupWizard, "Homing the printer".Localize(), instructionsText)
{
// Register listeners
printer.Connection.DetailedPrintingStateChanged += Connection_DetailedPrintingStateChanged;
}
public override void OnClosed(EventArgs e)
{
homingAxisObserved = false;
public override void OnClosed(EventArgs e)
{
homingAxisObserved = false;
// Unregister listeners
printer.Connection.DetailedPrintingStateChanged -= Connection_DetailedPrintingStateChanged;
// Unregister listeners
printer.Connection.DetailedPrintingStateChanged -= Connection_DetailedPrintingStateChanged;
base.OnClosed(e);
}
base.OnClosed(e);
}
public override void OnLoad(EventArgs args)
{
printer.Connection.HomeAxis(PrinterConnection.Axis.XYZ);
public override void OnLoad(EventArgs args)
{
printer.Connection.HomeAxis(PrinterConnection.Axis.XYZ);
if(!printer.Settings.GetValue<bool>(SettingsKey.z_homes_to_max))
{
// move so we don't heat the printer while the nozzle is touching the bed
printer.Connection.MoveAbsolute(PrinterConnection.Axis.Z, 10, printer.Settings.Helpers.ManualMovementSpeeds().Z);
}
if (!printer.Settings.GetValue<bool>(SettingsKey.z_homes_to_max))
{
// move so we don't heat the printer while the nozzle is touching the bed
printer.Connection.MoveAbsolute(PrinterConnection.Axis.Z, 10, printer.Settings.Helpers.ManualMovementSpeeds().Z);
}
NextButton.Enabled = false;
NextButton.Enabled = false;
// Always enable the advance button after 15 seconds
UiThread.RunOnIdle(() =>
{
// TODO: consider if needed. Ensures that if we miss a HomingAxis event, the user can still continue
if (!this.HasBeenClosed)
{
NextButton.Enabled = true;
}
}, 15);
// Always enable the advance button after 15 seconds
UiThread.RunOnIdle(() =>
{
// TODO: consider if needed. Ensures that if we miss a HomingAxis event, the user can still continue
if (!this.HasBeenClosed)
{
NextButton.Enabled = true;
}
}, 15);
base.OnLoad(args);
}
base.OnLoad(args);
}
private void Connection_DetailedPrintingStateChanged(object sender, EventArgs e)
{
if (printer.Connection.DetailedPrintingState == DetailedPrintingState.HomingAxis
&& !homingAxisObserved)
{
homingAxisObserved = true;
}
private void Connection_DetailedPrintingStateChanged(object sender, EventArgs e)
{
if (printer.Connection.DetailedPrintingState == DetailedPrintingState.HomingAxis
&& !homingAxisObserved)
{
homingAxisObserved = true;
}
if (homingAxisObserved
&& printer.Connection.DetailedPrintingState != DetailedPrintingState.HomingAxis)
{
NextButton.Enabled = true;
UiThread.RunOnIdle(() => NextButton.InvokeClick());
}
}
}
if (homingAxisObserved
&& printer.Connection.DetailedPrintingState != DetailedPrintingState.HomingAxis)
{
NextButton.Enabled = true;
UiThread.RunOnIdle(() => NextButton.InvokeClick());
}
}
}
}

View file

@ -1,53 +0,0 @@
/*
Copyright (c) 2019, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using MatterHackers.Localizations;
namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
public class ZCalibrationValidateComplete : WizardPage
{
public ZCalibrationValidateComplete(ISetupWizard setupWizard, string headerText, bool lastPage = true)
: base(setupWizard, headerText, "")
{
contentRow.AddChild(
this.CreateTextField(
"Precise probe calibration complete.".Localize() +
"\n • " +
"Your probe is now finely calibrated and should produce excellent first layer results".Localize()));
contentRow.BackgroundColor = theme.MinimalShade;
if (lastPage)
{
this.ShowWizardFinished();
}
}
}
}

View file

@ -1,273 +0,0 @@
/*
Copyright (c) 2019, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using MatterControl.Printing;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.PrinterCommunication;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
public class ZProbeCalibrateRetrieveTopProbeData : WizardPage
{
private bool validationRunning;
private bool oldAllowLeveling;
private Vector3 positionToSample;
private List<double> babySteppingValue;
private Vector3 sampledPosition;
private bool waitingToCompleteNextSample;
private bool dataCollected;
private List<double> samplesForSinglePosition;
private Vector3 positionToSampleWithProbeOffset;
public ZProbeCalibrateRetrieveTopProbeData(ISetupWizard setupWizard, string headerText)
: base(setupWizard, headerText, "")
{
contentRow.AddChild(this.CreateTextField("We will now sample the top of the part.".Localize()));
contentRow.BackgroundColor = theme.MinimalShade;
}
public override void OnClosed(EventArgs e)
{
CancelValidation();
printer.Connection.CanceleRequested -= Connection_PrintCanceled;
base.OnClosed(e);
}
private void CancelValidation()
{
if (validationRunning)
{
validationRunning = false;
printer.Connection.LineReceived -= GetZProbeHeight;
// If leveling was on when we started, make sure it is on when we are done.
printer.Connection.AllowLeveling = true;
// set the baby stepping back to the last known good value
printer.Settings.ForTools<double>(SettingsKey.baby_step_z_offset, (key, value, i) =>
{
printer.Settings.SetValue(key, babySteppingValue[i].ToString());
});
RetractProbe();
}
}
private void Connection_PrintCanceled(object sender, EventArgs e)
{
CancelValidation();
}
private void RetractProbe()
{
// make sure we raise the probe on close
if (printer.Settings.Helpers.ProbeBeingUsed
&& printer.Settings.GetValue<bool>(SettingsKey.has_z_servo))
{
// make sure the servo is retracted
var servoRetract = printer.Settings.GetValue<double>(SettingsKey.z_servo_retracted_angle);
printer.Connection.QueueLine($"M280 P0 S{servoRetract}");
}
}
private void SampleProbePoints()
{
if (waitingToCompleteNextSample)
{
return;
}
double startProbeHeight = printer.Settings.GetValue<double>(SettingsKey.print_leveling_probe_start) + ZProbePrintCalibrationPartPage.CalibrationObjectHeight(printer);
if (!dataCollected)
{
var validProbePosition2D = PrintLevelingWizard.EnsureInPrintBounds(printer, printer.Bed.BedCenter);
positionToSample = new Vector3(validProbePosition2D, startProbeHeight);
this.SamplePoint();
}
else
{
SaveSamplePoints();
CancelValidation();
}
}
private void GetZProbeHeight(object sender, string line)
{
if (line != null)
{
double sampleRead = double.MinValue;
if (line.StartsWith("Bed")) // marlin G30 return code (looks like: 'Bed Position X:20 Y:32 Z:.01')
{
sampledPosition.X = positionToSample.X;
sampledPosition.Y = positionToSample.Y;
GCodeFile.GetFirstNumberAfter("Z:", line, ref sampleRead);
}
else if (line.StartsWith("Z:")) // smoothie G30 return code (looks like: 'Z:10.01')
{
sampledPosition.X = positionToSample.X;
sampledPosition.Y = positionToSample.Y;
// smoothie returns the position relative to the start position
double reportedProbeZ = 0;
GCodeFile.GetFirstNumberAfter("Z:", line, ref reportedProbeZ);
sampleRead = positionToSample.Z - reportedProbeZ;
}
if (sampleRead != double.MinValue)
{
samplesForSinglePosition.Add(sampleRead);
int numberOfSamples = printer.Settings.GetValue<int>(SettingsKey.z_probe_samples);
if (samplesForSinglePosition.Count >= numberOfSamples)
{
samplesForSinglePosition.Sort();
if (samplesForSinglePosition.Count > 3)
{
// drop the high and low values
samplesForSinglePosition.RemoveAt(0);
samplesForSinglePosition.RemoveAt(samplesForSinglePosition.Count - 1);
}
sampledPosition.Z = Math.Round(samplesForSinglePosition.Average(), 2);
// When probe data has been collected, resume our thread to continue collecting
waitingToCompleteNextSample = false;
}
else
{
// add the next request for probe
printer.Connection.QueueLine("G30");
// raise the probe after each sample
var feedRates = printer.Settings.Helpers.ManualMovementSpeeds();
printer.Connection.QueueLine($"G1 X{positionToSampleWithProbeOffset.X:0.###}Y{positionToSampleWithProbeOffset.Y:0.###}Z{positionToSampleWithProbeOffset.Z:0.###} F{feedRates.X}");
}
}
}
}
private void SaveSamplePoints()
{
printer.Settings.ForTools<double>(SettingsKey.baby_step_z_offset, (key, value, i) =>
{
printer.Settings.SetValue(key, "0");
});
printer.Connection.AllowLeveling = oldAllowLeveling;
}
private void SetupForValidation()
{
validationRunning = true;
// make sure baby stepping is removed as this will be calibrated exactly (assuming it works)
printer.Settings.ForTools<double>(SettingsKey.baby_step_z_offset, (key, value, i) =>
{
// remember the current baby stepping values
babySteppingValue[i] = value;
printer.Settings.SetValue(key, "0");
});
oldAllowLeveling = printer.Connection.AllowLeveling;
// turn off print leveling
printer.Connection.AllowLeveling = false;
var levelingData = new PrintLevelingData()
{
LevelingSystem = printer.Settings.GetValue<LevelingSystem>(SettingsKey.print_leveling_solution)
};
}
private void DeployServo()
{
if (printer.Settings.GetValue<bool>(SettingsKey.has_z_servo))
{
// make sure the servo is deployed
var servoDeployCommand = printer.Settings.GetValue<double>(SettingsKey.z_servo_depolyed_angle);
printer.Connection.QueueLine($"M280 P0 S{servoDeployCommand}");
}
}
private Vector3 ProbeOffset
{
get => printer.Settings.GetValue<Vector3>(SettingsKey.probe_offset);
}
private Vector3 FeedRates
{
get => printer.Settings.Helpers.ManualMovementSpeeds();
}
private void SamplePoint()
{
positionToSampleWithProbeOffset = positionToSample;
var feedRates = FeedRates;
var probeOffset = ProbeOffset;
// subtract out the probe offset
// we are only interested in the xy position
probeOffset.Z = 0;
positionToSampleWithProbeOffset -= probeOffset;
printer.Connection.QueueLine($"G1 Z{positionToSample.Z:0.###} F{feedRates.Z}");
printer.Connection.QueueLine($"G1 X{positionToSampleWithProbeOffset.X:0.###}Y{positionToSampleWithProbeOffset.Y:0.###}Z{positionToSampleWithProbeOffset.Z:0.###} F{feedRates.X}");
// probe the current position
printer.Connection.QueueLine("G30");
// raise the probe after each sample
printer.Connection.QueueLine($"G1 X{positionToSampleWithProbeOffset.X:0.###}Y{positionToSampleWithProbeOffset.Y:0.###}Z{positionToSampleWithProbeOffset.Z:0.###} F{feedRates.X}");
}
public override void OnLoad(EventArgs args)
{
// register to listen to the printer
printer.Connection.LineReceived += GetZProbeHeight;
printer.Connection.CanceleRequested += Connection_PrintCanceled;
// we have just completed the print of the calibration object move to the probe position and probe the top
this.NextButton.Enabled = false;
// make sure we are on T0
printer.Connection.QueueLine("T0");
// Move to the correct z height
printer.Connection.MoveAbsolute(PrinterConnection.Axis.Z, 2, printer.Settings.Helpers.ManualMovementSpeeds().Z);
base.OnLoad(args);
}
}
}

View file

@ -1,142 +0,0 @@
/*
Copyright (c) 2019, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.PolygonMesh;
namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
public class ZProbePrintCalibrationPartPage : WizardPage
{
public ZProbePrintCalibrationPartPage(ISetupWizard setupWizard, PrinterConfig printer, string headerText, string details)
: base(setupWizard, headerText, details)
{
var spacer = new GuiWidget(15, 15);
contentRow.AddChild(spacer);
int tabIndex = 0;
contentRow.AddChild(
new TextWidget(
"This wizard will close to print a calibration part and resume after the print completes.".Localize(),
textColor: theme.TextColor,
pointSize: theme.DefaultFontSize)
{
Margin = new BorderDouble(bottom: theme.DefaultContainerPadding)
});
if (printer.Settings.GetValue<double>(SettingsKey.layer_height) < printer.Settings.GetValue<double>(SettingsKey.nozzle_diameter) / 2)
{
// The layer height is very small and it will be hard to see features. Show a warning.
AddSettingsRow(contentRow, printer, "The calibration object will printer better if the layer hight is set to a larger value. It is recommended that your increase it.".Localize(), SettingsKey.layer_height, theme, ref tabIndex);
}
if (printer.Settings.GetValue<bool>(SettingsKey.create_raft))
{
// The layer height is very small and it will be hard to see features. Show a warning.
AddSettingsRow(contentRow, printer, "A raft is not needed for the calibration object. It is recommended that you turn it off.".Localize(), SettingsKey.create_raft, theme, ref tabIndex);
}
if (printer.Settings.GetValue<int>(SettingsKey.top_solid_layers) < 4)
{
// The layer height is very small and it will be hard to see features. Show a warning.
AddSettingsRow(contentRow, printer, "You should have at least 3 top layers for this calibration to measure off of.".Localize(), SettingsKey.top_solid_layers, theme, ref tabIndex);
}
this.NextButton.Visible = false;
var startCalibrationPrint = theme.CreateDialogButton("Start Print".Localize());
startCalibrationPrint.Name = "Start Calibration Print";
startCalibrationPrint.Click += async (s, e) =>
{
var preCalibrationPrintViewMode = printer.ViewState.ViewMode;
// create the calibration objects
var item = CreateCalibrationObject(printer);
var calibrationObjectPrinter = new CalibrationObjectPrinter(printer, item);
// hide this window
this.DialogWindow.Visible = false;
await calibrationObjectPrinter.PrintCalibrationPart();
// Restore the original DialogWindow
this.DialogWindow.Visible = true;
// Restore to original view mode
printer.ViewState.ViewMode = preCalibrationPrintViewMode;
this.MoveToNextPage();
};
this.AcceptButton = startCalibrationPrint;
this.AddPageAction(startCalibrationPrint);
}
public static double CalibrationObjectHeight(PrinterConfig printer)
{
var layerHeight = printer.Settings.GetValue<double>(SettingsKey.layer_height);
var firstLayerHeight = printer.Settings.GetValue<double>(SettingsKey.first_layer_height);
return firstLayerHeight + layerHeight * 4;
}
private static IObject3D CreateCalibrationObject(PrinterConfig printer)
{
var printObject = new Object3D();
var layerHeight = printer.Settings.GetValue<double>(SettingsKey.layer_height);
var baseSize = 20;
var inset = 2.5;
// add a base
var mesh = PlatonicSolids.CreateCube(baseSize, baseSize, CalibrationObjectHeight(printer) - layerHeight);
mesh.Translate(0, 0, mesh.GetAxisAlignedBoundingBox().ZSize / 2);
printObject.Children.Add(new Object3D()
{
Mesh = mesh
});
// add a middle part where we will probe to find the height and the edges of
mesh = PlatonicSolids.CreateCube(baseSize - inset, baseSize - inset, CalibrationObjectHeight(printer));
mesh.Translate(0, 0, mesh.GetAxisAlignedBoundingBox().ZSize / 2);
printObject.Children.Add(new Object3D()
{
Mesh = mesh
});
return printObject;
}
}
}

View file

@ -141,7 +141,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public string SelectedTabKey
{
get => this.ActiveTab.Key;
get
{
return this.ActiveTab?.Key;
}
set
{
var foundTab = AllTabs.First();

View file

@ -1675,6 +1675,7 @@ Make sure that your printer is turned on. Some printers will appear to be connec
try
{
while (serialPort != null
&& serialPort.IsOpen
&& serialPort.BytesToRead > 0
&& readThreadHolder.IsCurrentThread())
{
@ -1756,6 +1757,11 @@ Make sure that your printer is turned on. Some printers will appear to be connec
}
Console.WriteLine("Exiting ReadFromPrinter method: " + CommunicationState.ToString());
if (CommunicationState == CommunicationStates.Connected)
{
// we are in an error condition where we have lost the com port
CommunicationState = CommunicationStates.Disconnected;
}
}
public void ReadPosition(PositionReadType positionReadType = PositionReadType.Other, bool forceToTopOfQueue = false)

View file

@ -35,8 +35,6 @@ using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.PolygonMesh;
using MatterHackers.PolygonMesh.Processors;

View file

@ -286,6 +286,9 @@ Translated:Alert
English:Align
Translated:Align
English:Aligning Z Axis
Translated:Aligning Z Axis
English:Alignment
Translated:Alignment
@ -2062,6 +2065,9 @@ Translated:Has Hardware Leveling
English:Has Heated Bed
Translated:Has Heated Bed
English:Has Independent Z Motors
Translated:Has Independent Z Motors
English:Has Power Control
Translated:Has Power Control
@ -5260,6 +5266,18 @@ Translated:The printer has the ability to check for continuity on the nozzle.
English:The printer has the ability to control the power supply. Enable this function to show the ATX Power Control section on the Controls pane.
Translated:The printer has the ability to control the power supply. Enable this function to show the ATX Power Control section on the Controls pane.
English:The printer has the ability to move each motor independently and the firmware has G34 enabled.
Translated:The printer has the ability to move each motor independently and the firmware has G34 enabled.
English:The printer has the ability to move each z motor independently and the firmware has [G34](https://reprap.org/wiki/G-code#G34:_Z_Stepper_Auto-Align) enabled.
Translated:The printer has the ability to move each z motor independently and the firmware has [G34](https://reprap.org/wiki/G-code#G34:_Z_Stepper_Auto-Align) enabled.
English:The printer has the ability to move each z motor independently and the firmware has G34 enabled.
Translated:The printer has the ability to move each z motor independently and the firmware has G34 enabled.
English:The printer is now aliging the z-axis. It will do the following:
Translated:The printer is now aliging the z-axis. It will do the following:
English:The printer moved below the minimum height set for conductive probing. Check that the nozzle is clean and there is continuity with the pad.
Translated:The printer moved below the minimum height set for conductive probing. Check that the nozzle is clean and there is continuity with the pad.