FPUTransform.cpp

changeset 0
2c8ba1964db7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FPUTransform.cpp	Sat Nov 07 13:23:07 2015 +0100
@@ -0,0 +1,190 @@
+#include "FPUTransform.h"
+
+#if defined(UMFPUSUPPORT) && (UMFPUSUPPORT > -1)
+
+#include "MatrixMath.h"
+
+float MasterTransform[4][4]; // this is the transform that describes how to move from
+							 // ideal coordinates to real world coords
+
+// private functions
+void loadMatrix(float X4, float Y3, float Z1, float X2, float Y2, float Z2, float X3, float Z3, float Z4);
+void transformDestination(float &X, float &Y, float &Z);
+
+bool FPUEnabled; // this is a bypass switch so that with one command the FPU can be
+				 // turned off
+
+void loadMatrix(float X4, float Y1, float Z1, float X2, float Y2, float Z2, float X3, float Z3, float Z4)
+{
+float Xdiff = X4 - X3;
+	serialPrintFloat(Xdiff);
+	SERIAL_ECHOLN("");
+float Ydiff = Y2 - Y1;
+	serialPrintFloat(Ydiff);
+	SERIAL_ECHOLN("");
+//clockwise
+float ZdiffX = Z4 - Z3;
+	serialPrintFloat(ZdiffX);
+	SERIAL_ECHOLN("");
+//anti clockwise
+float ZdiffY = Z1 - Z2;
+	serialPrintFloat(ZdiffY);
+	SERIAL_ECHOLN("");
+
+
+//modified to take advantage of small angle trig.
+float Xtheta = ZdiffX / Xdiff;
+//	serialPrintFloat(Xtheta);
+//	SERIAL_ECHOLN("");
+float Ytheta = ZdiffY / Ydiff;
+//	serialPrintFloat(Ytheta);
+//	SERIAL_ECHOLN("");
+float cosxtheta = 1-(Xtheta*Xtheta)/2;
+//	serialPrintFloat(cosxtheta);
+//	SERIAL_ECHOLN("");
+float sinxtheta = Xtheta;
+//	serialPrintFloat(sinxtheta);
+//	SERIAL_ECHOLN("");
+float cosytheta = 1-(Ytheta*Ytheta)/2;
+//	serialPrintFloat(cosytheta);
+//	SERIAL_ECHOLN("");
+float sinytheta = Ytheta;
+//	serialPrintFloat(sinytheta);
+//	SERIAL_ECHOLN("");
+
+//these transforms are to set the origin for each rotation
+float TranslateX0[4][4] = {{1.0, 0.0, 0.0, -X3},
+						    {0.0, 1.0, 0.0, -Y1}, 
+						    {0.0, 0.0, 1.0, -Z3}, 
+						    {0.0, 0.0, 0.0, 1.0}};
+
+float TranslateY0[4][4] = {{1.0, 0.0, 0.0, -X2},
+						   {0.0, 1.0, 0.0, -Y1}, 
+						   {0.0, 0.0, 1.0, -Z1}, 
+						   {0.0, 0.0, 0.0, 1.0}};
+
+//rotate in Y using XZ 
+float TransformY[4][4] = {{cosxtheta, 0.0, sinxtheta, 0.0},
+						  {      0.0, 1.0,        0.0, 0.0}, 
+						  {-sinxtheta, 0.0,  cosxtheta, 0.0}, 
+						  {      0.0, 0.0,        0.0, 1.0}};
+//rotate in X using YZ 
+float TransformX[4][4] = {{ 1.0,         0.0,         0.0, 0.0},
+						  { 0.0, cosytheta, sinytheta, 0.0}, 
+						  { 0.0,sinytheta, cosytheta, 0.0}, 
+						  { 0.0,         0.0,         0.0, 1.0}};
+
+
+// first translate point1 to 0 then rotate in Y then translate back
+float MatrixStage1[4][4];
+float MatrixStage2[4][4];
+//matrixMaths.MatrixMult((float*)TranslateY0, (float*)TransformX, 4, 4, 4, (float*)MatrixStage1);
+//matrixMaths.MatrixPrint((float*)MatrixStage1, 4, 4, "MatrixStage1");
+//TranslateY0[0][3] = -TranslateY0[0][3];
+//TranslateY0[1][3] = -TranslateY0[1][3];
+//TranslateY0[2][3] = -TranslateY0[2][3];
+//matrixMaths.MatrixPrint((float*)TranslateY0, 4, 4, "TranslateY0");
+//matrixMaths.MatrixMult((float*)MatrixStage1, (float*)TranslateY0, 4, 4, 4, (float*)MatrixStage2);
+//matrixMaths.MatrixPrint((float*)MatrixStage2, 4, 4, "MatrixStage2");
+//Now translate point3 to 0 and rotate in x before translating back
+float MatrixStage3[4][4];
+float MatrixStage4[4][4];
+//matrixMaths.MatrixMult((float*)MatrixStage2, (float*)TranslateX0, 4, 4, 4, (float*)MatrixStage3);
+//matrixMaths.MatrixPrint((float*)MatrixStage3, 4, 4, "MatrixStage3");
+//matrixMaths.MatrixMult((float*)MatrixStage3, (float*)TransformY, 4, 4, 4, (float*)MatrixStage4);
+matrixMaths.MatrixMult((float*)TransformX, (float*)TransformY, 4, 4, 4, (float*)MasterTransform);
+matrixMaths.MatrixPrint((float*)MatrixStage4, 4, 4, "MatrixStage4");
+//TranslateX0[0][3] = -TranslateX0[0][3];
+//TranslateX0[1][3] = -TranslateX0[1][3];
+//TranslateX0[2][3] = -TranslateX0[2][3];
+//matrixMaths.MatrixPrint((float*)TranslateX0, 4, 4, "TranslateX0");
+//matrixMaths.MatrixMult((float*)MatrixStage4, (float*)TranslateX0, 4, 4, 4, (float*)MasterTransform);
+//matrixMaths.MatrixPrint((float*)MasterTransform, 4, 4, "MasterTransform (pre-invert)");
+
+// We now have a way to translate from real-world coordinates to idealised coortdinates, 
+// but what we actually want is a way to transform from the idealised g-code coordinates
+// to real world coordinates. 
+// This is simply the inverse.
+matrixMaths.MatrixInvert((float*)MasterTransform, 4);
+matrixMaths.MatrixPrint((float*)MasterTransform, 4, 4, "MasterTransform");
+}
+
+void transformDestination(float &X, float &Y, float &Z)
+{
+float oldPoint[4][1]={{X}, {Y}, {Z}, {1.0}};
+float newPoint[1][4]={{0.0,0.0,0.0,0.0}};
+matrixMaths.MatrixMult((float*)MasterTransform, (float*)oldPoint, 4, 4, 1, (float*)newPoint);
+X=newPoint[0][0];
+Y=newPoint[0][1];
+Z=newPoint[0][2];
+}
+
+void FPUTransform_init()
+{
+if (FPUEnabled == true)
+  {
+  // It is important to ensure that if the bed levelling routine has not been called the 
+  // printer behaves as if the real world and idealised world are one and the same
+  matrixMaths.MatrixIdentity((float*)MasterTransform,4,4);
+  SERIAL_ECHO("transform configured to identity");
+  }
+else
+  {
+  SERIAL_ECHO("transform correction not enabled");
+  }
+}
+
+void FPUEnable()
+{
+	FPUEnabled = true;
+	FPUTransform_init();
+}
+
+void FPUReset()
+{
+	FPUTransform_init();
+}
+
+void FPUDisable()
+{
+	FPUEnabled = false;
+}
+
+void FPUTransform_determineBedOrientation()
+{
+int X3 = 15;
+float X4 = max_length[X_AXIS] - 20; 
+float X2 = (X4 + X3) / 2;
+int Y1 = 15;
+float Y2 = max_length[Y_AXIS] - 5;  
+float Z1;
+float Z2; 
+float Z3;
+float Z4;
+
+//get Z for X15 Y15, X15 Y(Y_MAX_LENGTH - 15) and X(max_length[X_AXIS] - 15) Y15
+Z3 = Probe_Bed(X3,Y1,PROBE_N);
+Z4 = Probe_Bed(X4,Y1,PROBE_N);
+Z1 = (Z3 + Z4) / 2;
+Z2 = Probe_Bed(X2,Y2,PROBE_N);
+if(FPUEnabled)
+	{
+	loadMatrix(X4, Y1, Z1, X2, Y2, Z2, X3, Z3, Z4);
+	}
+}
+
+void FPUTransform_transformDestination()
+{
+float XPoint = destination[X_AXIS];          // float variable 
+float YPoint = destination[Y_AXIS];          // float variable 
+float ZPoint = destination[Z_AXIS];          // float variable 
+if(FPUEnabled)
+	{
+	transformDestination(XPoint, YPoint, ZPoint);
+	}    
+modified_destination[X_AXIS] = XPoint;       // float variable 
+modified_destination[Y_AXIS] = YPoint;       // float variable 
+modified_destination[Z_AXIS] = ZPoint;       // float variable 
+}	
+
+#endif //UMFPUSUPPORT

mercurial