diff --git a/Configuration.h b/Configuration.h index c004198..ef87147 100644 --- a/Configuration.h +++ b/Configuration.h @@ -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) diff --git a/DDA.cpp b/DDA.cpp index 9bfbfad..e92d9fc 100644 --- a/DDA.cpp +++ b/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. diff --git a/DDA.h b/DDA.h index 763b3e2..a002de3 100644 --- a/DDA.h +++ b/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. diff --git a/GCodes.cpp b/GCodes.cpp index 8a7adb2..cd6e25d 100644 --- a/GCodes.cpp +++ b/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: diff --git a/GCodes.h b/GCodes.h index 1e29948..74c5cf4 100644 --- a/GCodes.h +++ b/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; diff --git a/Move.cpp b/Move.cpp index 6933612..85df530 100644 --- a/Move.cpp +++ b/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 diff --git a/Move.h b/Move.h index cab854b..3d4b5d5 100644 --- a/Move.h +++ b/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 }; //****************************************************************************************************** diff --git a/Platform.h b/Platform.h index 16cee07..c9f04ad 100644 --- a/Platform.h +++ b/Platform.h @@ -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; diff --git a/Release/RepRapFirmware-1.00p-corexy-experimental.bin b/Release/RepRapFirmware-1.00p-corexy-experimental.bin new file mode 100644 index 0000000..28b57a3 Binary files /dev/null and b/Release/RepRapFirmware-1.00p-corexy-experimental.bin differ diff --git a/RepRapFirmware.cpp b/RepRapFirmware.cpp index b35432a..bc20ebb 100644 --- a/RepRapFirmware.cpp +++ b/RepRapFirmware.cpp @@ -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); }