Main Page | Class List | File List | Class Members | File Members

UFTR.H

Go to the documentation of this file.
00001 /* File: UFTR.H 00002 Auth: Andy Forsberg <asf@cs.brown.edu> 00003 Nicholas Yang <nyang@cs.brown.edu> 00004 Desc: The UserFriendlyTrackerRegistration class stores both registered 00005 and raw unregistered samples of the free-tracker and the 00006 head-tracker. The user-friendly registration algorithm is 00007 implemented here in this file. 00008 */ 00009 00010 #ifndef __UFTR_H__ 00011 #define __UFTR_H__ 00012 00013 #include <fstream> 00014 void write_matrix( char *filename, cWtransf &xf ) 00015 { 00016 ofstream str(filename); 00017 for(int i=0;i<16;i++) { 00018 char buf[256]; 00019 double val = xf.matrix()[i]; 00020 sprintf(buf, "%10.4lf", val); 00021 str << buf << " "; 00022 } 00023 } 00024 00025 int read_matrix( char *filename, cWtransf &xf ) 00026 { 00027 ifstream str(filename); 00028 if (str.bad() || str.fail()) 00029 return 0; 00030 00031 for(int i=0;i<16;i++) { 00032 double val; 00033 str >> val; 00034 *((double *)xf.matrix()+i) = val; 00035 } 00036 return 1; 00037 } 00038 00039 00040 class UserFriendlyTrackerRegistration 00041 { 00042 protected: 00043 int _done_basic_reg; // Flag for completion of basic registration 00044 int _done_head_reg; // Flag for completion of head registration 00045 00046 Wtransf _K; // Transformation to the known point K 00047 Wtransf _sample_basic_C; // Raw free-tracker value at known point K 00048 Wtransf _sample_head_D; // Raw head-tracker value at known point K 00049 00050 Wtransf _raw_basic; // Raw unregistered free-tracker value 00051 Wtransf _raw_head; // Raw unregistered head-tracker value 00052 00053 Wtransf _reg_basic; // Registered free-tracker value 00054 Wtransf _reg_head; // Registered head-tracker value 00055 00056 Wtransf _mid_eye; // Location of the mid-eye point 00057 00058 public: 00059 UserFriendlyTrackerRegistration() 00060 { 00061 _done_basic_reg = _done_head_reg = 0; 00062 00063 // Define the known point K here in a transformation matrix; in our 00064 // case, we had the known point positioned at 1' 1/4" in front of the 00065 // screen (the 1/4" was added to account for the tracker's thickness) 00066 _K = Wtransf::translation(Wvec(0, 0, 1.0 + 1.0/12.0/4.0)); 00067 } 00068 00069 int done_basic_registration() const { return _done_basic_reg; } 00070 int done_head_registration () const { return _done_head_reg; } 00071 00072 // Returns samples for the free-tracker and head-tracker 00073 cWtransf &reg_basic() const { return _reg_basic; } 00074 cWtransf &reg_head() const { return _mid_eye; } 00075 cWtransf &raw_basic() const { return _raw_basic; } 00076 cWtransf &raw_head() const { return _raw_head; } 00077 00078 cWtransf &sample_basic_C() const { return _sample_basic_C; } 00079 cWtransf &sample_head_D() const { return _sample_head_D; } 00080 cWtransf &K() const { return _K; } 00081 00082 // Changes the known point K; registration should be performed again if 00083 // this is changed while the program is running 00084 void set_K(cWtransf &K) { _K = K; } 00085 00086 // Changes the saved sample point C for the free-tracker 00087 void grab_basic_sample_C() 00088 { 00089 _done_basic_reg = 1; 00090 _sample_basic_C = _raw_basic; 00091 write_matrix(".LAST-RUN-basic", _sample_basic_C); 00092 } 00093 00094 // Changes the saved sample point D for the head-tracker 00095 void grab_head_sample_D() 00096 { 00097 _done_head_reg = 1; 00098 _sample_head_D = _reg_head; 00099 write_matrix(".LAST-RUN-head", _sample_head_D); 00100 } 00101 00102 void use_last_runs_registration() { 00103 // use values from last run for basic & head registration 00104 read_matrix(".LAST-RUN-basic", _sample_basic_C); 00105 _done_basic_reg = 1; 00106 read_matrix(".LAST-RUN-head", _sample_head_D); 00107 _done_head_reg = 1; 00108 } 00109 00110 // Sets the saved raw unregistered transformation of the free-tracker 00111 void set_raw_basic_tracker_xf(cWtransf &xf) 00112 { 00113 _raw_basic = xf; 00114 00115 if (_done_basic_reg) 00116 _reg_basic = register_basic_sample(_raw_basic); 00117 } 00118 00119 // Sets the saved raw unregistered transformation of the head-tracker 00120 void set_raw_head_tracker_xf(cWtransf &xf) 00121 { 00122 _raw_head = xf; 00123 00124 if (_done_basic_reg) { 00125 _reg_head = register_basic_sample(_raw_head); 00126 00127 if (_done_head_reg) 00128 _mid_eye = register_head_sample(_reg_head); 00129 } 00130 } 00131 00132 // BASIC REGISTRATION: This is where the equation: 00133 // 00134 // X_reg = (K * C_inverted) * X_unreg 00135 // 00136 // is applied. It should be constantly called by the tracker handler 00137 // function, because as the tracker moves, the transformation matrix 00138 // X_unreg (this is what the function is returning), which corrects the 00139 // tracker transformations based on the registration, has to be 00140 // constantly updated. 00141 Wtransf register_basic_sample(cWtransf &xf) 00142 { 00143 return (_K * _sample_basic_C.invert() * xf); 00144 } 00145 00146 // TRACKED GLASSES REGISTRATION: This is where the head-tracking equation: 00147 // 00148 // H = X_reg * (R_inverted * (K * T_inverted)) 00149 // 00150 // is applied. This is constantly called by the tracker handler because 00151 // as the head moves, H (this is what the function is returning), which 00152 // corrects the head-tracking transformations based on the registration, 00153 // has to be constantly updated. Notice that it must make use of the 00154 // basic registration X_reg (the parameter xf below). 00155 Wtransf register_head_sample(cWtransf &xf) 00156 { 00157 // Get the rotation by zero-ing out the translation components 00158 Wtransf R = _sample_head_D; 00159 R(0, 3) = R(1, 3) = R(2, 3) = 0; 00160 00161 // Get the transformation matrix for the translation 00162 Wtransf T = Wtransf::translation(Wvec(_sample_head_D(0, 3), 00163 _sample_head_D(1, 3), _sample_head_D(2, 3))); 00164 00165 return (xf * (R.invert() * (_K * T.invert()))); 00166 } 00167 }; 00168 00169 #endif // __UFTR_H__

Generated on Thu Sep 16 10:45:37 2004 for uftr by doxygen 1.3.8