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:
authorDavid Crocker <dcrocker@eschertech.com>2019-01-24 20:24:03 +0300
committerDavid Crocker <dcrocker@eschertech.com>2019-01-24 20:24:03 +0300
commitcb1e5eb665b63ab4deee381fd1511d5722d9d963 (patch)
tree7d96793031a1d235d70e334d5d3a6643b9b5f237
parent057218b6af1482bbffedcd7e8a940b56075f4a7a (diff)
Towards 2.03beta1
Fixes to generalised Cartesian kinematics Support linear delta kinematics with up to 6 towers M106 Pn Sxx updates mapped fan speed if n is a mapped fan M408 S2 response now includes bed standby temperature Support G30 S-3 Added user-settable minimum radius to SCARA parameters 12864 bug fix: erase items that should no longer be visible
-rw-r--r--.cproject22
-rw-r--r--Maths/trilateration-l3.wxmxbin0 -> 60204 bytes
-rw-r--r--src/BugList.txt26
-rw-r--r--src/Display/Menu.cpp16
-rw-r--r--src/Display/MenuItem.cpp62
-rw-r--r--src/Display/MenuItem.h22
-rw-r--r--src/GCodes/GCodes.cpp45
-rw-r--r--src/GCodes/GCodes.h4
-rw-r--r--src/GCodes/GCodes2.cpp22
-rw-r--r--src/Movement/DDA.cpp89
-rw-r--r--src/Movement/DriveMovement.cpp15
-rw-r--r--src/Movement/DriveMovement.h9
-rw-r--r--src/Movement/Kinematics/CoreKinematics.cpp21
-rw-r--r--src/Movement/Kinematics/CoreKinematics.h7
-rw-r--r--src/Movement/Kinematics/HangprinterKinematics.cpp2
-rw-r--r--src/Movement/Kinematics/HangprinterKinematics.h2
-rw-r--r--src/Movement/Kinematics/Kinematics.cpp8
-rw-r--r--src/Movement/Kinematics/Kinematics.h8
-rw-r--r--src/Movement/Kinematics/LinearDeltaKinematics.cpp201
-rw-r--r--src/Movement/Kinematics/LinearDeltaKinematics.h30
-rw-r--r--src/Movement/Kinematics/PolarKinematics.cpp24
-rw-r--r--src/Movement/Kinematics/PolarKinematics.h2
-rw-r--r--src/Movement/Kinematics/RotaryDeltaKinematics.cpp2
-rw-r--r--src/Movement/Kinematics/RotaryDeltaKinematics.h2
-rw-r--r--src/Movement/Kinematics/ScaraKinematics.cpp10
-rw-r--r--src/Movement/Kinematics/ScaraKinematics.h3
-rw-r--r--src/Platform.cpp79
-rw-r--r--src/Platform.h4
-rw-r--r--src/RepRap.cpp4
-rw-r--r--src/Version.h2
30 files changed, 467 insertions, 276 deletions
diff --git a/.cproject b/.cproject
index 4d952da2..9fb39d0e 100644
--- a/.cproject
+++ b/.cproject
@@ -20,7 +20,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850" name="Duet085" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850" name="Duet085" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.947353540" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.1742191832" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
@@ -138,7 +138,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="${ProjName}-RADDS" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289" name="RADDS_RTOS" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="${ProjName}-RADDS" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289" name="RADDS_RTOS" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1027429289." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1973208555" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.2092504710" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
@@ -257,13 +257,13 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="${ProjName}-Alligator" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887" name="Alligator" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="${ProjName}-Alligator" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887" name="Alligator" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1745168887." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.623324432" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.645044151" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
<option id="cdt.managedbuild.option.gnu.cross.prefix.629438941" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.878309876" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
- <builder buildPath="${workspace_loc:/RepRapFirmware}/Alligator" id="cdt.managedbuild.builder.gnu.cross.1518897616" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
+ <builder buildPath="${workspace_loc:/RepRapFirmware}/Alligator" id="cdt.managedbuild.builder.gnu.cross.1518897616" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
<tool id="cdt.managedbuild.tool.gnu.cross.assembler.384615201" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1769413014" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
@@ -381,7 +381,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="Duet2CombinedFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622" name="Duet2_RTOS" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="Duet2CombinedFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622" name="Duet2_RTOS" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.435431950" name="Cross GCC" nonInternalBuilderId="cdt.managedbuild.builder.gnu.cross" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.1881231799" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
@@ -504,7 +504,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="DuetMaestroFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786" name="DuetM_RTOS" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="DuetMaestroFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786" name="DuetM_RTOS" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1494327638" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.1101985181" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
@@ -627,7 +627,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="Duet3Firmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116.1852610203" name="Duet3" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="Duet3Firmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116.1852610203" name="Duet3" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116.1852610203." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.5959303" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.163568524" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
@@ -766,7 +766,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="PccbFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786.1798324396" name="PCCB" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="PccbFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786.1798324396" name="PCCB" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786.1798324396." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1017317107" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.1932906636" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
@@ -888,7 +888,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="PccbFirmware_X5" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786.1798324396.239853003" name="PCCB_X5" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="PccbFirmware_X5" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786.1798324396.239853003" name="PCCB_X5" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.170574622.649587786.1798324396.239853003." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.2113529528" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.1216992967" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
@@ -1012,7 +1012,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="SAME70XPLDFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116.1852610203.216858457" name="SAME70XPLD" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="SAME70XPLDFirmware" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116.1852610203.216858457" name="SAME70XPLD" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.241502451.1275216290.274082366.1645191116.1852610203.216858457." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1157300775" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.2145914464" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
@@ -1150,7 +1150,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
- <configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1168118439" name="Duet085_RTOS" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf ${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin">
+ <configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1168118439" name="Duet085_RTOS" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary file" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.elf&quot; &quot;${workspace_loc:/${ProjName}/${ConfigName}}/${BuildArtifactFileBaseName}.bin&quot;">
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.516195201.976458850.1168118439." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.734437241" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
<option id="cdt.managedbuild.option.gnu.cross.path.546334814" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${GccPath}" valueType="string"/>
diff --git a/Maths/trilateration-l3.wxmx b/Maths/trilateration-l3.wxmx
new file mode 100644
index 00000000..b16bca05
--- /dev/null
+++ b/Maths/trilateration-l3.wxmx
Binary files differ
diff --git a/src/BugList.txt b/src/BugList.txt
index d87bd82c..7ca6034e 100644
--- a/src/BugList.txt
+++ b/src/BugList.txt
@@ -240,6 +240,9 @@ Done in 2.02 release:
- [done, ok] M572 and M221 with no extruder drive number to set all extruders used by the current tool, https://forum.duet3d.com/topic/8444/setting-pressure-advance-in-filament-file
- [done, ok with new filament monitor, test with old] Support filament sensor firmware v2
- [done, ok] Improve efficiency of debug print in WiFiInterface: don't keep calling cat and strlen
+- [done, ok] Filament monitor to use time since end of last nonprinting extruder move
+- [done, ok on bench] Fix continuous rotation speed error bug on Polar kinematics, https://forum.duet3d.com/topic/8747/polar-printing-polar-axis-rotation-issue/3
+- [done, ok, needs community test] Generalised Cartesian kinematics
- [done, test] Disable mdns in legacy Duets, https://forum.duet3d.com/topic/8352/duet-0-6-randomly-reboots/5
- [done, test] rr_fileinfo and M36 with no filename to include estimated print time and simulation time in the response, as in the report with a filename
- [done, test] In CNC and laser mode update user Z coordinate after tool change, https://forum.duet3d.com/topic/8181/tool-offset-honored-but-not-displayed-correctly
@@ -247,6 +250,14 @@ Done in 2.02 release:
- [done, test] G92 should not constrain the passed coordinates to the M208 limits if M564 S0 has been used to disable limits
- [done, test] Bug fix: month number written to height map.csv and filament files was too low by 1
- [done, test] wilriker PR to allow steps/mm to be quoted in M92, https://forum.duet3d.com/topic/8225/m92-parameter-to-indicate-microstepping/6
+- [done, ok but test with babystepping] Deferred DM allocation and removal of DM array
+- [done, test] G30 S-3 option, to set trigger height to stopped height
+- [done, test] Bug: 12864 display needs to be refreshed when a change in printer state alters visibility
+- [done, test] When M106 Pn Sxxx received, if n = current print cooling fan number, update the print cooling fan speed variable, https://forum.duet3d.com/topic/8540/part-fan-value-missing/6
+- [done, test] PR to send standby bed temperature in M408
+- [done] Scara R parameter to set min radius, https://github.com/dc42/RepRapFirmware/issues/221
+- [done, test] DAA to handle requested accel/decl > max
+- [could be related to visibility issue] Investigate 12864 display heater fault warning, https://forum.duet3d.com/topic/7718/12864-display-current-tool-temperatures/6
- Slow startup move issue, https://forum.duet3d.com/topic/8284/firmware-2-02-released/7 (adding S2 fixes it)
- M291 issue, https://forum.duet3d.com/topic/8381/m291-s2-does-not-block-macro-execution/5
- In laser mode allow M3 instead of S to control laser power? (wait for feedback, not as simple as it looked)
@@ -255,15 +266,16 @@ Done in 2.02 release:
- Danny's G1->G0 request? [added IntermediatePositionsReachable function]
- Warm up time not always displayed in 2.02
- For PanelDue, send heater data for the first heater in each tool, https://forum.duet3d.com/topic/8458/hide-unused-heater-channels-paneldue-5/4
-- Investigate 12864 display heater fault warning, https://forum.duet3d.com/topic/7718/12864-display-current-tool-temperatures/6
-- Generalised Cartesian axes; need to return bitmap of 'axes' involved for stall detect homing, see Platform::Stopped
-- Deffered allocation of DMs: don't create DMs for nonlocal drives, pass #steps to CAN interface instead
-- Remove the DM array
-- Filament monitor to use time since end of last nonprinting extruder move
-- DAA to handle requested accel/decl > max
+- Deferred allocation of DMs: don't create DMs for nonlocal drives, pass #steps to CAN interface instead
- Reports that DueX5 endstops stop working after a while, https://forum.duet3d.com/topic/8284/firmware-2-02-released/9
- I2C error recovery?
-- Test babystepping with the deferred DM allocation
+- Pressure advance issue? https://forum.duet3d.com/topic/8672/extruder-motors-skip-steps-with-pressure-advance-enabled/3
+- After pausing a print, if Cancel is pressed, cancel initial heating first like M108 does
+- 4-tower delta kinematics
+- Bug: M997 S1 sent from USB keeps returning M105 status reports while the wifi firmware is flashing
+- Test with Duet 3
+
+Look at icon generation, https://forum.duet3d.com/topic/8177/icon-generation/7
2.03 planned:
- Stop print after a short to ground report? https://forum.duet3d.com/topic/8239/duet-maestro-short-to-ground/10
diff --git a/src/Display/Menu.cpp b/src/Display/Menu.cpp
index 0479266e..ea88a15f 100644
--- a/src/Display/Menu.cpp
+++ b/src/Display/Menu.cpp
@@ -358,14 +358,12 @@ const char *Menu::ParseMenuLine(char * const commandWord)
{
const char *const acText = AppendString(text);
MenuItem * const pNewItem = new TextMenuItem(row, column, width, alignment, fontNumber, xVis, acText);
- pNewItem->UpdateWidth(lcd);
AddItem(pNewItem, false);
column += pNewItem->GetWidth() + 1;
}
else if (StringEqualsIgnoreCase(commandWord, "image") && fname != nullptr)
{
ImageMenuItem * const pNewItem = new ImageMenuItem(row, column, xVis, fname);
- pNewItem->UpdateWidth(lcd);
AddItem(pNewItem, false);
column += pNewItem->GetWidth() + 1;
}
@@ -375,7 +373,6 @@ const char *Menu::ParseMenuLine(char * const commandWord)
const char * const actionString = AppendString(action);
const char * const c_acFileString = AppendString(fname);
ButtonMenuItem * const pNewItem = new ButtonMenuItem(row, column, width, fontNumber, xVis, textString, actionString, c_acFileString);
- pNewItem->UpdateWidth(lcd);
AddItem(pNewItem, true);
column += pNewItem->GetWidth() + 1;
}
@@ -497,6 +494,7 @@ void Menu::Reload()
void Menu::AddItem(MenuItem *item, bool isSelectable)
{
+ item->UpdateWidthAndHeight(lcd);
MenuItem::AppendToList((isSelectable) ? &selectableItems : &unSelectableItems, item);
}
@@ -689,6 +687,18 @@ void Menu::Refresh()
void Menu::DrawAll()
{
+ // First erase any displayed items that should now be invisible
+ for (MenuItem *item = selectableItems; item != nullptr; item = item->GetNext())
+ {
+ item->EraseIfInvisible(lcd, rowOffset);
+ }
+
+ for (MenuItem *item = unSelectableItems; item != nullptr; item = item->GetNext())
+ {
+ item->EraseIfInvisible(lcd, rowOffset);
+ }
+
+ // Now draw items
const PixelNumber rightMargin = NumCols - currentMargin;
for (MenuItem *item = selectableItems; item != nullptr; item = item->GetNext())
{
diff --git a/src/Display/MenuItem.cpp b/src/Display/MenuItem.cpp
index e3d83665..c725066b 100644
--- a/src/Display/MenuItem.cpp
+++ b/src/Display/MenuItem.cpp
@@ -20,7 +20,7 @@
#include "PrintMonitor.h"
MenuItem::MenuItem(PixelNumber r, PixelNumber c, PixelNumber w, Alignment a, FontNumber fn, Visibility vis)
- : row(r), column(c), width(w), align(a), fontNumber(fn), visCase(vis), itemChanged(true), highlighted(false), next(nullptr)
+ : row(r), column(c), width(w), height(0), align(a), fontNumber(fn), visCase(vis), itemChanged(true), highlighted(false), drawn(false), next(nullptr)
{
}
@@ -88,6 +88,16 @@ bool MenuItem::IsVisible() const
}
}
+// Erase this item if it is drawn but should not be visible
+void MenuItem::EraseIfInvisible(Lcd7920& lcd, PixelNumber tOffset)
+{
+ if (drawn && !IsVisible())
+ {
+ lcd.Clear(row - tOffset, column, row + height, column + width);
+ drawn = false;
+ }
+}
+
TextMenuItem::TextMenuItem(PixelNumber r, PixelNumber c, PixelNumber w, Alignment a, FontNumber fn, Visibility vis, const char* t)
: MenuItem(r, c, w, a, fn, vis), text(t)
{
@@ -105,10 +115,11 @@ void TextMenuItem::Draw(Lcd7920& lcd, PixelNumber rightMargin, bool highlight, P
{
PrintAligned(lcd, tOffset, rightMargin);
itemChanged = false;
+ drawn = true;
}
}
-void TextMenuItem::UpdateWidth(Lcd7920& lcd)
+void TextMenuItem::UpdateWidthAndHeight(Lcd7920& lcd)
{
if (width == 0)
{
@@ -119,6 +130,11 @@ void TextMenuItem::UpdateWidth(Lcd7920& lcd)
lcd.print(text);
width = lcd.GetColumn();
}
+ if (height == 0)
+ {
+ lcd.SetFont(fontNumber);
+ height = lcd.GetFontHeight();
+ }
}
ButtonMenuItem::ButtonMenuItem(PixelNumber r, PixelNumber c, PixelNumber w, FontNumber fn, Visibility vis, const char* t, const char* cmd, char const* acFile)
@@ -140,10 +156,11 @@ void ButtonMenuItem::Draw(Lcd7920& lcd, PixelNumber rightMargin, bool highlight,
highlighted = highlight;
PrintAligned(lcd, tOffset, rightMargin);
itemChanged = false;
+ drawn = true;
}
}
-void ButtonMenuItem::UpdateWidth(Lcd7920& lcd)
+void ButtonMenuItem::UpdateWidthAndHeight(Lcd7920& lcd)
{
if (width == 0)
{
@@ -154,6 +171,11 @@ void ButtonMenuItem::UpdateWidth(Lcd7920& lcd)
CorePrint(lcd);
width = lcd.GetColumn();
}
+ if (height == 0)
+ {
+ lcd.SetFont(fontNumber);
+ height = lcd.GetFontHeight();
+ }
}
// TODO WS1: if we overflow the command or directory string, we should probably offer a return value that tells the caller to do nothing...
@@ -325,6 +347,7 @@ void ValueMenuItem::Draw(Lcd7920& lcd, PixelNumber rightMargin, bool highlight,
highlighted = highlight;
PrintAligned(lcd, tOffset, rightMargin);
itemChanged = false;
+ drawn = true;
}
}
@@ -334,6 +357,16 @@ bool ValueMenuItem::Select(const StringRef& cmd)
return false;
}
+void ValueMenuItem::UpdateWidthAndHeight(Lcd7920& lcd)
+{
+ // The width is always set for a ValueMenuItem so we just need to determine the height
+ if (height == 0)
+ {
+ lcd.SetFont(fontNumber);
+ height = lcd.GetFontHeight();
+ }
+}
+
PixelNumber ValueMenuItem::GetVisibilityRowOffset(PixelNumber tCurrentOffset, PixelNumber fontHeight) const
{
// TODO
@@ -663,6 +696,7 @@ void FilesMenuItem::Draw(Lcd7920& lcd, PixelNumber rightMargin, bool highlight,
m_oMS->AbandonFindNext(); // release the mutex, there may be more files that we don't have room to display
itemChanged = false;
+ drawn = true;
highlighted = highlight;
}
}
@@ -813,6 +847,16 @@ bool FilesMenuItem::Select(const StringRef& cmd)
return false;
}
+void FilesMenuItem::UpdateWidthAndHeight(Lcd7920& lcd)
+{
+ // The width is always set for a FilesMenuItem so we just need to determine the height
+ if (height == 0)
+ {
+ lcd.SetFont(fontNumber);
+ height = lcd.GetFontHeight() * numDisplayLines;
+ }
+}
+
PixelNumber FilesMenuItem::GetVisibilityRowOffset(PixelNumber tCurrentOffset, PixelNumber fontHeight) const
{
// TODO
@@ -859,21 +903,23 @@ void ImageMenuItem::Draw(Lcd7920& lcd, PixelNumber rightMargin, bool highlight,
fs->Close();
}
itemChanged = false;
+ drawn = true;
highlighted = highlight;
}
}
-void ImageMenuItem::UpdateWidth(Lcd7920& lcd)
+void ImageMenuItem::UpdateWidthAndHeight(Lcd7920& lcd)
{
- if (width == 0)
+ if (width == 0 || height == 0)
{
FileStore * const fs = reprap.GetPlatform().OpenFile(MENU_DIR, fileName.c_str(), OpenMode::read);
if (fs != nullptr)
{
- uint8_t w;
- fs->Read(w); // read the number of columns
+ uint8_t w[2];
+ fs->Read(w, 2); // read the number of columns
fs->Close();
- width = w;
+ width = w[0];
+ height = w[1];
}
}
}
diff --git a/src/Display/MenuItem.h b/src/Display/MenuItem.h
index 1ca16c7c..7bba6fac 100644
--- a/src/Display/MenuItem.h
+++ b/src/Display/MenuItem.h
@@ -49,8 +49,11 @@ public:
// 'clicks' is the number of encoder clicks to adjust by, or 0 if the button was pushed.
virtual bool Adjust(int clicks) { return true; }
- // If the width was specified as zero, update it with the actual width
- virtual void UpdateWidth(Lcd7920& lcd) { }
+ // If the width was specified as zero, update it with the actual width. Also update the height.
+ virtual void UpdateWidthAndHeight(Lcd7920& lcd) = 0;
+
+ // DC: I don't know what this one is for, the person who wrote it didn't document it
+ virtual PixelNumber GetVisibilityRowOffset(PixelNumber tCurrentOffset, PixelNumber fontHeight) const { return 0; }
virtual ~MenuItem() { }
@@ -59,10 +62,12 @@ public:
void SetChanged() { itemChanged = true; }
bool IsVisible() const;
- virtual PixelNumber GetVisibilityRowOffset(PixelNumber tCurrentOffset, PixelNumber fontHeight) const { return 0; }
+ // Erase this item if it is drawn but should not be visible
+ void EraseIfInvisible(Lcd7920& lcd, PixelNumber tOffset);
// Return the width of this item in pixels
PixelNumber GetWidth() const { return width; }
+ PixelNumber GetHeight() const { return height; }
static void AppendToList(MenuItem **root, MenuItem *item);
@@ -77,13 +82,14 @@ protected:
void PrintAligned(Lcd7920& lcd, PixelNumber tOffset, PixelNumber rightMargin);
const PixelNumber row, column;
- PixelNumber width;
+ PixelNumber width, height;
const Alignment align;
const FontNumber fontNumber;
const Visibility visCase;
bool itemChanged;
bool highlighted;
+ bool drawn;
private:
MenuItem *next;
@@ -97,7 +103,7 @@ public:
TextMenuItem(PixelNumber r, PixelNumber c, PixelNumber w, Alignment a, FontNumber fn, Visibility vis, const char *t);
void Draw(Lcd7920& lcd, PixelNumber maxWidth, bool highlight, PixelNumber tOffset) override;
- void UpdateWidth(Lcd7920& lcd) override;
+ void UpdateWidthAndHeight(Lcd7920& lcd) override;
protected:
void CorePrint(Lcd7920& lcd) override;
@@ -114,7 +120,7 @@ public:
ButtonMenuItem(PixelNumber r, PixelNumber c, PixelNumber w, FontNumber fn, Visibility vis, const char *t, const char *cmd, const char *acFile);
void Draw(Lcd7920& lcd, PixelNumber maxWidth, bool highlight, PixelNumber tOffset) override;
- void UpdateWidth(Lcd7920& lcd) override;
+ void UpdateWidthAndHeight(Lcd7920& lcd) override;
bool Select(const StringRef& cmd) override;
PixelNumber GetVisibilityRowOffset(PixelNumber tCurrentOffset, PixelNumber fontHeight) const override;
@@ -139,6 +145,7 @@ public:
bool Select(const StringRef& cmd) override;
bool CanAdjust() override { return true; }
bool Adjust(int clicks) override;
+ void UpdateWidthAndHeight(Lcd7920& lcd) override;
PixelNumber GetVisibilityRowOffset(PixelNumber tCurrentOffset, PixelNumber fontHeight) const override;
@@ -175,6 +182,7 @@ public:
void Enter(bool bForwardDirection) override;
int Advance(int nCounts) override;
bool Select(const StringRef& cmd) override;
+ void UpdateWidthAndHeight(Lcd7920& lcd) override;
PixelNumber GetVisibilityRowOffset(PixelNumber tCurrentOffset, PixelNumber fontHeight) const override;
@@ -215,7 +223,7 @@ public:
ImageMenuItem(PixelNumber r, PixelNumber c, Visibility vis, const char *pFileName);
void Draw(Lcd7920& lcd, PixelNumber rightMargin, bool highlight, PixelNumber tOffset) override;
- void UpdateWidth(Lcd7920& lcd) override;
+ void UpdateWidthAndHeight(Lcd7920& lcd) override;
private:
String<MaxFilenameLength> fileName;
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index ac49c6a5..0d9c5c25 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -948,7 +948,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
break;
}
- g30zHeightError = moveBuffer.coords[Z_AXIS] - platform.ZProbeStopHeight();
+ g30zHeightError = moveBuffer.coords[Z_AXIS] - platform.GetZProbeStopHeight();
g30zHeightErrorSum += g30zHeightError;
}
@@ -1215,7 +1215,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
float m[MaxAxes];
reprap.GetMove().GetCurrentMachinePosition(m, false); // get height without bed compensation
g30zStoppedHeight = m[Z_AXIS] - g30HValue; // save for later
- g30zHeightError = g30zStoppedHeight - platform.ZProbeStopHeight();
+ g30zHeightError = g30zStoppedHeight - platform.GetZProbeStopHeight();
g30zHeightErrorSum += g30zHeightError;
}
}
@@ -1223,9 +1223,9 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
if (g30ProbePointIndex < 0) // if no P parameter
{
// Simple G30 probing move
- if (g30SValue == -1 || g30SValue == -2)
+ if (g30SValue == -1 || g30SValue == -2 || g30SValue == -3)
{
- // G30 S-1 command taps once and reports the height, S-2 sets the tool offset to the negative of the current height
+ // G30 S-1 command taps once and reports the height, S-2 sets the tool offset to the negative of the current height, S-3 sets the Z probe trigger height
gb.SetState(GCodeState::probingAtPoint7); // special state for reporting the stopped height at the end
if (platform.GetZProbeType() != ZProbeType::none && !probeIsDeployed)
{
@@ -1237,7 +1237,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
if (tapsDone == 1 && !hadProbingError)
{
// Reset the Z axis origin according to the height error so that we can move back up to the dive height
- moveBuffer.coords[Z_AXIS] = platform.ZProbeStopHeight();
+ moveBuffer.coords[Z_AXIS] = platform.GetZProbeStopHeight();
reprap.GetMove().SetNewPosition(moveBuffer.coords, false);
reprap.GetMove().SetZeroHeightError(moveBuffer.coords);
g30zHeightError = 0; // there is no longer any height error from this probe
@@ -1343,8 +1343,16 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
break;
case GCodeState::probingAtPoint7:
- // Here when we have finished executing G30 S-1 or S-2 including retracting the probe if necessary
- if (g30SValue == -2)
+ // Here when we have finished executing G30 S-1 or S-2 or S-3 including retracting the probe if necessary
+ if (g30SValue == -3)
+ {
+ // Adjust the Z probe trigger height to the stop height
+ ZProbe zp = platform.GetCurrentZProbeParameters();
+ zp.triggerHeight = g30zStoppedHeight;
+ platform.SetZProbeParameters(platform.GetZProbeType(), zp);
+ reply.printf("Z probe trigger height set to %.3f mm", (double)g30zStoppedHeight);
+ }
+ else if (g30SValue == -2)
{
// Adjust the Z offset of the current tool to account for the height error
Tool * const tool = reprap.GetCurrentTool();
@@ -3143,7 +3151,7 @@ GCodeResult GCodes::DoHome(GCodeBuffer& gb, const StringRef& reply)
// We already own the movement lock before this is called.
GCodeResult GCodes::ExecuteG30(GCodeBuffer& gb, const StringRef& reply)
{
- g30SValue = (gb.Seen('S')) ? gb.GetIValue() : -3; // S-3 is equivalent to having no S parameter
+ g30SValue = (gb.Seen('S')) ? gb.GetIValue() : -4; // S-4 or lower is equivalent to having no S parameter
if (g30SValue == -2 && reprap.GetCurrentTool() == nullptr)
{
reply.copy("G30 S-2 commanded with no tool selected");
@@ -3750,30 +3758,33 @@ bool GCodes::ChangeMicrostepping(size_t drive, unsigned int microsteps, bool int
}
// Set the speeds of fans mapped for the current tool to lastDefaultFanSpeed
-void GCodes::SetMappedFanSpeed()
+void GCodes::SetMappedFanSpeed(float f)
{
- if (reprap.GetCurrentTool() == nullptr)
+ lastDefaultFanSpeed = f;
+ const Tool * const ct = reprap.GetCurrentTool();
+ if (ct == nullptr)
{
- platform.SetFanValue(0, lastDefaultFanSpeed);
+ platform.SetFanValue(0, f);
}
else
{
- const uint32_t fanMap = reprap.GetCurrentTool()->GetFanMapping();
+ const uint32_t fanMap = ct->GetFanMapping();
for (size_t i = 0; i < NUM_FANS; ++i)
{
if (IsBitSet(fanMap, i))
{
- platform.SetFanValue(i, lastDefaultFanSpeed);
+ platform.SetFanValue(i, f);
}
}
}
}
-// Set the mapped fan speed
-void GCodes::SetMappedFanSpeed(float f)
+// Return true if this fan number is currently being used as a print cooling fan
+bool GCodes::IsMappedFan(unsigned int fanNumber)
{
- lastDefaultFanSpeed = f;
- SetMappedFanSpeed();
+ const Tool * const ct = reprap.GetCurrentTool();
+ return (ct == nullptr) ? fanNumber == 0
+ : IsBitSet(ct->GetFanMapping(), fanNumber);
}
// Save the speeds of all fans
diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h
index 3e5859dc..dceb4b3c 100644
--- a/src/GCodes/GCodes.h
+++ b/src/GCodes/GCodes.h
@@ -223,7 +223,7 @@ public:
#endif
float GetMappedFanSpeed() const { return lastDefaultFanSpeed; } // Get the mapped fan speed
- void SetMappedFanSpeed(float f); // Set the mapped fan speed
+ void SetMappedFanSpeed(float f); // Set the speeds of fans mapped for the current tool
void HandleReply(GCodeBuffer& gb, GCodeResult rslt, const char *reply); // Handle G-Code replies
void EmergencyStop(); // Cancel everything
bool GetLastPrintingHeight(float& height) const; // Get the height in user coordinates of the last printing move
@@ -350,7 +350,7 @@ private:
bool DoEmergencyPause(); // Do an emergency pause following loss of power or a motor stall
#endif
- void SetMappedFanSpeed(); // Set the speeds of fans mapped for the current tool
+ bool IsMappedFan(unsigned int fanNumber); // Return true if this fan number is currently being used as a print cooling fan
void SaveFanSpeeds(); // Save the speeds of all fans
GCodeResult SetOrReportZProbe(GCodeBuffer& gb, const StringRef &reply); // Handle M558
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index ea306a21..39a433e0 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -1243,6 +1243,10 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
if (seenFanNum)
{
platform.SetFanValue(fanNum, f);
+ if (IsMappedFan(fanNum))
+ {
+ lastDefaultFanSpeed = f;
+ }
}
else
{
@@ -1262,16 +1266,14 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
}
else
{
- lastDefaultFanSpeed = pausedDefaultFanSpeed;
- SetMappedFanSpeed();
+ SetMappedFanSpeed(pausedDefaultFanSpeed);
}
}
}
break;
case 107: // Fan off - deprecated
- lastDefaultFanSpeed = 0.0;
- SetMappedFanSpeed();
+ SetMappedFanSpeed(0.0);
break;
case 108: // Cancel waiting for temperature
@@ -3641,7 +3643,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
const KinematicsType oldK = move.GetKinematics().GetKinematicsType(); // get the current kinematics type so we can tell whether it changed
bool seen = false;
- bool changedToCartesian = false;
if (gb.Seen('S'))
{
// Switch to the correct CoreXY mode
@@ -3650,7 +3651,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
{
case 0:
move.SetKinematics(KinematicsType::cartesian);
- changedToCartesian = true;
break;
case 1:
@@ -3671,14 +3671,10 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
if (result == GCodeResult::ok)
{
- if (!changedToCartesian) // don't ask the kinematics to process M667 if we switched to Cartesian mode
+ if (gb.Seen('X') || gb.Seen('Y') || gb.Seen('Z'))
{
- bool error = false;
- if (move.GetKinematics().Configure(667, gb, reply, error))
- {
- seen = true;
- }
- result = GetGCodeResultFromError(error);
+ reply.copy("M667 XYZ parameters are no longer supported, use M669 matrix parameters instead");
+ result = GCodeResult::error;
}
if (seen)
diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp
index 607365ac..ccd5e698 100644
--- a/src/Movement/DDA.cpp
+++ b/src/Movement/DDA.cpp
@@ -221,11 +221,11 @@ void DDA::DebugPrintAll() const
DebugPrint();
for (DriveMovement* dm = activeDMs; dm != nullptr; dm = dm->nextDM)
{
- dm->DebugPrint(isDeltaMovement);
+ dm->DebugPrint();
}
for (DriveMovement* dm = completedDMs; dm != nullptr; dm = dm->nextDM)
{
- dm->DebugPrint(isDeltaMovement);
+ dm->DebugPrint();
}
}
@@ -441,9 +441,9 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
// We use the Cartesian motion system to implement these moves, so the feed rate will be interpreted in Cartesian coordinates.
// This is wrong, we want the feed rate to apply to the drive that is moving the farthest.
float maxDistance = 0.0;
- for (size_t axis = 0; axis < DELTA_AXES; ++axis)
+ for (size_t axis = 0; axis < numTotalAxes; ++axis)
{
- if (normalisedDirectionVector[axis] > maxDistance)
+ if (k.GetMotionType(axis) == MotionType::segmentFreeDelta && normalisedDirectionVector[axis] > maxDistance)
{
maxDistance = normalisedDirectionVector[axis];
}
@@ -462,7 +462,7 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
// for diagonal moves. On other architectures, this is not OK and any movement in the XY plane should be limited on other ways.
if (doMotorMapping)
{
- k.LimitSpeedAndAcceleration(*this, normalisedDirectionVector, numVisibleAxes); // give the kinematics the chance to further restrict the speed and acceleration
+ k.LimitSpeedAndAcceleration(*this, normalisedDirectionVector, numVisibleAxes, continuousRotationShortcut); // give the kinematics the chance to further restrict the speed and acceleration
}
// 7. Calculate the provisional accelerate and decelerate distances and the top speed
@@ -741,6 +741,7 @@ LA_DEBUG;
}
// Try to push babystepping earlier in the move queue, returning the amount we pushed
+//TODO this won't work for CoreXZ, rotary delta, Kappa, or SCARA with Z crosstalk
float DDA::AdvanceBabyStepping(float amount)
{
DDA *cdda = this;
@@ -771,9 +772,12 @@ float DDA::AdvanceBabyStepping(float amount)
cdda->endCoordinates[Z_AXIS] += babySteppingDone;
if (cdda->isDeltaMovement)
{
- for (size_t tower = 0; tower < DELTA_AXES; ++tower)
+ for (size_t axis = 0; axis < reprap.GetGCodes().GetTotalAxes(); ++axis)
{
- cdda->endPoint[tower] += (int32_t)(babySteppingDone * reprap.GetPlatform().DriveStepsPerUnit(tower));
+ if (reprap.GetMove().GetKinematics().GetMotionType(axis) == MotionType::segmentFreeDelta)
+ {
+ cdda->endPoint[axis] += (int32_t)(babySteppingDone * reprap.GetPlatform().DriveStepsPerUnit(axis));
+ }
}
}
else
@@ -960,34 +964,47 @@ inline void DDA::AdjustAcceleration()
{
// Try to reduce the acceleration/deceleration of the move to cancel ringing
const float idealPeriod = reprap.GetMove().GetDRCperiod();
- const float accTime = (topSpeed - startSpeed)/acceleration;
- const bool adjustAcceleration =
- (accTime < idealPeriod && ((prev->state != DDAState::frozen && prev->state != DDAState::executing) || !prev->IsAccelerationMove()));
- float proposedAcceleration, proposedAccelDistance;
- if (adjustAcceleration)
- {
- proposedAcceleration = (topSpeed - startSpeed)/idealPeriod;
- proposedAccelDistance = (fsquare(topSpeed) - fsquare(startSpeed))/(2 * proposedAcceleration);
- }
- else
- {
- proposedAcceleration = acceleration;
- proposedAccelDistance = accelDistance;
- }
- const float decelTime = (topSpeed - endSpeed)/deceleration;
- const float adjustDeceleration =
- (decelTime < idealPeriod && (next->state != DDAState::provisional || !next->IsDecelerationMove()));
- float proposedDeceleration, proposedDecelDistance;
- if (adjustDeceleration)
+ float proposedAcceleration = acceleration, proposedAccelDistance = accelDistance;
+ bool adjustAcceleration = false;
+ if ((prev->state != DDAState::frozen && prev->state != DDAState::executing) || !prev->IsAccelerationMove())
{
- proposedDeceleration = (topSpeed - endSpeed)/idealPeriod;
- proposedDecelDistance = (fsquare(topSpeed) - fsquare(endSpeed))/(2 * proposedDeceleration);
+ const float accelTime = (topSpeed - startSpeed)/acceleration;
+ if (accelTime < idealPeriod)
+ {
+ proposedAcceleration = (topSpeed - startSpeed)/idealPeriod;
+ adjustAcceleration = true;
+ }
+ else if (accelTime < idealPeriod * 2)
+ {
+ proposedAcceleration = (topSpeed - startSpeed)/(idealPeriod * 2);
+ adjustAcceleration = true;
+ }
+ if (adjustAcceleration)
+ {
+ proposedAccelDistance = (fsquare(topSpeed) - fsquare(startSpeed))/(2 * proposedAcceleration);
+ }
}
- else
+
+ float proposedDeceleration = deceleration, proposedDecelDistance = decelDistance;
+ bool adjustDeceleration = false;
+ if (next->state != DDAState::provisional || !next->IsDecelerationMove())
{
- proposedDeceleration = deceleration;
- proposedDecelDistance = decelDistance;
+ const float decelTime = (topSpeed - endSpeed)/deceleration;
+ if (decelTime < idealPeriod)
+ {
+ proposedDeceleration = (topSpeed - endSpeed)/idealPeriod;
+ adjustDeceleration = true;
+ }
+ else if (decelTime < idealPeriod * 2)
+ {
+ proposedDeceleration = (topSpeed - endSpeed)/(idealPeriod * 2);
+ adjustDeceleration = true;
+ }
+ if (adjustDeceleration)
+ {
+ proposedDecelDistance = (fsquare(topSpeed) - fsquare(endSpeed))/(2 * proposedDeceleration);
+ }
}
if (adjustAcceleration || adjustDeceleration)
@@ -1111,8 +1128,6 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
params.zMovement = GetEndCoordinate(Z_AXIS, false) - prev->GetEndCoordinate(Z_AXIS, false);
#endif
params.dparams = static_cast<const LinearDeltaKinematics*>(&(reprap.GetMove().GetKinematics()));
- params.diagonalSquared = params.dparams->GetDiagonalSquared();
- params.a2b2D2 = params.a2plusb2 * params.diagonalSquared;
}
// Convert the accelerate/decelerate distances to times
@@ -1184,9 +1199,9 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[])
}
}
}
- else if (isDeltaMovement && drive < DELTA_AXES)
+ else if (isDeltaMovement && reprap.GetMove().GetKinematics().GetMotionType(drive) == MotionType::segmentFreeDelta)
{
- // On a delta we need to allocate a DM for all three towers even if there is no net movement
+ // On a delta we need to allocate a DM for all towers even if there is no net movement
DriveMovement* const pdm = DriveMovement::Allocate(drive, DMState::moving);
const int32_t delta = endPoint[drive] - prev->endPoint[drive];
pdm->totalSteps = labs(delta);
@@ -1778,7 +1793,7 @@ bool DDA::Step()
activeDMs = dm; // remove the chain from the list
while (dmToInsert != dm) // note that both of these may be nullptr
{
- const bool hasMoreSteps = (isDeltaMovement && dmToInsert->drive < DELTA_AXES)
+ const bool hasMoreSteps = (isDeltaMovement && dmToInsert->isDelta)
? dmToInsert->CalcNextStepTimeDelta(*this, true)
: dmToInsert->CalcNextStepTimeCartesian(*this, true);
DriveMovement * const nextToInsert = dmToInsert->nextDM;
@@ -1945,7 +1960,7 @@ void DDA::ReduceHomingSpeed()
DriveMovement* const pdm = FindDM(drive);
if (pdm != nullptr && pdm->state == DMState::moving)
{
- pdm->ReduceSpeed(*this, ProbingSpeedReductionFactor);
+ pdm->ReduceSpeed(ProbingSpeedReductionFactor);
}
}
}
diff --git a/src/Movement/DriveMovement.cpp b/src/Movement/DriveMovement.cpp
index ff38432f..222930ff 100644
--- a/src/Movement/DriveMovement.cpp
+++ b/src/Movement/DriveMovement.cpp
@@ -91,6 +91,7 @@ bool DriveMovement::PrepareCartesianAxis(const DDA& dda, const PrepParams& param
nextStepTime = 0;
stepInterval = 999999; // initialise to a large value so that we will calculate the time for just one step
stepsTillRecalc = 0; // so that we don't skip the calculation
+ isDelta = false;
return CalcNextStepTimeCartesian(dda, false);
}
@@ -101,7 +102,7 @@ bool DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params)
const float A = params.initialX - params.dparams->GetTowerX(drive);
const float B = params.initialY - params.dparams->GetTowerY(drive);
const float aAplusbB = A * dda.directionVector[X_AXIS] + B * dda.directionVector[Y_AXIS];
- const float dSquaredMinusAsquaredMinusBsquared = params.diagonalSquared - fsquare(A) - fsquare(B);
+ const float dSquaredMinusAsquaredMinusBsquared = params.dparams->GetDiagonalSquared(drive) - fsquare(A) - fsquare(B);
const float h0MinusZ0 = sqrtf(dSquaredMinusAsquaredMinusBsquared);
mp.delta.hmz0sK = roundS32(h0MinusZ0 * stepsPerMm * DriveMovement::K2);
mp.delta.minusAaPlusBbTimesKs = -roundS32(aAplusbB * stepsPerMm * DriveMovement::K2);
@@ -120,7 +121,7 @@ bool DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params)
{
// The distance to reversal is the solution to a quadratic equation. One root corresponds to the carriages being below the bed,
// the other root corresponds to the carriages being above the bed.
- const float drev = ((dda.directionVector[Z_AXIS] * sqrtf(params.a2b2D2 - fsquare(A * dda.directionVector[Y_AXIS] - B * dda.directionVector[X_AXIS])))
+ const float drev = ((dda.directionVector[Z_AXIS] * sqrtf(params.a2plusb2 * params.dparams->GetDiagonalSquared(drive) - fsquare(A * dda.directionVector[Y_AXIS] - B * dda.directionVector[X_AXIS])))
- aAplusbB)/params.a2plusb2;
if (drev > 0.0 && drev < dda.totalDistance) // if the reversal point is within range
{
@@ -181,6 +182,7 @@ bool DriveMovement::PrepareDeltaAxis(const DDA& dda, const PrepParams& params)
nextStepTime = 0;
stepInterval = 999999; // initialise to a large value so that we will calculate the time for just one step
stepsTillRecalc = 0; // so that we don't skip the calculation
+ isDelta = true;
return CalcNextStepTimeDelta(dda, false);
}
@@ -309,10 +311,11 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl
nextStepTime = 0;
stepInterval = 999999; // initialise to a large value so that we will calculate the time for just one step
stepsTillRecalc = 0; // so that we don't skip the calculation
+ isDelta = false;
return CalcNextStepTimeCartesian(dda, false);
}
-void DriveMovement::DebugPrint(bool isDeltaMovement) const
+void DriveMovement::DebugPrint() const
{
const size_t totalAxes = reprap.GetGCodes().GetTotalAxes();
char c = (drive < totalAxes) ? reprap.GetGCodes().GetAxisLetters()[drive] : (char)('0' + (drive - totalAxes));
@@ -323,7 +326,7 @@ void DriveMovement::DebugPrint(bool isDeltaMovement) const
c, (state == DMState::stepError) ? " ERR:" : ":", (direction) ? 'F' : 'B', totalSteps, nextStep, reverseStartStep, stepInterval,
twoDistanceToStopTimesCsquaredDivD);
- if (isDeltaMovement && drive < DELTA_AXES)
+ if (isDelta)
{
debugPrintf("hmz0sK=%" PRIi32 " minusAaPlusBbTimesKs=%" PRIi32 " dSquaredMinusAsquaredMinusBsquared=%" PRId64 "\n"
"2c2mmsda=%" PRIu64 "2c2mmsdd=%" PRIu64 " asdsk=%" PRIu32 " dsdsk=%" PRIu32 " mmstcdts=%" PRIu32 "\n",
@@ -573,9 +576,9 @@ pre(nextStep < totalSteps; stepsTillRecalc == 0)
}
// Reduce the speed of this movement. Called to reduce the homing speed when we detect we are near the endstop for a drive.
-void DriveMovement::ReduceSpeed(const DDA& dda, uint32_t inverseSpeedFactor)
+void DriveMovement::ReduceSpeed(uint32_t inverseSpeedFactor)
{
- if (dda.isDeltaMovement && drive < DELTA_AXES)
+ if (isDelta)
{
// Force the linear motion phase
mp.delta.accelStopDsK = 0;
diff --git a/src/Movement/DriveMovement.h b/src/Movement/DriveMovement.h
index 10a29761..8ab22dd4 100644
--- a/src/Movement/DriveMovement.h
+++ b/src/Movement/DriveMovement.h
@@ -111,9 +111,7 @@ struct PrepParams
float zMovement;
#endif
const LinearDeltaKinematics *dparams;
- float diagonalSquared;
float a2plusb2; // sum of the squares of the X and Y movement fractions
- float a2b2D2;
};
enum class DMState : uint8_t
@@ -136,8 +134,8 @@ public:
bool PrepareCartesianAxis(const DDA& dda, const PrepParams& params) __attribute__ ((hot));
bool PrepareDeltaAxis(const DDA& dda, const PrepParams& params) __attribute__ ((hot));
bool PrepareExtruder(const DDA& dda, const PrepParams& params, float& extrusionPending, float speedChange, bool doCompensation) __attribute__ ((hot));
- void ReduceSpeed(const DDA& dda, uint32_t inverseSpeedFactor);
- void DebugPrint(bool isDeltaMovement) const;
+ void ReduceSpeed(uint32_t inverseSpeedFactor);
+ void DebugPrint() const;
int32_t GetNetStepsLeft() const;
int32_t GetNetStepsTaken() const;
@@ -172,7 +170,8 @@ private:
uint8_t drive; // the drive that this DM controls
uint8_t microstepShift : 4, // log2 of the microstepping factor (for when we use dynamic microstepping adjustment)
direction : 1, // true=forwards, false=backwards
- fullCurrent : 1; // true if the drivers are set to the full current, false if they are set to the standstill current
+ fullCurrent : 1, // true if the drivers are set to the full current, false if they are set to the standstill current
+ isDelta : 1; // true if this DM uses segment-free delta kinematics
uint8_t stepsTillRecalc; // how soon we need to recalculate
uint32_t totalSteps; // total number of steps for this move
diff --git a/src/Movement/Kinematics/CoreKinematics.cpp b/src/Movement/Kinematics/CoreKinematics.cpp
index 1be02488..6e6c5fe0 100644
--- a/src/Movement/Kinematics/CoreKinematics.cpp
+++ b/src/Movement/Kinematics/CoreKinematics.cpp
@@ -68,10 +68,12 @@ void CoreKinematics::Recalc()
for (size_t axis = 0; axis < MaxAxes; ++axis)
{
+ motorsUsedByAxis[axis] = 0;
for (size_t motor = 0; motor < MaxAxes; ++motor)
{
if (inverseMatrix(axis, motor) != 0.0)
{
+ SetBit(motorsUsedByAxis[axis], motor);
if (motor < firstMotor[axis])
{
firstMotor[axis] = motor;
@@ -236,16 +238,6 @@ bool CoreKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const String
bool seen;
switch (mCode)
{
- case 667:
- seen = gb.Seen('S');
- if (gb.Seen('X') || gb.Seen('Y') || gb.Seen('Z'))
- {
- seen = true;
- error = true;
- reply.copy("M667 XYZ parameters are no longer supported. Please use M669 matrix paramerters instead.");
- }
- break;
-
case 669:
{
seen = gb.Seen('K');
@@ -388,7 +380,7 @@ void CoreKinematics::OnHomingSwitchTriggered(size_t axis, bool highEnd, const fl
// Limit the speed and acceleration of a move to values that the mechanics can handle
// The speeds along individual Cartesian axes have already been limited before this is called, so we need only be concerned with shared motors
-void CoreKinematics::LimitSpeedAndAcceleration(DDA& dda, const float* normalisedDirectionVector, size_t numVisibleAxes) const
+void CoreKinematics::LimitSpeedAndAcceleration(DDA& dda, const float* normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const
{
// For each shared motor, calculate how much of the total move it contributes
float motorMovements[MaxAxes];
@@ -426,4 +418,11 @@ void CoreKinematics::LimitSpeedAndAcceleration(DDA& dda, const float* normalised
}
}
+// Return a bitmap of the motors that are involved in homing a particular axis or tower. Used for implementing stall detection endstops.
+// Usually it is just the corresponding motor (hence this default implementation), but CoreXY and similar kinematics move multiple motors to home an individual axis.
+AxesBitmap CoreKinematics::MotorsUsedToHomeAxis(size_t axis) const
+{
+ return motorsUsedByAxis[axis];
+}
+
// End
diff --git a/src/Movement/Kinematics/CoreKinematics.h b/src/Movement/Kinematics/CoreKinematics.h
index 1eccf5df..6d1c2778 100644
--- a/src/Movement/Kinematics/CoreKinematics.h
+++ b/src/Movement/Kinematics/CoreKinematics.h
@@ -24,14 +24,19 @@ public:
bool QueryTerminateHomingMove(size_t axis) const override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const override;
HomingMode GetHomingMode() const override { return homeCartesianAxes; }
- void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const override;
+ void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const override;
+ AxesBitmap MotorsUsedToHomeAxis(size_t axis) const override;
private:
void Recalc(); // recalculate internal variables following a configuration change
bool HasSharedMotor(size_t axis) const; // return true if the axis doesn't have a single dedicated motor
+ // Primary parameters
FixedMatrix<float, MaxAxes, MaxAxes> inverseMatrix; // maps coordinates to motor positions
+
+ // Derived parameters
FixedMatrix<float, MaxAxes, MaxAxes> forwardMatrix; // maps motor positions to coordinates
+ AxesBitmap motorsUsedByAxis[MaxAxes]; // which motors are used to move each axis
AxesBitmap axesWithSharedMotors; // bitmap of axes without exclusive control of the corresponding motor, or that use other motors
bool modified; // true if matrix has been altered
uint8_t firstMotor[MaxAxes], lastMotor[MaxAxes]; // first and last motor used by each axis
diff --git a/src/Movement/Kinematics/HangprinterKinematics.cpp b/src/Movement/Kinematics/HangprinterKinematics.cpp
index d92c071b..f727c33f 100644
--- a/src/Movement/Kinematics/HangprinterKinematics.cpp
+++ b/src/Movement/Kinematics/HangprinterKinematics.cpp
@@ -269,7 +269,7 @@ AxesBitmap HangprinterKinematics::MustBeHomedAxes(AxesBitmap axesMoving, bool di
// Limit the speed and acceleration of a move to values that the mechanics can handle.
// The speeds in Cartesian space have already been limited.
-void HangprinterKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const
+void HangprinterKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const
{
// Limit the speed in the XY plane to the lower of the X and Y maximum speeds, and similarly for the acceleration
const float xyFactor = sqrtf(fsquare(normalisedDirectionVector[X_AXIS]) + fsquare(normalisedDirectionVector[Y_AXIS]));
diff --git a/src/Movement/Kinematics/HangprinterKinematics.h b/src/Movement/Kinematics/HangprinterKinematics.h
index a524e3b1..a9a43b18 100644
--- a/src/Movement/Kinematics/HangprinterKinematics.h
+++ b/src/Movement/Kinematics/HangprinterKinematics.h
@@ -37,7 +37,7 @@ public:
bool QueryTerminateHomingMove(size_t axis) const override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const override;
bool WriteResumeSettings(FileStore *f) const override;
- void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const override;
+ void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const override;
private:
static constexpr float DefaultSegmentsPerSecond = 100.0;
diff --git a/src/Movement/Kinematics/Kinematics.cpp b/src/Movement/Kinematics/Kinematics.cpp
index 0835222a..f0e7dbbc 100644
--- a/src/Movement/Kinematics/Kinematics.cpp
+++ b/src/Movement/Kinematics/Kinematics.cpp
@@ -130,11 +130,17 @@ AxesBitmap Kinematics::GetHomingFileName(AxesBitmap toBeHomed, AxesBitmap alread
return homeFirst & ~alreadyHomed;
}
+// Return a bitmap of the motors that are involved in homing a particular axis or tower. Used for implementing stall detection endstops.
+// Usually it is just the corresponding motor (hence this default implementation), but CoreXY and similar kinematics move multiple motors to home an individual axis.
+AxesBitmap Kinematics::MotorsUsedToHomeAxis(size_t axis) const
+{
+ return MakeBitmap<AxesBitmap>(axis);
+}
+
/*static*/ Kinematics *Kinematics::Create(KinematicsType k)
{
switch (k)
{
- case KinematicsType::linearDeltaPlusZ: // not implemented yet
default:
return nullptr;
diff --git a/src/Movement/Kinematics/Kinematics.h b/src/Movement/Kinematics/Kinematics.h
index 56f05318..d04d1579 100644
--- a/src/Movement/Kinematics/Kinematics.h
+++ b/src/Movement/Kinematics/Kinematics.h
@@ -29,7 +29,7 @@ enum class KinematicsType : uint8_t
hangprinter,
polar,
coreXYUV,
- linearDeltaPlusZ, // reserved for @sga, see https://forum.duet3d.com/topic/5775/aditional-carterian-z-axis-on-delta-printer
+ reserved, // reserved for @sga, see https://forum.duet3d.com/topic/5775/aditional-carterian-z-axis-on-delta-printer
rotaryDelta, // not yet implemented
markForged,
@@ -166,11 +166,15 @@ public:
// Limit the speed and acceleration of a move to values that the mechanics can handle.
// The speeds along individual Cartesian axes have already been limited before this is called.
- virtual void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const = 0;
+ virtual void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const = 0;
// Return true if the specified axis is a continuous rotation axis
virtual bool IsContinuousRotationAxis(size_t axis) const { return false; }
+ // Return a bitmap of the motors that are involved in homing a particular axis or tower. Used for implementing stall detection endstops.
+ // Usually it is just the corresponding motor, but CoreXY and similar kinematics move multiple motors to home an individual axis.
+ virtual AxesBitmap MotorsUsedToHomeAxis(size_t axis) const;
+
// Override this virtual destructor if your constructor allocates any dynamic memory
virtual ~Kinematics() { }
diff --git a/src/Movement/Kinematics/LinearDeltaKinematics.cpp b/src/Movement/Kinematics/LinearDeltaKinematics.cpp
index a0b9b5cf..dab6612e 100644
--- a/src/Movement/Kinematics/LinearDeltaKinematics.cpp
+++ b/src/Movement/Kinematics/LinearDeltaKinematics.cpp
@@ -13,7 +13,7 @@
#include "GCodes/GCodeBuffer.h"
-LinearDeltaKinematics::LinearDeltaKinematics() : Kinematics(KinematicsType::linearDelta, -1.0, 0.0, true)
+LinearDeltaKinematics::LinearDeltaKinematics() : Kinematics(KinematicsType::linearDelta, -1.0, 0.0, true), numTowers(UsualNumTowers)
{
Init();
}
@@ -26,17 +26,21 @@ const char *LinearDeltaKinematics::GetName(bool forStatusReport) const
void LinearDeltaKinematics::Init()
{
- diagonal = DefaultDiagonal;
radius = DefaultDeltaRadius;
xTilt = yTilt = 0.0;
printRadius = DefaultPrintRadius;
homedHeight = DefaultDeltaHomedHeight;
doneAutoCalibration = false;
- for (size_t axis = 0; axis < DELTA_AXES; ++axis)
+ for (size_t axis = 0; axis < UsualNumTowers; ++axis)
{
angleCorrections[axis] = 0.0;
endstopAdjustments[axis] = 0.0;
+ }
+
+ for (size_t axis = 0; axis < MaxTowers; ++axis)
+ {
+ diagonals[axis] = DefaultDiagonal;
towerX[axis] = towerY[axis] = 0.0;
}
@@ -63,13 +67,24 @@ void LinearDeltaKinematics::Recalc()
coreFc = fsquare(towerX[DELTA_C_AXIS]) + fsquare(towerY[DELTA_C_AXIS]);
Q = (Xca * Yab - Xab * Yca) * 2;
Q2 = fsquare(Q);
- D2 = fsquare(diagonal);
- // Calculate the base carriage height when the printer is homed, i.e. the carriages are at the endstops less the corrections
- const float tempHeight = diagonal; // any sensible height will do here
- float machinePos[DELTA_AXES];
- ForwardTransform(tempHeight, tempHeight, tempHeight, machinePos);
- homedCarriageHeight = homedHeight + tempHeight - machinePos[Z_AXIS];
+ // Calculate the base carriage heights when the printer is homed, i.e. the carriages are at the endstops, and the always-reachable height
+ alwaysReachableHeight = homedHeight;
+ for (size_t axis = 0; axis < numTowers; ++axis)
+ {
+ D2[axis] = fsquare(diagonals[axis]);
+ homedCarriageHeights[axis] = homedHeight + sqrtf(D2[axis] - fsquare(radius));
+ if (axis < UsualNumTowers)
+ {
+ homedCarriageHeights[axis] += endstopAdjustments[axis];
+ const float heightLimit = homedCarriageHeights[axis] - diagonals[axis];
+ if (heightLimit < alwaysReachableHeight)
+ {
+ alwaysReachableHeight = heightLimit;
+ }
+ }
+ }
+
printRadiusSquared = fsquare(printRadius);
}
@@ -81,15 +96,14 @@ void LinearDeltaKinematics::NormaliseEndstopAdjustments()
endstopAdjustments[DELTA_B_AXIS] -= eav;
endstopAdjustments[DELTA_C_AXIS] -= eav;
homedHeight += eav;
- homedCarriageHeight += eav; // no need for a full recalc, this is sufficient
}
// Calculate the motor position for a single tower from a Cartesian coordinate.
float LinearDeltaKinematics::Transform(const float machinePos[], size_t axis) const
{
- if (axis < DELTA_AXES)
+ if (axis < numTowers)
{
- return sqrtf(D2 - fsquare(machinePos[X_AXIS] - towerX[axis]) - fsquare(machinePos[Y_AXIS] - towerY[axis]))
+ return sqrtf(D2[axis] - fsquare(machinePos[X_AXIS] - towerX[axis]) - fsquare(machinePos[Y_AXIS] - towerY[axis]))
+ machinePos[Z_AXIS]
+ (machinePos[X_AXIS] * xTilt)
+ (machinePos[Y_AXIS] * yTilt);
@@ -101,7 +115,7 @@ float LinearDeltaKinematics::Transform(const float machinePos[], size_t axis) co
}
// Calculate the Cartesian coordinates from the motor coordinates
-void LinearDeltaKinematics::ForwardTransform(float Ha, float Hb, float Hc, float machinePos[DELTA_AXES]) const
+void LinearDeltaKinematics::ForwardTransform(float Ha, float Hb, float Hc, float machinePos[XYZ_AXES]) const
{
const float Fa = coreFa + fsquare(Ha);
const float Fb = coreFb + fsquare(Hb);
@@ -117,7 +131,7 @@ void LinearDeltaKinematics::ForwardTransform(float Ha, float Hb, float Hc, float
const float A = U2 + R2 + Q2;
const float minusHalfB = S * U + P * R + Ha * Q2 + towerX[DELTA_A_AXIS] * U * Q - towerY[DELTA_A_AXIS] * R * Q;
- const float C = fsquare(S + towerX[DELTA_A_AXIS] * Q) + fsquare(P - towerY[DELTA_A_AXIS] * Q) + (fsquare(Ha) - D2) * Q2;
+ const float C = fsquare(S + towerX[DELTA_A_AXIS] * Q) + fsquare(P - towerY[DELTA_A_AXIS] * Q) + (fsquare(Ha) - D2[DELTA_A_AXIS]) * Q2;
const float z = (minusHalfB - sqrtf(fsquare(minusHalfB) - A * C)) / A;
machinePos[X_AXIS] = (U * z - S) / Q;
@@ -129,7 +143,7 @@ void LinearDeltaKinematics::ForwardTransform(float Ha, float Hb, float Hc, float
bool LinearDeltaKinematics::CartesianToMotorSteps(const float machinePos[], const float stepsPerMm[], size_t numVisibleAxes, size_t numTotalAxes, int32_t motorPos[], bool isCoordinated) const
{
bool ok = true;
- for (size_t axis = 0; axis < min<size_t>(numVisibleAxes, DELTA_AXES); ++axis)
+ for (size_t axis = 0; axis < min<size_t>(numVisibleAxes, numTowers); ++axis)
{
const float pos = Transform(machinePos, axis);
if (isnan(pos) || isinf(pos))
@@ -143,7 +157,7 @@ bool LinearDeltaKinematics::CartesianToMotorSteps(const float machinePos[], cons
}
// Transform any additional axes linearly
- for (size_t axis = DELTA_AXES; axis < numVisibleAxes; ++axis)
+ for (size_t axis = numTowers; axis < numVisibleAxes; ++axis)
{
motorPos[axis] = lrintf(machinePos[axis] * stepsPerMm[axis]);
}
@@ -156,7 +170,7 @@ void LinearDeltaKinematics::MotorStepsToCartesian(const int32_t motorPos[], cons
ForwardTransform(motorPos[DELTA_A_AXIS]/stepsPerMm[DELTA_A_AXIS], motorPos[DELTA_B_AXIS]/stepsPerMm[DELTA_B_AXIS], motorPos[DELTA_C_AXIS]/stepsPerMm[DELTA_C_AXIS], machinePos);
// Convert any additional axes linearly
- for (size_t drive = DELTA_AXES; drive < numVisibleAxes; ++drive)
+ for (size_t drive = numTowers; drive < numVisibleAxes; ++drive)
{
machinePos[drive] = motorPos[drive]/stepsPerMm[drive];
}
@@ -192,14 +206,17 @@ bool LinearDeltaKinematics::LimitPosition(float coords[], size_t numVisibleAxes,
coords[Z_AXIS] = reprap.GetPlatform().AxisMinimum(Z_AXIS);
limited = true;
}
- else
+ else if (coords[Z_AXIS] > alwaysReachableHeight)
{
- // Determine the maximum reachable height at this radius, in the worst case when the head is on a radius to a tower
- const float maxHeight = homedCarriageHeight - sqrtf(D2 - fsquare(radius - sqrtf(diagonalSquared)));
- if (coords[Z_AXIS] > maxHeight)
+ // Determine the maximum reachable height at this position
+ for (size_t tower = 0; tower < UsualNumTowers; ++tower)
{
- coords[Z_AXIS] = maxHeight;
- limited = true;
+ const float carriageHeight = Transform(coords, tower);
+ if (carriageHeight > homedCarriageHeights[tower])
+ {
+ coords[Z_AXIS] -= (carriageHeight - homedCarriageHeights[tower]);
+ limited = true;
+ }
}
}
}
@@ -246,13 +263,13 @@ bool LinearDeltaKinematics::DoAutoCalibration(size_t numFactors, const RandomPro
//uint32_t startTime = reprap.GetPlatform()->GetInterruptClocks();
// Transform the probing points to motor endpoints and store them in a matrix, so that we can do multiple iterations using the same data
- FixedMatrix<floatc_t, MaxCalibrationPoints, DELTA_AXES> probeMotorPositions;
+ FixedMatrix<floatc_t, MaxCalibrationPoints, UsualNumTowers> probeMotorPositions;
floatc_t corrections[MaxCalibrationPoints];
floatc_t initialSumOfSquares = 0.0;
for (size_t i = 0; i < numPoints; ++i)
{
corrections[i] = 0.0;
- float machinePos[DELTA_AXES];
+ float machinePos[XYZ_AXES];
const floatc_t zp = reprap.GetMove().GetProbeCoordinates(i, machinePos[X_AXIS], machinePos[Y_AXIS], probePoints.PointWasCorrected(i));
machinePos[Z_AXIS] = 0.0;
@@ -351,22 +368,22 @@ bool LinearDeltaKinematics::DoAutoCalibration(size_t numFactors, const RandomPro
}
// Save the old homed carriage heights before we change the endstop corrections
- float homedCarriageHeights[DELTA_AXES];
- for (size_t drive = 0; drive < DELTA_AXES; ++drive)
+ float oldHomedCarriageHeights[UsualNumTowers];
+ for (size_t drive = 0; drive < UsualNumTowers; ++drive)
{
- homedCarriageHeights[drive] = GetHomedCarriageHeight(drive);
+ oldHomedCarriageHeights[drive] = GetHomedCarriageHeight(drive);
}
Adjust(numFactors, solution); // adjust the delta parameters
- float heightAdjust[DELTA_AXES];
- for (size_t drive = 0; drive < DELTA_AXES; ++drive)
+ float heightAdjust[UsualNumTowers];
+ for (size_t drive = 0; drive < UsualNumTowers; ++drive)
{
- heightAdjust[drive] = GetHomedCarriageHeight(drive) - homedCarriageHeights[drive];
+ heightAdjust[drive] = GetHomedCarriageHeight(drive) - oldHomedCarriageHeights[drive];
}
// Adjust the motor endpoints to allow for the change to endstop adjustments
- reprap.GetMove().AdjustMotorPositions(heightAdjust, DELTA_AXES);
+ reprap.GetMove().AdjustMotorPositions(heightAdjust, UsualNumTowers);
// Calculate the expected probe heights using the new parameters
{
@@ -374,11 +391,11 @@ bool LinearDeltaKinematics::DoAutoCalibration(size_t numFactors, const RandomPro
floatc_t sumOfSquares = 0.0;
for (size_t i = 0; i < numPoints; ++i)
{
- for (size_t axis = 0; axis < DELTA_AXES; ++axis)
+ for (size_t axis = 0; axis < UsualNumTowers; ++axis)
{
probeMotorPositions(i, axis) += solution[axis];
}
- float newPosition[DELTA_AXES];
+ float newPosition[XYZ_AXES];
ForwardTransform(probeMotorPositions(i, DELTA_A_AXIS), probeMotorPositions(i, DELTA_B_AXIS), probeMotorPositions(i, DELTA_C_AXIS), newPosition);
corrections[i] = newPosition[Z_AXIS];
expectedResiduals[i] = probePoints.GetZHeight(i) + newPosition[Z_AXIS];
@@ -422,7 +439,7 @@ bool LinearDeltaKinematics::DoAutoCalibration(size_t numFactors, const RandomPro
// Return the type of motion computation needed by an axis
MotionType LinearDeltaKinematics::GetMotionType(size_t axis) const
{
- return (axis < DELTA_AXES) ? MotionType::segmentFreeDelta : MotionType::linear;
+ return (axis < numTowers) ? MotionType::segmentFreeDelta : MotionType::linear;
}
// Compute the derivative of height with respect to a parameter at the specified motor endpoints.
@@ -467,8 +484,11 @@ floatc_t LinearDeltaKinematics::ComputeDerivative(unsigned int deriv, float ha,
break;
case 6:
- hiParams.diagonal += perturb;
- loParams.diagonal -= perturb;
+ for (size_t tower = 0; tower < UsualNumTowers; ++tower)
+ {
+ hiParams.diagonals[tower] += perturb;
+ loParams.diagonals[tower] -= perturb;
+ }
hiParams.Recalc();
loParams.Recalc();
break;
@@ -479,7 +499,7 @@ floatc_t LinearDeltaKinematics::ComputeDerivative(unsigned int deriv, float ha,
break;
}
- float newPos[DELTA_AXES];
+ float newPos[XYZ_AXES];
hiParams.ForwardTransform((deriv == 0) ? ha + perturb : ha, (deriv == 1) ? hb + perturb : hb, (deriv == 2) ? hc + perturb : hc, newPos);
if (deriv == 7)
{
@@ -508,8 +528,6 @@ floatc_t LinearDeltaKinematics::ComputeDerivative(unsigned int deriv, float ha,
// Y tilt adjustment
void LinearDeltaKinematics::Adjust(size_t numFactors, const floatc_t v[])
{
- const float oldCarriageHeightA = GetHomedCarriageHeight(DELTA_A_AXIS); // save for later
-
// Update endstop adjustments
endstopAdjustments[DELTA_A_AXIS] += (float)v[0];
endstopAdjustments[DELTA_B_AXIS] += (float)v[1];
@@ -527,7 +545,10 @@ void LinearDeltaKinematics::Adjust(size_t numFactors, const floatc_t v[])
if (numFactors == 7 || numFactors == 9)
{
- diagonal += (float)v[6];
+ for (size_t tower = 0; tower < UsualNumTowers; ++tower)
+ {
+ diagonals[tower] += (float)v[6];
+ }
}
if (numFactors == 8)
@@ -541,15 +562,9 @@ void LinearDeltaKinematics::Adjust(size_t numFactors, const floatc_t v[])
yTilt += (float)v[8]/printRadius;
}
}
-
- Recalc();
}
- // Adjusting the diagonal and the tower positions affects the homed carriage height.
- // We need to adjust homedHeight to allow for this, to get the change that was requested in the endstop corrections.
- const float heightError = GetHomedCarriageHeight(DELTA_A_AXIS) - oldCarriageHeightA - (float)v[0];
- homedHeight -= heightError;
- homedCarriageHeight -= heightError;
+ Recalc();
// Note: if we adjusted the X and Y tilts, and there are any endstop adjustments, then the homed position won't be exactly in the centre
// and changing the tilt will therefore affect the homed height. We ignore this for now. If it is ever significant, a second autocalibration
@@ -559,9 +574,16 @@ void LinearDeltaKinematics::Adjust(size_t numFactors, const floatc_t v[])
// Print all the parameters for debugging
void LinearDeltaKinematics::PrintParameters(const StringRef& reply) const
{
- reply.printf("Stops X%.3f Y%.3f Z%.3f height %.3f diagonal %.3f radius %.3f xcorr %.2f ycorr %.2f zcorr %.2f xtilt %.3f%% ytilt %.3f%%\n",
- (double)endstopAdjustments[DELTA_A_AXIS], (double)endstopAdjustments[DELTA_B_AXIS], (double)endstopAdjustments[DELTA_C_AXIS], (double)homedHeight, (double)diagonal, (double)radius,
- (double)angleCorrections[DELTA_A_AXIS], (double)angleCorrections[DELTA_B_AXIS], (double)angleCorrections[DELTA_C_AXIS], (double)(xTilt * 100.0), (double)(yTilt * 100.0));
+ reply.printf("Stops X%.3f Y%.3f Z%.3f height %.3f diagonals",
+ (double)endstopAdjustments[DELTA_A_AXIS], (double)endstopAdjustments[DELTA_B_AXIS], (double)endstopAdjustments[DELTA_C_AXIS], (double)homedHeight);
+ for (size_t tower = 0; tower < numTowers; ++tower)
+ {
+ reply.catf("%c%.3f", (tower == 0) ? ' ' : ':', (double)diagonals[tower]);
+ }
+ reply.catf(" radius %.3f xcorr %.2f ycorr %.2f zcorr %.2f xtilt %.3f%% ytilt %.3f%%\n",
+ (double)radius,
+ (double)angleCorrections[DELTA_A_AXIS], (double)angleCorrections[DELTA_B_AXIS], (double)angleCorrections[DELTA_C_AXIS],
+ (double)(xTilt * 100.0), (double)(yTilt * 100.0));
}
// Write the parameters that are set by auto calibration to a file, returning true if success
@@ -571,8 +593,15 @@ bool LinearDeltaKinematics::WriteCalibrationParameters(FileStore *f) const
if (ok)
{
String<ScratchStringLength> scratchString;
- scratchString.printf("M665 L%.3f R%.3f H%.3f B%.1f X%.3f Y%.3f Z%.3f\n",
- (double)diagonal, (double)radius, (double)homedHeight, (double)printRadius, (double)angleCorrections[DELTA_A_AXIS], (double)angleCorrections[DELTA_B_AXIS], (double)angleCorrections[DELTA_C_AXIS]);
+ scratchString.copy("M665 ");
+ for (size_t tower = 0; tower < numTowers; ++tower)
+ {
+ scratchString.catf("%c%.3f", (tower == 0) ? 'L' : ':', (double)diagonals[tower]);
+ }
+
+ scratchString.catf(" R%.3f H%.3f B%.1f X%.3f Y%.3f Z%.3f\n",
+ (double)radius, (double)homedHeight, (double)printRadius,
+ (double)angleCorrections[DELTA_A_AXIS], (double)angleCorrections[DELTA_B_AXIS], (double)angleCorrections[DELTA_C_AXIS]);
ok = f->Write(scratchString.c_str());
if (ok)
{
@@ -605,7 +634,18 @@ bool LinearDeltaKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
case 665:
{
bool seen = false;
- gb.TryGetFValue('L', diagonal, seen);
+ if (gb.Seen('L'))
+ {
+ seen = true;
+ size_t numValues = MaxAxes;
+ gb.GetFloatArray(diagonals, numValues, false);
+ while (numValues < 3)
+ {
+ diagonals[numValues++] = diagonals[0];
+ }
+ numTowers = numValues;
+ }
+
gb.TryGetFValue('R', radius, seen);
if (gb.Seen('B'))
@@ -637,9 +677,14 @@ bool LinearDeltaKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
}
else
{
- reply.printf("Diagonal %.3f, delta radius %.3f, homed height %.3f, bed radius %.1f"
+ reply.copy("Diagonals");
+ for (size_t tower = 0; tower < numTowers; ++tower)
+ {
+ reply.catf("%c%.3f", (tower == 0) ? ' ' : ':', (double)diagonals[tower]);
+ }
+ reply.catf(", delta radius %.3f, homed height %.3f, bed radius %.1f"
", X %.3f" DEGREE_SYMBOL ", Y %.3f" DEGREE_SYMBOL ", Z %.3f" DEGREE_SYMBOL,
- (double)diagonal, (double)radius,
+ (double)radius,
(double)homedHeight, (double)printRadius,
(double)angleCorrections[DELTA_A_AXIS], (double)angleCorrections[DELTA_B_AXIS], (double)angleCorrections[DELTA_C_AXIS]);
}
@@ -673,6 +718,41 @@ bool LinearDeltaKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
return seen;
}
+ case 669:
+ {
+ // X and Y give the X and Y coordinates of the additional towers beyond the first three
+ // The correct number of L parameters must have been given in the M665 command first
+ size_t numX = 0, numY = 0;
+ if (gb.Seen('X'))
+ {
+ numX = MaxTowers - UsualNumTowers;
+ gb.GetFloatArray(towerX + UsualNumTowers, numX, false);
+ if (numX != numTowers - UsualNumTowers)
+ {
+ reply.copy("Wrong number of X values");
+ error = true;
+ return true;
+ }
+ }
+ if (gb.Seen('Y'))
+ {
+ numY = MaxTowers - UsualNumTowers;
+ gb.GetFloatArray(towerY + UsualNumTowers, numY, false);
+ if (numY != numTowers - UsualNumTowers)
+ {
+ reply.copy("Wrong number of Y values");
+ error = true;
+ return true;
+ }
+ }
+ if (numX != 0 || numY != 0)
+ {
+ Recalc(); // recalculate the homed carriage heights
+ return true;
+ }
+ return Kinematics::Configure(mCode, gb, reply, error);
+ }
+
default:
return Kinematics::Configure(mCode, gb, reply, error);
}
@@ -707,7 +787,7 @@ AxesBitmap LinearDeltaKinematics::MustBeHomedAxes(AxesBitmap axesMoving, bool di
AxesBitmap LinearDeltaKinematics::GetHomingFileName(AxesBitmap toBeHomed, AxesBitmap alreadyHomed, size_t numVisibleAxes, const StringRef& filename) const
{
// If homing X, Y or Z we must home all the towers
- if ((toBeHomed & LowestNBits<AxesBitmap>(DELTA_AXES)) != 0)
+ if ((toBeHomed & LowestNBits<AxesBitmap>(XYZ_AXES)) != 0)
{
filename.copy("homedelta.g");
return 0;
@@ -727,12 +807,11 @@ bool LinearDeltaKinematics::QueryTerminateHomingMove(size_t axis) const
// Take the action needed to define the current position, normally by calling dda.SetDriveCoordinate() and return false.
void LinearDeltaKinematics::OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const
{
- if (axis < DELTA_AXES)
+ if (axis < numTowers)
{
if (highEnd)
{
- const float hitPoint = GetHomedCarriageHeight(axis);
- dda.SetDriveCoordinate(lrintf(hitPoint * stepsPerMm[axis]), axis);
+ dda.SetDriveCoordinate(lrintf(homedCarriageHeights[axis] * stepsPerMm[axis]), axis);
}
}
else
@@ -745,7 +824,7 @@ void LinearDeltaKinematics::OnHomingSwitchTriggered(size_t axis, bool highEnd, c
// Limit the speed and acceleration of a move to values that the mechanics can handle.
// The speeds in Cartesian space have already been limited.
-void LinearDeltaKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const
+void LinearDeltaKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const
{
// Limit the speed in the XY plane to the lower of the X and Y maximum speeds, and similarly for the acceleration
const float xyFactor = sqrtf(fsquare(normalisedDirectionVector[X_AXIS]) + fsquare(normalisedDirectionVector[Y_AXIS]));
diff --git a/src/Movement/Kinematics/LinearDeltaKinematics.h b/src/Movement/Kinematics/LinearDeltaKinematics.h
index 99980317..4ea71815 100644
--- a/src/Movement/Kinematics/LinearDeltaKinematics.h
+++ b/src/Movement/Kinematics/LinearDeltaKinematics.h
@@ -11,8 +11,6 @@
#include "RepRapFirmware.h"
#include "Kinematics.h"
-constexpr size_t DELTA_AXES = 3;
-
// Class to hold the parameter for a delta machine.
class LinearDeltaKinematics : public Kinematics
{
@@ -43,13 +41,13 @@ public:
bool QueryTerminateHomingMove(size_t axis) const override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const override;
bool WriteResumeSettings(FileStore *f) const override;
- void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const override;
+ void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const override;
// Public functions specific to this class
- float GetDiagonalSquared() const { return D2; }
+ float GetDiagonalSquared(size_t tower) const { return D2[tower]; }
float GetTowerX(size_t axis) const { return towerX[axis]; }
float GetTowerY(size_t axis) const { return towerY[axis]; }
- float GetHomedCarriageHeight(size_t axis) const { return homedCarriageHeight + endstopAdjustments[axis]; }
+ float GetHomedCarriageHeight(size_t axis) const { return homedCarriageHeights[axis] + endstopAdjustments[axis]; }
float GetHomedHeight() const { return homedHeight; }
private:
@@ -57,12 +55,15 @@ private:
void Recalc();
void NormaliseEndstopAdjustments(); // Make the average of the endstop adjustments zero
float Transform(const float headPos[], size_t axis) const; // Calculate the motor position for a single tower from a Cartesian coordinate
- void ForwardTransform(float Ha, float Hb, float Hc, float headPos[]) const; // Calculate the Cartesian position from the motor positions
+ void ForwardTransform(float Ha, float Hb, float Hc, float headPos[XYZ_AXES]) const; // Calculate the Cartesian position from the motor positions
floatc_t ComputeDerivative(unsigned int deriv, float ha, float hb, float hc) const; // Compute the derivative of height with respect to a parameter at a set of motor endpoints
void Adjust(size_t numFactors, const floatc_t v[]); // Perform 3-, 4-, 6- or 7-factor adjustment
void PrintParameters(const StringRef& reply) const; // Print all the parameters for debugging
+ static constexpr size_t MaxTowers = 6; // maximum number of delta towers
+ static constexpr size_t UsualNumTowers = 3; // the usual number of towers, which are the ones we use for forward kinematics and the ones we calibrate
+
// Axis names used internally
static constexpr size_t DELTA_A_AXIS = 0;
static constexpr size_t DELTA_B_AXIS = 1;
@@ -75,22 +76,25 @@ private:
static constexpr float DefaultDeltaHomedHeight = 240.0;
// Core parameters
- float diagonal; // The diagonal rod length, all 3 are assumed to be the same length
+ size_t numTowers;
+ float diagonals[MaxTowers]; // The diagonal rod lengths
float radius; // The nominal delta radius, before any fine tuning of tower positions
- float angleCorrections[DELTA_AXES]; // Tower position corrections
- float endstopAdjustments[DELTA_AXES]; // How much above or below the ideal position each endstop is
+ float angleCorrections[UsualNumTowers]; // Tower position corrections for the first 3 axes
+ float endstopAdjustments[UsualNumTowers]; // How much above or below the ideal position each endstop is
float printRadius;
float homedHeight;
float xTilt, yTilt; // How much we need to raise Z for each unit of movement in the +X and +Y directions
// Derived values
- float towerX[DELTA_AXES]; // The X coordinate of each tower
- float towerY[DELTA_AXES]; // The Y coordinate of each tower
+ float towerX[MaxTowers]; // The X coordinate of each tower
+ float towerY[MaxTowers]; // The Y coordinate of each tower
float printRadiusSquared;
- float homedCarriageHeight;
+ float homedCarriageHeights[MaxTowers];
float Xbc, Xca, Xab, Ybc, Yca, Yab;
float coreFa, coreFb, coreFc;
- float Q, Q2, D2;
+ float Q, Q2;
+ float D2[MaxTowers];
+ float alwaysReachableHeight;
bool doneAutoCalibration; // True if we have done auto calibration
};
diff --git a/src/Movement/Kinematics/PolarKinematics.cpp b/src/Movement/Kinematics/PolarKinematics.cpp
index 5f891edf..e250eda4 100644
--- a/src/Movement/Kinematics/PolarKinematics.cpp
+++ b/src/Movement/Kinematics/PolarKinematics.cpp
@@ -257,13 +257,29 @@ void PolarKinematics::OnHomingSwitchTriggered(size_t axis, bool highEnd, const f
// Limit the speed and acceleration of a move to values that the mechanics can handle.
// The speeds in Cartesian space have already been limited.
-void PolarKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const
+void PolarKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const
{
- const int32_t turntableMovement = labs(dda.DriveCoordinates()[1] - dda.GetPrevious()->DriveCoordinates()[1]);
+ int32_t turntableMovement = labs(dda.DriveCoordinates()[1] - dda.GetPrevious()->DriveCoordinates()[1]);
if (turntableMovement != 0)
{
- const float stepRatio = dda.GetTotalDistance() * reprap.GetPlatform().DriveStepsPerUnit(1)/turntableMovement;
- dda.LimitSpeedAndAcceleration(stepRatio * maxTurntableSpeed, stepRatio * maxTurntableAcceleration);
+ const float stepsPerDegree = reprap.GetPlatform().DriveStepsPerUnit(1);
+ if (continuousRotationShortcut)
+ {
+ const int32_t stepsPerRotation = lrintf(360.0 * stepsPerDegree);
+ if (turntableMovement > stepsPerRotation/2)
+ {
+ turntableMovement -= stepsPerRotation;
+ }
+ else if (turntableMovement < -stepsPerRotation/2)
+ {
+ turntableMovement += stepsPerRotation;
+ }
+ }
+ if (turntableMovement != 0)
+ {
+ const float stepRatio = dda.GetTotalDistance() * stepsPerDegree/abs(turntableMovement);
+ dda.LimitSpeedAndAcceleration(stepRatio * maxTurntableSpeed, stepRatio * maxTurntableAcceleration);
+ }
}
}
diff --git a/src/Movement/Kinematics/PolarKinematics.h b/src/Movement/Kinematics/PolarKinematics.h
index 6a020a4a..c4d13c31 100644
--- a/src/Movement/Kinematics/PolarKinematics.h
+++ b/src/Movement/Kinematics/PolarKinematics.h
@@ -30,7 +30,7 @@ public:
AxesBitmap GetHomingFileName(AxesBitmap toBeHomed, AxesBitmap alreadyHomed, size_t numVisibleAxes, const StringRef& filename) const override;
bool QueryTerminateHomingMove(size_t axis) const override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const override;
- void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const override;
+ void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const override;
bool IsContinuousRotationAxis(size_t axis) const override;
private:
diff --git a/src/Movement/Kinematics/RotaryDeltaKinematics.cpp b/src/Movement/Kinematics/RotaryDeltaKinematics.cpp
index 2f25c521..ca274436 100644
--- a/src/Movement/Kinematics/RotaryDeltaKinematics.cpp
+++ b/src/Movement/Kinematics/RotaryDeltaKinematics.cpp
@@ -359,7 +359,7 @@ bool RotaryDeltaKinematics::WriteResumeSettings(FileStore *f) const
// Limit the speed and acceleration of a move to values that the mechanics can handle.
// The speeds in Cartesian space have already been limited.
-void RotaryDeltaKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const
+void RotaryDeltaKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const
{
// Limit the speed in the XY plane to the lower of the X and Y maximum speeds, and similarly for the acceleration
const float xyFactor = sqrtf(fsquare(normalisedDirectionVector[X_AXIS]) + fsquare(normalisedDirectionVector[Y_AXIS]));
diff --git a/src/Movement/Kinematics/RotaryDeltaKinematics.h b/src/Movement/Kinematics/RotaryDeltaKinematics.h
index f735fc17..c149068f 100644
--- a/src/Movement/Kinematics/RotaryDeltaKinematics.h
+++ b/src/Movement/Kinematics/RotaryDeltaKinematics.h
@@ -37,7 +37,7 @@ public:
bool QueryTerminateHomingMove(size_t axis) const override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const override;
bool WriteResumeSettings(FileStore *f) const override;
- void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const override;
+ void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const override;
private:
void Init();
diff --git a/src/Movement/Kinematics/ScaraKinematics.cpp b/src/Movement/Kinematics/ScaraKinematics.cpp
index e0e60786..9f51d9b6 100644
--- a/src/Movement/Kinematics/ScaraKinematics.cpp
+++ b/src/Movement/Kinematics/ScaraKinematics.cpp
@@ -22,7 +22,7 @@ ScaraKinematics::ScaraKinematics()
thetaLimits[1] = DefaultMaxTheta;
psiLimits[0] = DefaultMinPsi;
psiLimits[1] = DefaultMaxPsi;
- crosstalk[0] = crosstalk[1] = crosstalk[2] = 0.0;
+ crosstalk[0] = crosstalk[1] = crosstalk[2] = requestedMinRadius = 0.0;
Recalc();
}
@@ -195,6 +195,7 @@ bool ScaraKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const Strin
error = true;
return true;
}
+ gb.TryGetFValue('R', requestedMinRadius, seen);
if (seen || seenNonGeometry)
{
@@ -438,7 +439,7 @@ void ScaraKinematics::OnHomingSwitchTriggered(size_t axis, bool highEnd, const f
// Limit the speed and acceleration of a move to values that the mechanics can handle.
// The speeds in Cartesian space have already been limited.
-void ScaraKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const
+void ScaraKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const
{
// For now we limit the speed in the XY plane to the lower of the X and Y maximum speeds, and similarly for the acceleration.
// Limiting the angular rates of the arms would be better.
@@ -465,8 +466,9 @@ void ScaraKinematics::Recalc()
distalArmLengthSquared = fsquare(distalArmLength);
twoPd = proximalArmLength * distalArmLength * 2;
- minRadius = sqrtf(proximalArmLengthSquared + distalArmLengthSquared
- - twoPd * max<float>(cosf(psiLimits[0] * DegreesToRadians), cosf(psiLimits[1] * DegreesToRadians))) * 1.005;
+ minRadius = max<float>(sqrtf(proximalArmLengthSquared + distalArmLengthSquared
+ - twoPd * max<float>(cosf(psiLimits[0] * DegreesToRadians), cosf(psiLimits[1] * DegreesToRadians))) * 1.005,
+ requestedMinRadius);
// If the total angle range is greater than 360 degrees, we assume that it supports continuous rotation
supportsContinuousRotation[0] = (thetaLimits[1] - thetaLimits[0] > 360.0);
diff --git a/src/Movement/Kinematics/ScaraKinematics.h b/src/Movement/Kinematics/ScaraKinematics.h
index f9cc5740..beef3971 100644
--- a/src/Movement/Kinematics/ScaraKinematics.h
+++ b/src/Movement/Kinematics/ScaraKinematics.h
@@ -42,7 +42,7 @@ public:
AxesBitmap GetHomingFileName(AxesBitmap toBeHomed, AxesBitmap alreadyHomed, size_t numVisibleAxes, const StringRef& filename) const override;
bool QueryTerminateHomingMove(size_t axis) const override;
void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const override;
- void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes) const override;
+ void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector, size_t numVisibleAxes, bool continuousRotationShortcut) const override;
bool IsContinuousRotationAxis(size_t axis) const override;
private:
@@ -69,6 +69,7 @@ private:
float crosstalk[3]; // proximal to distal, proximal to X and distal to Z crosstalk
float xOffset; // where bed X=0 is relative to the proximal joint
float yOffset; // where bed Y=0 is relative to the proximal joint
+ float requestedMinRadius; // requested minimum radius
bool supportsContinuousRotation[2]; // true if the (proximal, distal) arms support continuous rotation
// Derived parameters
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 4182fe4d..c68a4ec0 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -747,7 +747,7 @@ int Platform::GetZProbeSecondaryValues(int& v1, int& v2)
}
// Get our best estimate of the Z probe temperature
-float Platform::GetZProbeTemperature()
+float Platform::GetZProbeTemperature() const
{
for (size_t i = 0; i < NumBedHeaters; i++)
{
@@ -765,7 +765,7 @@ float Platform::GetZProbeTemperature()
return 25.0; // assume 25C if we can't read the bed temperature
}
-float Platform::ZProbeStopHeight()
+float Platform::GetZProbeStopHeight() const
{
return GetCurrentZProbeParameters().GetStopHeight(GetZProbeTemperature());
}
@@ -2684,17 +2684,17 @@ void Platform::UpdateConfiguredHeaters()
}
}
-EndStopHit Platform::Stopped(size_t drive) const
+EndStopHit Platform::Stopped(size_t axisOrExtruder) const
{
const size_t numAxes = reprap.GetGCodes().GetTotalAxes();
- if (drive < numAxes)
+ if (axisOrExtruder < numAxes)
{
- switch (endStopInputType[drive])
+ switch (endStopInputType[axisOrExtruder])
{
case EndStopInputType::zProbe:
{
const EndStopHit rslt = GetZProbeResult();
- return (rslt == EndStopHit::lowHit && endStopPos[drive] == EndStopPosition::highEndStop)
+ return (rslt == EndStopHit::lowHit && endStopPos[axisOrExtruder] == EndStopPosition::highEndStop)
? EndStopHit::highHit
: rslt;
}
@@ -2702,65 +2702,40 @@ EndStopHit Platform::Stopped(size_t drive) const
#if HAS_STALL_DETECT
case EndStopInputType::motorStall:
{
- bool motorIsStalled;
- switch (reprap.GetMove().GetKinematics().GetKinematicsType())
+ bool motorIsStalled = false;
+ AxesBitmap motorsUsed = reprap.GetMove().GetKinematics().MotorsUsedToHomeAxis(axisOrExtruder);
+ for (size_t motor = 0; motorsUsed != 0; ++motor)
{
- case KinematicsType::coreXY:
- // Both X and Y motors are involved in homing X or Y
- motorIsStalled = (drive == X_AXIS || drive == Y_AXIS)
- ? AnyAxisMotorStalled(X_AXIS) || AnyAxisMotorStalled(Y_AXIS)
- : AnyAxisMotorStalled(drive);
- break;
-
- case KinematicsType::coreXYU:
- // Both X and Y motors are involved in homing X or Y, and both U and V motors are involved in homing U
- motorIsStalled = (drive == X_AXIS || drive == Y_AXIS)
- ? AnyAxisMotorStalled(X_AXIS) || AnyAxisMotorStalled(Y_AXIS)
- : (drive == U_AXIS)
- ? AnyAxisMotorStalled(U_AXIS) || AnyAxisMotorStalled(V_AXIS)
- : AnyAxisMotorStalled(drive);
- break;
-
- case KinematicsType::coreXYUV:
- // Both X and Y motors are involved in homing X or Y, and both U and V motors are involved in homing U and V
- motorIsStalled = (drive == X_AXIS || drive == Y_AXIS)
- ? AnyAxisMotorStalled(X_AXIS) || AnyAxisMotorStalled(Y_AXIS)
- : (drive == U_AXIS || drive == V_AXIS)
- ? AnyAxisMotorStalled(U_AXIS) || AnyAxisMotorStalled(V_AXIS)
- : AnyAxisMotorStalled(drive);
- break;
-
- case KinematicsType::coreXZ:
- // Both X and Z motors are involved in homing X or Z
- motorIsStalled = (drive == X_AXIS || drive == Z_AXIS)
- ? AnyAxisMotorStalled(X_AXIS) || AnyAxisMotorStalled(Z_AXIS)
- : AnyAxisMotorStalled(drive);
- break;
-
- default:
- motorIsStalled = AnyAxisMotorStalled(drive);
- break;
+ if (IsBitSet(motorsUsed, motor))
+ {
+ if (AnyAxisMotorStalled(motor))
+ {
+ motorIsStalled = true;
+ break;
+ }
+ ClearBit(motorsUsed, motor);
+ }
}
return (!motorIsStalled) ? EndStopHit::noStop
- : (endStopPos[drive] == EndStopPosition::highEndStop) ? EndStopHit::highHit
+ : (endStopPos[axisOrExtruder] == EndStopPosition::highEndStop) ? EndStopHit::highHit
: EndStopHit::lowHit;
}
break;
#endif
case EndStopInputType::activeLow:
- if (drive < NumEndstops && endStopPins[drive] != NoPin)
+ if (axisOrExtruder < NumEndstops && endStopPins[axisOrExtruder] != NoPin)
{
- const bool b = IoPort::ReadPin(endStopPins[drive]);
- return (b) ? EndStopHit::noStop : (endStopPos[drive] == EndStopPosition::highEndStop) ? EndStopHit::highHit : EndStopHit::lowHit;
+ const bool b = IoPort::ReadPin(endStopPins[axisOrExtruder]);
+ return (b) ? EndStopHit::noStop : (endStopPos[axisOrExtruder] == EndStopPosition::highEndStop) ? EndStopHit::highHit : EndStopHit::lowHit;
}
break;
case EndStopInputType::activeHigh:
- if (drive < NumEndstops && endStopPins[drive] != NoPin)
+ if (axisOrExtruder < NumEndstops && endStopPins[axisOrExtruder] != NoPin)
{
- const bool b = !IoPort::ReadPin(endStopPins[drive]);
- return (b) ? EndStopHit::noStop : (endStopPos[drive] == EndStopPosition::highEndStop) ? EndStopHit::highHit : EndStopHit::lowHit;
+ const bool b = !IoPort::ReadPin(endStopPins[axisOrExtruder]);
+ return (b) ? EndStopHit::noStop : (endStopPos[axisOrExtruder] == EndStopPosition::highEndStop) ? EndStopHit::highHit : EndStopHit::lowHit;
}
break;
@@ -2769,10 +2744,10 @@ EndStopHit Platform::Stopped(size_t drive) const
}
}
#if HAS_STALL_DETECT
- else if (drive < NumDirectDrivers)
+ else if (axisOrExtruder < NumDirectDrivers)
{
// Endstop is for an extruder drive, so use stall detection
- return (ExtruderMotorStalled(drive - numAxes)) ? EndStopHit::highHit : EndStopHit::noStop;
+ return (ExtruderMotorStalled(axisOrExtruder - numAxes)) ? EndStopHit::highHit : EndStopHit::noStop;
}
#endif
return EndStopHit::noStop;
diff --git a/src/Platform.h b/src/Platform.h
index 2f9aa7cf..817c3cdc 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -465,7 +465,7 @@ public:
// Z probe
void SetZProbeDefaults();
- float ZProbeStopHeight();
+ float GetZProbeStopHeight() const;
float GetZProbeDiveHeight() const;
float GetZProbeStartingHeight();
float GetZProbeTravelSpeed() const;
@@ -484,7 +484,7 @@ public:
void SetZProbeModState(bool b) const;
// Heat and temperature
- float GetZProbeTemperature(); // Get our best estimate of the Z probe temperature
+ float GetZProbeTemperature() const; // Get our best estimate of the Z probe temperature
volatile ThermistorAveragingFilter& GetAdcFilter(size_t channel)
pre(channel < ARRAY_SIZE(adcFilters))
diff --git a/src/RepRap.cpp b/src/RepRap.cpp
index 36a28934..3d532418 100644
--- a/src/RepRap.cpp
+++ b/src/RepRap.cpp
@@ -1075,8 +1075,8 @@ OutputBuffer *RepRap::GetStatusResponse(uint8_t type, ResponseSource source)
const int8_t bedHeater = (NumBedHeaters > 0) ? heat->GetBedHeater(0) : -1;
if (bedHeater != -1)
{
- response->catf("\"bed\":{\"current\":%.1f,\"active\":%.1f,\"state\":%d,\"heater\":%d},",
- (double)heat->GetTemperature(bedHeater), (double)heat->GetActiveTemperature(bedHeater),
+ response->catf("\"bed\":{\"current\":%.1f,\"active\":%.1f,\"standby\":%.1f,\"state\":%d,\"heater\":%d},",
+ (double)heat->GetTemperature(bedHeater), (double)heat->GetActiveTemperature(bedHeater), (double)heat->GetStandbyTemperature(bedHeater),
heat->GetStatus(bedHeater), bedHeater);
}
diff --git a/src/Version.h b/src/Version.h
index ad7b125f..cf228222 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -20,7 +20,7 @@
#endif
#ifndef DATE
-# define DATE "2019-01-16b2"
+# define DATE "2019-01-24b1"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d"