Version 1.00p (added CoreXY support)

Added CoreXY, CoreXZ and CoreYZ support, ndbaled using M667 command.
This commit is contained in:
David Crocker 2015-03-09 11:38:31 +00:00
parent 0e48d9861a
commit 3c748277bf
10 changed files with 216 additions and 140 deletions

View file

@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H
#define NAME "RepRapFirmware"
#define VERSION "1.00o-dc42"
#define DATE "2015-03-06"
#define VERSION "1.00p-dc42"
#define DATE "2015-03-07"
#define AUTHORS "reprappro, dc42, zpl"
#define FLASH_SAVE_ENABLED (1)

14
DDA.cpp
View file

@ -71,14 +71,16 @@ void DDA::Init()
}
// Set up a real move. Return true if it represents real movement, else false.
bool DDA::Init(const float nextMove[], EndstopChecks ce, bool doDeltaMapping, FilePosition fPos)
bool DDA::Init(const float nextMove[], EndstopChecks ce, bool doMotorMapping, FilePosition fPos)
{
// 1. Compute the new endpoints and the movement vector
const int32_t *positionNow = prev->DriveCoordinates();
if (doDeltaMapping)
if (doMotorMapping)
{
reprap.GetMove()->DeltaTransform(nextMove, endPoint); // transform the axis coordinates if on a delta printer
isDeltaMovement = (endPoint[X_AXIS] != positionNow[X_AXIS]) || (endPoint[Y_AXIS] != positionNow[Y_AXIS]) || (endPoint[Z_AXIS] != positionNow[Z_AXIS]);
const Move *move = reprap.GetMove();
move->MotorTransform(nextMove, endPoint); // transform the axis coordinates if on a delta or CoreXY printer
isDeltaMovement = move->IsDeltaMode()
&& (endPoint[X_AXIS] != positionNow[X_AXIS] || endPoint[Y_AXIS] != positionNow[Y_AXIS] || endPoint[Z_AXIS] != positionNow[Z_AXIS]);
}
else
{
@ -91,7 +93,7 @@ bool DDA::Init(const float nextMove[], EndstopChecks ce, bool doDeltaMapping, Fi
for (size_t drive = 0; drive < DRIVES; drive++)
{
accelerations[drive] = normalAccelerations[drive];
if (drive >= AXES || !doDeltaMapping)
if (drive >= AXES || !doMotorMapping)
{
endPoint[drive] = Move::MotorEndPointToMachine(drive, nextMove[drive]);
}
@ -152,7 +154,7 @@ bool DDA::Init(const float nextMove[], EndstopChecks ce, bool doDeltaMapping, Fi
endStopsToCheck = ce;
filePos = fPos;
// The end coordinates will be valid at the end of this move if it does not involve endstop checks and is not a special move on a delta printer
endCoordinatesValid = (ce == 0) && (doDeltaMapping || !reprap.GetMove()->IsDeltaMode());
endCoordinatesValid = (ce == 0) && (doMotorMapping || !reprap.GetMove()->IsDeltaMode());
// 4. Normalise the direction vector and compute the amount of motion.
// If there is any XYZ movement, then we normalise it so that the total XYZ movement has unit length.

2
DDA.h
View file

@ -31,7 +31,7 @@ public:
DDA(DDA* n);
bool Init(const float nextMove[], EndstopChecks ce,
bool doDeltaMapping, FilePosition fPos); // Set up a new move, returning true if it represents real movement
bool doMotorMapping, FilePosition fPos); // Set up a new move, returning true if it represents real movement
void Init(); // Set up initial positions for machine startup
bool Start(uint32_t tim); // Start executing the DDA, i.e. move the move.
bool Step(); // Take one step of the DDA, called by timed interrupt.

View file

@ -322,7 +322,7 @@ void GCodes::Spin()
float currentZ = moveBuffer[Z_AXIS];
memcpy(moveBuffer, pausedMoveBuffer, sizeof(moveBuffer));
moveBuffer[DRIVES] = 5000 / minutesToSeconds;// ask for a good feed rate, we may have paused during a slow move
disableDeltaMapping = false;
moveType = 0;
endStopsToCheck = 0;
moveFilePos = noFilePosition;
if (state == GCodeState::resuming1 && currentZ > pausedMoveBuffer[Z_AXIS])
@ -523,7 +523,7 @@ bool GCodes::AllMovesAreFinishedAndMoveBufferIsLoaded()
return false;
reprap.GetMove()->ResumeMoving();
reprap.GetMove()->GetCurrentUserPosition(moveBuffer, false);
reprap.GetMove()->GetCurrentUserPosition(moveBuffer, 0);
return true;
}
@ -719,13 +719,13 @@ int GCodes::SetUpMove(GCodeBuffer *gb, StringRef& reply)
// Check to see if the move is a 'homing' move that endstops are checked on.
endStopsToCheck = 0;
disableDeltaMapping = false;
moveType = 0;
if (gb->Seen('S'))
{
int ival = gb->GetIValue();
if (ival == 1 || ival == 2)
{
disableDeltaMapping = true; // if on a delta printer, don't do delta mapping for this move
moveType = ival;
}
if (ival == 1)
@ -743,7 +743,7 @@ int GCodes::SetUpMove(GCodeBuffer *gb, StringRef& reply)
if (reprap.GetMove()->IsDeltaMode())
{
// Extra checks to avoid damaging delta printers
if (disableDeltaMapping && !axesRelative)
if (moveType != 0 && !axesRelative)
{
// We have been asked to do a move without delta mapping on a delta machine, but the move is not relative.
// This may be damaging and is almost certainly a user mistake, so ignore the move.
@ -751,7 +751,7 @@ int GCodes::SetUpMove(GCodeBuffer *gb, StringRef& reply)
return 1;
}
if (!disableDeltaMapping && !AllAxesAreHomed())
if (moveType == 0 && !AllAxesAreHomed())
{
// The user may be attempting to move a delta printer to an XYZ position before homing the axes
// This may be damaging and is almost certainly a user mistake, so ignore the move. But allow extruder-only moves.
@ -764,24 +764,24 @@ int GCodes::SetUpMove(GCodeBuffer *gb, StringRef& reply)
}
// Load the last position and feed rate into moveBuffer
reprap.GetMove()->GetCurrentUserPosition(moveBuffer, disableDeltaMapping);
reprap.GetMove()->GetCurrentUserPosition(moveBuffer, moveType);
moveBuffer[DRIVES] *= speedFactorChange; // account for any change in the speed factor since the last move
speedFactorChange = 1.0;
// Load the move buffer with either the absolute movement required or the relative movement required
moveAvailable = LoadMoveBufferFromGCode(gb, false, limitAxes && !disableDeltaMapping);
moveAvailable = LoadMoveBufferFromGCode(gb, false, limitAxes && moveType == 0);
if (moveAvailable)
{
moveFilePos = (gb == fileGCode) ? filePos : noFilePosition;
//debugPrintf("Queue move pos %u\n", moveFilePos);
}
return (disableDeltaMapping) ? 2 : 1;// note that disableDeltaMapping is true if there are any endstops to check, even on a Cartesian printer
return (moveType != 0) ? 2 : 1;
}
// The Move class calls this function to find what to do next.
bool GCodes::ReadMove(float m[], EndstopChecks& ce, bool& noDeltaMapping, FilePosition& fPos)
bool GCodes::ReadMove(float m[], EndstopChecks& ce, uint8_t& rMoveType, FilePosition& fPos)
{
if (!moveAvailable)
{
@ -793,7 +793,7 @@ bool GCodes::ReadMove(float m[], EndstopChecks& ce, bool& noDeltaMapping, FilePo
m[i] = moveBuffer[i];
}
ce = endStopsToCheck;
noDeltaMapping = disableDeltaMapping;
rMoveType = moveType;
fPos = moveFilePos;
ClearMove();
return true;
@ -803,7 +803,7 @@ void GCodes::ClearMove()
{
moveAvailable = false;
endStopsToCheck = 0;
disableDeltaMapping = false;
moveType = 0;
}
// Run a file macro. Prior to calling this, 'state' must be set to the state we want to enter when the macro has been completed.
@ -876,7 +876,7 @@ bool GCodes::SetPositions(GCodeBuffer *gb)
return false;
}
reprap.GetMove()->GetCurrentUserPosition(moveBuffer, false); // make sure move buffer is up to date
reprap.GetMove()->GetCurrentUserPosition(moveBuffer, 0); // make sure move buffer is up to date
if (LoadMoveBufferFromGCode(gb, true, false))
{
SetPositions(moveBuffer);
@ -2503,7 +2503,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
if (!wasSimulating)
{
// Starting a new simulation, so save the current position
reprap.GetMove()->GetCurrentUserPosition(savedMoveBuffer, false);
reprap.GetMove()->GetCurrentUserPosition(savedMoveBuffer, 0);
}
}
else if (wasSimulating)
@ -2567,7 +2567,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
// Save the current positions as we may need them later
float positionNow[DRIVES];
Move *move = reprap.GetMove();
move->GetCurrentUserPosition(positionNow, false);
move->GetCurrentUserPosition(positionNow, 0);
bool seen = false;
for (size_t axis = 0; axis < AXES; axis++)
@ -3728,7 +3728,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
{
float positionNow[DRIVES];
Move *move = reprap.GetMove();
move->GetCurrentUserPosition(positionNow, false); // get the current position, we may need it later
move->GetCurrentUserPosition(positionNow, 0); // get the current position, we may need it later
DeltaParameters& params = move->AccessDeltaParams();
bool wasInDeltaMode = params.IsDeltaMode(); // remember whether we were in delta mode
bool seen = false;
@ -3780,65 +3780,87 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
break;
case 666: // Set delta endstop adjustments
{
DeltaParameters& params = reprap.GetMove()->AccessDeltaParams();
bool seen = false;
if (gb->Seen('X'))
{
params.SetEndstopAdjustment(X_AXIS, gb->GetFValue());
seen = true;
DeltaParameters& params = reprap.GetMove()->AccessDeltaParams();
bool seen = false;
if (gb->Seen('X'))
{
params.SetEndstopAdjustment(X_AXIS, gb->GetFValue());
seen = true;
}
if (gb->Seen('Y'))
{
params.SetEndstopAdjustment(Y_AXIS, gb->GetFValue());
seen = true;
}
if (gb->Seen('Z'))
{
params.SetEndstopAdjustment(Z_AXIS, gb->GetFValue());
seen = true;
}
if (!seen)
{
reply.printf("Endstop adjustments X%.2f Y%.2f Z%.2f\n", params.GetEndstopAdjustment(X_AXIS),
params.GetEndstopAdjustment(Y_AXIS), params.GetEndstopAdjustment(Z_AXIS));
}
}
if (gb->Seen('Y'))
break;
case 667: // Set CoreXY mode
{
params.SetEndstopAdjustment(Y_AXIS, gb->GetFValue());
seen = true;
Move* move = reprap.GetMove();
if (gb->Seen('S'))
{
float positionNow[DRIVES];
move->GetCurrentUserPosition(positionNow, 0); // get the current position, we may need it later
int newMode = gb->GetIValue();
if (newMode != move->GetCoreXYMode())
{
move->SetCoreXYMode(newMode);
SetPositions(positionNow);
SetAllAxesNotHomed();
}
}
else
{
reply.printf("Printer mode is %s\n", move->GetGeometryString());
}
}
if (gb->Seen('Z'))
{
params.SetEndstopAdjustment(Z_AXIS, gb->GetFValue());
seen = true;
}
if (!seen)
{
reply.printf("Endstop adjustments X%.2f Y%.2f Z%.2f\n", params.GetEndstopAdjustment(X_AXIS),
params.GetEndstopAdjustment(Y_AXIS), params.GetEndstopAdjustment(Z_AXIS));
}
}
break;
case 906: // Set/report Motor currents
{
bool seen = false;
for (int8_t axis = 0; axis < AXES; axis++)
{
if (gb->Seen(axisLetters[axis]))
bool seen = false;
for (int8_t axis = 0; axis < AXES; axis++)
{
platform->SetMotorCurrent(axis, gb->GetFValue());
seen = true;
if (gb->Seen(axisLetters[axis]))
{
platform->SetMotorCurrent(axis, gb->GetFValue());
seen = true;
}
}
}
if (gb->Seen(extrudeLetter))
{
float eVals[DRIVES - AXES];
int eCount = DRIVES - AXES;
gb->GetFloatArray(eVals, eCount);
// 2014-09-29 DC42: we no longer insist that the user supplies values for all possible extruder drives
for (int8_t e = 0; e < eCount; e++)
if (gb->Seen(extrudeLetter))
{
platform->SetMotorCurrent(AXES + e, eVals[e]);
float eVals[DRIVES - AXES];
int eCount = DRIVES - AXES;
gb->GetFloatArray(eVals, eCount);
// 2014-09-29 DC42: we no longer insist that the user supplies values for all possible extruder drives
for (int8_t e = 0; e < eCount; e++)
{
platform->SetMotorCurrent(AXES + e, eVals[e]);
}
}
else if (!seen)
{
reply.printf("Axis currents (mA) - X:%d, Y:%d, Z:%d, E:", (int) platform->MotorCurrent(X_AXIS),
(int) platform->MotorCurrent(Y_AXIS), (int) platform->MotorCurrent(Z_AXIS));
for (int8_t drive = AXES; drive < DRIVES; drive++)
{
reply.catf("%d%c", (int) platform->MotorCurrent(drive), (drive < DRIVES - 1) ? ':' : '\n');
}
}
}
else if (!seen)
{
reply.printf("Axis currents (mA) - X:%d, Y:%d, Z:%d, E:", (int) platform->MotorCurrent(X_AXIS),
(int) platform->MotorCurrent(Y_AXIS), (int) platform->MotorCurrent(Z_AXIS));
for (int8_t drive = AXES; drive < DRIVES; drive++)
{
reply.catf("%d%c", (int) platform->MotorCurrent(drive), (drive < DRIVES - 1) ? ':' : '\n');
}
}
}
break;
case 998:

View file

@ -81,7 +81,7 @@ class GCodes
void Init(); // Set it up
void Exit(); // Shut it down
void Reset(); // Reset some parameter to defaults
bool ReadMove(float* m, EndstopChecks& ce, bool& noDeltaMapping, FilePosition& fPos); // Called by the Move class to get a movement set by the last G Code
bool ReadMove(float* m, EndstopChecks& ce, uint8_t& rMoveType, FilePosition& fPos); // Called by the Move class to get a movement set by the last G Code
void ClearMove();
void QueueFileToPrint(const char* fileName); // Open a file of G Codes to run
void DeleteFile(const char* fileName); // Does what it says
@ -172,7 +172,7 @@ class GCodes
float savedMoveBuffer[DRIVES+1]; // The position and feedrate when we started the current simulation
float pausedMoveBuffer[DRIVES+1]; // Move coordinates; last is feed rate
EndstopChecks endStopsToCheck; // Which end stops we check them on the next move
bool disableDeltaMapping; // True if delta mapping should be bypassed for the next move
uint8_t moveType; // 0 = normal move, 1 = homing move, 2 = direct motor move
GCodeState state; // The main state variable of the GCode state machine
bool drivesRelative;
bool axesRelative;

172
Move.cpp
View file

@ -112,7 +112,7 @@ Move::Move(Platform* p, GCodes* g) : currentDda(NULL)
// Build the DDA ring
DDA *dda = new DDA(NULL);
ddaRingGetPointer = ddaRingAddPointer = dda;
for(size_t i = 1; i < DdaRingLength; i++)
for (size_t i = 1; i < DdaRingLength; i++)
{
DDA *oldDda = dda;
dda = new DDA(dda);
@ -126,6 +126,7 @@ void Move::Init()
{
// Reset Cartesian mode
deltaParams.Init();
coreXYMode = 0;
// Empty the ring
ddaRingGetPointer = ddaRingAddPointer;
@ -226,16 +227,17 @@ void Move::Spin()
// If there's a G Code move available, add it to the DDA ring for processing.
float nextMove[DRIVES + 1];
EndstopChecks endStopsToCheck;
bool noDeltaMapping;
uint8_t moveType;
FilePosition filePos;
if (reprap.GetGCodes()->ReadMove(nextMove, endStopsToCheck, noDeltaMapping, filePos))
if (reprap.GetGCodes()->ReadMove(nextMove, endStopsToCheck, moveType, filePos))
{
currentFeedrate = nextMove[DRIVES]; // might be G1 with just an F field
if (!noDeltaMapping || !IsDeltaMode())
bool doMotorMapping = (moveType == 0) || (moveType == 1 && !IsDeltaMode());
if (doMotorMapping)
{
Transform(nextMove);
}
if (ddaRingAddPointer->Init(nextMove, endStopsToCheck, IsDeltaMode() && !noDeltaMapping, filePos))
if (ddaRingAddPointer->Init(nextMove, endStopsToCheck, doMotorMapping, filePos))
{
ddaRingAddPointer = ddaRingAddPointer->GetNext();
idleCount = 0;
@ -372,7 +374,7 @@ FilePosition Move::PausePrint(float positions[DRIVES+1])
}
else
{
GetCurrentUserPosition(positions, false);
GetCurrentUserPosition(positions, 0);
}
return fPos;
@ -435,22 +437,11 @@ void Move::SetPositions(const float move[DRIVES])
void Move::EndPointToMachine(const float coords[], int32_t ep[], size_t numDrives) const
{
if (IsDeltaMode())
MotorTransform(coords, ep);
for (size_t drive = AXES; drive < numDrives; ++drive)
{
DeltaTransform(coords, ep);
for (size_t drive = AXES; drive < numDrives; ++drive)
{
ep[drive] = MotorEndPointToMachine(drive, coords[drive]);
}
ep[drive] = MotorEndPointToMachine(drive, coords[drive]);
}
else
{
for (size_t drive = 0; drive < DRIVES; drive++)
{
ep[drive] = MotorEndPointToMachine(drive, coords[drive]);
}
}
}
void Move::SetFeedrate(float feedRate)
@ -474,22 +465,102 @@ 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, so only call it when necessary, and never from the step ISR.
void Move::MachineToEndPoint(const int32_t motorPos[], float machinePos[], size_t numDrives) const
{
const float *stepsPerUnit = reprap.GetPlatform()->GetDriveStepsPerUnit();
// Convert the axes
if (IsDeltaMode())
{
InverseDeltaTransform(motorPos, machinePos); // convert the axes
for (size_t drive = AXES; drive < numDrives; ++drive)
deltaParams.InverseTransform(motorPos[A_AXIS]/stepsPerUnit[A_AXIS], motorPos[B_AXIS]/stepsPerUnit[B_AXIS], motorPos[C_AXIS]/stepsPerUnit[C_AXIS], machinePos);
// We don't do inverse transforms very often, so if debugging is enabled, print them
if (reprap.Debug(moduleMove))
{
machinePos[drive] = MotorEndpointToPosition(motorPos[drive], drive);
debugPrintf("Inverse transformed %d %d %d to %f %f %f\n", motorPos[0], motorPos[1], motorPos[2], machinePos[0], machinePos[1], machinePos[2]);
}
}
else
{
for (size_t drive = 0; drive < numDrives; ++drive)
switch (coreXYMode)
{
machinePos[drive] = MotorEndpointToPosition(motorPos[drive], drive);
case 1: // CoreXY
machinePos[X_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Y_AXIS]) - (motorPos[Y_AXIS] * stepsPerUnit[X_AXIS]))/(2 * stepsPerUnit[X_AXIS] * stepsPerUnit[Y_AXIS]);
machinePos[Y_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Y_AXIS]) + (motorPos[Y_AXIS] * stepsPerUnit[X_AXIS]))/(2 * stepsPerUnit[X_AXIS] * stepsPerUnit[Y_AXIS]);
machinePos[Z_AXIS] = motorPos[Z_AXIS]/stepsPerUnit[Z_AXIS];
break;
case 2: // CoreXZ
machinePos[X_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Z_AXIS]) - (motorPos[Z_AXIS] * stepsPerUnit[X_AXIS]))/(2 * stepsPerUnit[X_AXIS] * stepsPerUnit[Z_AXIS]);
machinePos[Y_AXIS] = motorPos[Y_AXIS]/stepsPerUnit[Y_AXIS];
machinePos[Z_AXIS] = ((motorPos[X_AXIS] * stepsPerUnit[Z_AXIS]) + (motorPos[Z_AXIS] * stepsPerUnit[X_AXIS]))/(2 * stepsPerUnit[X_AXIS] * stepsPerUnit[Z_AXIS]);
break;
case 3: // CoreYZ
machinePos[X_AXIS] = motorPos[X_AXIS]/stepsPerUnit[X_AXIS];
machinePos[Y_AXIS] = ((motorPos[Y_AXIS] * stepsPerUnit[Z_AXIS]) - (motorPos[Z_AXIS] * stepsPerUnit[Y_AXIS]))/(2 * stepsPerUnit[Y_AXIS] * stepsPerUnit[Z_AXIS]);
machinePos[Z_AXIS] = ((motorPos[Y_AXIS] * stepsPerUnit[Z_AXIS]) + (motorPos[Z_AXIS] * stepsPerUnit[Y_AXIS]))/(2 * stepsPerUnit[Y_AXIS] * stepsPerUnit[Z_AXIS]);
break;
default:
machinePos[X_AXIS] = motorPos[X_AXIS]/stepsPerUnit[X_AXIS];
machinePos[Y_AXIS] = motorPos[Y_AXIS]/stepsPerUnit[Y_AXIS];
machinePos[Z_AXIS] = motorPos[Z_AXIS]/stepsPerUnit[Z_AXIS];
break;
}
}
// Convert the extruders
for (size_t drive = AXES; drive < numDrives; ++drive)
{
machinePos[drive] = motorPos[drive]/stepsPerUnit[drive];
}
}
// Convert Cartesian coordinates to delta motor steps
void Move::MotorTransform(const float machinePos[AXES], int32_t motorPos[AXES]) const
{
if (IsDeltaMode())
{
for (size_t axis = 0; axis < AXES; ++axis)
{
motorPos[axis] = MotorEndPointToMachine(axis, deltaParams.Transform(machinePos, axis));
}
if (reprap.Debug(moduleMove) && reprap.Debug(moduleDda))
{
debugPrintf("Transformed %f %f %f to %d %d %d\n", machinePos[0], machinePos[1], machinePos[2], motorPos[0], motorPos[1], motorPos[2]);
}
}
else
{
switch (coreXYMode)
{
case 1:
motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, machinePos[X_AXIS] + machinePos[Y_AXIS]);
motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, machinePos[Y_AXIS] - machinePos[X_AXIS]);
motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, machinePos[Z_AXIS]);
break;
case 2:
motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, machinePos[X_AXIS] + machinePos[Z_AXIS]);
motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, machinePos[Y_AXIS]);
motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, machinePos[Z_AXIS] - machinePos[X_AXIS]);
break;
case 3:
motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, machinePos[X_AXIS]);
motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, machinePos[Y_AXIS] + machinePos[Z_AXIS]);
motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, machinePos[Z_AXIS] - machinePos[Y_AXIS]);
break;
default:
motorPos[X_AXIS] = MotorEndPointToMachine(X_AXIS, machinePos[X_AXIS]);
motorPos[Y_AXIS] = MotorEndPointToMachine(Y_AXIS, machinePos[Y_AXIS]);
motorPos[Z_AXIS] = MotorEndPointToMachine(Z_AXIS, machinePos[Z_AXIS]);
break;
}
}
}
@ -576,38 +647,6 @@ void Move::InverseBedTransform(float xyzPoint[AXES]) const
}
}
// Convert motor step positions to Cartesian machine coordinates.
// Used after homing and after individual motor moves.
// Because this is computationally expensive, we only call it when necessary, and never from the step ISR.
void Move::InverseDeltaTransform(const int32_t motorPos[AXES], float machinePos[AXES]) const
{
deltaParams.InverseTransform(
MotorEndpointToPosition(motorPos[A_AXIS], A_AXIS),
MotorEndpointToPosition(motorPos[B_AXIS], B_AXIS),
MotorEndpointToPosition(motorPos[C_AXIS], C_AXIS),
machinePos);
// We don't do inverse transforms very often, so if debugging is enabled, print them
if (reprap.Debug(moduleMove))
{
debugPrintf("Inverse transformed %d %d %d to %f %f %f\n", motorPos[0], motorPos[1], motorPos[2], machinePos[0], machinePos[1], machinePos[2]);
}
}
// Convert Cartesian coordinates to delta motor steps
void Move::DeltaTransform(const float machinePos[AXES], int32_t motorPos[AXES]) const
{
for (size_t axis = 0; axis < AXES; ++axis)
{
motorPos[axis] = MotorEndPointToMachine(axis, deltaParams.Transform(machinePos, axis));
}
if (reprap.Debug(moduleMove) && reprap.Debug(moduleDda))
{
debugPrintf("Transformed %f %f %f to %d %d %d\n", machinePos[0], machinePos[1], machinePos[2], motorPos[0], motorPos[1], motorPos[2]);
}
}
void Move::SetIdentityTransform()
{
identityBedTransform = true;
@ -919,14 +958,14 @@ void Move::ZProbeTriggered(DDA* hitDDA)
}
// Return the untransformed machine coordinates
void Move::GetCurrentMachinePosition(float m[DRIVES + 1], bool disableDeltaMapping) const
void Move::GetCurrentMachinePosition(float m[DRIVES + 1], bool disableMotorMapping) const
{
DDA *lastQueuedMove = ddaRingAddPointer->GetPrevious();
for (size_t i = 0; i < DRIVES; i++)
{
if (i < AXES)
{
m[i] = lastQueuedMove->GetEndCoordinate(i, disableDeltaMapping);
m[i] = lastQueuedMove->GetEndCoordinate(i, disableMotorMapping);
}
else
{
@ -942,10 +981,10 @@ void Move::GetCurrentMachinePosition(float m[DRIVES + 1], bool disableDeltaMappi
}
// Return the transformed machine coordinates
void Move::GetCurrentUserPosition(float m[DRIVES + 1], bool disableDeltaMapping) const
void Move::GetCurrentUserPosition(float m[DRIVES + 1], uint8_t moveType) const
{
GetCurrentMachinePosition(m, disableDeltaMapping);
if (!disableDeltaMapping)
GetCurrentMachinePosition(m, moveType == 2 || (moveType == 1 && IsDeltaMode()));
if (moveType == 0)
{
InverseTransform(m);
}
@ -1100,4 +1139,13 @@ void Move::PrintCurrentDda() const
}
}
const char* Move::GetGeometryString() const
{
return (IsDeltaMode()) ? "Delta"
: (coreXYMode == 1) ? "CoreXY"
: (coreXYMode == 2) ? "CoreXZ"
: (coreXYMode == 3) ? "CoreYZ"
: "Cartesian";
}
// End

13
Move.h
View file

@ -82,7 +82,7 @@ public:
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], bool disableDeltaMapping) const; // Return the position (after all queued moves have been executed) in transformed coords
void GetCurrentUserPosition(float m[DRIVES + 1], uint8_t moveType) const; // Return the position (after all queued moves have been executed) in transformed coords
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
@ -117,10 +117,14 @@ public:
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; }
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 DeltaTransform(const float machinePos[AXES], int32_t motorPos[AXES]) const; // Convert Cartesian coordinates to delta motor coordinates
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;
@ -138,7 +142,7 @@ private:
void SetProbedBedEquation(StringRef& reply); // When we have a full set of probed points, work out the bed's equation
void BedTransform(float move[AXES]) const; // Take a position and apply the bed compensations
void GetCurrentMachinePosition(float m[DRIVES + 1], bool disableDeltaMapping) const; // Get the current position and feedrate in untransformed coords
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
@ -150,8 +154,6 @@ private:
DDA* DDARingGet(); // Get the next DDA ring entry to be run
bool DDARingEmpty() const; // Anything there?
void InverseDeltaTransform(const int32_t motorPos[AXES], float machinePos[AXES]) const; // Convert axis motor coordinates to Cartesian
DDA* volatile currentDda;
DDA* ddaRingAddPointer;
DDA* volatile ddaRingGetPointer;
@ -180,6 +182,7 @@ private:
float longWait; // A long time for things that need to be done occasionally
DeltaParameters deltaParams; // Information about the delta parameters of this machine
int coreXYMode; // 0 = Cartesian, 1 = CoreXY, 2 = CoreXZ, 3 = CoreYZ
};
//******************************************************************************************************

View file

@ -633,6 +633,7 @@ public:
void SetMotorCurrent(byte drive, float current);
float MotorCurrent(size_t drive);
float DriveStepsPerUnit(size_t drive) const;
const float *GetDriveStepsPerUnit() const { return driveStepsPerUnit; }
void SetDriveStepsPerUnit(size_t drive, float value);
float Acceleration(size_t drive) const;
const float* Accelerations() const;

Binary file not shown.

View file

@ -1081,7 +1081,7 @@ void RepRap::GetLegacyStatusResponse(StringRef& response, uint8_t type, int seq)
else if (type == 3)
{
// Add the static fields. For now this is just geometry and the machine name, but other fields could be added e.g. axis lengths.
response.catf(",\"geometry\":\"%s\",\"myName\":", move->IsDeltaMode() ? "delta" : "cartesian");
response.catf(",\"geometry\":\"%s\",\"myName\":", move->GetGeometryString());
EncodeString(response, myName, 2, false);
}