@@ -394,18 +394,22 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
394
394
xAxes = nextMove.xAxes ;
395
395
yAxes = nextMove.yAxes ;
396
396
endStopsToCheck = nextMove.endStopsToCheck ;
397
- canPauseAfter = nextMove.canPauseAfter ;
398
- usingStandardFeedrate = nextMove.usingStandardFeedrate ;
399
397
filePos = nextMove.filePos ;
400
- isPrintingMove = xyMoving && extruding;
401
- usePressureAdvance = nextMove.usePressureAdvance ;
402
398
virtualExtruderPosition = nextMove.virtualExtruderPosition ;
403
399
proportionLeft = nextMove.proportionLeft ;
404
400
401
+ canPauseAfter = nextMove.canPauseAfter ;
402
+ usingStandardFeedrate = nextMove.usingStandardFeedrate ;
403
+ isPrintingMove = xyMoving && extruding;
404
+ usePressureAdvance = nextMove.usePressureAdvance ;
405
405
hadLookaheadUnderrun = false ;
406
+ hadHiccup = false ;
406
407
isLeadscrewAdjustmentMove = false ;
407
408
goingSlow = false ;
408
409
410
+ // 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
411
+ endCoordinatesValid = (endStopsToCheck == 0 ) && doMotorMapping;
412
+
409
413
#if SUPPORT_IOBITS
410
414
laserPwmOrIoBits = nextMove.laserPwmOrIoBits ;
411
415
#endif
@@ -416,9 +420,6 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
416
420
accelerations[Z_AXIS] = ZProbeMaxAcceleration;
417
421
}
418
422
419
- // 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
420
- endCoordinatesValid = (endStopsToCheck == 0 ) && doMotorMapping;
421
-
422
423
// 4. Normalise the direction vector and compute the amount of motion.
423
424
if (xyMoving)
424
425
{
@@ -448,11 +449,11 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
448
449
}
449
450
450
451
// 5. Compute the maximum acceleration available
451
- float normalisedDirectionVector[DRIVES]; // Used to hold a unit-length vector in the direction of motion
452
+ float normalisedDirectionVector[DRIVES]; // used to hold a unit-length vector in the direction of motion
452
453
memcpy (normalisedDirectionVector, directionVector, sizeof (normalisedDirectionVector));
453
454
Absolute (normalisedDirectionVector, DRIVES);
454
455
acceleration = maxAcceleration = VectorBoxIntersection (normalisedDirectionVector, accelerations, DRIVES);
455
- if (xyMoving && !move. IsDRCenabled ()) // apply M204 acceleration limits to XY moves
456
+ if (xyMoving) // apply M204 acceleration limits to XY moves
456
457
{
457
458
acceleration = min<float >(acceleration, (isPrintingMove) ? move.GetMaxPrintingAcceleration () : move.GetMaxTravelAcceleration ());
458
459
}
@@ -556,17 +557,18 @@ bool DDA::Init(const float_t adjustments[DRIVES])
556
557
isDeltaMovement = false ;
557
558
isPrintingMove = false ;
558
559
xyMoving = false ;
559
- endStopsToCheck = 0 ;
560
560
canPauseAfter = true ;
561
561
usingStandardFeedrate = false ;
562
562
usePressureAdvance = false ;
563
- virtualExtruderPosition = prev->virtualExtruderPosition ;
564
563
hadLookaheadUnderrun = false ;
564
+ hadHiccup = false ;
565
+ goingSlow = false ;
566
+ endStopsToCheck = 0 ;
567
+ virtualExtruderPosition = prev->virtualExtruderPosition ;
565
568
xAxes = prev->xAxes ;
566
569
yAxes = prev->yAxes ;
567
570
filePos = prev->filePos ;
568
571
endCoordinatesValid = prev->endCoordinatesValid ;
569
- goingSlow = false ;
570
572
571
573
#if SUPPORT_LASER && SUPPORT_IOBITS
572
574
if (reprap.GetGCodes ().GetMachineType () == MachineType::laser)
@@ -1051,67 +1053,118 @@ pre(disableDeltaMapping || drive < MaxAxes)
1051
1053
}
1052
1054
1053
1055
// Adjust the acceleration and deceleration to reduce ringing
1056
+ // Only called if topSpeed > startSpeed & topSpeed > endSpeed
1054
1057
// This is only called once, so inlined for speed
1055
1058
inline void DDA::AdjustAcceleration ()
1056
1059
{
1057
1060
// Try to reduce the acceleration/deceleration of the move to cancel ringing
1058
1061
const float idealPeriod = reprap.GetMove ().GetDRCperiod ();
1059
-
1060
1062
const float accTime = (topSpeed - startSpeed)/acceleration;
1061
1063
const bool adjustAcceleration =
1062
- (accTime < idealPeriod && accTime > 0.2 * idealPeriod && ((prev->state != DDAState::frozen && prev->state != DDAState::executing) || !prev->IsAccelerationMove ()));
1064
+ (accTime < idealPeriod && ((prev->state != DDAState::frozen && prev->state != DDAState::executing) || !prev->IsAccelerationMove ()));
1065
+ float proposedAcceleration, proposedAccelDistance;
1063
1066
if (adjustAcceleration)
1064
1067
{
1065
- acceleration = (topSpeed - startSpeed)/idealPeriod;
1066
- accelDistance = (fsquare (topSpeed) - fsquare (startSpeed))/(2 *acceleration);
1068
+ proposedAcceleration = (topSpeed - startSpeed)/idealPeriod;
1069
+ proposedAccelDistance = (fsquare (topSpeed) - fsquare (startSpeed))/(2 * proposedAcceleration);
1070
+ }
1071
+ else
1072
+ {
1073
+ proposedAcceleration = acceleration;
1074
+ proposedAccelDistance = accelDistance;
1067
1075
}
1068
1076
1069
1077
const float decelTime = (topSpeed - endSpeed)/deceleration;
1070
1078
const float adjustDeceleration =
1071
- (decelTime < idealPeriod && decelTime > 0.2 * idealPeriod && (next->state != DDAState::provisional || !next->IsDecelerationMove ()));
1079
+ (decelTime < idealPeriod && (next->state != DDAState::provisional || !next->IsDecelerationMove ()));
1080
+ float proposedDeceleration, proposedDecelDistance;
1072
1081
if (adjustDeceleration)
1073
1082
{
1074
- deceleration = (topSpeed - endSpeed)/idealPeriod;
1075
- decelDistance = (fsquare (topSpeed) - fsquare (endSpeed))/(2 * deceleration);
1083
+ proposedDeceleration = (topSpeed - endSpeed)/idealPeriod;
1084
+ proposedDecelDistance = (fsquare (topSpeed) - fsquare (endSpeed))/(2 * proposedDeceleration);
1085
+ }
1086
+ else
1087
+ {
1088
+ proposedDeceleration = deceleration;
1089
+ proposedDecelDistance = decelDistance;
1076
1090
}
1077
1091
1078
1092
if (adjustAcceleration || adjustDeceleration)
1079
1093
{
1080
- if (accelDistance + decelDistance > totalDistance)
1094
+ const float drcMinimumAcceleration = reprap.GetMove ().GetDRCminimumAcceleration ();
1095
+ if (proposedAccelDistance + proposedDecelDistance <= totalDistance)
1081
1096
{
1082
- // We can't keep this as a trapezoidal move
1097
+ if (proposedAcceleration < drcMinimumAcceleration || proposedDeceleration < drcMinimumAcceleration)
1098
+ {
1099
+ return ;
1100
+ }
1101
+ acceleration = proposedAcceleration;
1102
+ deceleration = proposedDeceleration;
1103
+ accelDistance = proposedAccelDistance;
1104
+ decelDistance = proposedDecelDistance;
1105
+ }
1106
+ else
1107
+ {
1108
+ // We can't keep this as a trapezoidal move with the original top speed.
1109
+ // Try an accelerate-decelerate move with acceleration and deceleration times equal to the ideal period.
1083
1110
const float twiceTotalDistance = 2 * totalDistance;
1084
- if (adjustAcceleration && adjustDeceleration && (startSpeed + endSpeed) * idealPeriod < totalDistance)
1111
+ float proposedTopSpeed = totalDistance/idealPeriod - (startSpeed + endSpeed)/2 ;
1112
+ if (proposedTopSpeed > startSpeed && proposedTopSpeed > endSpeed)
1085
1113
{
1086
- // Change it into an accelerate-decelerate move with equal acceleration and deceleration times
1087
- acceleration = (twiceTotalDistance - (3 * startSpeed + endSpeed) * idealPeriod)/(2 * fsquare (idealPeriod));
1088
- deceleration = (twiceTotalDistance - (startSpeed + 3 * endSpeed) * idealPeriod)/(2 * fsquare (idealPeriod));
1089
- topSpeed = (totalDistance/idealPeriod) - (startSpeed + endSpeed)/2 ;
1114
+ proposedAcceleration = (twiceTotalDistance - ((3 * startSpeed + endSpeed) * idealPeriod))/(2 * fsquare (idealPeriod));
1115
+ proposedDeceleration = (twiceTotalDistance - ((startSpeed + 3 * endSpeed) * idealPeriod))/(2 * fsquare (idealPeriod));
1116
+ if ( proposedAcceleration < drcMinimumAcceleration || proposedDeceleration < drcMinimumAcceleration
1117
+ || proposedAcceleration > acceleration || proposedDeceleration > deceleration
1118
+ )
1119
+ {
1120
+ return ;
1121
+ }
1122
+ topSpeed = proposedTopSpeed;
1123
+ acceleration = proposedAcceleration;
1124
+ deceleration = proposedDeceleration;
1090
1125
accelDistance = startSpeed * idealPeriod + (acceleration * fsquare (idealPeriod))/2 ;
1091
1126
decelDistance = endSpeed * idealPeriod + (deceleration * fsquare (idealPeriod))/2 ;
1092
1127
}
1093
1128
else if (startSpeed < endSpeed)
1094
1129
{
1095
1130
// Change it into an accelerate-only move, accelerating as slowly as we can
1096
- acceleration = (fsquare (endSpeed) - fsquare (startSpeed))/twiceTotalDistance;
1131
+ proposedAcceleration = (fsquare (endSpeed) - fsquare (startSpeed))/twiceTotalDistance;
1132
+ if (proposedAcceleration < drcMinimumAcceleration)
1133
+ {
1134
+ return ; // avoid very small accelerations because they can be problematic
1135
+ }
1136
+ acceleration = proposedAcceleration;
1097
1137
topSpeed = endSpeed;
1098
1138
accelDistance = totalDistance;
1099
1139
decelDistance = 0.0 ;
1100
1140
}
1101
- else
1141
+ else if (startSpeed > endSpeed)
1102
1142
{
1103
1143
// Change it into a decelerate-only move, decelerating as slowly as we can
1104
- deceleration = (fsquare (startSpeed) - fsquare (endSpeed))/twiceTotalDistance;
1144
+ proposedDeceleration = (fsquare (startSpeed) - fsquare (endSpeed))/twiceTotalDistance;
1145
+ if (proposedDeceleration < drcMinimumAcceleration)
1146
+ {
1147
+ return ; // avoid very small accelerations because they can be problematic
1148
+ }
1149
+ deceleration = proposedDeceleration;
1105
1150
topSpeed = startSpeed;
1106
1151
accelDistance = 0.0 ;
1107
1152
decelDistance = totalDistance;
1108
1153
}
1154
+ else
1155
+ {
1156
+ // Start and end speeds are exactly the same, possibly zero, so give up trying to adjust this move
1157
+ return ;
1158
+ }
1109
1159
}
1110
- const float totalTime = (topSpeed - startSpeed)/acceleration + (topSpeed - endSpeed)/deceleration + (totalDistance - accelDistance - decelDistance)/topSpeed;
1160
+
1161
+ const float totalTime = (topSpeed - startSpeed)/acceleration
1162
+ + (topSpeed - endSpeed)/deceleration
1163
+ + (totalDistance - accelDistance - decelDistance)/topSpeed;
1111
1164
clocksNeeded = (uint32_t )(totalTime * StepClockRate);
1112
1165
if (reprap.Debug (moduleMove))
1113
1166
{
1114
- debugPrintf (" New a=%f d=%f \n " , (double )acceleration, (double )deceleration);
1167
+ debugPrintf (" New a=%.1f d=%.1f \n " , (double )acceleration, (double )deceleration);
1115
1168
}
1116
1169
}
1117
1170
}
@@ -1171,7 +1224,7 @@ void DDA::Prepare(uint8_t simMode)
1171
1224
const size_t numAxes = reprap.GetGCodes ().GetTotalAxes ();
1172
1225
for (size_t drive = 0 ; drive < DRIVES; ++drive)
1173
1226
{
1174
- DriveMovement* const pdm = pddm[ drive] ;
1227
+ DriveMovement* const pdm = FindDM ( drive) ;
1175
1228
if (pdm != nullptr && pdm->state == DMState::moving)
1176
1229
{
1177
1230
if (isLeadscrewAdjustmentMove)
@@ -1209,7 +1262,8 @@ void DDA::Prepare(uint8_t simMode)
1209
1262
&& ( pdm->totalSteps > 1000000
1210
1263
|| pdm->reverseStartStep < pdm->mp .cart .decelStartStep
1211
1264
|| (pdm->reverseStartStep <= pdm->totalSteps
1212
- && pdm->mp .cart .fourMaxStepDistanceMinusTwoDistanceToStopTimesCsquaredDivD > (int64_t )(pdm->mp .cart .twoCsquaredTimesMmPerStepDivD * pdm->reverseStartStep ))
1265
+ && pdm->mp .cart .fourMaxStepDistanceMinusTwoDistanceToStopTimesCsquaredDivD > (int64_t )(pdm->mp .cart .twoCsquaredTimesMmPerStepDivD * pdm->reverseStartStep )
1266
+ )
1213
1267
)
1214
1268
)
1215
1269
{
@@ -1587,7 +1641,7 @@ pre(state == frozen)
1587
1641
return true ; // schedule another interrupt immediately
1588
1642
}
1589
1643
1590
- uint32_t DDA::numHiccups = 0 ;
1644
+ unsigned int DDA::numHiccups = 0 ;
1591
1645
uint32_t DDA::lastStepLowTime = 0 ;
1592
1646
uint32_t DDA::lastDirChangeTime = 0 ;
1593
1647
@@ -1695,6 +1749,7 @@ bool DDA::Step()
1695
1749
moveStartTime += delayClocks;
1696
1750
nextStepDue += delayClocks;
1697
1751
++numHiccups;
1752
+ hadHiccup = true ;
1698
1753
}
1699
1754
1700
1755
// 8. Schedule next interrupt, or if it would be too soon, generate more steps immediately
@@ -1819,6 +1874,13 @@ void DDA::ReduceHomingSpeed()
1819
1874
1820
1875
bool DDA::HasStepError () const
1821
1876
{
1877
+ #if 0 //debug
1878
+ if (hadHiccup)
1879
+ {
1880
+ return true; // temporary for debugging DAA
1881
+ }
1882
+ #endif
1883
+
1822
1884
for (size_t drive = 0 ; drive < DRIVES; ++drive)
1823
1885
{
1824
1886
const DriveMovement* const pdm = FindDM (drive);
0 commit comments