Skip to content

Commit 635314b

Browse files
committed
Version 2.02beta1
Fixed issues with dynamic acceleration adjustment More work on rotary delta kinematics
1 parent d7f8763 commit 635314b

File tree

8 files changed

+192
-137
lines changed

8 files changed

+192
-137
lines changed

src/GCodes/GCodes2.cpp

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,34 +1929,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
19291929
break;
19301930

19311931
case 204: // Set max travel and printing accelerations
1932-
{
1933-
Move& move = reprap.GetMove();
1934-
bool seen = false;
1935-
if (gb.Seen('S'))
1936-
{
1937-
// For backwards compatibility with old versions of Marlin (e.g. for Cura and the Prusa fork of slic3r), set both accelerations
1938-
const float acc = gb.GetFValue();
1939-
move.SetMaxPrintingAcceleration(acc);
1940-
move.SetMaxTravelAcceleration(acc);
1941-
seen = true;
1942-
}
1943-
if (gb.Seen('P'))
1944-
{
1945-
move.SetMaxPrintingAcceleration(gb.GetFValue());
1946-
seen = true;
1947-
}
1948-
if (gb.Seen('T'))
1949-
{
1950-
move.SetMaxTravelAcceleration(gb.GetFValue());
1951-
seen = true;
1952-
}
1953-
if (!seen)
1954-
{
1955-
reply.printf("Maximum printing acceleration %.1f, maximum travel acceleration %.1f%s",
1956-
(double)move.GetMaxPrintingAcceleration(), (double)move.GetMaxTravelAcceleration(),
1957-
(move.IsDRCenabled()) ? " (both currently ignored because DRC is enabled)" : "");
1958-
}
1959-
}
1932+
result = reprap.GetMove().ConfigureAccelerations(gb, reply);
19601933
break;
19611934

19621935
case 206: // Offset axes
@@ -3671,18 +3644,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
36713644
#endif
36723645

36733646
case 593: // Configure dynamic ringing cancellation
3674-
if (gb.Seen('F'))
3675-
{
3676-
reprap.GetMove().SetDRCfreq(gb.GetFValue());
3677-
}
3678-
else if (reprap.GetMove().IsDRCenabled())
3679-
{
3680-
reply.printf("Dynamic ringing cancellation at %.1fHz", (double)reprap.GetMove().GetDRCfreq());
3681-
}
3682-
else
3683-
{
3684-
reply.copy("Dynamic ringing cancellation is disabled");
3685-
}
3647+
result = reprap.GetMove().ConfigureDynamicAcceleration(gb, reply);
36863648
break;
36873649

36883650
case 665: // Set delta configuration

src/Movement/DDA.cpp

Lines changed: 96 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -394,18 +394,22 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
394394
xAxes = nextMove.xAxes;
395395
yAxes = nextMove.yAxes;
396396
endStopsToCheck = nextMove.endStopsToCheck;
397-
canPauseAfter = nextMove.canPauseAfter;
398-
usingStandardFeedrate = nextMove.usingStandardFeedrate;
399397
filePos = nextMove.filePos;
400-
isPrintingMove = xyMoving && extruding;
401-
usePressureAdvance = nextMove.usePressureAdvance;
402398
virtualExtruderPosition = nextMove.virtualExtruderPosition;
403399
proportionLeft = nextMove.proportionLeft;
404400

401+
canPauseAfter = nextMove.canPauseAfter;
402+
usingStandardFeedrate = nextMove.usingStandardFeedrate;
403+
isPrintingMove = xyMoving && extruding;
404+
usePressureAdvance = nextMove.usePressureAdvance;
405405
hadLookaheadUnderrun = false;
406+
hadHiccup = false;
406407
isLeadscrewAdjustmentMove = false;
407408
goingSlow = false;
408409

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+
409413
#if SUPPORT_IOBITS
410414
laserPwmOrIoBits = nextMove.laserPwmOrIoBits;
411415
#endif
@@ -416,9 +420,6 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
416420
accelerations[Z_AXIS] = ZProbeMaxAcceleration;
417421
}
418422

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-
422423
// 4. Normalise the direction vector and compute the amount of motion.
423424
if (xyMoving)
424425
{
@@ -448,11 +449,11 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping)
448449
}
449450

450451
// 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
452453
memcpy(normalisedDirectionVector, directionVector, sizeof(normalisedDirectionVector));
453454
Absolute(normalisedDirectionVector, DRIVES);
454455
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
456457
{
457458
acceleration = min<float>(acceleration, (isPrintingMove) ? move.GetMaxPrintingAcceleration() : move.GetMaxTravelAcceleration());
458459
}
@@ -556,17 +557,18 @@ bool DDA::Init(const float_t adjustments[DRIVES])
556557
isDeltaMovement = false;
557558
isPrintingMove = false;
558559
xyMoving = false;
559-
endStopsToCheck = 0;
560560
canPauseAfter = true;
561561
usingStandardFeedrate = false;
562562
usePressureAdvance = false;
563-
virtualExtruderPosition = prev->virtualExtruderPosition;
564563
hadLookaheadUnderrun = false;
564+
hadHiccup = false;
565+
goingSlow = false;
566+
endStopsToCheck = 0;
567+
virtualExtruderPosition = prev->virtualExtruderPosition;
565568
xAxes = prev->xAxes;
566569
yAxes = prev->yAxes;
567570
filePos = prev->filePos;
568571
endCoordinatesValid = prev->endCoordinatesValid;
569-
goingSlow = false;
570572

571573
#if SUPPORT_LASER && SUPPORT_IOBITS
572574
if (reprap.GetGCodes().GetMachineType() == MachineType::laser)
@@ -1051,67 +1053,118 @@ pre(disableDeltaMapping || drive < MaxAxes)
10511053
}
10521054

10531055
// Adjust the acceleration and deceleration to reduce ringing
1056+
// Only called if topSpeed > startSpeed & topSpeed > endSpeed
10541057
// This is only called once, so inlined for speed
10551058
inline void DDA::AdjustAcceleration()
10561059
{
10571060
// Try to reduce the acceleration/deceleration of the move to cancel ringing
10581061
const float idealPeriod = reprap.GetMove().GetDRCperiod();
1059-
10601062
const float accTime = (topSpeed - startSpeed)/acceleration;
10611063
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;
10631066
if (adjustAcceleration)
10641067
{
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;
10671075
}
10681076

10691077
const float decelTime = (topSpeed - endSpeed)/deceleration;
10701078
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;
10721081
if (adjustDeceleration)
10731082
{
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;
10761090
}
10771091

10781092
if (adjustAcceleration || adjustDeceleration)
10791093
{
1080-
if (accelDistance + decelDistance > totalDistance)
1094+
const float drcMinimumAcceleration = reprap.GetMove().GetDRCminimumAcceleration();
1095+
if (proposedAccelDistance + proposedDecelDistance <= totalDistance)
10811096
{
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.
10831110
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)
10851113
{
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;
10901125
accelDistance = startSpeed * idealPeriod + (acceleration * fsquare(idealPeriod))/2;
10911126
decelDistance = endSpeed * idealPeriod + (deceleration * fsquare(idealPeriod))/2;
10921127
}
10931128
else if (startSpeed < endSpeed)
10941129
{
10951130
// 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;
10971137
topSpeed = endSpeed;
10981138
accelDistance = totalDistance;
10991139
decelDistance = 0.0;
11001140
}
1101-
else
1141+
else if (startSpeed > endSpeed)
11021142
{
11031143
// 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;
11051150
topSpeed = startSpeed;
11061151
accelDistance = 0.0;
11071152
decelDistance = totalDistance;
11081153
}
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+
}
11091159
}
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;
11111164
clocksNeeded = (uint32_t)(totalTime * StepClockRate);
11121165
if (reprap.Debug(moduleMove))
11131166
{
1114-
debugPrintf("New a=%f d=%f\n", (double)acceleration, (double)deceleration);
1167+
debugPrintf("New a=%.1f d=%.1f\n", (double)acceleration, (double)deceleration);
11151168
}
11161169
}
11171170
}
@@ -1171,7 +1224,7 @@ void DDA::Prepare(uint8_t simMode)
11711224
const size_t numAxes = reprap.GetGCodes().GetTotalAxes();
11721225
for (size_t drive = 0; drive < DRIVES; ++drive)
11731226
{
1174-
DriveMovement* const pdm = pddm[drive];
1227+
DriveMovement* const pdm = FindDM(drive);
11751228
if (pdm != nullptr && pdm->state == DMState::moving)
11761229
{
11771230
if (isLeadscrewAdjustmentMove)
@@ -1209,7 +1262,8 @@ void DDA::Prepare(uint8_t simMode)
12091262
&& ( pdm->totalSteps > 1000000
12101263
|| pdm->reverseStartStep < pdm->mp.cart.decelStartStep
12111264
|| (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+
)
12131267
)
12141268
)
12151269
{
@@ -1587,7 +1641,7 @@ pre(state == frozen)
15871641
return true; // schedule another interrupt immediately
15881642
}
15891643

1590-
uint32_t DDA::numHiccups = 0;
1644+
unsigned int DDA::numHiccups = 0;
15911645
uint32_t DDA::lastStepLowTime = 0;
15921646
uint32_t DDA::lastDirChangeTime = 0;
15931647

@@ -1695,6 +1749,7 @@ bool DDA::Step()
16951749
moveStartTime += delayClocks;
16961750
nextStepDue += delayClocks;
16971751
++numHiccups;
1752+
hadHiccup = true;
16981753
}
16991754

17001755
// 8. Schedule next interrupt, or if it would be too soon, generate more steps immediately
@@ -1819,6 +1874,13 @@ void DDA::ReduceHomingSpeed()
18191874

18201875
bool DDA::HasStepError() const
18211876
{
1877+
#if 0 //debug
1878+
if (hadHiccup)
1879+
{
1880+
return true; // temporary for debugging DAA
1881+
}
1882+
#endif
1883+
18221884
for (size_t drive = 0; drive < DRIVES; ++drive)
18231885
{
18241886
const DriveMovement* const pdm = FindDM(drive);

src/Movement/DDA.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class DDA
130130
static int32_t loggedProbePositions[XYZ_AXES * MaxLoggedProbePositions];
131131
#endif
132132

133-
static uint32_t numHiccups; // how many times we delayed an interrupt to avoid using too much CPU time in interrupts
133+
static unsigned int numHiccups; // how many times we delayed an interrupt to avoid using too much CPU time in interrupts
134134
static uint32_t lastStepLowTime; // when we last completed a step pulse to a slow driver
135135
static uint32_t lastDirChangeTime; // when we last change the DIR signal to a slow driver
136136

@@ -177,6 +177,7 @@ class DDA
177177
uint8_t goingSlow : 1; // True if we have slowed the movement because the Z probe is approaching its threshold
178178
uint8_t isLeadscrewAdjustmentMove : 1; // True if this is a leadscrews adjustment move
179179
uint8_t usingStandardFeedrate : 1; // True if this move uses the standard feed rate
180+
uint8_t hadHiccup : 1; // True if we had a hiccup while executing this move
180181
};
181182
uint16_t flags; // so that we can print all the flags at once for debugging
182183
};

src/Movement/DriveMovement.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ void DriveMovement::PrepareCartesianAxis(const DDA& dda, const PrepParams& param
7878
else
7979
{
8080
mp.cart.decelStartStep = (uint32_t)(params.decelStartDistance * stepsPerMm) + 1;
81-
const uint64_t initialDecelSpeedTimesCdivDSquared = isquare64(params.topSpeedTimesCdivD);
82-
twoDistanceToStopTimesCsquaredDivD = initialDecelSpeedTimesCdivDSquared + roundU64((params.decelStartDistance * (StepClockRateSquared * 2))/dda.deceleration);
81+
twoDistanceToStopTimesCsquaredDivD = isquare64(params.topSpeedTimesCdivD) + roundU64((params.decelStartDistance * (StepClockRateSquared * 2))/dda.deceleration);
8382
}
8483

8584
// No reverse phase

0 commit comments

Comments
 (0)