00001 /* 00002 * DataThreads.cc 00003 * 00004 * Created on: Feb 19, 2010 00005 * Author: uscr 00006 */ 00007 00008 #include <cstdio> 00009 00010 #include <opencv/highgui.h> 00011 #include <opencv/cv.h> 00012 #include <pthread.h> 00013 #include <sys/time.h> 00014 00015 #include "Control.h" 00016 #include "DataThreads.h" 00017 #include "Atomic6DOF.h" 00018 #include "TestrigGUI.h" 00019 #include "KalmanFilter.h" 00020 #include "SimpleRectangleFinder.h" 00021 00022 extern struct currentIMUData curIMUData; 00023 extern struct KalmanFilterData pitchFilter, rollFilter; 00024 00025 struct CollectedData myData; 00026 bool isRunning; 00027 TestrigGUI * myGui; 00028 pthread_mutex_t camMutex, imuMutex; 00029 00030 CvCapture * camera; 00031 IplImage * frame; 00032 00033 double outlierWeights[OUTLIER_SUM_RANGE]; 00034 double weightedSum[NUM_POINTS]; 00035 00036 00037 void initializeDataThreads() { 00038 00039 isRunning = true; 00040 00041 myData.oldestPoint = 0; 00042 00043 for (int i = 0; i < NUM_POINTS; i++) { 00044 myData.camPitchAngle[i] = 0; 00045 myData.camRollAngle[i] = 0; 00046 myData.imuPitchAccelVal[i] = 0; 00047 myData.imuPitchAngle[i] = 0; 00048 myData.imuPitchGyroVal[i] = 0; 00049 myData.imuRollAccelVal[i] = 0; 00050 myData.imuRollAngle[i] = 0; 00051 myData.imuRollGyroVal[i] = 0; 00052 myData.imuDeltaT[i] = 0; 00053 } 00054 00055 for (int i = 0; i < OUTLIER_SUM_RANGE; i++) { 00056 myData.imuOutlierSumPoints[i] = 0; 00057 outlierWeights[i] = 1.0; 00058 } 00059 00060 for (int i = 0; i < STARTING_SUM_NUM; i++) { 00061 00062 } 00063 00064 myData.imuLastT = 0; 00065 00066 //myData.currentCamImage = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3); 00067 myData.frameCounter = 0; 00068 00069 pthread_mutex_init(&camMutex, NULL); 00070 pthread_mutex_init(&imuMutex, NULL); 00071 00072 } 00073 00074 void shutdownDataThreads() { 00075 isRunning = false; 00076 } 00077 00078 void * runGuiThread(void * var) { 00079 00080 while (isRunning) { 00081 myGui->emitReadyToUpdateGUI(); 00082 usleep(100000); 00083 } 00084 00085 pthread_mutex_destroy(&camMutex); 00086 pthread_mutex_destroy(&imuMutex); 00087 pthread_exit(NULL); 00088 return NULL; 00089 } 00090 00091 void * runIMUThread(void * var) { 00092 00093 if (!initializeAtomic6DOF()) { 00094 printf("Not getting IMU stuffs...That makes me a sad panda.\n"); 00095 pthread_exit(NULL); 00096 } 00097 00098 // if (!initializeController()) { 00099 // printf("Not getting Propeller stuffs...\n"); 00100 // pthread_exit(NULL); 00101 // } 00102 00103 // for (unsigned char i = 0; i < 30; i++) { 00104 // setMotors(i, i, i, i); 00105 // usleep(100000); 00106 // } 00107 00108 struct timeval curTime; 00109 00110 initializeKalmanFilter(&pitchFilter, 0.012, 0.001, 0.003); 00111 initializeKalmanFilter(&rollFilter, 0.012, 0.001, 0.003); 00112 00113 while (isRunning) { 00114 00115 while (!isIMUDataReady()) {} 00116 gettimeofday(&curTime, 0); 00117 00118 //do kalman stuffs here 00119 double delta_t = (curTime.tv_usec - myData.imuLastT)/ 1000000.0; 00120 if (delta_t < 0) 00121 delta_t += 1.0; 00122 00123 //update gui 00124 pthread_mutex_lock(&imuMutex); 00125 int oldestVal = myData.oldestPoint; 00126 updateKalmanFilter(&pitchFilter, curIMUData.adj_gyro_pitch, curIMUData.adj_accel_pitch, delta_t); 00127 updateKalmanFilter(&rollFilter, curIMUData.adj_gyro_roll, curIMUData.adj_accel_roll, delta_t); 00128 myData.imuPitchAccelVal[oldestVal] = curIMUData.accel_y; 00129 myData.imuPitchGyroVal[oldestVal] = curIMUData.gyro_pitch; 00130 myData.imuRollAccelVal[oldestVal] = curIMUData.accel_x; 00131 myData.imuRollGyroVal[oldestVal] = curIMUData.gyro_roll; 00132 myData.imuPitchAngle[oldestVal] = pitchFilter.x_0; 00133 myData.imuRollAngle[oldestVal] = rollFilter.x_0; 00134 myData.imuDeltaT[oldestVal] = delta_t*1000.0; 00135 myData.imuLastT = curTime.tv_usec; 00136 00137 myData.oldestPoint++; 00138 if (myData.oldestPoint == NUM_POINTS) 00139 myData.oldestPoint = 0; 00140 pthread_mutex_unlock(&imuMutex); 00141 00142 00143 00144 usleep(2000); 00145 00146 } 00147 00148 //printf ("leaving IMU\n"); 00149 shutdownAtomic6DOF(); 00150 //shutdownController(); 00151 00152 pthread_exit(NULL); 00153 00154 return NULL; 00155 } 00156 00157 void * runCamThread(void * var) { 00158 pthread_exit(NULL); 00159 //Initialize OpenCV: 00160 IplImage * gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1); 00161 IplImage * rChan = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1); 00162 00163 //Initialize Rectangle Finder: 00164 SimpleRectangleFinder rect (rChan); 00165 00166 00167 while (isRunning) { 00168 00169 //Get the red channel and grayscale from the current frame 00170 frame = cvQueryFrame(camera); 00171 //cvShowImage("test", frame); 00172 /* 00173 cvCvtColor(frame, gray, CV_RGB2GRAY); 00174 cvSplit(frame, NULL, NULL, rChan, NULL); 00175 00176 //Perform subtract away the average channel intensity from 00177 // the red channel intensity - this gives how strongly an object 00178 // is exclusively red 00179 cvMax (rChan, gray, rChan); 00180 cvSub (rChan, gray, rChan); 00181 00182 //Split the values - if they are above the threshold, make them 255 00183 // otherwise make them 0 00184 cvThreshold (rChan, rChan, RED_THRESH, 255, CV_THRESH_BINARY); 00185 00186 int centerx, centery; 00187 rect.search(rChan, AR_PATT_WIDTH, centerx, centery); 00188 00189 cvCircle(frame, cvPoint(centerx, centery), 10, CV_RGB(0, 255, 0), 5); 00190 00191 //printf("\n--------------------------\n"); 00192 //cvDrawContours(frame, accepted_contours, CV_RGB(255,0,0), CV_RGB(0,255,0), 10, 1, 00193 // CV_AA, cvPoint(0, 0)); 00194 */ 00195 00196 pthread_mutex_lock(&camMutex); 00197 cvCopy(frame, myData.currentCamImage); 00198 myData.frameCounter++; 00199 pthread_mutex_unlock(&camMutex); 00200 00201 usleep(20000); 00202 } 00203 /* 00204 printf("Got Frame (%dx%d)\n", frame->width, frame->height); 00205 00206 cvCvtColor (frame, abgr, CV_RGB2RGBA); 00207 00208 //convert to abgr 00209 for (long i = 0; i < frame->imageSize; i += 4) { 00210 temp1 = frame->imageData[i]; 00211 temp2 = frame->imageData[i + 1]; 00212 frame->imageData[i] = frame->imageData[i + 3]; 00213 frame->imageData[i+1] = frame->imageData[i + 2]; 00214 frame->imageData[i+3] = temp1; 00215 frame->imageData[i+2] = temp2; 00216 } 00217 00218 if( arDetectMarker((ARUint8 *) frame->imageData, AR_PATT_THRESH, &marker_info, &marker_num) < 0 ) { 00219 printf ("marker error, aborting!\n"); 00220 pthread_exit(NULL); 00221 } 00222 00223 if (marker_num > 0) { 00224 //arGetTransMatCont( marker_info, patt_trans_old, patt_center, AR_PATT_WIDTH, patt_trans_new); 00225 00226 memcpy(patt_trans_old, patt_trans_new, 12*sizeof(double)); 00227 00228 cvCircle(frame, cvPoint(marker_info->pos[0], marker_info->pos[1]), 10, CV_RGB(255,0,0)); 00229 printf("Center: (%f, %f)\n", marker_info->pos[0], marker_info->pos[1]); 00230 printf ("%d markers detected!\n", marker_num); 00231 00232 marker_info; 00233 }*/ 00234 00235 cvReleaseImage(&gray); 00236 cvReleaseImage(&rChan); 00237 00238 pthread_exit(NULL); 00239 }