Now you can download a copy of these docs so you can use them offline! Download now
AxisCamera.cpp
00001 00002 /******************************************************************************** 00003 * Project : FIRST Motor Controller 00004 * File Name : AxisCamera.cpp 00005 * Contributors : TD, ELF, JDG, SVK 00006 * Creation Date : July 29, 2008 00007 * Revision History : Source code & revision history maintained at sourceforge.WPI.edu 00008 * File Description : Axis camera access for the FIRST Vision API 00009 * The camera task runs as an independent thread 00010 */ 00011 /*----------------------------------------------------------------------------*/ 00012 /* Copyright (c) FIRST 2008. All Rights Reserved. */ 00013 /* Open Source Software - may be modified and shared by FRC teams. The code */ 00014 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ 00015 /*----------------------------------------------------------------------------*/ 00016 00017 00018 #include "sockLib.h" 00019 #include "vxWorks.h" 00020 00021 #include "errno.h" 00022 #include "fioLib.h" 00023 #include "hostLib.h" 00024 #include "inetLib.h" 00025 #include "signal.h" 00026 #include "sigLib.h" // for signal 00027 #include <string> 00028 #include "time.h" 00029 #include "usrLib.h" 00030 00031 #include "AxisCamera.h" 00032 #include "BaeUtilities.h" 00033 #include "FrcError.h" 00034 #include "Task.h" 00035 #include "Timer.h" 00036 #include "VisionAPI.h" 00037 00039 #define DEFAULT_PACKET_SIZE 512 00040 00042 IMAQ_FUNC int Priv_ReadJPEGString_C(Image* _image, const unsigned char* _string, UINT32 _stringLength); 00043 00044 // To locally enable debug printing: set AxisCamera_debugFlag to a 1, to disable set to 0 00045 int AxisCamera_debugFlag = 0; 00046 #define DPRINTF if(AxisCamera_debugFlag)dprintf 00047 00049 struct { 00050 int readerPID; // Set to taskID for signaling 00051 int index; /* -1,0,1 */ 00052 int acquire; /* 0:STOP CAMERA; 1:START CAMERA */ 00053 int cameraReady; /* 0: CAMERA NOT INITIALIZED; 1: CAMERA INITIALIZED */ 00054 int decode; /* 0:disable decoding; 1:enable decoding to HSL Image */ 00055 struct { 00056 // 00057 // To find the latest image timestamp, access: 00058 // globalCamera.data[globalCamera.index].timestamp 00059 // 00060 double timestamp; // when image was taken 00061 char* cameraImage; // jpeg image string 00062 int cameraImageSize; // image size 00063 Image* decodedImage; // image decoded to NI Image object 00064 int decodedImageSize; // size of decoded image 00065 }data[2]; 00066 int cameraMetrics[CAM_NUM_METRICS]; 00067 }globalCamera; 00068 00069 /* run flag */ 00070 static short cont = 0; 00071 00082 int GetImageBlocking(Image* image, double *timestamp, double lastImageTimestamp) 00083 { 00084 char funcName[]="GetImageBlocking"; 00085 int success; 00086 double startTime = GetTime(); 00087 00088 while (1) 00089 { 00090 success = GetImage(image, timestamp); 00091 if (!success) return (success); 00092 00093 if (*timestamp > lastImageTimestamp) 00094 return (1); // GOOD IMAGE RETURNED 00095 00096 if (GetTime() > (startTime + MAX_BLOCKING_TIME_SEC)) 00097 { 00098 imaqSetError(ERR_CAMERA_BLOCKING_TIMEOUT, funcName); 00099 globalCamera.cameraMetrics[CAM_BLOCKING_TIMEOUT]++; 00100 return (0); // NO IMAGE AVAILABLE WITHIN specified time 00101 } 00102 globalCamera.cameraMetrics[CAM_BLOCKING_COUNT]++; 00103 taskDelay (1); 00104 } 00105 } 00106 00111 int CameraInitialized() 00112 { 00113 char funcName[]="CameraInitialized"; 00114 int success = 0; 00115 /* check to see if camera is initialized */ 00116 if (!globalCamera.cameraReady) { 00117 imaqSetError(ERR_CAMERA_NOT_INITIALIZED, funcName); 00118 DPRINTF (LOG_DEBUG, "Camera request before camera is initialized"); 00119 globalCamera.cameraMetrics[CAM_GETIMAGE_BEFORE_INIT]++; 00120 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++; 00121 return success; 00122 } 00123 00124 if (globalCamera.index == -1){ 00125 imaqSetError(ERR_CAMERA_NO_BUFFER_AVAILABLE, funcName); 00126 DPRINTF (LOG_DEBUG, "No camera image available"); 00127 globalCamera.cameraMetrics[CAM_GETIMAGE_BEFORE_AVAILABLE]++; 00128 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++; 00129 return success; 00130 } 00131 return 1; 00132 } 00133 00142 int GetImage(Image* image, double *timestamp) 00143 { 00144 char funcName[]="GetImage"; 00145 int success = 0; 00146 int readIndex; 00147 int readCount = 10; 00148 double currentTime = time(NULL); 00149 double currentImageTimestamp; 00150 00151 /* check to see if camera is initialized */ 00152 00153 if (!CameraInitialized()) {return success;} 00154 00155 /* try readCount times to get an image */ 00156 while (readCount) { 00157 readIndex = globalCamera.index; 00158 if (!imaqDuplicate(image, globalCamera.data[readIndex].decodedImage)) { 00159 int errorCode = GetLastVisionError(); 00160 DPRINTF (LOG_DEBUG,"Error duplicating image= %i %s ", errorCode, GetVisionErrorText(errorCode)); 00161 } 00162 // save the timestamp to check before returning 00163 currentImageTimestamp = globalCamera.data[readIndex].timestamp; 00164 00165 // make sure this buffer is not being written to now 00166 if (readIndex == globalCamera.index) break; 00167 readCount--; 00168 } 00169 00170 /* were we successful ? */ 00171 if (readCount){ 00172 success = 1; 00173 if (timestamp != NULL) 00174 *timestamp = currentImageTimestamp; // Return image timestamp 00175 } else{ 00176 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++; 00177 } 00178 00179 /* Ensure the buffered image is not too old - set this "stale time" above */ 00180 if (currentTime > globalCamera.data[globalCamera.index].timestamp + CAMERA_IMAGE_STALE_TIME_SEC){ 00181 DPRINTF (LOG_CRITICAL, "STALE camera image (THIS COULD BE A BAD IMAGE)"); 00182 imaqSetError(ERR_CAMERA_STALE_IMAGE, funcName); 00183 globalCamera.cameraMetrics[CAM_STALE_IMAGE]++; 00184 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++; 00185 success = 0; 00186 } 00187 globalCamera.cameraMetrics[CAM_GETIMAGE_SUCCESS]++; 00188 return success; 00189 } 00190 00198 int GetImageData(char** imageData, int* numBytes, double* currentImageTimestamp) 00199 { 00200 int success = 0; 00201 int readIndex; 00202 int readCount = 10; 00203 int cameraImageSize; 00204 char *cameraImageString; 00205 00206 /* check to see if camera is initialized */ 00207 00208 if (!CameraInitialized()) {return success;} 00209 00210 /* try readCount times to get an image */ 00211 while (readCount) { 00212 readIndex = globalCamera.index; 00213 cameraImageSize = globalCamera.data[readIndex].cameraImageSize; 00214 //cameraImageString = (Image *) malloc(cameraImageSize); 00215 cameraImageString = new char[cameraImageSize]; 00216 if (NULL == cameraImageString) { 00217 DPRINTF (LOG_DEBUG, "Unable to allocate cameraImage"); 00218 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++; 00219 return success; 00220 } 00221 memcpy (cameraImageString, globalCamera.data[readIndex].cameraImage, cameraImageSize); 00222 *currentImageTimestamp = globalCamera.data[readIndex].timestamp; 00223 // make sure this buffer is not being written to now 00224 if (readIndex == globalCamera.index) break; 00225 free (cameraImageString); 00226 readCount--; 00227 } 00228 if (readCount){ 00229 *imageData = cameraImageString; 00230 *numBytes = cameraImageSize; 00231 return 1; 00232 } 00233 return (OK); 00234 } 00235 00246 int GetImageDataBlocking(char** imageData, int* numBytes, double* timestamp, double lastImageTimestamp) 00247 { 00248 00249 char funcName[]="GetImageDataBlocking"; 00250 int success; 00251 double startTime = GetTime(); 00252 00253 *imageData = NULL; 00254 while (1) 00255 { 00256 success = GetImageData(imageData, numBytes, timestamp); 00257 if (!success) return (success); 00258 00259 if (*timestamp > lastImageTimestamp) 00260 return (1); // GOOD IMAGE DATA RETURNED 00261 00262 delete *imageData; 00263 *imageData = NULL; 00264 00265 if (GetTime() > (startTime + MAX_BLOCKING_TIME_SEC)) 00266 { 00267 imaqSetError(ERR_CAMERA_BLOCKING_TIMEOUT, funcName); 00268 return (0); // NO IMAGE AVAILABLE WITHIN specified time 00269 } 00270 globalCamera.cameraMetrics[CAM_BLOCKING_COUNT]++; 00271 taskDelay (1); 00272 } 00273 } 00274 00280 int GetCameraMetric(FrcvCameraMetric metric) 00281 { return globalCamera.cameraMetrics[metric]; } 00282 00289 int CameraCloseSocket(char *errstring, int socket) 00290 { 00291 DPRINTF (LOG_CRITICAL, "Closing socket - CAMERA ERROR: %s", errstring ); 00292 close (socket); 00293 return (ERROR); 00294 } 00295 00296 00307 static int CameraReadLine(int camSock, char* buffer, int bufSize, bool stripLineEnding) { 00308 char funcName[]="CameraReadLine"; 00309 // Need at least 3 bytes in the buffer to pull this off. 00310 if (bufSize < 3) { 00311 imaqSetError(ERR_CAMERA_FAILURE, funcName); 00312 return 0; 00313 } 00314 // Reduce size by 1 to allow for null terminator. 00315 --bufSize; 00316 // Read upto bufSize characters. 00317 for (int i=0;i < bufSize;++i, ++buffer) { 00318 // Read one character. 00319 if (read (camSock, buffer, 1) <= 0) { 00320 imaqSetError(ERR_CAMERA_FAILURE, funcName); 00321 return 0; 00322 } 00323 // Line endings can be "\r\n" or just "\n". So always 00324 // look for a "\n". If you got just a "\n" and 00325 // stripLineEnding is false, then convert it into a \r\n 00326 // because callers expect a \r\n. 00327 // If the combination of the previous character and the current character 00328 // is "\r\n", the line ending 00329 if (*buffer=='\n') { 00330 // If asked to strip the line ending, then set the buffer to the previous 00331 // character. 00332 if (stripLineEnding) { 00333 if (i > 0 && *(buffer-1)=='\r') { 00334 --buffer; 00335 } 00336 } 00337 else { 00338 // If the previous character was not a '\r', 00339 if (i == 0 || *(buffer-1)!='\r') { 00340 // Make the current character a '\r'. 00341 *buffer = '\r'; 00342 // If space permits, add back the '\n'. 00343 if (i < bufSize-1) { 00344 ++buffer; 00345 *buffer = '\n'; 00346 } 00347 } 00348 // Set the buffer past the current character ('\n') 00349 ++buffer; 00350 } 00351 break; 00352 } 00353 } 00354 // Null terminate. 00355 *buffer = '\0'; 00356 return 1; 00357 } 00358 00365 static int CameraSkipUntilEmptyLine(int camSock) { 00366 char buffer[1024]; 00367 int success = 0; 00368 while(1) { 00369 success = CameraReadLine(camSock, buffer, sizeof(buffer), true); 00370 if (*buffer == '\0') { 00371 return success; 00372 } 00373 } 00374 return success; 00375 } 00376 00392 static int CameraOpenSocketAndIssueAuthorizedRequest(const char* serverName, const char* request) 00393 { 00394 char funcName[]="cameraOpenSocketAndIssueAuthorizedRequest"; 00395 00396 struct sockaddr_in cameraAddr; 00397 int sockAddrSize; 00398 int camSock = ERROR; 00399 00400 // The camera is expected to have one of the following username, password combinations. 00401 // This routine will return an error if it does not find one of these. 00402 static const char* authenticationStrings[] = { 00403 "RlJDOkZSQw==", /* FRC, FRC */ 00404 "cm9vdDpwYXNz", /* root, admin*/ 00405 "cm9vdDphZG1pbg==" /* root, pass*/ 00406 }; 00407 00408 static const int numAuthenticationStrings = sizeof(authenticationStrings)/sizeof(authenticationStrings[0]); 00409 00410 static const char *requestTemplate = "%s " \ 00411 "HTTP/1.1\n" \ 00412 "User-Agent: HTTPStreamClient\n" \ 00413 "Connection: Keep-Alive\n" \ 00414 "Cache-Control: no-cache\n" \ 00415 "Authorization: Basic %s\n\n"; 00416 00417 int i = 0; 00418 for (;i < numAuthenticationStrings;++i) { 00419 char buffer[1024]; 00420 00421 sprintf(buffer, requestTemplate, request, authenticationStrings[i]); 00422 00423 /* create camera socket */ 00424 //DPRINTF (LOG_DEBUG, "creating camSock" ); 00425 if ((camSock = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) { 00426 imaqSetError(ERR_CAMERA_SOCKET_CREATE_FAILED, funcName); 00427 perror("Failed to create socket"); 00428 return (ERROR); 00429 } 00430 00431 sockAddrSize = sizeof (struct sockaddr_in); 00432 bzero ((char *) &cameraAddr, sockAddrSize); 00433 cameraAddr.sin_family = AF_INET; 00434 cameraAddr.sin_len = (u_char) sockAddrSize; 00435 cameraAddr.sin_port = htons (CAMERA_PORT); 00436 00437 if (( (int)(cameraAddr.sin_addr.s_addr = inet_addr (const_cast<char*>(serverName)) ) == ERROR) && 00438 ( (int)(cameraAddr.sin_addr.s_addr = hostGetByName (const_cast<char*>(serverName)) ) == ERROR)) 00439 { 00440 imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName); 00441 return CameraCloseSocket("Failed to get IP, check hostname or IP", camSock); 00442 } 00443 00444 //DPRINTF (LOG_INFO, "connecting camSock" ); 00445 if (connect (camSock, (struct sockaddr *) &cameraAddr, sockAddrSize) == ERROR) { 00446 imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName); 00447 return CameraCloseSocket("Failed to connect to camera - check networ", camSock); 00448 } 00449 00450 //DPRINTF (LOG_DEBUG, "writing GET request to camSock" ); 00451 if (write (camSock, buffer, strlen(buffer) ) == ERROR) { 00452 imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName); 00453 return CameraCloseSocket("Failed to send GET request", camSock); 00454 } 00455 00456 // Read one line with the line ending removed. 00457 if (!CameraReadLine(camSock, buffer, 1024, true)) { 00458 return CameraCloseSocket("Bad response to GET request", camSock); 00459 } 00460 00461 // Check if the response is of the format HTTP/<version> 200 OK. 00462 float discard; 00463 if (sscanf(buffer, "HTTP/%f 200 OK", &discard) == 1) { 00464 break; 00465 } 00466 00467 // We have to close the connection because in the case of failure 00468 // the server closes the connection. 00469 close(camSock); 00470 } 00471 // If none of the attempts were successful, then let the caller know. 00472 if (numAuthenticationStrings == i) { 00473 imaqSetError(ERR_CAMERA_AUTHORIZATION_FAILED, funcName); 00474 fprintf(stderr, "Expected username/password combination not found on camera"); 00475 return ERROR; 00476 } 00477 return camSock; 00478 } 00479 00480 00486 int ConfigureCamera(char *configString){ 00487 char funcName[]="ConfigureCamera"; 00488 char *serverName = "192.168.0.90"; /* camera @ */ 00489 int success = 0; 00490 int camSock = 0; 00491 00492 /* Generate camera configuration string */ 00493 char * getStr1 = 00494 "GET /axis-cgi/admin/param.cgi?action=update&ImageSource.I0.Sensor."; 00495 00496 char cameraRequest[strlen(getStr1) + strlen(configString)]; 00497 sprintf (cameraRequest, "%s%s", getStr1, configString); 00498 DPRINTF(LOG_DEBUG, "camera configuration string: \n%s", cameraRequest); 00499 camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest); 00500 DPRINTF(LOG_DEBUG, "camera socket# = %i", camSock); 00501 00502 //read response 00503 success = CameraSkipUntilEmptyLine(camSock); 00504 //DPRINTF(LOG_DEBUG, "succcess from CameraSkipUntilEmptyLine: %i", success); 00505 char buffer[3]; // set property - 3 00506 success = CameraReadLine(camSock, buffer, 3, true); 00507 //DPRINTF(LOG_DEBUG, "succcess from CameraReadLine: %i", success); 00508 DPRINTF(LOG_DEBUG, "line read from camera \n%s", buffer); 00509 if (strcmp(buffer, "OK") != 0) { 00510 imaqSetError(ERR_CAMERA_COMMAND_FAILURE, funcName); 00511 DPRINTF(LOG_DEBUG, "setting ERR_CAMERA_COMMAND_FAILURE - OK not found"); 00512 } 00513 DPRINTF (LOG_INFO, "\nConfigureCamera ENDING success = %i\n", success ); 00514 00515 /* clean up */ 00516 close (camSock); 00517 return (1); 00518 } 00519 00520 00527 int GetCameraSetting(char *configString, char *cameraResponse){ 00528 char *serverName = "192.168.0.90"; /* camera @ */ 00529 int success = 0; 00530 int camSock = 0; 00531 00532 /* Generate camera request string */ 00533 char * getStr1 = 00534 "GET /axis-cgi/admin/param.cgi?action=list&group=ImageSource.I0.Sensor."; 00535 char cameraRequest[strlen(getStr1) + strlen(configString)]; 00536 sprintf (cameraRequest, "%s%s", getStr1, configString); 00537 DPRINTF(LOG_DEBUG, "camera configuration string: \n%s", cameraRequest); 00538 camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest); 00539 DPRINTF(LOG_DEBUG, "return from CameraOpenSocketAndIssueAuthorizedRequest %i", camSock); 00540 00541 //read response 00542 success = CameraSkipUntilEmptyLine(camSock); 00543 success = CameraReadLine(camSock, cameraResponse, 1024, true); 00544 DPRINTF(LOG_DEBUG, "succcess from CameraReadLine: %i", success); 00545 DPRINTF(LOG_DEBUG, "line read from camera \n%s", cameraResponse); 00546 DPRINTF (LOG_INFO, "\nGetCameraSetting ENDING success = %i\n", success ); 00547 00548 /* clean up */ 00549 close (camSock); 00550 return (1); 00551 } 00552 00560 int GetImageSetting(char *configString, char *cameraResponse){ 00561 char *serverName = "192.168.0.90"; /* camera @ */ 00562 int success = 0; 00563 int camSock = 0; 00564 00565 /* Generate camera request string */ 00566 char *getStr1 = "GET /axis-cgi/admin/param.cgi?action=list&group=Image.I0.Appearance."; 00567 char cameraRequest[strlen(getStr1) + strlen(configString)]; 00568 sprintf (cameraRequest, "%s%s", getStr1, configString); 00569 DPRINTF(LOG_DEBUG, "camera configuration string: \n%s", cameraRequest); 00570 camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest); 00571 DPRINTF(LOG_DEBUG, "return from CameraOpenSocketAndIssueAuthorizedRequest %i", camSock); 00572 00573 //read response 00574 success = CameraSkipUntilEmptyLine(camSock); 00575 success = CameraReadLine(camSock, cameraResponse, 1024, true); 00576 DPRINTF(LOG_DEBUG, "succcess from CameraReadLine: %i", success); 00577 DPRINTF(LOG_DEBUG, "line read from camera \n%s", cameraResponse); 00578 DPRINTF (LOG_INFO, "\nGetCameraSetting ENDING success = %i\n", success ); 00579 00580 /* clean up */ 00581 close (camSock); 00582 return (1); 00583 } 00584 00585 00586 #define MEASURE_SOCKET_TIME 1 00587 00596 int cameraJPEGServer(int frames, int compression, ImageResolution resolution, ImageRotation rotation) 00597 { 00598 char funcName[]="cameraJPEGServer"; 00599 char *serverName = "192.168.0.90"; /* camera @ */ 00600 cont = 1; 00601 int errorCode = 0; 00602 int printCounter = 0; 00603 int writeIndex; 00604 int authorizeCount = 0; 00605 int authorizeConfirmed = 0; 00606 static const int authenticationStringsCount = 3; 00607 static const char* authenticationStrings[] = { 00608 "cm9vdDphZG1pbg==", /* root, admin*/ 00609 "RlJDOkZSQw==", /* FRC, FRC */ 00610 "cm9vdDpwYXNz==" /* root, pass*/ 00611 }; 00612 00613 DPRINTF (LOG_DEBUG, "cameraJPEGServer" ); 00614 00615 struct sockaddr_in cameraAddr; 00616 int sockAddrSize; 00617 int camSock = 0; 00618 00619 char resStr[10]; 00620 switch (resolution) { 00621 case k640x480: { sprintf(resStr,"640x480"); break; } 00622 case k320x240: { sprintf(resStr,"320x240"); break; } 00623 case k160x120: { sprintf(resStr,"160x120"); break; } 00624 default: {DPRINTF (LOG_DEBUG, "code error - resolution input" ); break; } 00625 } 00626 00627 /* Generate camera initialization string */ 00628 /* changed resolution to 160x120 from 320x240 */ 00629 /* supported resolutions are: 640x480, 640x360, 320x240, 160x120 */ 00630 char * getStr1 = 00631 "GET /axis-cgi/mjpg/video.cgi?showlength=1&camera=1&"; 00632 00633 char insertStr[100]; 00634 sprintf (insertStr, "des_fps=%i&compression=%i&resolution=%s&rotation=%i", 00635 frames, compression, resStr, (int)rotation); 00636 00637 char * getStr2 = " HTTP/1.1\n\ 00638 User-Agent: HTTPStreamClient\n\ 00639 Host: 192.150.1.100\n\ 00640 Connection: Keep-Alive\n\ 00641 Cache-Control: no-cache\n\ 00642 Authorization: Basic %s;\n\n"; 00643 00644 char getStr[strlen(getStr1) + strlen(insertStr) + strlen(getStr2)]; 00645 sprintf (getStr, "%s:%s%s", getStr1, insertStr, getStr2); 00646 00647 DPRINTF(LOG_DEBUG, "revised camera string: \n%s", getStr); 00648 /* Allocation */ 00649 char tempBuffer[1024]; 00650 00651 RETRY: 00652 Wait(0.1); //bug fix - don't pester camera if it's booting 00653 while (globalCamera.acquire == 0) Wait(0.1); 00654 00655 if (!authorizeConfirmed){ 00656 if (authorizeCount < authenticationStringsCount){ 00657 sprintf (tempBuffer, getStr, authenticationStrings[authorizeCount]); 00658 } else { 00659 imaqSetError(ERR_CAMERA_AUTHORIZATION_FAILED, funcName); 00660 fprintf(stderr, "Camera authorization failed ... Incorrect password on camera!!"); 00661 return (ERROR); 00662 } 00663 } 00664 00665 while (1) 00666 { 00667 globalCamera.cameraMetrics[CAM_SOCKET_INIT_ATTEMPTS]++; 00668 00669 /* create camera socket */ 00670 DPRINTF (LOG_DEBUG, "creating camSock" ); 00671 if ((camSock = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) { 00672 imaqSetError(ERR_CAMERA_SOCKET_CREATE_FAILED, funcName); 00673 perror("Failed to create socket"); 00674 cont = 0; 00675 return (ERROR); 00676 } 00677 00678 sockAddrSize = sizeof (struct sockaddr_in); 00679 bzero ((char *) &cameraAddr, sockAddrSize); 00680 cameraAddr.sin_family = AF_INET; 00681 cameraAddr.sin_len = (u_char) sockAddrSize; 00682 cameraAddr.sin_port = htons (CAMERA_PORT); 00683 00684 DPRINTF (LOG_DEBUG, "getting IP" ); 00685 if (( (int)(cameraAddr.sin_addr.s_addr = inet_addr (serverName) ) == ERROR) && 00686 ( (int)(cameraAddr.sin_addr.s_addr = hostGetByName (serverName) ) == ERROR)) 00687 { 00688 CameraCloseSocket("Failed to get IP, check hostname or IP", camSock); 00689 continue; 00690 } 00691 00692 DPRINTF (LOG_INFO, "Attempting to connect to camSock" ); 00693 if (connect (camSock, (struct sockaddr *) &cameraAddr, sockAddrSize) == ERROR) { 00694 imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName); 00695 CameraCloseSocket("Failed to connect to camera - check network", camSock); 00696 continue; 00697 } 00698 00699 #if MEASURE_SOCKET_SETUP 00700 socketEndTime = GetTime(); 00701 setupTime = socketEndTime - socketStartTime; 00702 printf("\n***socket setup time = %g\n", setupTime ); 00703 #endif 00704 00705 globalCamera.cameraMetrics[CAM_SOCKET_OPEN]++; 00706 break; 00707 } // end while (trying to connect to camera) 00708 00709 DPRINTF (LOG_DEBUG, "writing GET request to camSock" ); 00710 if (write (camSock, tempBuffer , strlen(tempBuffer) ) == ERROR) { 00711 return CameraCloseSocket("Failed to send GET request", camSock); 00712 } 00713 00714 //DPRINTF (LOG_DEBUG, "reading header" ); 00715 /* Find content-length, then read that many bytes */ 00716 int counter = 2; 00717 char* contentString = "Content-Length: "; 00718 char* authorizeString = "200 OK"; 00719 00720 #define MEASURE_TIME 0 00721 #if MEASURE_TIME 00722 //timing parameters - only measure one at the time 00723 double loopStartTime = 0.0; // measuring speed of execution loop 00724 double loopEndTime = 0.0; 00725 double cameraStartTime = 0.0; 00726 double cameraEndTime = 0.0; 00727 double previousStartTime = 0.0; 00728 int performanceLoopCounter = 0; 00729 int maxCount = 30; 00730 #endif 00731 00732 while (cont) { 00733 #if MEASURE_TIME 00734 previousStartTime = loopStartTime; // first time is bogus 00735 loopStartTime = GetTime(); 00736 #endif 00737 // If camera has been turned OFF, jump to RETRY 00738 //if (globalCamera.acquire == 0) goto RETRY; 00739 00740 /* Determine writer index */ 00741 if (globalCamera.index == 0) 00742 writeIndex = 1; 00743 else 00744 writeIndex = 0; 00745 00746 /* read header */ 00747 //TODO: check for error in header, increment ERR_CAMERA_HEADER_ERROR 00748 char initialReadBuffer[DEFAULT_PACKET_SIZE] = ""; 00749 char intermediateBuffer[1]; 00750 char *trailingPtr = initialReadBuffer; 00751 int trailingCounter = 0; 00752 00753 00754 #if MEASURE_TIME 00755 cameraStartTime = GetTime(); 00756 #endif 00757 00758 while (counter) { 00759 if (read (camSock, intermediateBuffer, 1) <= 0) { 00760 CameraCloseSocket("Failed to read image header", camSock); 00761 globalCamera.cameraMetrics[ERR_CAMERA_HEADER_ERROR]++; 00762 goto RETRY; 00763 } 00764 00765 strncat(initialReadBuffer, intermediateBuffer, 1); 00766 if (NULL != strstr(trailingPtr, "\r\n\r\n")) { 00767 00768 if (!authorizeConfirmed){ 00769 00770 if (strstr(initialReadBuffer, authorizeString)) 00771 { 00772 authorizeConfirmed = 1; 00773 /* set camera to initialized */ 00774 globalCamera.cameraReady = 1; 00775 } 00776 else 00777 { 00778 CameraCloseSocket("Not authorized to connect to camera", camSock); 00779 authorizeCount++; 00780 goto RETRY; 00781 } 00782 } 00783 --counter; 00784 } 00785 if (++trailingCounter >= 4) { 00786 trailingPtr++; 00787 } 00788 } 00789 00790 counter = 1; 00791 char *contentLength = strstr(initialReadBuffer, contentString); 00792 if (contentLength == NULL) { 00793 globalCamera.cameraMetrics[ERR_CAMERA_HEADER_ERROR]++; 00794 CameraCloseSocket("No content-length token found in packet", camSock); 00795 goto RETRY; 00796 } 00797 /* get length of image content */ 00798 contentLength = contentLength + strlen(contentString); 00799 globalCamera.data[writeIndex].cameraImageSize = atol (contentLength); 00800 00801 if(globalCamera.data[writeIndex].cameraImage) 00802 free(globalCamera.data[writeIndex].cameraImage); 00803 //globalCamera.data[writeIndex].cameraImage = (Image *) malloc(globalCamera.data[writeIndex].cameraImageSize); 00804 globalCamera.data[writeIndex].cameraImage = (char*)malloc(globalCamera.data[writeIndex].cameraImageSize); 00805 if (NULL == globalCamera.data[writeIndex].cameraImage) { 00806 return CameraCloseSocket("Failed to allocate space for imageString", camSock); 00807 } 00808 globalCamera.cameraMetrics[CAM_BUFFERS_WRITTEN]++; 00809 00810 // 00811 // This is a blocking camera read function, and will block if the camera 00812 // has been disconnected from the cRIO. If however the camera is 00813 // POWERED OFF while connected to the cRIO, this function NEVER RETURNS 00814 // 00815 int bytesRead = fioRead (camSock, (char *)globalCamera.data[writeIndex].cameraImage, 00816 globalCamera.data[writeIndex].cameraImageSize); 00817 00818 #if MEASURE_TIME 00819 cameraEndTime = GetTime(); 00820 #endif 00821 00822 //DPRINTF (LOG_DEBUG, "Completed fioRead function - bytes read:%d", bytesRead); 00823 if (bytesRead <= 0) { 00824 CameraCloseSocket("Failed to read image data", camSock); 00825 goto RETRY; 00826 } else if (bytesRead != globalCamera.data[writeIndex].cameraImageSize){ 00827 fprintf(stderr, "ERROR: Failed to read entire image: readLength does not match bytes read"); 00828 globalCamera.cameraMetrics[CAM_BAD_IMAGE_SIZE]++; 00829 } 00830 // if decoding the JPEG to an HSL Image, do it here 00831 if (globalCamera.decode) { 00832 if(globalCamera.data[writeIndex].decodedImage) 00833 frcDispose(globalCamera.data[writeIndex].decodedImage); 00834 globalCamera.data[writeIndex].decodedImage = frcCreateImage(IMAQ_IMAGE_HSL); 00835 if (! Priv_ReadJPEGString_C(globalCamera.data[writeIndex].decodedImage, 00836 (const unsigned char *)globalCamera.data[writeIndex].cameraImage, 00837 globalCamera.data[writeIndex].cameraImageSize) ) { 00838 DPRINTF (LOG_DEBUG, "failure creating Image"); 00839 } 00840 } 00841 00842 // TODO: React to partial image 00843 globalCamera.data[writeIndex].timestamp = GetTime(); 00844 globalCamera.index = writeIndex; 00845 00846 /* signal a listening task */ 00847 if (globalCamera.readerPID) { 00848 if (taskKill (globalCamera.readerPID,SIGUSR1) == OK) 00849 DPRINTF (LOG_DEBUG, "SIGNALING PID= %i", globalCamera.readerPID); 00850 else 00851 globalCamera.cameraMetrics[CAM_PID_SIGNAL_ERR]++; 00852 DPRINTF (LOG_DEBUG, "ERROR SIGNALING PID= %i", globalCamera.readerPID); 00853 } 00854 00855 globalCamera.cameraMetrics[CAM_NUM_IMAGE]++; 00856 printCounter ++; 00857 if (printCounter == 1000) { 00858 DPRINTF (LOG_DEBUG, "imageCounter = %i", globalCamera.cameraMetrics[CAM_NUM_IMAGE]); 00859 printCounter=0; 00860 } 00861 00862 taskDelay(1); 00863 00864 #if MEASURE_TIME 00865 loopEndTime = GetTime(); 00866 performanceLoopCounter++; 00867 if (performanceLoopCounter <= maxCount) { 00868 DPRINTF (LOG_DEBUG, "%i DONE!!!: loop = ,%g, camera = ,%g, difference = ,%g, loopRate= ,%g,", 00869 performanceLoopCounter, loopEndTime-loopStartTime, cameraEndTime-cameraStartTime, 00870 (loopEndTime-loopStartTime) - (cameraEndTime-cameraStartTime), 00871 loopStartTime-previousStartTime); 00872 } 00873 #endif 00874 } /* end while (cont) */ 00875 00876 /* clean up */ 00877 close (camSock); 00878 cont = 0; 00879 DPRINTF (LOG_INFO, "\nJPEG SERVER ENDING errorCode = %i\n", errorCode ); 00880 00881 return (OK); 00882 } 00883 00888 void StartImageSignal(int taskId) // Start issuing a SIGUSR1 signal to the specified taskId 00889 { globalCamera.readerPID = taskId; } 00890 00894 void StartImageAcquisition() 00895 { 00896 globalCamera.cameraMetrics[CAM_STARTS]++; 00897 globalCamera.acquire = 1; 00898 DPRINTF(LOG_DEBUG, "starting acquisition"); 00899 } 00900 00901 00905 void StopImageAcquisition() 00906 { globalCamera.cameraMetrics[CAM_STOPS]++; globalCamera.acquire = 0; } 00907 00908 00918 static int initCamera(int frames, int compression, ImageResolution resolution, ImageRotation rotation) 00919 { 00920 //SetDebugFlag ( DEBUG_SCREEN_AND_FILE ) ; 00921 00922 DPRINTF(LOG_DEBUG, "\n+++++ camera task starting: rotation = %i", (int)rotation); 00923 int errorCode; 00924 00925 /* Initialize globalCamera area 00926 * Set decode to 1 - always want to decode images for processing 00927 * If ONLY sending images to the dashboard, you could set it to 0 */ 00928 bzero ((char *)&globalCamera, sizeof(globalCamera)); 00929 globalCamera.index = -1; 00930 globalCamera.decode = 1; 00931 00932 /* allow writing to vxWorks target */ 00933 Priv_SetWriteFileAllowed(1); 00934 00935 /* start acquisition immediately */ 00936 StartImageAcquisition(); 00937 00938 /* cameraJPEGServer runs until camera is stopped */ 00939 DPRINTF (LOG_DEBUG, "calling cameraJPEGServer" ); 00940 errorCode = cameraJPEGServer(frames, compression, resolution, rotation); 00941 DPRINTF (LOG_INFO, "errorCode from cameraJPEGServer = %i\n", errorCode ); 00942 return (OK); 00943 } 00944 00945 Task g_axisCameraTask("Camera", (FUNCPTR)initCamera); 00946 00955 int StartCameraTask() 00956 { 00957 return StartCameraTask(10, 0, k160x120, ROT_0); 00958 } 00959 int StartCameraTask(int frames, int compression, ImageResolution resolution, ImageRotation rotation) 00960 { 00961 char funcName[]="startCameraTask"; 00962 DPRINTF(LOG_DEBUG, "starting camera"); 00963 00964 int cameraTaskID = 0; 00965 00966 //range check 00967 if (frames < 1) frames = 1; 00968 else if (frames > 30) frames = 30; 00969 if (compression < 0) compression = 0; 00970 else if (compression > 100) compression = 100; 00971 00972 // stop any prior copy of running task 00973 StopCameraTask(); 00974 00975 // spawn camera task 00976 bool started = g_axisCameraTask.Start(frames, compression, resolution, rotation); 00977 cameraTaskID = g_axisCameraTask.GetID(); 00978 DPRINTF(LOG_DEBUG, "spawned task id %i", cameraTaskID); 00979 00980 if (!started) { 00981 DPRINTF(LOG_DEBUG, "camera task failed to start"); 00982 imaqSetError(ERR_CAMERA_TASK_SPAWN_FAILED, funcName); 00983 return -1; 00984 } 00985 return cameraTaskID; 00986 } 00987 00992 int StopCameraTask() 00993 { 00994 std::string taskName("FRC_Camera"); 00995 // check for prior copy of running task 00996 int oldTaskID = taskNameToId(const_cast<char*>(taskName.c_str())); 00997 if(oldTaskID != ERROR) { taskDelete(oldTaskID); } 00998 return oldTaskID; 00999 } 01000 01001 #if 0 01002 /* if you want to run this task by itself to debug 01003 * enable this code and make RunProgram the entry point 01004 */ 01005 extern "C" 01006 { 01007 void RunProgram(); 01008 int AxisCamera_StartupLibraryInit(); 01009 } 01011 void RunProgram() 01012 { StartCameraTask();} 01013 01015 int AxisCamera_StartupLibraryInit() 01016 { RunProgram(); return 0; } 01017 01018 #endif 01019 01020 01021
Generated on Thu Jan 12 2012 22:35:17 for WPILibC++ by
1.7.1