diff options
author | David Crocker <dcrocker@eschertech.com> | 2018-02-15 19:29:12 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2018-02-15 19:29:28 +0300 |
commit | 6629a8d0d5372637c70217f3bdfb0c0d339f21d1 (patch) | |
tree | 9274b9311978326aa24989e758f3a8928cea0508 /src/Movement | |
parent | 56ce29027a745be0def9d53168513f8ecafd0208 (diff) |
Version 1.21RC2
The filament usage comments generated by Ideamaker are now recognised
A separate Z probe type (P9 in M558) is now used for BLTouch and
compatible Z probes. When this is selected, the deployprobe.g macro is
run just before each probing move, and retractprobe.g is run every time
the probe triggers, or at the end of the probing move if it doesn't
trigger
All heaters are turned off during probing moves if parameter B1 is
specified in the M558 command
The M671 command can be used with just one pair of X and Y coordinates,
which disables the manual bed calibration assistant
Continuous rotation proximal and distal joints are now supported on
SCARA printers, and continuous rotation turntables are assumed on Polar
printers
When beginning a print from SD card, macro /sys/start.g is run if it is
present
Sending M0 or M1 from a source other than the SD card no longer stops an
SD card print that is not paused
When a serial input channel detects a framing or overrun error other
than in a GCode end-of-line comment, the line of GCode in which it
occurs is discarded
When the M207 Z hop setting was changed during a print while a travel
move is in progress, at the end of the travel move the head was lowered
by the new value for Z hop instead of the original value
Endstop pins 5-9 (E2-E6) on the expansion connector are now working
If neither of the /www/reprap.htm and /www/html404.htm files was present
when the web server as asked to fetch a file, it returned a 404 error,
however there was no associated plain text response so most browsers
displayed a blank screen (fixed in Duet WiFi/Ethernet build only)
If a G0 or G1 command resulted in no movement (e.g. because it was a
duplicate of a previous line) then correct synchronisation between
subsequent movement and non-movement commands was lost
Diffstat (limited to 'src/Movement')
-rw-r--r-- | src/Movement/DDA.cpp | 27 | ||||
-rw-r--r-- | src/Movement/Kinematics/Kinematics.h | 3 | ||||
-rw-r--r-- | src/Movement/Kinematics/PolarKinematics.cpp | 6 | ||||
-rw-r--r-- | src/Movement/Kinematics/PolarKinematics.h | 1 | ||||
-rw-r--r-- | src/Movement/Kinematics/ScaraKinematics.cpp | 22 | ||||
-rw-r--r-- | src/Movement/Kinematics/ScaraKinematics.h | 4 | ||||
-rw-r--r-- | src/Movement/Kinematics/ZLeadscrewKinematics.cpp | 5 | ||||
-rw-r--r-- | src/Movement/Move.cpp | 6 |
8 files changed, 60 insertions, 14 deletions
diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp index 3d41bdc8..54fe9e95 100644 --- a/src/Movement/DDA.cpp +++ b/src/Movement/DDA.cpp @@ -271,6 +271,8 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping) float accelerations[DRIVES]; const float * const normalAccelerations = reprap.GetPlatform().Accelerations(); const size_t numAxes = reprap.GetGCodes().GetTotalAxes(); + const Kinematics& k = move.GetKinematics(); + for (size_t drive = 0; drive < DRIVES; drive++) { accelerations[drive] = normalAccelerations[drive]; @@ -280,7 +282,27 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping) } endCoordinates[drive] = nextMove.coords[drive]; - const int32_t delta = (drive < numAxes) ? endPoint[drive] - positionNow[drive] : endPoint[drive]; + int32_t delta; + if (drive < numAxes) + { + delta = endPoint[drive] - positionNow[drive]; + if (k.IsContinuousRotationAxis(drive)) + { + const int32_t stepsPerRotation = lrintf(360.0 * reprap.GetPlatform().DriveStepsPerUnit(drive)); + if (delta > stepsPerRotation/2) + { + delta -= stepsPerRotation; + } + else if (delta < -stepsPerRotation/2) + { + delta += stepsPerRotation; + } + } + } + else + { + delta = endPoint[drive]; + } if (drive < numAxes && doMotorMapping) { @@ -390,7 +412,6 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping) // There is some XY movement, so normalise the direction vector so that the total XYZ movement has unit length and 'totalDistance' is the XYZ distance moved. // This means that the user gets the feed rate that he asked for. It also makes the delta calculations simpler. // First do the bed tilt compensation for deltas. - const Kinematics& k = move.GetKinematics(); directionVector[Z_AXIS] += (directionVector[X_AXIS] * k.GetTiltCorrection(X_AXIS)) + (directionVector[Y_AXIS] * k.GetTiltCorrection(Y_AXIS)); totalDistance = NormaliseXYZ(); @@ -446,7 +467,7 @@ bool DDA::Init(GCodes::RawMove &nextMove, bool doMotorMapping) // for diagonal moves. On a delta, this is not OK and any movement in the XY plane should be limited to the X/Y axis values, which we assume to be equal. if (doMotorMapping) { - reprap.GetMove().GetKinematics().LimitSpeedAndAcceleration(*this, normalisedDirectionVector); // give the kinematics the chance to further restrict the speed and acceleration + k.LimitSpeedAndAcceleration(*this, normalisedDirectionVector); // give the kinematics the chance to further restrict the speed and acceleration } // 7. Calculate the provisional accelerate and decelerate distances and the top speed diff --git a/src/Movement/Kinematics/Kinematics.h b/src/Movement/Kinematics/Kinematics.h index bfc90fef..b6bd0c5e 100644 --- a/src/Movement/Kinematics/Kinematics.h +++ b/src/Movement/Kinematics/Kinematics.h @@ -156,6 +156,9 @@ public: // The speeds along individual Cartesian axes have already been limited before this is called. virtual void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector) const = 0; + // Return true if the specified axis is a continuous rotation axis + virtual bool IsContinuousRotationAxis(size_t axis) const { return false; } + // Override this virtual destructor if your constructor allocates any dynamic memory virtual ~Kinematics() { } diff --git a/src/Movement/Kinematics/PolarKinematics.cpp b/src/Movement/Kinematics/PolarKinematics.cpp index 0084dd85..c9781ada 100644 --- a/src/Movement/Kinematics/PolarKinematics.cpp +++ b/src/Movement/Kinematics/PolarKinematics.cpp @@ -250,6 +250,12 @@ void PolarKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalise } } +// Return true if the specified axis is a continuous rotation axis +bool PolarKinematics::IsContinuousRotationAxis(size_t axis) const +{ + return axis == 1; +} + // Update the derived parameters after the master parameters have been changed void PolarKinematics::Recalc() { diff --git a/src/Movement/Kinematics/PolarKinematics.h b/src/Movement/Kinematics/PolarKinematics.h index 58b0cc36..fa5c670c 100644 --- a/src/Movement/Kinematics/PolarKinematics.h +++ b/src/Movement/Kinematics/PolarKinematics.h @@ -30,6 +30,7 @@ public: bool QueryTerminateHomingMove(size_t axis) const override; void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const override; void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector) const override; + bool IsContinuousRotationAxis(size_t axis) const override; private: static constexpr float DefaultSegmentsPerSecond = 100.0; diff --git a/src/Movement/Kinematics/ScaraKinematics.cpp b/src/Movement/Kinematics/ScaraKinematics.cpp index 2fae5433..34634891 100644 --- a/src/Movement/Kinematics/ScaraKinematics.cpp +++ b/src/Movement/Kinematics/ScaraKinematics.cpp @@ -61,10 +61,10 @@ bool ScaraKinematics::CalculateThetaAndPsi(const float machinePos[], bool isCoor if (armMode != switchedMode) { // The following equations choose arm mode 0 i.e. distal arm rotated anticlockwise relative to proximal arm - if (psi >= psiLimits[0] && psi <= psiLimits[1]) + if (supportsContinuousRotation[1] || (psi >= psiLimits[0] && psi <= psiLimits[1])) { theta = atan2f(SCARA_K1 * y - SCARA_K2 * x, SCARA_K1 * x + SCARA_K2 * y); - if (theta >= thetaLimits[0] && theta <= thetaLimits[1]) + if (supportsContinuousRotation[0] || (theta >= thetaLimits[0] && theta <= thetaLimits[1])) { break; } @@ -73,10 +73,10 @@ bool ScaraKinematics::CalculateThetaAndPsi(const float machinePos[], bool isCoor else { // The following equations choose arm mode 1 i.e. distal arm rotated clockwise relative to proximal arm - if ((-psi) >= psiLimits[0] && (-psi) <= psiLimits[1]) + if (supportsContinuousRotation[1] || ((-psi) >= psiLimits[0] && (-psi) <= psiLimits[1])) { theta = atan2f(SCARA_K1 * y + SCARA_K2 * x, SCARA_K1 * x - SCARA_K2 * y); - if (theta >= thetaLimits[0] && theta <= thetaLimits[1]) + if (supportsContinuousRotation[0] || (theta >= thetaLimits[0] && theta <= thetaLimits[1])) { psi = -psi; break; @@ -430,17 +430,27 @@ void ScaraKinematics::LimitSpeedAndAcceleration(DDA& dda, const float *normalise } } +// Return true if the specified axis is a continuous rotation axis +bool ScaraKinematics::IsContinuousRotationAxis(size_t axis) const +{ + return axis < 2 && supportsContinuousRotation[axis]; +} + // Recalculate the derived parameters void ScaraKinematics::Recalc() { proximalArmLengthSquared = fsquare(proximalArmLength); distalArmLengthSquared = fsquare(distalArmLength); - twoPd = proximalArmLength * distalArmLength * 2.0f; + twoPd = proximalArmLength * distalArmLength * 2; minRadius = sqrtf(proximalArmLengthSquared + distalArmLengthSquared - twoPd * max<float>(cosf(psiLimits[0] * DegreesToRadians), cosf(psiLimits[1] * DegreesToRadians))) * 1.005; - if (psiLimits[0] < 0.0 && psiLimits[1] > 0.0) + // If the total angle range is greater than 360 degrees, we assume that it supports continuous rotation + supportsContinuousRotation[0] = (thetaLimits[1] - thetaLimits[0] > 360.0); + supportsContinuousRotation[1] = (psiLimits[1] - psiLimits[0] > 360.0); + + if (supportsContinuousRotation[1] || (psiLimits[0] <= 0.0 && psiLimits[1] >= 0.0)) { // Zero distal arm angle is reachable maxRadius = proximalArmLength + distalArmLength; diff --git a/src/Movement/Kinematics/ScaraKinematics.h b/src/Movement/Kinematics/ScaraKinematics.h index 36efbe83..b6193b6a 100644 --- a/src/Movement/Kinematics/ScaraKinematics.h +++ b/src/Movement/Kinematics/ScaraKinematics.h @@ -41,6 +41,7 @@ public: bool QueryTerminateHomingMove(size_t axis) const override; void OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const override; void LimitSpeedAndAcceleration(DDA& dda, const float *normalisedDirectionVector) const override; + bool IsContinuousRotationAxis(size_t axis) const override; private: static constexpr float DefaultSegmentsPerSecond = 100.0; @@ -63,9 +64,10 @@ private: float distalArmLength; float thetaLimits[2]; // minimum proximal joint angle float psiLimits[2]; // minimum distal joint angle - float crosstalk[3]; // if we rotate the distal arm motor, for each full rotation the Z height goes up by this amount + float crosstalk[3]; // proximal to distal, proximal to X and distal to Z crosstalk float xOffset; // where bed X=0 is relative to the proximal joint float yOffset; // where bed Y=0 is relative to the proximal joint + bool supportsContinuousRotation[2]; // true if the (proximal, distal) arms support continuous rotation // Derived parameters float minRadius, minRadiusSquared; diff --git a/src/Movement/Kinematics/ZLeadscrewKinematics.cpp b/src/Movement/Kinematics/ZLeadscrewKinematics.cpp index db43dbc1..1e263e8b 100644 --- a/src/Movement/Kinematics/ZLeadscrewKinematics.cpp +++ b/src/Movement/Kinematics/ZLeadscrewKinematics.cpp @@ -29,6 +29,7 @@ bool ZLeadscrewKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const { // Configuring leadscrew positions. // We no longer require the number of leadscrews to equal the number of motors. If there is a mismatch then auto calibration just prints the corrections. + // We now allow just 1 pair of coordinates to be specified, which in effect clears the M671 settings. bool seenX = false, seenY = false; size_t xSize = MaxLeadscrews, ySize = MaxLeadscrews; if (gb.Seen('X')) @@ -48,7 +49,7 @@ bool ZLeadscrewKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const bool seenP = false; gb.TryGetFValue('P', screwPitch, seenP); - if (seenX && seenY && xSize == ySize && xSize > 1) + if (seenX && seenY && xSize == ySize) { numLeadscrews = xSize; return false; // successful configuration @@ -56,7 +57,7 @@ bool ZLeadscrewKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const if (seenX || seenY) { - reply.copy("Specify 2, 3 or 4 X and Y coordinates in M671"); + reply.copy("Specify 1, 2, 3 or 4 X and Y coordinates in M671"); return true; } diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp index b779b735..93adf343 100644 --- a/src/Movement/Move.cpp +++ b/src/Movement/Move.cpp @@ -217,6 +217,7 @@ void Move::Spin() { AxisAndBedTransform(nextMove.coords, nextMove.xAxes, nextMove.yAxes, true); } + if (ddaRingAddPointer->Init(nextMove, !IsRawMotorMove(nextMove.moveType))) { ddaRingAddPointer = ddaRingAddPointer->GetNext(); @@ -234,6 +235,7 @@ void Move::Spin() lastStateChangeTime = now; } } + #if 0 // see above // Save the amount of extrusion not done for (size_t drive = numAxes; drive < DRIVES; ++drive) @@ -373,7 +375,7 @@ bool Move::IsRawMotorMove(uint8_t moveType) const // Return true if the specified point is accessible to the Z probe bool Move::IsAccessibleProbePoint(float x, float y) const { - const ZProbeParameters& params = reprap.GetPlatform().GetCurrentZProbeParameters(); + const ZProbe& params = reprap.GetPlatform().GetCurrentZProbeParameters(); return kinematics->IsReachable(x - params.xOffset, y - params.yOffset, false); } @@ -1168,7 +1170,7 @@ float Move::GetProbeCoordinates(int count, float& x, float& y, bool wantNozzlePo y = probePoints.GetYCoord(count); if (wantNozzlePosition) { - const ZProbeParameters& rp = reprap.GetPlatform().GetCurrentZProbeParameters(); + const ZProbe& rp = reprap.GetPlatform().GetCurrentZProbeParameters(); x -= rp.xOffset; y -= rp.yOffset; } |