Hi, I have recently resumed my corexyu project and ran into a similar issue when trying to home one of the x, y or u axis. It zeroed/reseted the other two axis after homing. I have upgraded the firmware to 3.1.1 and started config from scratch as my old sd-card was broken.
I looked at the code and from my very limited understanding of it it looks like it sets all axis when trying to home one axis.
void CoreKinematics::OnHomingSwitchTriggered(size_t axis, bool highEnd, const float stepsPerMm[], DDA& dda) const
{
const float hitPoint = (highEnd) ? reprap.GetPlatform().AxisMaximum(axis) : reprap.GetPlatform().AxisMinimum(axis);
if (HasSharedMotor(axis))
{
float tempCoordinates[MaxAxes];
const size_t numTotalAxes = reprap.GetGCodes().GetTotalAxes();
for (size_t axis = 0; axis < numTotalAxes; ++axis)
{
tempCoordinates[axis] = dda.GetEndCoordinate(axis, false);
}
tempCoordinates[axis] = hitPoint;
dda.SetPositions(tempCoordinates, numTotalAxes);
}
else
{
dda.SetDriveCoordinate(lrintf(hitPoint * inverseMatrix(axis, axis) * stepsPerMm[axis]), axis);
}
}
CoreKinematics::OnHomingSwitchTriggered builds a array (tempCoordinates) for all axis. Sets the homing axis to its max or min limit in the array and then uses the array in dda.SetPositions. I’m suspecting that dda.GetEndCoordinate used to get position for all the axis that was not homing returns zeros for some reason.
// Get a Cartesian end coordinate from this move
float DDA::GetEndCoordinate(size_t drive, bool disableMotorMapping)
pre(disableDeltaMapping || drive < MaxAxes)
{
if (disableMotorMapping)
{
return Move::MotorStepsToMovement(drive, endPoint[drive]);
}
else
{
const size_t visibleAxes = reprap.GetGCodes().GetVisibleAxes();
if (drive < visibleAxes && !flags.endCoordinatesValid)
{
reprap.GetMove().MotorStepsToCartesian(endPoint, visibleAxes, reprap.GetGCodes().GetTotalAxes(), endCoordinates);
flags.endCoordinatesValid = true;
}
return endCoordinates[drive];
}
}
If I follow MotorStepsToCartesian it ends up back in CoreKinematics::MotorStepsToCartesian.
void CoreKinematics::MotorStepsToCartesian(const int32_t motorPos[], const float stepsPerMm[], size_t numVisibleAxes, size_t numTotalAxes, float machinePos[]) const
{
// If there are more motors than visible axes (e.g. CoreXYU which has a V motor), we assume that we can ignore the trailing ones when calculating the machine position
for (size_t axis = 0; axis < numVisibleAxes; ++axis)
{
float position = 0.0;
const size_t motorLimit = min<size_t>(numVisibleAxes, lastMotor[axis] + 1);
for (size_t motor = firstMotor[axis]; motor < motorLimit; ++motor)
{
const float factor = forwardMatrix(motor, axis);
if (factor != 0.0)
{
position += factor * (float)motorPos[motor] / stepsPerMm[motor];
}
}
machinePos[axis] = position;
}
}
This function uses the “forwardMatrix” to calculate the result.
I had previously noticed getting a “Invalid kinematics matrix” when running
M669 K5 X1:1:0:0:0 Y-1:1:0:-1:1 Z0:0:1:0:0 U0:0:0:1:1 V0:0:0:0:0
I need this to get the axis to move correctly. I noticed I got the same error message if I ran “M669 K5” without the movement coefficients so I ignored it. Now, looking at the code that generates the error message, it also zeros the “forwardMatrix”.
forwardMatrix.Fill(0.0);
reprap.GetPlatform().Message(ErrorMessage, "Invalid kinematics matrix\n");
That would cause MotorStepsToCartesian to report back all zeros and cause the homing problem.
Have I specified invalid movement coefficients? (It works for normal movement)
M669 K5 X1:1:0:0:0 Y-1:1:0:-1:1 Z0:0:1:0:0 U0:0:0:1:1 V0:0:0:0:0
Is the default “inverseMatrix” that you get from “M669 K5” invalid.
Is the validation of the “inverseMatrix” bugged?
const bool ok = tempMatrix.GaussJordan(MaxAxes, 2 * MaxAxes);