Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Movement/Move.cpp')
-rw-r--r--src/Movement/Move.cpp270
1 files changed, 90 insertions, 180 deletions
diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp
index de7a2658..e8c09e76 100644
--- a/src/Movement/Move.cpp
+++ b/src/Movement/Move.cpp
@@ -30,8 +30,6 @@ Move::Move() : currentDda(NULL), scheduledMoves(0), completedMoves(0)
void Move::Init()
{
- deltaProbing = false;
-
// Empty the ring
ddaRingGetPointer = ddaRingCheckPointer = ddaRingAddPointer;
DDA *dda = ddaRingAddPointer;
@@ -183,88 +181,85 @@ void Move::Spin()
}
}
- if (!deltaProbing)
+ // See whether we need to kick off a move
+ if (currentDda == nullptr)
{
- // See whether we need to kick off a move
- if (currentDda == nullptr)
+ // No DDA is executing, so start executing a new one if possible
+ if (idleCount > 10) // better to have a few moves in the queue so that we can do lookahead
{
- // No DDA is executing, so start executing a new one if possible
- if (idleCount > 10) // better to have a few moves in the queue so that we can do lookahead
+ DDA *dda = ddaRingGetPointer;
+ if (dda->GetState() == DDA::provisional)
+ {
+ dda->Prepare();
+ }
+ if (dda->GetState() == DDA::frozen)
{
- DDA *dda = ddaRingGetPointer;
- if (dda->GetState() == DDA::provisional)
+ if (simulationMode != 0)
{
- dda->Prepare();
+ currentDda = dda; // pretend we are executing this move
}
- if (dda->GetState() == DDA::frozen)
+ else
{
- if (simulationMode != 0)
+ Platform::DisableStepInterrupt(); // should be disabled already because we weren't executing a move, but make sure
+ if (StartNextMove(Platform::GetInterruptClocks())) // start the next move
{
- currentDda = dda; // pretend we are executing this move
+ Interrupt();
}
- else
- {
- Platform::DisableStepInterrupt(); // should be disabled already because we weren't executing a move, but make sure
- if (StartNextMove(Platform::GetInterruptClocks())) // start the next move
- {
- Interrupt();
- }
- }
- iState = IdleState::busy;
- }
- else if (!simulationMode != 0 && iState == IdleState::busy && !reprap.GetGCodes().IsPaused() && idleTimeout > 0.0)
- {
- lastMoveTime = reprap.GetPlatform().Time(); // record when we first noticed that the machine was idle
- iState = IdleState::timing;
- }
- else if (!simulationMode != 0 && iState == IdleState::timing && reprap.GetPlatform().Time() - lastMoveTime >= idleTimeout)
- {
- reprap.GetPlatform().SetDriversIdle(); // put all drives in idle hold
- iState = IdleState::idle;
}
+ iState = IdleState::busy;
+ }
+ else if (!simulationMode != 0 && iState == IdleState::busy && !reprap.GetGCodes().IsPaused() && idleTimeout > 0.0)
+ {
+ lastMoveTime = reprap.GetPlatform().Time(); // record when we first noticed that the machine was idle
+ iState = IdleState::timing;
+ }
+ else if (!simulationMode != 0 && iState == IdleState::timing && reprap.GetPlatform().Time() - lastMoveTime >= idleTimeout)
+ {
+ reprap.GetPlatform().SetDriversIdle(); // put all drives in idle hold
+ iState = IdleState::idle;
}
}
+ }
- DDA *cdda = currentDda; // currentDda is volatile, so copy it
- if (cdda != nullptr)
+ DDA *cdda = currentDda; // currentDda is volatile, so copy it
+ if (cdda != nullptr)
+ {
+ // See whether we need to prepare any moves
+ int32_t preparedTime = 0;
+ uint32_t preparedCount = 0;
+ DDA::DDAState st;
+ while ((st = cdda->GetState()) == DDA::completed || st == DDA::executing || st == DDA::frozen)
{
- // See whether we need to prepare any moves
- int32_t preparedTime = 0;
- uint32_t preparedCount = 0;
- DDA::DDAState st;
- while ((st = cdda->GetState()) == DDA::completed || st == DDA::executing || st == DDA::frozen)
+ preparedTime += cdda->GetTimeLeft();
+ ++preparedCount;
+ cdda = cdda->GetNext();
+ if (cdda == ddaRingAddPointer)
{
- preparedTime += cdda->GetTimeLeft();
- ++preparedCount;
- cdda = cdda->GetNext();
- if (cdda == ddaRingAddPointer)
- {
- break;
- }
+ break;
}
+ }
- // If the number of prepared moves will execute in less than the minimum time, prepare another move
- while (st == DDA::provisional
- && preparedTime < (int32_t)(DDA::stepClockRate/8) // prepare moves one eighth of a second ahead of when they will be needed
- && preparedCount < DdaRingLength/2 // but don't prepare more than half the ring
- )
- {
- cdda->Prepare();
- preparedTime += cdda->GetTimeLeft();
- ++preparedCount;
- cdda = cdda->GetNext();
- st = cdda->GetState();
- }
+ // If the number of prepared moves will execute in less than the minimum time, prepare another move
+ while (st == DDA::provisional
+ && preparedTime < (int32_t)(DDA::stepClockRate/8) // prepare moves one eighth of a second ahead of when they will be needed
+ && preparedCount < DdaRingLength/2 // but don't prepare more than half the ring
+ )
+ {
+ cdda->Prepare();
+ preparedTime += cdda->GetTimeLeft();
+ ++preparedCount;
+ cdda = cdda->GetNext();
+ st = cdda->GetState();
+ }
- // If we are simulating and the move pipeline is reasonably full, simulate completion of the current move
- if (simulationMode != 0 && idleCount >= 10)
- {
- // Simulate completion of the current move
+ // If we are simulating and the move pipeline is reasonably full, simulate completion of the current move
+ if (simulationMode != 0 && idleCount >= 10)
+ {
+ // Simulate completion of the current move
//DEBUG
//currentDda->DebugPrint();
- simulationTime += currentDda->CalcTime();
- CurrentMoveCompleted();
- }
+ simulationTime += currentDda->CalcTime();
+ CurrentMoveCompleted();
}
}
@@ -355,7 +350,7 @@ FilePosition Move::PausePrint(float positions[DRIVES], float& pausedFeedRate, ui
if (ddaRingAddPointer != savedDdaRingAddPointer)
{
- const size_t numAxes = reprap.GetGCodes().GetNumAxes();
+ const size_t numAxes = reprap.GetGCodes().GetTotalAxes();
// We are going to skip some moves. dda points to the last move we are going to print.
for (size_t axis = 0; axis < numAxes; ++axis)
@@ -444,8 +439,8 @@ void Move::Diagnostics(MessageType mtype)
char ch = ' ';
for (size_t i = 0; i < DDA::numLoggedProbePositions; ++i)
{
- float xyzPos[CART_AXES];
- MotorStepsToCartesian(DDA::loggedProbePositions + (CART_AXES * i), CART_AXES, xyzPos);
+ float xyzPos[XYZ_AXES];
+ MotorStepsToCartesian(DDA::loggedProbePositions + (XYZ_AXES * i), XYZ_AXES, XYZ_AXES, xyzPos);
p.MessageF(mtype, "%c%.2f,%.2f", ch, xyzPos[X_AXIS], xyzPos[Y_AXIS]);
ch = ',';
}
@@ -480,7 +475,7 @@ void Move::EndPointToMachine(const float coords[], int32_t ep[], size_t numDrive
{
if (CartesianToMotorSteps(coords, ep))
{
- const size_t numAxes = reprap.GetGCodes().GetNumAxes();
+ const size_t numAxes = reprap.GetGCodes().GetTotalAxes();
for (size_t drive = numAxes; drive < numDrives; ++drive)
{
ep[drive] = MotorEndPointToMachine(drive, coords[drive]);
@@ -496,16 +491,16 @@ int32_t Move::MotorEndPointToMachine(size_t drive, float coord)
// Convert motor coordinates to machine coordinates. Used after homing and after individual motor moves.
// This is computationally expensive on a delta or SCARA machine, so only call it when necessary, and never from the step ISR.
-void Move::MotorStepsToCartesian(const int32_t motorPos[], size_t numDrives, float machinePos[]) const
+void Move::MotorStepsToCartesian(const int32_t motorPos[], size_t numVisibleAxes, size_t numTotalAxes, float machinePos[]) const
{
- kinematics->MotorStepsToCartesian(motorPos, reprap.GetPlatform().GetDriveStepsPerUnit(), numDrives, machinePos);
+ kinematics->MotorStepsToCartesian(motorPos, reprap.GetPlatform().GetDriveStepsPerUnit(), numVisibleAxes, numTotalAxes, machinePos);
}
// Convert Cartesian coordinates to motor steps, axes only, returning true if successful.
// Used to perform movement and G92 commands.
-bool Move::CartesianToMotorSteps(const float machinePos[MAX_AXES], int32_t motorPos[MAX_AXES]) const
+bool Move::CartesianToMotorSteps(const float machinePos[MaxAxes], int32_t motorPos[MaxAxes]) const
{
- const bool b = kinematics->CartesianToMotorSteps(machinePos, reprap.GetPlatform().GetDriveStepsPerUnit(), reprap.GetGCodes().GetNumAxes(), motorPos);
+ const bool b = kinematics->CartesianToMotorSteps(machinePos, reprap.GetPlatform().GetDriveStepsPerUnit(), reprap.GetGCodes().GetVisibleAxes(), reprap.GetGCodes().GetTotalAxes(), motorPos);
if (reprap.Debug(moduleMove) && reprap.Debug(moduleDda))
{
if (b)
@@ -520,7 +515,7 @@ bool Move::CartesianToMotorSteps(const float machinePos[MAX_AXES], int32_t motor
return b;
}
-void Move::AxisAndBedTransform(float xyzPoint[MAX_AXES], uint32_t xAxes, bool useBedCompensation) const
+void Move::AxisAndBedTransform(float xyzPoint[MaxAxes], uint32_t xAxes, bool useBedCompensation) const
{
AxisTransform(xyzPoint);
if (useBedCompensation)
@@ -529,14 +524,14 @@ void Move::AxisAndBedTransform(float xyzPoint[MAX_AXES], uint32_t xAxes, bool us
}
}
-void Move::InverseAxisAndBedTransform(float xyzPoint[MAX_AXES], uint32_t xAxes) const
+void Move::InverseAxisAndBedTransform(float xyzPoint[MaxAxes], uint32_t xAxes) const
{
InverseBedTransform(xyzPoint, xAxes);
InverseAxisTransform(xyzPoint);
}
// Do the Axis transform BEFORE the bed transform
-void Move::AxisTransform(float xyzPoint[MAX_AXES]) const
+void Move::AxisTransform(float xyzPoint[MaxAxes]) const
{
//TODO should we transform U axis instead of/as well as X if we are in dual carriage mode?
xyzPoint[X_AXIS] += tanXY*xyzPoint[Y_AXIS] + tanXZ*xyzPoint[Z_AXIS];
@@ -544,7 +539,7 @@ void Move::AxisTransform(float xyzPoint[MAX_AXES]) const
}
// Invert the Axis transform AFTER the bed transform
-void Move::InverseAxisTransform(float xyzPoint[MAX_AXES]) const
+void Move::InverseAxisTransform(float xyzPoint[MaxAxes]) const
{
//TODO should we transform U axis instead of/as well as X if we are in dual carriage mode?
xyzPoint[Y_AXIS] -= tanYZ*xyzPoint[Z_AXIS];
@@ -552,12 +547,12 @@ void Move::InverseAxisTransform(float xyzPoint[MAX_AXES]) const
}
// Do the bed transform AFTER the axis transform
-void Move::BedTransform(float xyzPoint[MAX_AXES], uint32_t xAxes) const
+void Move::BedTransform(float xyzPoint[MaxAxes], uint32_t xAxes) const
{
if (!useTaper || xyzPoint[Z_AXIS] < taperHeight)
{
float zCorrection = 0.0;
- const size_t numAxes = reprap.GetGCodes().GetNumAxes();
+ const size_t numAxes = reprap.GetGCodes().GetVisibleAxes();
unsigned int numXAxes = 0;
// Transform the Z coordinate based on the average correction for each axis used as an X axis.
@@ -589,10 +584,10 @@ void Move::BedTransform(float xyzPoint[MAX_AXES], uint32_t xAxes) const
}
// Invert the bed transform BEFORE the axis transform
-void Move::InverseBedTransform(float xyzPoint[MAX_AXES], uint32_t xAxes) const
+void Move::InverseBedTransform(float xyzPoint[MaxAxes], uint32_t xAxes) const
{
float zCorrection = 0.0;
- const size_t numAxes = reprap.GetGCodes().GetNumAxes();
+ const size_t numAxes = reprap.GetGCodes().GetVisibleAxes();
unsigned int numXAxes = 0;
// Transform the Z coordinate based on the average correction for each axis used as an X axis.
@@ -759,49 +754,6 @@ void Move::AdjustMotorPositions(const float_t adjustment[], size_t numMotors)
liveCoordinatesValid = false; // force the live XYZ position to be recalculated
}
-static void ShortDelay()
-{
- for (unsigned int i = 0; i < 10; ++i)
- {
- asm volatile("nop");
- asm volatile("nop");
- asm volatile("nop");
- asm volatile("nop");
- asm volatile("nop");
- asm volatile("nop");
- asm volatile("nop");
- asm volatile("nop");
- asm volatile("nop");
- }
-}
-
-// This is the function that is called by the timer interrupt to step the motors when we are using the experimental delta probe.
-// The movements are quite slow so it is not time-critical.
-void Move::DeltaProbeInterrupt()
-{
- bool again;
- do
- {
- if (reprap.GetPlatform().GetZProbeResult() == EndStopHit::lowHit)
- {
- deltaProbe.Trigger();
- }
-
- const bool dir = deltaProbe.GetDirection();
- Platform& platform = reprap.GetPlatform();
- platform.SetDirection(X_AXIS, dir);
- platform.SetDirection(Y_AXIS, dir);
- platform.SetDirection(Z_AXIS, dir);
- ShortDelay();
- const uint32_t steppersMoving = platform.GetDriversBitmap(X_AXIS) | platform.GetDriversBitmap(Y_AXIS) | platform.GetDriversBitmap(Z_AXIS);
- Platform::StepDriversHigh(steppersMoving);
- ShortDelay();
- Platform::StepDriversLow();
- const uint32_t tim = deltaProbe.CalcNextStepTime();
- again = (tim != 0xFFFFFFFF && platform.ScheduleInterrupt(tim + deltaProbingStartTime));
- } while (again);
-}
-
// This is called from the step ISR when the current move has been completed
void Move::CurrentMoveCompleted()
{
@@ -837,7 +789,7 @@ bool Move::TryStartNextMove(uint32_t startTime)
// This is called from the step ISR. Any variables it modifies that are also read by code outside the ISR must be declared 'volatile'.
void Move::HitLowStop(size_t axis, DDA* hitDDA)
{
- if (axis < reprap.GetGCodes().GetNumAxes() && !IsDeltaMode()) // should always be true
+ if (axis < reprap.GetGCodes().GetTotalAxes() && !IsDeltaMode()) // should always be true
{
JustHomed(axis, reprap.GetPlatform().AxisMinimum(axis), hitDDA);
}
@@ -846,7 +798,7 @@ void Move::HitLowStop(size_t axis, DDA* hitDDA)
// This is called from the step ISR. Any variables it modifies that are also read by code outside the ISR must be declared 'volatile'.
void Move::HitHighStop(size_t axis, DDA* hitDDA)
{
- if (axis < reprap.GetGCodes().GetNumAxes()) // should always be true
+ if (axis < reprap.GetGCodes().GetTotalAxes()) // should always be true
{
const float hitPoint = (IsDeltaMode())
? ((LinearDeltaKinematics*)kinematics)->GetHomedCarriageHeight(axis) // this is a delta printer, so the motor is at the homed carriage height for this drive
@@ -860,13 +812,13 @@ void Move::JustHomed(size_t axisHomed, float hitPoint, DDA* hitDDA)
{
if (IsCoreXYAxis(axisHomed))
{
- float tempCoordinates[CART_AXES];
- for (size_t axis = 0; axis < CART_AXES; ++axis)
+ float tempCoordinates[XYZ_AXES];
+ for (size_t axis = 0; axis < XYZ_AXES; ++axis)
{
tempCoordinates[axis] = hitDDA->GetEndCoordinate(axis, false);
}
tempCoordinates[axisHomed] = hitPoint;
- hitDDA->SetPositions(tempCoordinates, CART_AXES);
+ hitDDA->SetPositions(tempCoordinates, XYZ_AXES);
}
else
{
@@ -887,7 +839,7 @@ void Move::ZProbeTriggered(DDA* hitDDA)
void Move::GetCurrentMachinePosition(float m[DRIVES], bool disableMotorMapping) const
{
DDA * const lastQueuedMove = ddaRingAddPointer->GetPrevious();
- const size_t numAxes = reprap.GetGCodes().GetNumAxes();
+ const size_t numAxes = reprap.GetGCodes().GetVisibleAxes();
for (size_t i = 0; i < DRIVES; i++)
{
if (i < numAxes)
@@ -930,7 +882,7 @@ void Move::GetCurrentUserPosition(float m[DRIVES], uint8_t moveType, uint32_t xA
void Move::LiveCoordinates(float m[DRIVES], uint32_t xAxes)
{
// The live coordinates and live endpoints are modified by the ISR, so be careful to get a self-consistent set of them
- const size_t numAxes = reprap.GetGCodes().GetNumAxes(); // do this before we disable interrupts
+ const size_t numVisibleAxes = reprap.GetGCodes().GetVisibleAxes(); // do this before we disable interrupts
cpu_irq_disable();
if (liveCoordinatesValid)
{
@@ -940,19 +892,20 @@ void Move::LiveCoordinates(float m[DRIVES], uint32_t xAxes)
}
else
{
+ const size_t numTotalAxes = reprap.GetGCodes().GetTotalAxes(); // do this before we disable interrupts
// Only the extruder coordinates are valid, so we need to convert the motor endpoints to coordinates
- memcpy(m + numAxes, const_cast<const float *>(liveCoordinates + numAxes), sizeof(m[0]) * (DRIVES - numAxes));
- int32_t tempEndPoints[MAX_AXES];
+ memcpy(m + numTotalAxes, const_cast<const float *>(liveCoordinates + numTotalAxes), sizeof(m[0]) * (DRIVES - numTotalAxes));
+ int32_t tempEndPoints[MaxAxes];
memcpy(tempEndPoints, const_cast<const int32_t*>(liveEndPoints), sizeof(tempEndPoints));
cpu_irq_enable();
- MotorStepsToCartesian(tempEndPoints, numAxes, m); // this is slow, so do it with interrupts enabled
+ MotorStepsToCartesian(tempEndPoints, numVisibleAxes, numTotalAxes, m); // this is slow, so do it with interrupts enabled
// If the ISR has not updated the endpoints, store the live coordinates back so that we don't need to do it again
cpu_irq_disable();
if (memcmp(tempEndPoints, const_cast<const int32_t*>(liveEndPoints), sizeof(tempEndPoints)) == 0)
{
- memcpy(const_cast<float *>(liveCoordinates), m, sizeof(m[0]) * numAxes);
+ memcpy(const_cast<float *>(liveCoordinates), m, sizeof(m[0]) * numVisibleAxes);
liveCoordinatesValid = true;
}
cpu_irq_enable();
@@ -969,13 +922,13 @@ void Move::SetLiveCoordinates(const float coords[DRIVES])
liveCoordinates[drive] = coords[drive];
}
liveCoordinatesValid = true;
- EndPointToMachine(coords, const_cast<int32_t *>(liveEndPoints), reprap.GetGCodes().GetNumAxes());
+ EndPointToMachine(coords, const_cast<int32_t *>(liveEndPoints), reprap.GetGCodes().GetVisibleAxes());
}
void Move::ResetExtruderPositions()
{
cpu_irq_disable();
- for (size_t eDrive = reprap.GetGCodes().GetNumAxes(); eDrive < DRIVES; eDrive++)
+ for (size_t eDrive = reprap.GetGCodes().GetTotalAxes(); eDrive < DRIVES; eDrive++)
{
liveCoordinates[eDrive] = 0.0;
}
@@ -1055,47 +1008,4 @@ bool Move::IsCoreXYAxis(size_t axis) const
}
}
-// Do a delta probe returning -1 if still probing, 0 if failed, 1 if success
-int Move::DoDeltaProbe(float frequency, float amplitude, float rate, float distance)
-{
- if (deltaProbing)
- {
- if (deltaProbe.Finished())
- {
- deltaProbing = false;
- return (deltaProbe.Overran()) ? 0 : 1;
- }
- }
- else
- {
- if (currentDda != nullptr || !DDARingEmpty())
- {
- return 0;
- }
- if (!deltaProbe.Init(frequency, amplitude, rate, distance))
- {
- return 0;
- }
-
- const uint32_t firstInterruptTime = deltaProbe.Start();
- if (firstInterruptTime != 0xFFFFFFFF)
- {
- Platform& platform = reprap.GetPlatform();
- platform.EnableDrive(X_AXIS);
- platform.EnableDrive(Y_AXIS);
- platform.EnableDrive(Z_AXIS);
- deltaProbing = true;
- iState = IdleState::busy;
- const irqflags_t flags = cpu_irq_save();
- deltaProbingStartTime = platform.GetInterruptClocks();
- if (platform.ScheduleInterrupt(firstInterruptTime + deltaProbingStartTime))
- {
- Interrupt();
- }
- cpu_irq_restore(flags);
- }
- }
- return -1;
-}
-
// End