This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
reprapfirmware-dc42/Move.h
David Crocker b4b82c6546 Version 1.09j
Bug fix: Pause function sometimes used to hang while running pause macro
file
Don't wait for all moved to complete when executing a G92 command that
just resets extruder positions
M574 endstop configuration now overrides M558 when determining whether
or not to use the Z probe instead of a homing switch
Added XYZ parameters to M667 command to support CoreXZ etc. machines
with paired axis ratios that are not 1:1
Minor change to step ISR to improve timings and service drives in
round-robin order
2015-09-06 14:10:42 +01:00

195 lines
11 KiB
C++

/*
* Move.h
*
* Created on: 7 Dec 2014
* Author: David
*/
#ifndef MOVE_H_
#define MOVE_H_
#include "DDA.h"
#include "Matrix.h"
#include "DeltaParameters.h"
#include "DeltaProbe.h"
const unsigned int DdaRingLength = 20;
enum PointCoordinateSet
{
unset = 0,
xSet = 1,
ySet = 2,
zSet = 4,
xyCorrected = 8,
probeError = 16
};
/**
* This is the master movement class. It controls all movement in the machine.
*/
class Move
{
public:
Move(Platform* p, GCodes* g);
void Init(); // Start me up
void Spin(); // Called in a tight loop to keep the class going
void Exit(); // Shut down
void GetCurrentUserPosition(float m[DRIVES + 1], uint8_t moveType) const; // Return the position (after all queued moves have been executed) in transformed coords
int32_t GetEndPoint(size_t drive) const { return liveEndPoints[drive]; } // Get the current position of a motor
void LiveCoordinates(float m[DRIVES]); // Gives the last point at the end of the last complete DDA transformed to user coords
void Interrupt(); // The hardware's (i.e. platform's) interrupt should call this.
void InterruptTime(); // Test function - not used
bool AllMovesAreFinished(); // Is the look-ahead ring empty? Stops more moves being added as well.
void ResumeMoving(); // Allow moves to be added after a call to AllMovesAreFinished()
void DoLookAhead(); // Run the look-ahead procedure
void HitLowStop(size_t axis, DDA* hitDDA); // What to do when a low endstop is hit
void HitHighStop(size_t axis, DDA* hitDDA); // What to do when a high endstop is hit
void ZProbeTriggered(DDA* hitDDA); // What to do when a the Z probe is triggered
void SetPositions(const float move[DRIVES]); // Force the coordinates to be these
void SetFeedrate(float feedRate); // Sometimes we want to override the feed rate
void SetLiveCoordinates(const float coords[DRIVES]); // Force the live coordinates (see above) to be these
void SetXBedProbePoint(int index, float x); // Record the X coordinate of a probe point
void SetYBedProbePoint(int index, float y); // Record the Y coordinate of a probe point
void SetZBedProbePoint(int index, float z, bool wasXyCorrected, bool wasError); // Record the Z coordinate of a probe point
float XBedProbePoint(int index) const; // Get the X coordinate of a probe point
float YBedProbePoint(int index) const; // Get the Y coordinate of a probe point
float ZBedProbePoint(int index)const ; // Get the Z coordinate of a probe point
int NumberOfProbePoints() const; // How many points to probe have been set? 0 if incomplete
int NumberOfXYProbePoints() const; // How many XY coordinates of probe points have been set (Zs may not have been probed yet)
bool AllProbeCoordinatesSet(int index) const; // XY, and Z all set for this one?
bool XYProbeCoordinatesSet(int index) const; // Just XY set for this one?
void FinishedBedProbing(int sParam, StringRef& reply); // Calibrate or set the bed equiation after probing
float SecondDegreeTransformZ(float x, float y) const; // Used for second degree bed equation
void SetAxisCompensation(int8_t axis, float tangent); // Set an axis-pair compensation angle
float AxisCompensation(int8_t axis) const; // The tangent value
void SetIdentityTransform(); // Cancel the bed equation; does not reset axis angle compensation
void Transform(float move[]) const; // Take a position and apply the bed and the axis-angle compensations
void InverseTransform(float move[]) const; // Go from a transformed point back to user coordinates
void Diagnostics(); // Report useful stuff
const DeltaParameters& GetDeltaParams() const { return deltaParams; }
DeltaParameters& AccessDeltaParams() { return deltaParams; }
bool IsDeltaMode() const { return deltaParams.IsDeltaMode(); }
const char* GetGeometryString() const;
int GetCoreXYMode() const { return coreXYMode; }
void SetCoreXYMode(int mode) { coreXYMode = mode; }
float GetCoreAxisFactor(size_t axis) const { return axisFactors[axis]; }
void setCoreAxisFactor(size_t axis, float f) { axisFactors[axis] = f; }
bool IsCoreXYAxis(size_t axis) const; // return true if the specified axis shares its motors with another
void CurrentMoveCompleted(); // signals that the current move has just been completed
bool StartNextMove(uint32_t startTime); // start the next move, returning true if Step() needs to be called immediately
void MotorTransform(const float machinePos[AXES], int32_t motorPos[AXES]) const; // Convert Cartesian coordinates to delta motor coordinates
void MachineToEndPoint(const int32_t motorPos[], float machinePos[], size_t numDrives) const; // Convert motor coordinates to machine coordinates
void EndPointToMachine(const float coords[], int32_t ep[], size_t numDrives) const;
void Simulate(bool sim); // Enter or leave simulation mode
float GetSimulationTime() const { return simulationTime; } // Get the accumulated simulation time
void PrintCurrentDda() const; // For debugging
FilePosition PausePrint(float positions[DRIVES+1]); // Pause the print as soon as we can
bool NoLiveMovement() const; // Is a move running, or are there any queued?
int DoDeltaProbe(float frequency, float amplitude, float rate, float distance);
static int32_t MotorEndPointToMachine(size_t drive, float coord); // Convert a single motor position to number of steps
static float MotorEndpointToPosition(int32_t endpoint, size_t drive); // Convert number of motor steps to motor position
private:
enum class IdleState : uint8_t { idle, busy, timing };
void SetProbedBedEquation(size_t numPoints, StringRef& reply); // When we have a full set of probed points, work out the bed's equation
void DoDeltaCalibration(size_t numPoints, StringRef& reply);
void BedTransform(float move[AXES]) const; // Take a position and apply the bed compensations
void GetCurrentMachinePosition(float m[DRIVES + 1], bool disableMotorMapping) const; // Get the current position and feedrate in untransformed coords
void InverseBedTransform(float move[AXES]) const; // Go from a bed-transformed point back to user coordinates
void AxisTransform(float move[AXES]) const; // Take a position and apply the axis-angle compensations
void InverseAxisTransform(float move[AXES]) const; // Go from an axis transformed point back to user coordinates
void BarycentricCoordinates(size_t p0, size_t p1, // Compute the barycentric coordinates of a point in a triangle
size_t p2, float x, float y, float& l1, // (see http://en.wikipedia.org/wiki/Barycentric_coordinate_system).
float& l2, float& l3) const;
float TriangleZ(float x, float y) const; // Interpolate onto a triangular grid
void AdjustDeltaParameters(const float v[], size_t numFactors); // Perform delta adjustment
void JustHomed(size_t axis, float hitPoint, DDA* hitDDA); // deal with setting positions after a drive has been homed
static void PrintMatrix(const char* s, const MathMatrix<float>& m, size_t numRows = 0, size_t maxCols = 0); // for debugging
static void PrintVector(const char *s, const float *v, size_t numElems); // for debugging
bool DDARingAdd(); // Add a processed look-ahead entry to the DDA ring
DDA* DDARingGet(); // Get the next DDA ring entry to be run
bool DDARingEmpty() const; // Anything there?
DDA* volatile currentDda;
DDA* ddaRingAddPointer;
DDA* volatile ddaRingGetPointer;
DDA* ddaRingCheckPointer;
bool addNoMoreMoves; // If true, allow no more moves to be added to the look-ahead
bool active; // Are we live and running?
bool simulating; // Are we simulating, or really printing?
unsigned int idleCount; // The number of times Spin was called and had no new moves to process
float simulationTime; // Print time since we started simulating
float currentFeedrate; // Err... the current feed rate...
volatile float liveCoordinates[DRIVES]; // The endpoint that the machine moved to in the last completed move
volatile bool liveCoordinatesValid; // True if the XYZ live coordinates are reliable (the extruder ones always are)
volatile int32_t liveEndPoints[DRIVES]; // The XYZ endpoints of the last completed move in motor coordinates
float xBedProbePoints[MaxProbePoints]; // The X coordinates of the points on the bed at which to probe
float yBedProbePoints[MaxProbePoints]; // The Y coordinates of the points on the bed at which to probe
float zBedProbePoints[MaxProbePoints]; // The Z coordinates of the points on the bed at which to probe
float baryXBedProbePoints[5]; // The X coordinates of the triangle corner points
float baryYBedProbePoints[5]; // The Y coordinates of the triangle corner points
float baryZBedProbePoints[5]; // The Z coordinates of the triangle corner points
uint8_t probePointSet[MaxProbePoints]; // Has the XY of this point been set? Has the Z been probed?
float aX, aY, aC; // Bed plane explicit equation z' = z + aX*x + aY*y + aC
float tanXY, tanYZ, tanXZ; // Axis compensation - 90 degrees + angle gives angle between axes
int numBedCompensationPoints; // The number of points we are actually using for bed compensation, 0 means identity bed transform
float xRectangle, yRectangle; // The side lengths of the rectangle used for second-degree bed compensation
float idleTimeout; // How long we wait with no activity before we reduce motor currents to idle
float lastMoveTime; // The approximate time at which the last move was completed, or 0
float longWait; // A long time for things that need to be done occasionally
IdleState iState; // whether the idle timer is active
DeltaParameters deltaParams; // Information about the delta parameters of this machine
DeltaProbe deltaProbe; // Delta probing state
uint32_t deltaProbingStartTime;
bool deltaProbing;
int coreXYMode; // 0 = Cartesian, 1 = CoreXY, 2 = CoreXZ, 3 = CoreYZ
float axisFactors[AXES]; // How much further the motors need to move for each axis movement, on a CoreXY/CoreXZ/CoreYZ machine
unsigned int stepErrors; // count of step errors, for diagnostics
};
//******************************************************************************************************
inline bool Move::DDARingEmpty() const
{
return ddaRingGetPointer == ddaRingAddPointer;
}
inline bool Move::NoLiveMovement() const
{
return DDARingEmpty() && currentDda == nullptr; // must test currentDda and DDARingEmpty *in this order* !
}
// To wait until all the current moves in the buffers are
// complete, call this function repeatedly and wait for it to
// return true. Then do whatever you wanted to do after all
// current moves have finished. THEN CALL THE ResumeMoving() FUNCTION
// OTHERWISE NOTHING MORE WILL EVER HAPPEN.
inline bool Move::AllMovesAreFinished()
{
addNoMoreMoves = true;
return NoLiveMovement();
}
inline void Move::ResumeMoving()
{
addNoMoreMoves = false;
}
#endif /* MOVE_H_ */