Version 1.00p (added CoreXY support)
Added CoreXY, CoreXZ and CoreYZ support, ndbaled using M667 command.
This commit is contained in:
parent
0e48d9861a
commit
3c748277bf
10 changed files with 216 additions and 140 deletions
|
@ -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
14
DDA.cpp
|
@ -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
2
DDA.h
|
@ -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.
|
||||
|
|
144
GCodes.cpp
144
GCodes.cpp
|
@ -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:
|
||||
|
|
4
GCodes.h
4
GCodes.h
|
@ -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
172
Move.cpp
|
@ -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
13
Move.h
|
@ -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
|
||||
};
|
||||
|
||||
//******************************************************************************************************
|
||||
|
|
|
@ -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;
|
||||
|
|
BIN
Release/RepRapFirmware-1.00p-corexy-experimental.bin
Normal file
BIN
Release/RepRapFirmware-1.00p-corexy-experimental.bin
Normal file
Binary file not shown.
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue