Second degree (ruled quadratic surface) bed plane compensation added. Probe three points to get plane compensation. Probe 4 [0 = min, 1 = max: (x0, y0), (x0, y1), (x1, y1), (x1, y0) in that order] to get second degree compensation. Also M115 print version added.

This commit is contained in:
Adrian Bowyer 2013-12-03 14:41:49 +00:00
parent 820b17857a
commit 1a8ffb2d00
6 changed files with 113 additions and 34 deletions

View file

@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H #define CONFIGURATION_H
#define NAME "RepRapFirmware" #define NAME "RepRapFirmware"
#define VERSION "0.29" #define VERSION "0.30"
#define DATE "2013-12-01" #define DATE "2013-12-03"
#define LAST_AUTHOR "reprappro.com" #define LAST_AUTHOR "reprappro.com"
// Other firmware that we might switch to be compatible with. // Other firmware that we might switch to be compatible with.
@ -60,7 +60,7 @@ enum Compatibility
#define STANDBY_INTERRUPT_RATE 2.0e-4 // Seconds #define STANDBY_INTERRUPT_RATE 2.0e-4 // Seconds
#define NUMBER_OF_PROBE_POINTS 3 #define NUMBER_OF_PROBE_POINTS 4
#define Z_DIVE 5.0 // Height from which to probe the bed (mm) #define Z_DIVE 5.0 // Height from which to probe the bed (mm)
#define SILLY_Z_VALUE -9999.0 #define SILLY_Z_VALUE -9999.0

View file

@ -670,7 +670,7 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer *gb)
if(gb->Seen('S')) if(gb->Seen('S'))
{ {
zProbesSet = true; zProbesSet = true;
reprap.GetMove()->SetProbedBedPlane(); reprap.GetMove()->SetProbedBedEquation();
} }
return true; return true;
} else } else
@ -682,7 +682,7 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer *gb)
if(gb->Seen('S')) if(gb->Seen('S'))
{ {
zProbesSet = true; zProbesSet = true;
reprap.GetMove()->SetProbedBedPlane(); reprap.GetMove()->SetProbedBedEquation();
} }
return true; return true;
} }
@ -691,20 +691,20 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer *gb)
return false; return false;
} }
// This probes multiple points on the bed (usually three in a // This probes multiple points on the bed (three in a
// triangle), then sets the bed transformation to compensate // triangle or four in the corners), then sets the bed transformation to compensate
// for the bed not quite being the plane Z = 0. // for the bed not quite being the plane Z = 0.
bool GCodes::DoMultipleZProbe() bool GCodes::DoMultipleZProbe()
{ {
if(DoSingleZProbe()) if(DoSingleZProbe())
probeCount++; probeCount++;
if(probeCount >= NUMBER_OF_PROBE_POINTS) if(probeCount >= reprap.GetMove()->NumberOfProbePoints())
{ {
probeCount = 0; probeCount = 0;
zProbesSet = true; zProbesSet = true;
reprap.GetMove()->SetZProbing(false); reprap.GetMove()->SetZProbing(false);
reprap.GetMove()->SetProbedBedPlane(); reprap.GetMove()->SetProbedBedEquation();
return true; return true;
} }
return false; return false;
@ -1075,6 +1075,7 @@ void GCodes::HandleReply(bool error, bool fromLine, char* reply, char gMOrT, int
if( (gMOrT == 'M' && code == 105) || (gMOrT == 'G' && code == 998)) if( (gMOrT == 'M' && code == 105) || (gMOrT == 'G' && code == 998))
{ {
platform->GetLine()->Write(response); platform->GetLine()->Write(response);
platform->GetLine()->Write(" ");
platform->GetLine()->Write(reply); platform->GetLine()->Write(reply);
platform->GetLine()->Write("\n"); platform->GetLine()->Write("\n");
return; return;
@ -1340,6 +1341,10 @@ bool GCodes::ActOnGcode(GCodeBuffer *gb)
result = false; result = false;
break; break;
case 115: // Print firmware version
snprintf(reply, STRING_LENGTH, "FIRMWARE_NAME:%s FIRMWARE_VERSION:%s ELECTRONICS:%s DATE:%s", NAME, VERSION, ELECTRONICS, DATE);
break;
case 109: // Depricated case 109: // Depricated
if(gb->Seen('S')) if(gb->Seen('S'))
{ {

View file

@ -147,25 +147,20 @@ void Move::Init()
tanXY = 0.0; tanXY = 0.0;
tanYZ = 0.0; tanYZ = 0.0;
tanXZ = 0.0; tanXZ = 0.0;
zPlaneSet = false; zEquationSet = false;
lastZHit = 0.0; lastZHit = 0.0;
zProbing = false; zProbing = false;
xBedProbePoints[0] = 0.2*platform->AxisLength(X_AXIS); for(uint8_t point = 0; point < NUMBER_OF_PROBE_POINTS; point++)
yBedProbePoints[0] = 0.2*platform->AxisLength(Y_AXIS); {
zBedProbePoints[0] = 0.0; xBedProbePoints[point] = (0.2 + 0.6*(float)(point%2))*platform->AxisLength(X_AXIS);
probePointSet[0] = false; yBedProbePoints[point] = (0.2 + 0.6*(float)(point/2))*platform->AxisLength(Y_AXIS);
zBedProbePoints[point] = 0.0;
probePointSet[point] = unset;
}
xBedProbePoints[1] = 0.8*platform->AxisLength(X_AXIS); secondDegreeCompensation = false;
yBedProbePoints[1] = 0.2*platform->AxisLength(Y_AXIS);
zBedProbePoints[1] = 0.0;
probePointSet[1] = false;
xBedProbePoints[2] = 0.5*platform->AxisLength(X_AXIS);
yBedProbePoints[2] = 0.8*platform->AxisLength(Y_AXIS);
zBedProbePoints[2] = 0.0;
probePointSet[2] = false;
lastTime = platform->Time(); lastTime = platform->Time();
longWait = lastTime; longWait = lastTime;
@ -609,28 +604,64 @@ void Move::SetIdentityTransform()
aC = 0.0; aC = 0.0;
} }
void Move::Transform(float xyzPoint[]) void Move::Transform(float xyzPoint[])
{ {
xyzPoint[X_AXIS] = xyzPoint[X_AXIS] + tanXY*xyzPoint[Y_AXIS] + tanXZ*xyzPoint[Z_AXIS]; xyzPoint[X_AXIS] = xyzPoint[X_AXIS] + tanXY*xyzPoint[Y_AXIS] + tanXZ*xyzPoint[Z_AXIS];
xyzPoint[Y_AXIS] = xyzPoint[Y_AXIS] + tanYZ*xyzPoint[Z_AXIS]; xyzPoint[Y_AXIS] = xyzPoint[Y_AXIS] + tanYZ*xyzPoint[Z_AXIS];
if(secondDegreeCompensation)
xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] + SecondDegreeTransformZ(xyzPoint[X_AXIS], xyzPoint[Y_AXIS]);
else
xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] + aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC; xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] + aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC;
// platform->GetLine()->Write(xyzPoint[Y_AXIS]);
// platform->GetLine()->Write('\n');
} }
void Move::InverseTransform(float xyzPoint[]) void Move::InverseTransform(float xyzPoint[])
{ {
if(secondDegreeCompensation)
xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] - SecondDegreeTransformZ(xyzPoint[X_AXIS], xyzPoint[Y_AXIS]);
else
xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] - (aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC); xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] - (aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC);
xyzPoint[Y_AXIS] = xyzPoint[Y_AXIS] - tanYZ*xyzPoint[Z_AXIS]; xyzPoint[Y_AXIS] = xyzPoint[Y_AXIS] - tanYZ*xyzPoint[Z_AXIS];
xyzPoint[X_AXIS] = xyzPoint[X_AXIS] - (tanXY*xyzPoint[Y_AXIS] + tanXZ*xyzPoint[Z_AXIS]); xyzPoint[X_AXIS] = xyzPoint[X_AXIS] - (tanXY*xyzPoint[Y_AXIS] + tanXZ*xyzPoint[Z_AXIS]);
} }
void Move::SetProbedBedPlane() void Move::SetProbedBedEquation()
{ {
if(AllProbeCoordinatesSet(0) && AllProbeCoordinatesSet(1) && AllProbeCoordinatesSet(2))
{
secondDegreeCompensation = AllProbeCoordinatesSet(3);
if(secondDegreeCompensation)
{
/*
* Transform to a ruled-surface quadratic. The corner points for interpolation are indexed:
*
* ^ [1] [2]
* |
* Y
* |
* | [0] [3]
* -----X---->
*
* These are the scaling factors to apply to x and y coordinates to get them into the
* unit interval [0, 1].
*/
aX = 1.0/(xBedProbePoints[3] - xBedProbePoints[0]);
aY = 1.0/(yBedProbePoints[1] - yBedProbePoints[0]);
zEquationSet = true;
return;
}
} else
{
platform->Message(HOST_MESSAGE, "Attempt to set bed compensation before all probe points have been recorded.");
return;
}
float xkj, ykj, zkj; float xkj, ykj, zkj;
float xlj, ylj, zlj; float xlj, ylj, zlj;
float a, b, c, d; // Implicit plane equation - what we need to do a proper job float a, b, c, d; // Implicit plane equation - what we need to do a proper job
if(!probePointSet[0] || !probePointSet[1] || !probePointSet[2])
platform->Message(HOST_MESSAGE, "Attempt to set bed plane when probing is incomplete!\n");
xkj = xBedProbePoints[1] - xBedProbePoints[0]; xkj = xBedProbePoints[1] - xBedProbePoints[0];
ykj = yBedProbePoints[1] - yBedProbePoints[0]; ykj = yBedProbePoints[1] - yBedProbePoints[0];
zkj = zBedProbePoints[1] - zBedProbePoints[0]; zkj = zBedProbePoints[1] - zBedProbePoints[0];
@ -644,7 +675,7 @@ void Move::SetProbedBedPlane()
aX = -a/c; aX = -a/c;
aY = -b/c; aY = -b/c;
aC = -d/c; aC = -d/c;
zPlaneSet = true; zEquationSet = true;
} }
// FIXME // FIXME

47
Move.h
View file

@ -52,6 +52,14 @@ enum MovementType
eMove = 4 eMove = 4
}; };
enum PointCoordinateSet
{
unset = 0,
xSet = 1,
ySet = 2,
zSet = 4
};
class LookAhead class LookAhead
{ {
@ -166,8 +174,11 @@ class Move
float xBedProbePoint(int index); float xBedProbePoint(int index);
float yBedProbePoint(int index); float yBedProbePoint(int index);
float zBedProbePoint(int index); float zBedProbePoint(int index);
int NumberOfProbePoints();
bool AllProbeCoordinatesSet(int index);
void SetZProbing(bool probing); void SetZProbing(bool probing);
void SetProbedBedPlane(); void SetProbedBedEquation();
float SecondDegreeTransformZ(float x, float y);
float GetLastProbedZ(); float GetLastProbedZ();
void SetAxisCompensation(int8_t axis, float tangent); void SetAxisCompensation(int8_t axis, float tangent);
void SetIdentityTransform(); void SetIdentityTransform();
@ -225,12 +236,13 @@ class Move
float xBedProbePoints[NUMBER_OF_PROBE_POINTS]; float xBedProbePoints[NUMBER_OF_PROBE_POINTS];
float yBedProbePoints[NUMBER_OF_PROBE_POINTS]; float yBedProbePoints[NUMBER_OF_PROBE_POINTS];
float zBedProbePoints[NUMBER_OF_PROBE_POINTS]; float zBedProbePoints[NUMBER_OF_PROBE_POINTS];
bool probePointSet[NUMBER_OF_PROBE_POINTS]; uint8_t probePointSet[NUMBER_OF_PROBE_POINTS];
float aX, aY, aC; // Bed plane explicit equation z' = z + aX*x + aY*y + aC float aX, aY, aC; // Bed plane explicit equation z' = z + aX*x + aY*y + aC
bool zPlaneSet; bool zEquationSet;
float tanXY, tanYZ, tanXZ; // 90 degrees + angle gives angle between axes float tanXY, tanYZ, tanXZ; // 90 degrees + angle gives angle between axes
float lastZHit; float lastZHit;
bool zProbing; bool zProbing;
bool secondDegreeCompensation;
float longWait; float longWait;
}; };
@ -425,6 +437,7 @@ inline void Move::SetXBedProbePoint(int index, float x)
return; return;
} }
xBedProbePoints[index] = x; xBedProbePoints[index] = x;
probePointSet[index] |= xSet;
} }
inline void Move::SetYBedProbePoint(int index, float y) inline void Move::SetYBedProbePoint(int index, float y)
@ -435,6 +448,7 @@ inline void Move::SetYBedProbePoint(int index, float y)
return; return;
} }
yBedProbePoints[index] = y; yBedProbePoints[index] = y;
probePointSet[index] |= ySet;
} }
inline void Move::SetZBedProbePoint(int index, float z) inline void Move::SetZBedProbePoint(int index, float z)
@ -445,7 +459,7 @@ inline void Move::SetZBedProbePoint(int index, float z)
return; return;
} }
zBedProbePoints[index] = z; zBedProbePoints[index] = z;
probePointSet[index] = true; probePointSet[index] |= zSet;
} }
inline float Move::xBedProbePoint(int index) inline float Move::xBedProbePoint(int index)
@ -473,6 +487,31 @@ inline float Move::GetLastProbedZ()
return lastZHit; return lastZHit;
} }
inline bool Move::AllProbeCoordinatesSet(int index)
{
return probePointSet[index] == xSet | ySet | zSet;
}
/*
* Transform to a ruled-surface quadratic. The corner points for interpolation are indexed:
*
* ^ [1] [2]
* |
* Y
* |
* | [0] [3]
* -----X---->
*
* The values of x and y are transformed to put them in the interval [0, 1].
*/
inline float Move::SecondDegreeTransformZ(float x, float y)
{
x = (x - xBedProbePoints[0])*aX;
y = (y - yBedProbePoints[0])*aY;
return (1.0 - x)*(1.0 - y)*zBedProbePoints[0] + x*(1.0 - y)*zBedProbePoints[3] + (1.0 - x)*y*zBedProbePoints[1] + x*y*zBedProbePoints[2];
}
inline void Move::SetAxisCompensation(int8_t axis, float tangent) inline void Move::SetAxisCompensation(int8_t axis, float tangent)
{ {
switch(axis) switch(axis)

View file

@ -34,6 +34,10 @@ Licence: GPL
#ifndef PLATFORM_H #ifndef PLATFORM_H
#define PLATFORM_H #define PLATFORM_H
// What are we supposed to be running on
#define ELECTRONICS "Duet"
// Language-specific includes // Language-specific includes
#include <stdio.h> #include <stdio.h>

Binary file not shown.