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 NAME "RepRapFirmware"
#define VERSION "0.29"
#define DATE "2013-12-01"
#define VERSION "0.30"
#define DATE "2013-12-03"
#define LAST_AUTHOR "reprappro.com"
// 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 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 SILLY_Z_VALUE -9999.0

View file

@ -670,7 +670,7 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer *gb)
if(gb->Seen('S'))
{
zProbesSet = true;
reprap.GetMove()->SetProbedBedPlane();
reprap.GetMove()->SetProbedBedEquation();
}
return true;
} else
@ -682,7 +682,7 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer *gb)
if(gb->Seen('S'))
{
zProbesSet = true;
reprap.GetMove()->SetProbedBedPlane();
reprap.GetMove()->SetProbedBedEquation();
}
return true;
}
@ -691,20 +691,20 @@ bool GCodes::SetSingleZProbeAtAPosition(GCodeBuffer *gb)
return false;
}
// This probes multiple points on the bed (usually three in a
// triangle), then sets the bed transformation to compensate
// This probes multiple points on the bed (three in a
// triangle or four in the corners), then sets the bed transformation to compensate
// for the bed not quite being the plane Z = 0.
bool GCodes::DoMultipleZProbe()
{
if(DoSingleZProbe())
probeCount++;
if(probeCount >= NUMBER_OF_PROBE_POINTS)
if(probeCount >= reprap.GetMove()->NumberOfProbePoints())
{
probeCount = 0;
zProbesSet = true;
reprap.GetMove()->SetZProbing(false);
reprap.GetMove()->SetProbedBedPlane();
reprap.GetMove()->SetProbedBedEquation();
return true;
}
return false;
@ -1072,9 +1072,10 @@ void GCodes::HandleReply(bool error, bool fromLine, char* reply, char gMOrT, int
return;
}
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(" ");
platform->GetLine()->Write(reply);
platform->GetLine()->Write("\n");
return;
@ -1340,6 +1341,10 @@ bool GCodes::ActOnGcode(GCodeBuffer *gb)
result = false;
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
if(gb->Seen('S'))
{

View file

@ -147,25 +147,20 @@ void Move::Init()
tanXY = 0.0;
tanYZ = 0.0;
tanXZ = 0.0;
zPlaneSet = false;
zEquationSet = false;
lastZHit = 0.0;
zProbing = false;
xBedProbePoints[0] = 0.2*platform->AxisLength(X_AXIS);
yBedProbePoints[0] = 0.2*platform->AxisLength(Y_AXIS);
zBedProbePoints[0] = 0.0;
probePointSet[0] = false;
for(uint8_t point = 0; point < NUMBER_OF_PROBE_POINTS; point++)
{
xBedProbePoints[point] = (0.2 + 0.6*(float)(point%2))*platform->AxisLength(X_AXIS);
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);
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;
secondDegreeCompensation = false;
lastTime = platform->Time();
longWait = lastTime;
@ -609,28 +604,64 @@ void Move::SetIdentityTransform()
aC = 0.0;
}
void Move::Transform(float xyzPoint[])
{
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[Z_AXIS] = xyzPoint[Z_AXIS] + aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC;
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;
// platform->GetLine()->Write(xyzPoint[Y_AXIS]);
// platform->GetLine()->Write('\n');
}
void Move::InverseTransform(float xyzPoint[])
{
xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] - (aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC);
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[Y_AXIS] = xyzPoint[Y_AXIS] - tanYZ*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 xlj, ylj, zlj;
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];
ykj = yBedProbePoints[1] - yBedProbePoints[0];
zkj = zBedProbePoints[1] - zBedProbePoints[0];
@ -644,7 +675,7 @@ void Move::SetProbedBedPlane()
aX = -a/c;
aY = -b/c;
aC = -d/c;
zPlaneSet = true;
zEquationSet = true;
}
// FIXME

47
Move.h
View file

@ -52,6 +52,14 @@ enum MovementType
eMove = 4
};
enum PointCoordinateSet
{
unset = 0,
xSet = 1,
ySet = 2,
zSet = 4
};
class LookAhead
{
@ -166,8 +174,11 @@ class Move
float xBedProbePoint(int index);
float yBedProbePoint(int index);
float zBedProbePoint(int index);
int NumberOfProbePoints();
bool AllProbeCoordinatesSet(int index);
void SetZProbing(bool probing);
void SetProbedBedPlane();
void SetProbedBedEquation();
float SecondDegreeTransformZ(float x, float y);
float GetLastProbedZ();
void SetAxisCompensation(int8_t axis, float tangent);
void SetIdentityTransform();
@ -225,12 +236,13 @@ class Move
float xBedProbePoints[NUMBER_OF_PROBE_POINTS];
float yBedProbePoints[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
bool zPlaneSet;
bool zEquationSet;
float tanXY, tanYZ, tanXZ; // 90 degrees + angle gives angle between axes
float lastZHit;
bool zProbing;
bool secondDegreeCompensation;
float longWait;
};
@ -425,6 +437,7 @@ inline void Move::SetXBedProbePoint(int index, float x)
return;
}
xBedProbePoints[index] = x;
probePointSet[index] |= xSet;
}
inline void Move::SetYBedProbePoint(int index, float y)
@ -435,6 +448,7 @@ inline void Move::SetYBedProbePoint(int index, float y)
return;
}
yBedProbePoints[index] = y;
probePointSet[index] |= ySet;
}
inline void Move::SetZBedProbePoint(int index, float z)
@ -445,7 +459,7 @@ inline void Move::SetZBedProbePoint(int index, float z)
return;
}
zBedProbePoints[index] = z;
probePointSet[index] = true;
probePointSet[index] |= zSet;
}
inline float Move::xBedProbePoint(int index)
@ -473,6 +487,31 @@ inline float Move::GetLastProbedZ()
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)
{
switch(axis)

View file

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

Binary file not shown.