Skip to content

Commit

Permalink
Version 2.02beta1
Browse files Browse the repository at this point in the history
Fixed issues with dynamic acceleration adjustment
More work on rotary delta kinematics
  • Loading branch information
dc42 committed Aug 12, 2018
1 parent d7f8763 commit 635314b
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 137 deletions.
42 changes: 2 additions & 40 deletions src/GCodes/GCodes2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
130 changes: 96 additions & 34 deletions src/Movement/DDA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
{
Expand Down Expand Up @@ -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());
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
)
)
)
{
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/Movement/DDA.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class DDA
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

Expand Down Expand Up @@ -177,6 +177,7 @@ class DDA
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
};
Expand Down
3 changes: 1 addition & 2 deletions src/Movement/DriveMovement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 635314b

Please sign in to comment.