diff options
author | David Crocker <dcrocker@eschertech.com> | 2018-08-12 22:18:02 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2018-08-12 22:18:02 +0300 |
commit | 635314b5043d3ae0617823dda7167b0b3551238b (patch) | |
tree | 437ab0bc4c0d53a08f6145c1b488c80b3c64cebe | |
parent | d7f876384aba6a66c77a9cd2507b051e8888fdc8 (diff) |
Version 2.02beta12.02beta1
Fixed issues with dynamic acceleration adjustment
More work on rotary delta kinematics
-rw-r--r-- | src/GCodes/GCodes2.cpp | 42 | ||||
-rw-r--r-- | src/Movement/DDA.cpp | 130 | ||||
-rw-r--r-- | src/Movement/DDA.h | 3 | ||||
-rw-r--r-- | src/Movement/DriveMovement.cpp | 3 | ||||
-rw-r--r-- | src/Movement/Kinematics/RotaryDeltaKinematics.cpp | 71 | ||||
-rw-r--r-- | src/Movement/Move.cpp | 70 | ||||
-rw-r--r-- | src/Movement/Move.h | 8 | ||||
-rw-r--r-- | src/Version.h | 2 |
8 files changed, 192 insertions, 137 deletions
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 0e4e598d..d0e1e392 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -1929,34 +1929,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) break; case 204: // Set max travel and printing accelerations - { - Move& move = reprap.GetMove(); - bool seen = false; - if (gb.Seen('S')) - { - // For backwards compatibility with old versions of Marlin (e.g. for Cura and the Prusa fork of slic3r), set both accelerations - const float acc = gb.GetFValue(); - move.SetMaxPrintingAcceleration(acc); - move.SetMaxTravelAcceleration(acc); - seen = true; - } - if (gb.Seen('P')) - { - move.SetMaxPrintingAcceleration(gb.GetFValue()); - seen = true; - } - if (gb.Seen('T')) - { - move.SetMaxTravelAcceleration(gb.GetFValue()); - seen = true; - } - if (!seen) - { - reply.printf("Maximum printing acceleration %.1f, maximum travel acceleration %.1f%s", - (double)move.GetMaxPrintingAcceleration(), (double)move.GetMaxTravelAcceleration(), - (move.IsDRCenabled()) ? " (both currently ignored because DRC is enabled)" : ""); - } - } + result = reprap.GetMove().ConfigureAccelerations(gb, reply); break; case 206: // Offset axes @@ -3671,18 +3644,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) #endif case 593: // Configure dynamic ringing cancellation - if (gb.Seen('F')) - { - reprap.GetMove().SetDRCfreq(gb.GetFValue()); - } - else if (reprap.GetMove().IsDRCenabled()) - { - reply.printf("Dynamic ringing cancellation at %.1fHz", (double)reprap.GetMove().GetDRCfreq()); - } - else - { - reply.copy("Dynamic ringing cancellation is disabled"); - } + result = reprap.GetMove().ConfigureDynamicAcceleration(gb, reply); break; case 665: // Set delta configuration diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp index d37a4a95..9ca2034c 100644 --- a/src/Movement/DDA.cpp +++ b/src/Movement/DDA.cpp @@ -394,18 +394,22 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping) xAxes = nextMove.xAxes; yAxes = nextMove.yAxes; endStopsToCheck = nextMove.endStopsToCheck; - canPauseAfter = nextMove.canPauseAfter; - usingStandardFeedrate = nextMove.usingStandardFeedrate; filePos = nextMove.filePos; - isPrintingMove = xyMoving && extruding; - usePressureAdvance = nextMove.usePressureAdvance; virtualExtruderPosition = nextMove.virtualExtruderPosition; proportionLeft = nextMove.proportionLeft; + canPauseAfter = nextMove.canPauseAfter; + usingStandardFeedrate = nextMove.usingStandardFeedrate; + isPrintingMove = xyMoving && extruding; + usePressureAdvance = nextMove.usePressureAdvance; hadLookaheadUnderrun = false; + hadHiccup = false; isLeadscrewAdjustmentMove = false; goingSlow = false; + // The end coordinates will be valid at the end of this move if it does not involve endstop checks and is not a raw motor move + endCoordinatesValid = (endStopsToCheck == 0) && doMotorMapping; + #if SUPPORT_IOBITS laserPwmOrIoBits = nextMove.laserPwmOrIoBits; #endif @@ -416,9 +420,6 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping) accelerations[Z_AXIS] = ZProbeMaxAcceleration; } - // The end coordinates will be valid at the end of this move if it does not involve endstop checks and is not a raw motor move - endCoordinatesValid = (endStopsToCheck == 0) && doMotorMapping; - // 4. Normalise the direction vector and compute the amount of motion. if (xyMoving) { @@ -448,11 +449,11 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping) } // 5. Compute the maximum acceleration available - float normalisedDirectionVector[DRIVES]; // Used to hold a unit-length vector in the direction of motion + float normalisedDirectionVector[DRIVES]; // used to hold a unit-length vector in the direction of motion memcpy(normalisedDirectionVector, directionVector, sizeof(normalisedDirectionVector)); Absolute(normalisedDirectionVector, DRIVES); acceleration = maxAcceleration = VectorBoxIntersection(normalisedDirectionVector, accelerations, DRIVES); - if (xyMoving && !move.IsDRCenabled()) // apply M204 acceleration limits to XY moves + if (xyMoving) // apply M204 acceleration limits to XY moves { acceleration = min<float>(acceleration, (isPrintingMove) ? move.GetMaxPrintingAcceleration() : move.GetMaxTravelAcceleration()); } @@ -556,17 +557,18 @@ bool DDA::Init(const float_t adjustments[DRIVES]) isDeltaMovement = false; isPrintingMove = false; xyMoving = false; - endStopsToCheck = 0; canPauseAfter = true; usingStandardFeedrate = false; usePressureAdvance = false; - virtualExtruderPosition = prev->virtualExtruderPosition; hadLookaheadUnderrun = false; + hadHiccup = false; + goingSlow = false; + endStopsToCheck = 0; + virtualExtruderPosition = prev->virtualExtruderPosition; xAxes = prev->xAxes; yAxes = prev->yAxes; filePos = prev->filePos; endCoordinatesValid = prev->endCoordinatesValid; - goingSlow = false; #if SUPPORT_LASER && SUPPORT_IOBITS if (reprap.GetGCodes().GetMachineType() == MachineType::laser) @@ -1051,67 +1053,118 @@ pre(disableDeltaMapping || drive < MaxAxes) } // Adjust the acceleration and deceleration to reduce ringing +// Only called if topSpeed > startSpeed & topSpeed > endSpeed // This is only called once, so inlined for speed 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 && accTime > 0.2 * idealPeriod && ((prev->state != DDAState::frozen && prev->state != DDAState::executing) || !prev->IsAccelerationMove())); + (accTime < idealPeriod && ((prev->state != DDAState::frozen && prev->state != DDAState::executing) || !prev->IsAccelerationMove())); + float proposedAcceleration, proposedAccelDistance; if (adjustAcceleration) { - acceleration = (topSpeed - startSpeed)/idealPeriod; - accelDistance = (fsquare(topSpeed) - fsquare(startSpeed))/(2 *acceleration); + 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 && decelTime > 0.2 * idealPeriod && (next->state != DDAState::provisional || !next->IsDecelerationMove())); + (decelTime < idealPeriod && (next->state != DDAState::provisional || !next->IsDecelerationMove())); + float proposedDeceleration, proposedDecelDistance; if (adjustDeceleration) { - deceleration = (topSpeed - endSpeed)/idealPeriod; - decelDistance = (fsquare(topSpeed) - fsquare(endSpeed))/(2 * deceleration); + proposedDeceleration = (topSpeed - endSpeed)/idealPeriod; + proposedDecelDistance = (fsquare(topSpeed) - fsquare(endSpeed))/(2 * proposedDeceleration); + } + else + { + proposedDeceleration = deceleration; + proposedDecelDistance = decelDistance; } if (adjustAcceleration || adjustDeceleration) { - if (accelDistance + decelDistance > totalDistance) + const float drcMinimumAcceleration = reprap.GetMove().GetDRCminimumAcceleration(); + if (proposedAccelDistance + proposedDecelDistance <= totalDistance) { - // We can't keep this as a trapezoidal move + if (proposedAcceleration < drcMinimumAcceleration || proposedDeceleration < drcMinimumAcceleration) + { + return; + } + acceleration = proposedAcceleration; + deceleration = proposedDeceleration; + accelDistance = proposedAccelDistance; + decelDistance = proposedDecelDistance; + } + else + { + // We can't keep this as a trapezoidal move with the original top speed. + // Try an accelerate-decelerate move with acceleration and deceleration times equal to the ideal period. const float twiceTotalDistance = 2 * totalDistance; - if (adjustAcceleration && adjustDeceleration && (startSpeed + endSpeed) * idealPeriod < totalDistance) + float proposedTopSpeed = totalDistance/idealPeriod - (startSpeed + endSpeed)/2; + if (proposedTopSpeed > startSpeed && proposedTopSpeed > endSpeed) { - // Change it into an accelerate-decelerate move with equal acceleration and deceleration times - acceleration = (twiceTotalDistance - (3 * startSpeed + endSpeed) * idealPeriod)/(2 * fsquare(idealPeriod)); - deceleration = (twiceTotalDistance - (startSpeed + 3 * endSpeed) * idealPeriod)/(2 * fsquare(idealPeriod)); - topSpeed = (totalDistance/idealPeriod) - (startSpeed + endSpeed)/2; + proposedAcceleration = (twiceTotalDistance - ((3 * startSpeed + endSpeed) * idealPeriod))/(2 * fsquare(idealPeriod)); + proposedDeceleration = (twiceTotalDistance - ((startSpeed + 3 * endSpeed) * idealPeriod))/(2 * fsquare(idealPeriod)); + if ( proposedAcceleration < drcMinimumAcceleration || proposedDeceleration < drcMinimumAcceleration + || proposedAcceleration > acceleration || proposedDeceleration > deceleration + ) + { + return; + } + topSpeed = proposedTopSpeed; + acceleration = proposedAcceleration; + deceleration = proposedDeceleration; accelDistance = startSpeed * idealPeriod + (acceleration * fsquare(idealPeriod))/2; decelDistance = endSpeed * idealPeriod + (deceleration * fsquare(idealPeriod))/2; } else if (startSpeed < endSpeed) { // Change it into an accelerate-only move, accelerating as slowly as we can - acceleration = (fsquare(endSpeed) - fsquare(startSpeed))/twiceTotalDistance; + proposedAcceleration = (fsquare(endSpeed) - fsquare(startSpeed))/twiceTotalDistance; + if (proposedAcceleration < drcMinimumAcceleration) + { + return; // avoid very small accelerations because they can be problematic + } + acceleration = proposedAcceleration; topSpeed = endSpeed; accelDistance = totalDistance; decelDistance = 0.0; } - else + else if (startSpeed > endSpeed) { // Change it into a decelerate-only move, decelerating as slowly as we can - deceleration = (fsquare(startSpeed) - fsquare(endSpeed))/twiceTotalDistance; + proposedDeceleration = (fsquare(startSpeed) - fsquare(endSpeed))/twiceTotalDistance; + if (proposedDeceleration < drcMinimumAcceleration) + { + return; // avoid very small accelerations because they can be problematic + } + deceleration = proposedDeceleration; topSpeed = startSpeed; accelDistance = 0.0; decelDistance = totalDistance; } + else + { + // Start and end speeds are exactly the same, possibly zero, so give up trying to adjust this move + return; + } } - const float totalTime = (topSpeed - startSpeed)/acceleration + (topSpeed - endSpeed)/deceleration + (totalDistance - accelDistance - decelDistance)/topSpeed; + + const float totalTime = (topSpeed - startSpeed)/acceleration + + (topSpeed - endSpeed)/deceleration + + (totalDistance - accelDistance - decelDistance)/topSpeed; clocksNeeded = (uint32_t)(totalTime * StepClockRate); if (reprap.Debug(moduleMove)) { - debugPrintf("New a=%f d=%f\n", (double)acceleration, (double)deceleration); + debugPrintf("New a=%.1f d=%.1f\n", (double)acceleration, (double)deceleration); } } } @@ -1171,7 +1224,7 @@ void DDA::Prepare(uint8_t simMode) const size_t numAxes = reprap.GetGCodes().GetTotalAxes(); for (size_t drive = 0; drive < DRIVES; ++drive) { - DriveMovement* const pdm = pddm[drive]; + DriveMovement* const pdm = FindDM(drive); if (pdm != nullptr && pdm->state == DMState::moving) { if (isLeadscrewAdjustmentMove) @@ -1209,7 +1262,8 @@ void DDA::Prepare(uint8_t simMode) && ( pdm->totalSteps > 1000000 || pdm->reverseStartStep < pdm->mp.cart.decelStartStep || (pdm->reverseStartStep <= pdm->totalSteps - && pdm->mp.cart.fourMaxStepDistanceMinusTwoDistanceToStopTimesCsquaredDivD > (int64_t)(pdm->mp.cart.twoCsquaredTimesMmPerStepDivD * pdm->reverseStartStep)) + && pdm->mp.cart.fourMaxStepDistanceMinusTwoDistanceToStopTimesCsquaredDivD > (int64_t)(pdm->mp.cart.twoCsquaredTimesMmPerStepDivD * pdm->reverseStartStep) + ) ) ) { @@ -1587,7 +1641,7 @@ pre(state == frozen) return true; // schedule another interrupt immediately } -uint32_t DDA::numHiccups = 0; +unsigned int DDA::numHiccups = 0; uint32_t DDA::lastStepLowTime = 0; uint32_t DDA::lastDirChangeTime = 0; @@ -1695,6 +1749,7 @@ bool DDA::Step() moveStartTime += delayClocks; nextStepDue += delayClocks; ++numHiccups; + hadHiccup = true; } // 8. Schedule next interrupt, or if it would be too soon, generate more steps immediately @@ -1819,6 +1874,13 @@ void DDA::ReduceHomingSpeed() bool DDA::HasStepError() const { +#if 0 //debug + if (hadHiccup) + { + return true; // temporary for debugging DAA + } +#endif + for (size_t drive = 0; drive < DRIVES; ++drive) { const DriveMovement* const pdm = FindDM(drive); diff --git a/src/Movement/DDA.h b/src/Movement/DDA.h index caaa7918..2e465436 100644 --- a/src/Movement/DDA.h +++ b/src/Movement/DDA.h @@ -130,7 +130,7 @@ public: static int32_t loggedProbePositions[XYZ_AXES * MaxLoggedProbePositions]; #endif - static uint32_t numHiccups; // how many times we delayed an interrupt to avoid using too much CPU time in interrupts + static unsigned int numHiccups; // how many times we delayed an interrupt to avoid using too much CPU time in interrupts static uint32_t lastStepLowTime; // when we last completed a step pulse to a slow driver static uint32_t lastDirChangeTime; // when we last change the DIR signal to a slow driver @@ -177,6 +177,7 @@ private: uint8_t goingSlow : 1; // True if we have slowed the movement because the Z probe is approaching its threshold uint8_t isLeadscrewAdjustmentMove : 1; // True if this is a leadscrews adjustment move uint8_t usingStandardFeedrate : 1; // True if this move uses the standard feed rate + uint8_t hadHiccup : 1; // True if we had a hiccup while executing this move }; uint16_t flags; // so that we can print all the flags at once for debugging }; diff --git a/src/Movement/DriveMovement.cpp b/src/Movement/DriveMovement.cpp index 7ebbc6c5..189b0d7c 100644 --- a/src/Movement/DriveMovement.cpp +++ b/src/Movement/DriveMovement.cpp @@ -78,8 +78,7 @@ void DriveMovement::PrepareCartesianAxis(const DDA& dda, const PrepParams& param else { mp.cart.decelStartStep = (uint32_t)(params.decelStartDistance * stepsPerMm) + 1; - const uint64_t initialDecelSpeedTimesCdivDSquared = isquare64(params.topSpeedTimesCdivD); - twoDistanceToStopTimesCsquaredDivD = initialDecelSpeedTimesCdivDSquared + roundU64((params.decelStartDistance * (StepClockRateSquared * 2))/dda.deceleration); + twoDistanceToStopTimesCsquaredDivD = isquare64(params.topSpeedTimesCdivD) + roundU64((params.decelStartDistance * (StepClockRateSquared * 2))/dda.deceleration); } // No reverse phase diff --git a/src/Movement/Kinematics/RotaryDeltaKinematics.cpp b/src/Movement/Kinematics/RotaryDeltaKinematics.cpp index 3b59d215..8323bbb8 100644 --- a/src/Movement/Kinematics/RotaryDeltaKinematics.cpp +++ b/src/Movement/Kinematics/RotaryDeltaKinematics.cpp @@ -77,14 +77,14 @@ bool RotaryDeltaKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const { bool seen = false; size_t numValues = 3; - if (gb.TryGetFloatArray('L', numValues, armLengths, reply, seen, true)) + if (gb.TryGetFloatArray('U', numValues, armLengths, reply, seen, true)) { error = true; return true; } numValues = 3; - if (gb.TryGetFloatArray('R', numValues, rodLengths, reply, seen, true)) + if (gb.TryGetFloatArray('L', numValues, rodLengths, reply, seen, true)) { error = true; return true; @@ -127,7 +127,7 @@ bool RotaryDeltaKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const } else { - reply.printf("Arms (%.3f,%.2f,%.3f)mm, rods (%.3f,%.3f,%.3f)mm, bearingHeights (%.3f,%.2f,%.3f)mm" + reply.printf("Kinematics is rotary delta, arms (%.3f,%.2f,%.3f)mm, rods (%.3f,%.3f,%.3f)mm, bearingHeights (%.3f,%.2f,%.3f)mm" ", arm movement %.1f to %.1f" DEGREE_SYMBOL ", delta radius %.3f, bed radius %.1f" ", angle corrections (%.3f,%.3f,%.3f)" DEGREE_SYMBOL , @@ -186,9 +186,10 @@ bool RotaryDeltaKinematics::CartesianToMotorSteps(const float machinePos[], cons // TEMP DEBUG if (reprap.Debug(moduleMove)) { - debugPrintf("Transformed %.2f,%.2f,%.2f mm to %" PRIi32 ",%" PRIi32 ",%" PRIi32 "steps\n", + debugPrintf("Transformed %.2f,%.2f,%.2f mm to %" PRIi32 ",%" PRIi32 ",%" PRIi32 " steps %s\n", (double)machinePos[0], (double)machinePos[1], (double)machinePos[2], - motorPos[0], motorPos[1], motorPos[2]); + motorPos[0], motorPos[1], motorPos[2], + (ok) ? "ok" : "fail"); } // Transform any additional axes linearly @@ -424,69 +425,43 @@ float RotaryDeltaKinematics::Transform(const float machinePos[], size_t axis) co void RotaryDeltaKinematics::ForwardTransform(float Ha, float Hb, float Hc, float machinePos[DELTA_AXES]) const { // Calculate the Cartesian coordinates of the joints at the moving ends of the arms - const float angleA = Ha * DegreesToRadians; + const float angleA = Ha * DegreesToRadians; const float posAX = (radius + (armLengths[DELTA_A_AXIS] * cosf(angleA))) * armAngleCosines[DELTA_A_AXIS]; const float posAY = (radius + (armLengths[DELTA_A_AXIS] * cosf(angleA))) * armAngleSines[DELTA_A_AXIS]; - const float posAZ = bearingHeights[DELTA_A_AXIS] + sinf(angleA); + const float posAZ = bearingHeights[DELTA_A_AXIS] + (armLengths[DELTA_A_AXIS] * sinf(angleA)); const float angleB = Hb * DegreesToRadians; const float posBX = (radius + (armLengths[DELTA_B_AXIS] * cosf(angleB))) * armAngleCosines[DELTA_B_AXIS]; const float posBY = (radius + (armLengths[DELTA_B_AXIS] * cosf(angleB))) * armAngleSines[DELTA_B_AXIS]; - const float posBZ = bearingHeights[DELTA_B_AXIS] + sinf(angleB); + const float posBZ = bearingHeights[DELTA_B_AXIS] + (armLengths[DELTA_A_AXIS] * sinf(angleB)); const float angleC = Hc * DegreesToRadians; const float posCX = (radius + (armLengths[DELTA_C_AXIS] * cosf(angleC))) * armAngleCosines[DELTA_C_AXIS]; const float posCY = (radius + (armLengths[DELTA_C_AXIS] * cosf(angleC))) * armAngleSines[DELTA_C_AXIS]; - const float posCZ = bearingHeights[DELTA_C_AXIS] + sinf(angleC); + const float posCZ = bearingHeights[DELTA_C_AXIS] + (armLengths[DELTA_A_AXIS] * sinf(angleC)); // Calculate some intermediate values that we will use more than once const float Da2 = fsquare(posAX) + fsquare(posAY) + fsquare(posAZ); const float Db2 = fsquare(posBX) + fsquare(posBY) + fsquare(posBZ); const float Dc2 = fsquare(posCX) + fsquare(posCY) + fsquare(posCZ); - const float Xab = posAX - posBX; - const float Xbc = posBX - posCX; - const float Xca = posCX - posAX; - - const float Yab = posAY - posBY; - const float Ybc = posBY - posCY; - const float Yca = posCY - posAY; - - const float Zca = posCZ - posAZ; - // Calculate PQRST such that x = (Qz + S)/P, y = (Rz + T)/P. - const float P = ( posBX * Yca - - posAX * posCY - + posAY * posCX - - posBY * Xca - ) * 2; - - const float Q = ( posBY * Zca - - posAY * posCZ - + posAZ * posCY - - posBZ * Yca - ) * 2; - - const float R = - ( posBX * Zca - + posAX * posCZ - + posAZ * posCX - - posBZ * Xca - ) * 2; + const float P = (posBX * posCY - posAX * posCY - posCX * posBY + posAX * posBY + posCX * posAY - posBX * posAY) * 2; + const float Q = ((posBY - posAY) * posCZ + (posAY - posCY) * posBZ + (posCY - posBY) * posAZ) * 2; + const float R = ((posBX - posAX) * posCZ + (posAX - posCX) * posBZ + (posCX - posBX) * posAZ) * 2; - const float P2 = fsquare(P); - const float U = (posAZ * P2) + (posAX * Q * P) + (posAY * R * P); - const float A = (P2 + fsquare(Q) + fsquare(R)) * 2; - - const float S = - Yab * (rodSquared[DELTA_C_AXIS] - Dc2) - - Yca * (rodSquared[DELTA_B_AXIS] - Db2) - - Ybc * (rodSquared[DELTA_A_AXIS] - Da2); - const float T = - Xab * (rodSquared[DELTA_C_AXIS] - Dc2) - + Xca * (rodSquared[DELTA_B_AXIS] - Db2) - + Xbc * (rodSquared[DELTA_A_AXIS] - Da2); + const float S = (rodSquared[DELTA_A_AXIS] - rodSquared[DELTA_B_AXIS] + Db2 - Da2) * posCY + + (rodSquared[DELTA_C_AXIS] - rodSquared[DELTA_A_AXIS] + Da2 - Dc2) * posBY + + (rodSquared[DELTA_B_AXIS] - rodSquared[DELTA_C_AXIS] + Dc2 - Db2) * posAY; + const float T = (rodSquared[DELTA_A_AXIS] - rodSquared[DELTA_B_AXIS] + Db2 - Da2) * posCX + + (rodSquared[DELTA_C_AXIS] - rodSquared[DELTA_A_AXIS] + Da2 - Dc2) * posBX + + (rodSquared[DELTA_B_AXIS] - rodSquared[DELTA_C_AXIS] + Dc2 - Db2) * posAX; // Calculate quadratic equation coefficients - const float halfB = (S * Q) - (R * T) - U; - const float C = fsquare(S) + fsquare(T) + (posAY * T - posAX * S) * P * 2 + (Da2 - rodSquared[DELTA_A_AXIS]) * P2; + const float P2 = fsquare(P); + const float A = P2 + fsquare(Q) + fsquare(R); + const float halfB = (P * R * posAY) - (P2 * posAZ) - (P * Q * posAX) + (R * T) + (Q * S); + const float C = fsquare(S) + fsquare(T) + (T * posAY - S * posAX) * P * 2 + (Da2 - rodSquared[DELTA_A_AXIS]) * P2; // Solve the quadratic equation for z const float z = (- halfB - sqrtf(fsquare(halfB) - A * C))/A; diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp index b1553de5..37d5a771 100644 --- a/src/Movement/Move.cpp +++ b/src/Movement/Move.cpp @@ -35,6 +35,7 @@ #include "Move.h" #include "Platform.h" +#include "GCodes/GCodeBuffer.h" #include "Tools/Tool.h" constexpr uint32_t UsualMinimumPreparedTime = StepClockRate/10; // 100ms @@ -75,6 +76,7 @@ void Move::Init() numLookaheadUnderruns = numPrepareUnderruns = numLookaheadErrors = 0; maxPrintingAcceleration = maxTravelAcceleration = 10000.0; drcEnabled = false; // disable dynamic ringing cancellation + drcMinimumAcceleration = 10.0; // Clear the transforms SetIdentityTransform(); @@ -598,9 +600,10 @@ void Move::Diagnostics(MessageType mtype) { Platform& p = reprap.GetPlatform(); p.Message(mtype, "=== Move ===\n"); - p.MessageF(mtype, "Hiccups: %" PRIu32 ", StepErrors: %u, LaErrors: %u, FreeDm: %d, MinFreeDm: %d, MaxWait: %" PRIu32 "ms, Underruns: %u, %u\n", + p.MessageF(mtype, "Hiccups: %u, StepErrors: %u, LaErrors: %u, FreeDm: %d, MinFreeDm: %d, MaxWait: %" PRIu32 "ms, Underruns: %u, %u\n", DDA::numHiccups, stepErrors, numLookaheadErrors, DriveMovement::NumFree(), DriveMovement::MinFree(), longestGcodeWaitInterval, numLookaheadUnderruns, numPrepareUnderruns); DDA::numHiccups = 0; + stepErrors = 0; numLookaheadUnderruns = numPrepareUnderruns = numLookaheadErrors = 0; longestGcodeWaitInterval = 0; DriveMovement::ResetMinFree(); @@ -1292,18 +1295,69 @@ bool Move::WriteResumeSettings(FileStore *f) const return kinematics->WriteResumeSettings(f) && (!usingMesh || f->Write("G29 S1\n")); } -// Set the DRC frequency or disable DRC -void Move::SetDRCfreq(float f) +// Process M204 +GCodeResult Move::ConfigureAccelerations(GCodeBuffer&gb, const StringRef& reply) { - if (f >= 4.0 && f <= 10000.0) + bool seen = false; + if (gb.Seen('S')) { - drcPeriod = 1.0/f; - drcEnabled = true; + // For backwards compatibility with old versions of Marlin (e.g. for Cura and the Prusa fork of slic3r), set both accelerations + seen = true; + maxTravelAcceleration = maxPrintingAcceleration = gb.GetFValue(); } - else + if (gb.Seen('P')) + { + seen = true; + maxPrintingAcceleration = gb.GetFValue(); + } + if (gb.Seen('T')) + { + seen = true; + maxTravelAcceleration = gb.GetFValue(); + } + if (!seen) + { + reply.printf("Maximum printing acceleration %.1f, maximum travel acceleration %.1f", (double)maxPrintingAcceleration, (double)maxTravelAcceleration); + } + return GCodeResult::ok; +} + +// Process M593 +GCodeResult Move::ConfigureDynamicAcceleration(GCodeBuffer& gb, const StringRef& reply) +{ + bool seen = false; + if (gb.Seen('F')) + { + seen = true; + const float f = gb.GetFValue(); + if (f >= 4.0 && f <= 10000.0) + { + drcPeriod = 1.0/f; + drcEnabled = true; + } + else + { + drcEnabled = false; + } + } + if (gb.Seen('L')) { - drcEnabled = false; + seen = true; + drcMinimumAcceleration = max<float>(gb.GetFValue(), 1.0); // very low accelerations cause problems with the maths + } + + if (!seen) + { + if (reprap.GetMove().IsDRCenabled()) + { + reply.printf("Dynamic ringing cancellation at %.1fHz, min. acceleration %.1f", (double)(1.0/drcPeriod), (double)drcMinimumAcceleration); + } + else + { + reply.copy("Dynamic ringing cancellation is disabled"); + } } + return GCodeResult::ok; } // For debugging diff --git a/src/Movement/Move.h b/src/Movement/Move.h index e8a6bb32..87070b4b 100644 --- a/src/Movement/Move.h +++ b/src/Movement/Move.h @@ -71,14 +71,15 @@ public: unsigned int GetNumProbePoints() const; // Return the number of currently used probe points float PushBabyStepping(float amount); // Try to push some babystepping through the lookahead queue + GCodeResult ConfigureAccelerations(GCodeBuffer&gb, const StringRef& reply); // process M204 + GCodeResult ConfigureDynamicAcceleration(GCodeBuffer& gb, const StringRef& reply); // process M593 + float GetMaxPrintingAcceleration() const { return maxPrintingAcceleration; } - void SetMaxPrintingAcceleration(float acc) { maxPrintingAcceleration = acc; } float GetMaxTravelAcceleration() const { return maxTravelAcceleration; } - void SetMaxTravelAcceleration(float acc) { maxTravelAcceleration = acc; } float GetDRCfreq() const { return 1.0/drcPeriod; } float GetDRCperiod() const { return drcPeriod; } + float GetDRCminimumAcceleration() const { return drcMinimumAcceleration; } float IsDRCenabled() const { return drcEnabled; } - void SetDRCfreq(float f); void Diagnostics(MessageType mtype); // Report useful stuff void RecordLookaheadError() { ++numLookaheadErrors; } // Record a lookahead error @@ -179,6 +180,7 @@ private: float maxPrintingAcceleration; float maxTravelAcceleration; float drcPeriod; // the period of ringing that we don't want to excite + float drcMinimumAcceleration; // the minimum value that we reduce acceleration to unsigned int numLookaheadUnderruns; // How many times we have run out of moves to adjust during lookahead unsigned int numPrepareUnderruns; // How many times we wanted a new move but there were only un-prepared moves in the queue diff --git a/src/Version.h b/src/Version.h index 10f4fb28..326e2994 100644 --- a/src/Version.h +++ b/src/Version.h @@ -22,7 +22,7 @@ #endif #ifndef DATE -# define DATE "2018-08-11b4" +# define DATE "2018-08-12b5" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman" |