First implementation of the optimised maximum speed in any direction code. This is still buggy. To print with, use the previous release.

This commit is contained in:
Adrian Bowyer 2014-01-16 17:49:59 +00:00
parent eaeadd174b
commit 0ea1b57328
6 changed files with 173 additions and 65 deletions

View file

@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H
#define NAME "RepRapFirmware"
#define VERSION "0.59"
#define DATE "2014-01-15"
#define VERSION "0.60"
#define DATE "2014-01-16"
#define LAST_AUTHOR "reprappro.com"
// Other firmware that we might switch to be compatible with.

195
Move.cpp
View file

@ -179,15 +179,34 @@ void Move::Spin()
for(int8_t drive = 0; drive < DRIVES; drive++)
nextMachineEndPoints[drive] = LookAhead::EndPointToMachine(drive, nextMove[drive]);
int8_t movementType = GetMovementType(lastMove->MachineEndPoints(), nextMachineEndPoints);
float minS, maxS, maxA, steps;
int8_t axis;
//int8_t movementType = GetMovementType(lastMove->MachineEndPoints(), nextMachineEndPoints);
// Throw it away if there's no real movement.
if(movementType == noMove)
if(!MaxTruncatedProjection(lastMove->MachineEndPoints(), nextMachineEndPoints, platform->MaxFeedrate(), maxS, axis))
{
platform->ClassReport("Move", longWait);
return;
}
MaxTruncatedProjection(lastMove->MachineEndPoints(), nextMachineEndPoints, platform->InstantDv(), minS, axis);
MaxTruncatedProjection(lastMove->MachineEndPoints(), nextMachineEndPoints, platform->Acceleration(), maxA, axis);
steps = platform->DriveStepsPerUnit(axis);
SerialUSB.print("min, max, a and s: ");
SerialUSB.print(minS);
SerialUSB.print(" ");
SerialUSB.print(maxS);
SerialUSB.print(" ");
SerialUSB.print(maxA);
SerialUSB.print(" ");
SerialUSB.print(steps);
SerialUSB.print("\n");
// Real move - record its feedrate with it, not here.
@ -195,30 +214,30 @@ void Move::Spin()
// Promote minimum feedrates and restrict maximum feedrates; assumes xy overrides e overrides z FIXME??
float minS, maxS, maxA, steps;
if(movementType & xyMove)
{
minS = platform->InstantDv(X_AXIS);
maxS = platform->MaxFeedrate(X_AXIS); // Assumes X and Y are equal. FIXME?
maxA = platform->Acceleration(X_AXIS);
steps = platform->DriveStepsPerUnit(X_AXIS);
//platform->Message(HOST_MESSAGE, " xyMove\n");
} else if(movementType & eMove)
{
minS = platform->InstantDv(AXES);
maxS = platform->MaxFeedrate(AXES); // Picks up the value for the first extruder. FIXME?
maxA = platform->Acceleration(AXES);
steps = platform->DriveStepsPerUnit(AXES);
//platform->Message(HOST_MESSAGE, " eMove\n");
} else // Must be z
{
minS = platform->InstantDv(Z_AXIS);
maxS = platform->MaxFeedrate(Z_AXIS);
maxA = platform->Acceleration(Z_AXIS);
steps = platform->DriveStepsPerUnit(Z_AXIS);
//platform->Message(HOST_MESSAGE, " zMove\n");
}
//
//
// if(movementType & xyMove)
// {
// minS = platform->InstantDv(X_AXIS);
// maxS = platform->MaxFeedrate(X_AXIS); // Assumes X and Y are equal. FIXME?
// maxA = platform->Acceleration(X_AXIS);
//
// //platform->Message(HOST_MESSAGE, " xyMove\n");
// } else if(movementType & eMove)
// {
// minS = platform->InstantDv(AXES);
// maxS = platform->MaxFeedrate(AXES); // Picks up the value for the first extruder. FIXME?
// maxA = platform->Acceleration(AXES);
// steps = platform->DriveStepsPerUnit(AXES);
// //platform->Message(HOST_MESSAGE, " eMove\n");
// } else // Must be z
// {
// minS = platform->InstantDv(Z_AXIS);
// maxS = platform->MaxFeedrate(Z_AXIS);
// maxA = platform->Acceleration(Z_AXIS);
// steps = platform->DriveStepsPerUnit(Z_AXIS);
// //platform->Message(HOST_MESSAGE, " zMove\n");
// }
nextMove[DRIVES] = fmax(fmin(nextMove[DRIVES], maxS), minS);
@ -271,6 +290,70 @@ void Move::Diagnostics()
*/
}
/*
* Box[] is a constraint on a vector - say a list of maximum speeds for
* each axis. sp[] and ep[] are the start and end points of that vector.
* This finds the length of that vector such that it extends to the surface
* of the box. It then sets the length of the resulting vector. It also
* returns the axis corresponding to the longest component of vector.
*
* If the machine moves along the vector at that speed, then all the speeds along
* all the other directions are guaranteed not to lie outside the box.
*
* Note that this means that for, say, a diagonal move in X and Y with equal
* maxima along each axis, then the maximum speed returned will be sqrt(2) times
* that speed.
*
* The function returns true if input vector is not of 0 length.
*/
bool Move::MaxTruncatedProjection(long sp[], long ep[], float box[], float& length, int8_t& axis)
{
float vector[DRIVES];
long lVector;
float s;
float t = FLT_MAX; // Slight hack
int8_t drive;
for(drive = 0; drive < DRIVES; drive++)
{
lVector = labs(ep[drive] - sp[drive]);
if(lVector)
{
vector[drive] = MachineToPoint(lVector, drive);
s = box[drive]/vector[drive];
if(s < t)
t = s;
} else
vector[drive] = 0.0;
}
if(t == FLT_MAX) // No movement, so result doesn't matter. But safest not to set it to 0.
{
length = box[0];
return false;
}
length = 0.0;
s = vector[0];
axis = 0;
for(drive = 0; drive < DRIVES; drive++)
{
length += vector[drive]*vector[drive];
if(vector[drive] > s)
{
s = vector[drive];
axis = drive;
}
}
length = sqrt(length)*t;
return true;
}
// This returns false if it is not possible
// to use the result as the basis for the
// next move because the look ahead ring
@ -307,36 +390,36 @@ bool Move::GetCurrentState(float m[])
// for the bed's plane, which means that a move is MAINLY and XY move, or MAINLY a Z move. It
// is the main type of move that is returned.
int8_t Move::GetMovementType(long p0[], long p1[])
{
int8_t result = noMove;
long dxy = 0;
long dz = 0;
long d;
for(int8_t drive = 0; drive < DRIVES; drive++)
{
if(drive < AXES)
{
d = llabs(p1[drive] - p0[drive]);
if(drive == Z_AXIS)
dz = d;
else if(d > dxy)
dxy = d;
} else
{
if( p1[drive] )
result |= eMove;
}
}
dxy *= (long)roundf(platform->DriveStepsPerUnit(Z_AXIS)/platform->DriveStepsPerUnit(X_AXIS));
if(dxy > dz)
result |= xyMove;
else if(dz)
result |= zMove;
return result;
}
//int8_t Move::GetMovementType(long p0[], long p1[])
//{
// int8_t result = noMove;
// long dxy = 0;
// long dz = 0;
// long d;
//
// for(int8_t drive = 0; drive < DRIVES; drive++)
// {
// if(drive < AXES)
// {
// d = llabs(p1[drive] - p0[drive]);
// if(drive == Z_AXIS)
// dz = d;
// else if(d > dxy)
// dxy = d;
// } else
// {
// if( p1[drive] )
// result |= eMove;
// }
// }
// dxy *= (long)roundf(platform->DriveStepsPerUnit(Z_AXIS)/platform->DriveStepsPerUnit(X_AXIS));
// if(dxy > dz)
// result |= xyMove;
// else if(dz)
// result |= zMove;
//
// return result;
//}
void Move::SetStepHypotenuse()
{

15
Move.h
View file

@ -194,7 +194,7 @@ class Move
void Diagnostics();
float ComputeCurrentCoordinate(int8_t drive, LookAhead* la, DDA* runningDDA);
void SetStepHypotenuse();
float MachineToPoint(long steps, int8_t drive);
friend class DDA;
@ -211,7 +211,7 @@ class Move
bool LookAheadRingFull();
bool LookAheadRingAdd(long ep[], float feedRate, float vv, bool ce, float minS, float maxS, float maxA, float s);
LookAhead* LookAheadRingGet();
int8_t GetMovementType(long sp[], long ep[]);
bool MaxTruncatedProjection(long sp[], long ep[], float box[], float& length, int8_t& axis);
float liveCoordinates[DRIVES + 1];
@ -276,9 +276,7 @@ inline float LookAhead::V()
inline float LookAhead::MachineToEndPoint(int8_t drive)
{
if(drive >= DRIVES)
platform->Message(HOST_MESSAGE, "MachineToEndPoint() called for feedrate!\n");
return ((float)(endPoint[drive]))/platform->DriveStepsPerUnit(drive);
return move->MachineToPoint(endPoint[drive], drive);
}
@ -425,6 +423,13 @@ inline void Move::LiveCoordinates(float m[])
InverseTransform(m);
}
inline float Move::MachineToPoint(long steps, int8_t drive)
{
if(drive >= DRIVES)
platform->Message(HOST_MESSAGE, "MachineToPoint() called for feedrate!\n");
return ((float)(steps))/platform->DriveStepsPerUnit(drive);
}
// These are the actual numbers that we want to be the coordinates, so
// don't transform them.

View file

@ -407,7 +407,7 @@ void MassStorage::Init()
hsmciPinsinit();
// Initialize SD MMC stack
sd_mmc_init();
delay(20);
delay(5);
int sdPresentCount = 0;
while ((CTRL_NO_PRESENT == sd_mmc_check(0)) && (sdPresentCount < 5))
{

View file

@ -507,10 +507,15 @@ class Platform
void CoolingFan(float speed);
//void SetHeatOn(int8_t ho); //TEMPORARY - this will go away...
friend class Move;
//-------------------------------------------------------------------------------------------------------
protected:
void ReturnFileStore(FileStore* f);
void ReturnFileStore(FileStore* f);
float* Acceleration();
float* MaxFeedrate();
float* InstantDv();
private:
@ -720,6 +725,21 @@ inline float Platform::InstantDv(int8_t drive)
return instantDvs[drive];
}
inline float* Platform::Acceleration()
{
return accelerations;
}
inline float* Platform::MaxFeedrate()
{
return maxFeedrates;
}
inline float* Platform::InstantDv()
{
return instantDvs;
}
inline bool Platform::HighStopButNotLow(int8_t axis)
{
return (lowStopPins[axis] < 0) && (highStopPins[axis] >= 0);