#include "survive_cal.h" #include #include #include "linmath.h" #include #include #include #include #include static int LH_ID; void OrthoSolve( FLT T[4][4], // OUTPUT: 4x4 transformation matrix FLT S_out[2][SENSORS_PER_OBJECT], // OUTPUT: array of screenspace points FLT S_in[2][SENSORS_PER_OBJECT], // INPUT: array of screenspace points FLT X_in[3][SENSORS_PER_OBJECT], // INPUT: array of offsets int nPoints); typedef struct { int something; //Stuff } DummyData; int PoserDaveOrtho( SurviveObject * so, PoserData * pd ) { PoserType pt = pd->pt; SurviveContext * ctx = so->ctx; DummyData * dd = so->PoserData; if( !dd ) so->PoserData = dd = malloc( sizeof( DummyData ) ); switch( pt ) { case POSERDATA_IMU: { PoserDataIMU * imu = (PoserDataIMU*)pd; //printf( "IMU:%s (%f %f %f) (%f %f %f)\n", so->codename, imu->accel[0], imu->accel[1], imu->accel[2], imu->gyro[0], imu->gyro[1], imu->gyro[2] ); break; } case POSERDATA_LIGHT: { PoserDataLight * l = (PoserDataLight*)pd; //printf( "LIG:%s %d @ %f rad, %f s (AC %d) (TC %d)\n", so->codename, l->sensor_id, l->angle, l->length, l->acode, l->timecode ); break; } case POSERDATA_FULL_SCENE: { PoserDataFullScene * fs = (PoserDataFullScene*)pd; for( LH_ID = 0; LH_ID < 2; LH_ID++ ) { int i; int max_hits = 0; FLT S_in[2][SENSORS_PER_OBJECT]; FLT X_in[3][SENSORS_PER_OBJECT]; for( i = 0; i < SENSORS_PER_OBJECT; i++ ) { //Load all our valid points into something the LHFinder can use. if( fs->lengths[i][LH_ID][0] > 0 ) { S_in[0][max_hits] = fs->angles[i][LH_ID][0]; S_in[1][max_hits] = fs->angles[i][LH_ID][1]; X_in[0][max_hits] = so->sensor_locations[i*3+0]; X_in[1][max_hits] = so->sensor_locations[i*3+1]; X_in[2][max_hits] = so->sensor_locations[i*3+2]; max_hits++; } } FLT tOut[4][4]; FLT S_out[2][SENSORS_PER_OBJECT]; OrthoSolve( tOut, S_out, S_in, X_in, max_hits ); //Now, we need to solve where we are as a function of where //the lighthouses are. FLT quat[4]; FLT posoff[3] = { tOut[0][3], tOut[1][3], tOut[2][3] }; FLT MT[4][4]; //matrix44transpose( MT, &tOut[0][0] ); matrix44copy( &MT[0][0], &tOut[0][0] ); quatfrommatrix( quat, &MT[0][0] ); //printf( "QUAT: %f %f %f %f = %f\n", quat[0], quat[1], quat[2], quat[3], quatmagnitude(quat) ); //quat[2] -= 0.005; //fixes up lh0 in test data set. quatnormalize( quat, quat ); printf( "QUAT: %f %f %f %f = %f [%f %f %f]\n", quat[0], quat[1], quat[2], quat[3], quatmagnitude(quat), posoff[0], posoff[1], posoff[2] ); for( i = 0; i < max_hits;i++ ) { FLT pt[3] = { X_in[0][i], X_in[1][i], X_in[2][i] }; quatrotatevector( pt, quat, pt ); add3d( pt, pt, posoff ); printf( "OUT %f %f %f ANGLE %f %f AOUT %f %f\n", pt[0], pt[1], pt[2], S_in[0][i], S_in[1][i], atan2( pt[0], pt[1] ), atan2( pt[2], pt[1] ) ); } so->FromLHPose[LH_ID].Pos[0] = posoff[0]; so->FromLHPose[LH_ID].Pos[1] = posoff[1]; so->FromLHPose[LH_ID].Pos[2] = posoff[2]; so->FromLHPose[LH_ID].Rot[0] = quat[0]; so->FromLHPose[LH_ID].Rot[1] = quat[1]; so->FromLHPose[LH_ID].Rot[2] = quat[2]; so->FromLHPose[LH_ID].Rot[3] = quat[3]; } break; } case POSERDATA_DISASSOCIATE: { free( dd ); so->PoserData = 0; //printf( "Need to disassociate.\n" ); break; } } } REGISTER_LINKTIME( PoserDaveOrtho ); #define PRINT_MAT(A,M,N) { \ int m,n; \ printf(#A "\n"); \ for (m=0; m 0 && err < bestErr) { x[1][0]=x_y; y[1][0]=y_y; z[1][0]=z_y; bestErr=err; } if ( i == 0 && j == 1 && k == 0) { x[1][0]=x_y; y[1][0]=y_y; z[1][0]=z_y; bestErr=err; } z_y = -z_y; } y_y = -y_y; } x_y = -x_y; } printf("bestErr %f\n", bestErr); */ //------------------------- // A test version of the rescaling to the proper length //------------------------- FLT ydist2 = ydist; FLT bestBestErr = 9999.0; FLT bestYdist = 0; for (ydist2=ydist-0.1; ydist2 %f %f %f\n", x_y, y_y, z_y ); // Exhaustively flip the minus sign of the z axis until we find the right one . . . FLT bestErr = 9999.0; FLT xy_dot2 = x2[0][0]*y2[0][0] + x2[2][0]*y2[2][0]; FLT yz_dot2 = y2[0][0]*z2[0][0] + y2[2][0]*z2[2][0]; FLT zx_dot2 = z2[0][0]*x2[0][0] + z2[2][0]*x2[2][0]; for (i=0;i<2;i++) { for (j=0;j<2;j++) { for(k=0;k<2;k++) { // Calculate the error term FLT xy_dot = xy_dot2 + x_y*y_y; FLT yz_dot = yz_dot2 + y_y*z_y; FLT zx_dot = zx_dot2 + z_y*x_y; FLT err = _ABS(xy_dot) + _ABS(yz_dot) + _ABS(zx_dot); // Calculate the handedness FLT cx,cy,cz; CrossProduct(cx,cy,cz,x2[0][0],x_y,x2[2][0],y2[0][0],y_y,y2[2][0]); FLT hand = cx*z2[0][0] + cy*z_y + cz*z2[2][0]; printf("err %f hand %f\n", err, hand); // If we are the best right-handed frame so far if (hand > 0 && err < bestErr) { x2[1][0]=x_y; y2[1][0]=y_y; z2[1][0]=z_y; bestErr=err; } z_y = -z_y; } y_y = -y_y; } x_y = -x_y; } printf("ydist2 %f bestErr %f\n",ydist2,bestErr); if (bestErr < bestBestErr) { memcpy(x,x2,3*sizeof(FLT)); memcpy(y,y2,3*sizeof(FLT)); memcpy(z,z2,3*sizeof(FLT)); bestBestErr = bestErr; bestYdist = ydist2; } } ydist = bestYdist; /* for (i=0; i