diff --git a/Configuration.h b/Configuration.h index 899a0a1..4ef8a62 100644 --- a/Configuration.h +++ b/Configuration.h @@ -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. diff --git a/Move.cpp b/Move.cpp index 2cc3147..11b1458 100644 --- a/Move.cpp +++ b/Move.cpp @@ -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() { diff --git a/Move.h b/Move.h index 123fcbe..f9b2884 100644 --- a/Move.h +++ b/Move.h @@ -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. diff --git a/Platform.cpp b/Platform.cpp index d03b82b..ac28853 100644 --- a/Platform.cpp +++ b/Platform.cpp @@ -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)) { diff --git a/Platform.h b/Platform.h index a274225..0962afc 100644 --- a/Platform.h +++ b/Platform.h @@ -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); diff --git a/Release/RepRapFirmware-058-14-01-2014.bin b/Release/RepRapFirmware-060-16-01-2014.bin similarity index 68% rename from Release/RepRapFirmware-058-14-01-2014.bin rename to Release/RepRapFirmware-060-16-01-2014.bin index fa59e76..9cdaedb 100755 Binary files a/Release/RepRapFirmware-058-14-01-2014.bin and b/Release/RepRapFirmware-060-16-01-2014.bin differ