31 #include "AxisCamera.h"
32 #include "BaeUtilities.h"
36 #include "VisionAPI.h"
42 #define DEFAULT_PACKET_SIZE 512
45 IMAQ_FUNC
int Priv_ReadJPEGString_C(Image* _image,
const unsigned char* _string, uint32_t _stringLength);
48 int AxisCamera_debugFlag = 0;
49 #define DPRINTF if(AxisCamera_debugFlag)dprintf
69 int cameraMetrics[CAM_NUM_METRICS];
73 static short cont = 0;
85 int GetImageBlocking(Image* image,
double *timestamp,
double lastImageTimestamp)
87 char funcName[]=
"GetImageBlocking";
89 double startTime = GetTime();
93 success = GetImage(image, timestamp);
94 if (!success)
return (success);
96 if (*timestamp > lastImageTimestamp)
99 if (GetTime() > (startTime + MAX_BLOCKING_TIME_SEC))
101 imaqSetError(ERR_CAMERA_BLOCKING_TIMEOUT, funcName);
102 globalCamera.cameraMetrics[CAM_BLOCKING_TIMEOUT]++;
105 globalCamera.cameraMetrics[CAM_BLOCKING_COUNT]++;
114 int CameraInitialized()
116 char funcName[]=
"CameraInitialized";
119 if (!globalCamera.cameraReady) {
120 imaqSetError(ERR_CAMERA_NOT_INITIALIZED, funcName);
121 DPRINTF (LOG_DEBUG,
"Camera request before camera is initialized");
122 globalCamera.cameraMetrics[CAM_GETIMAGE_BEFORE_INIT]++;
123 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;
127 if (globalCamera.index == -1){
128 imaqSetError(ERR_CAMERA_NO_BUFFER_AVAILABLE, funcName);
129 DPRINTF (LOG_DEBUG,
"No camera image available");
130 globalCamera.cameraMetrics[CAM_GETIMAGE_BEFORE_AVAILABLE]++;
131 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;
145 int GetImage(Image* image,
double *timestamp)
147 char funcName[]=
"GetImage";
151 double currentTime = time(NULL);
152 double currentImageTimestamp;
156 if (!CameraInitialized()) {
return success;}
160 readIndex = globalCamera.index;
161 if (!imaqDuplicate(image, globalCamera.data[readIndex].decodedImage)) {
162 int errorCode = GetLastVisionError();
163 DPRINTF (LOG_DEBUG,
"Error duplicating image= %i %s ", errorCode, GetVisionErrorText(errorCode));
166 currentImageTimestamp = globalCamera.data[readIndex].timestamp;
169 if (readIndex == globalCamera.index)
break;
176 if (timestamp != NULL)
177 *timestamp = currentImageTimestamp;
179 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;
183 if (currentTime > globalCamera.data[globalCamera.index].timestamp + CAMERA_IMAGE_STALE_TIME_SEC){
184 DPRINTF (LOG_CRITICAL,
"STALE camera image (THIS COULD BE A BAD IMAGE)");
185 imaqSetError(ERR_CAMERA_STALE_IMAGE, funcName);
186 globalCamera.cameraMetrics[CAM_STALE_IMAGE]++;
187 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;
190 globalCamera.cameraMetrics[CAM_GETIMAGE_SUCCESS]++;
201 int GetImageData(
char** imageData,
int* numBytes,
double* currentImageTimestamp)
207 char *cameraImageString;
211 if (!CameraInitialized()) {
return success;}
215 readIndex = globalCamera.index;
216 cameraImageSize = globalCamera.data[readIndex].cameraImageSize;
218 cameraImageString =
new char[cameraImageSize];
219 if (NULL == cameraImageString) {
220 DPRINTF (LOG_DEBUG,
"Unable to allocate cameraImage");
221 globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;
224 memcpy (cameraImageString, globalCamera.data[readIndex].cameraImage, cameraImageSize);
225 *currentImageTimestamp = globalCamera.data[readIndex].timestamp;
227 if (readIndex == globalCamera.index)
break;
228 free (cameraImageString);
232 *imageData = cameraImageString;
233 *numBytes = cameraImageSize;
249 int GetImageDataBlocking(
char** imageData,
int* numBytes,
double* timestamp,
double lastImageTimestamp)
252 char funcName[]=
"GetImageDataBlocking";
254 double startTime = GetTime();
259 success = GetImageData(imageData, numBytes, timestamp);
260 if (!success)
return (success);
262 if (*timestamp > lastImageTimestamp)
268 if (GetTime() > (startTime + MAX_BLOCKING_TIME_SEC))
270 imaqSetError(ERR_CAMERA_BLOCKING_TIMEOUT, funcName);
273 globalCamera.cameraMetrics[CAM_BLOCKING_COUNT]++;
283 int GetCameraMetric(FrcvCameraMetric metric)
284 {
return globalCamera.cameraMetrics[metric]; }
292 int CameraCloseSocket(
const char *errstring,
int socket)
294 DPRINTF (LOG_CRITICAL,
"Closing socket - CAMERA ERROR: %s", errstring );
310 static int CameraReadLine(
int camSock,
char* buffer,
int bufSize,
bool stripLineEnding) {
311 char funcName[]=
"CameraReadLine";
314 imaqSetError(ERR_CAMERA_FAILURE, funcName);
320 for (
int i=0;i < bufSize;++i, ++buffer) {
322 if (read (camSock, buffer, 1) <= 0) {
323 imaqSetError(ERR_CAMERA_FAILURE, funcName);
335 if (stripLineEnding) {
336 if (i > 0 && *(buffer-1)==
'\r') {
342 if (i == 0 || *(buffer-1)!=
'\r') {
368 static int CameraSkipUntilEmptyLine(
int camSock) {
372 success = CameraReadLine(camSock, buffer,
sizeof(buffer),
true);
373 if (*buffer ==
'\0') {
395 static int CameraOpenSocketAndIssueAuthorizedRequest(
const char* serverName,
const char* request)
397 char funcName[]=
"cameraOpenSocketAndIssueAuthorizedRequest";
399 struct sockaddr_in cameraAddr;
405 static const char* authenticationStrings[] = {
411 static const int numAuthenticationStrings =
sizeof(authenticationStrings)/
sizeof(authenticationStrings[0]);
413 static const char *requestTemplate =
"%s " \
415 "User-Agent: HTTPStreamClient\n" \
416 "Connection: Keep-Alive\n" \
417 "Cache-Control: no-cache\n" \
418 "Authorization: Basic %s\n\n";
421 for (;i < numAuthenticationStrings;++i) {
424 sprintf(buffer, requestTemplate, request, authenticationStrings[i]);
428 if ((camSock = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) {
429 imaqSetError(ERR_CAMERA_SOCKET_CREATE_FAILED, funcName);
430 perror(
"Failed to create socket");
434 sockAddrSize =
sizeof (
struct sockaddr_in);
435 bzero ((
char *) &cameraAddr, sockAddrSize);
436 cameraAddr.sin_family = AF_INET;
437 cameraAddr.sin_len = (u_char) sockAddrSize;
438 cameraAddr.sin_port = htons (CAMERA_PORT);
440 if (( (
int)(cameraAddr.sin_addr.s_addr = inet_addr (const_cast<char*>(serverName)) ) == ERROR) &&
441 ( (
int)(cameraAddr.sin_addr.s_addr = hostGetByName (const_cast<char*>(serverName)) ) == ERROR))
443 imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName);
444 return CameraCloseSocket(
"Failed to get IP, check hostname or IP", camSock);
448 if (connect (camSock, (
struct sockaddr *) &cameraAddr, sockAddrSize) == ERROR) {
449 imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName);
450 return CameraCloseSocket(
"Failed to connect to camera - check networ", camSock);
454 if (write (camSock, buffer, strlen(buffer) ) == ERROR) {
455 imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName);
456 return CameraCloseSocket(
"Failed to send GET request", camSock);
460 if (!CameraReadLine(camSock, buffer, 1024,
true)) {
461 return CameraCloseSocket(
"Bad response to GET request", camSock);
466 if (sscanf(buffer,
"HTTP/%f 200 OK", &discard) == 1) {
475 if (numAuthenticationStrings == i) {
476 imaqSetError(ERR_CAMERA_AUTHORIZATION_FAILED, funcName);
477 fprintf(stderr,
"Expected username/password combination not found on camera");
489 int ConfigureCamera(
char *configString){
490 char funcName[]=
"ConfigureCamera";
491 const char *serverName =
"192.168.0.90";
496 const char * getStr1 =
497 "GET /axis-cgi/admin/param.cgi?action=update&ImageSource.I0.Sensor.";
499 char cameraRequest[strlen(getStr1) + strlen(configString)];
500 sprintf (cameraRequest,
"%s%s", getStr1, configString);
501 DPRINTF(LOG_DEBUG,
"camera configuration string: \n%s", cameraRequest);
502 camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest);
503 DPRINTF(LOG_DEBUG,
"camera socket# = %i", camSock);
506 success = CameraSkipUntilEmptyLine(camSock);
509 success = CameraReadLine(camSock, buffer, 3,
true);
511 DPRINTF(LOG_DEBUG,
"line read from camera \n%s", buffer);
512 if (strcmp(buffer,
"OK") != 0) {
513 imaqSetError(ERR_CAMERA_COMMAND_FAILURE, funcName);
514 DPRINTF(LOG_DEBUG,
"setting ERR_CAMERA_COMMAND_FAILURE - OK not found");
516 DPRINTF (LOG_INFO,
"\nConfigureCamera ENDING success = %i\n", success );
530 int GetCameraSetting(
char *configString,
char *cameraResponse){
531 const char *serverName =
"192.168.0.90";
536 const char * getStr1 =
537 "GET /axis-cgi/admin/param.cgi?action=list&group=ImageSource.I0.Sensor.";
538 char cameraRequest[strlen(getStr1) + strlen(configString)];
539 sprintf (cameraRequest,
"%s%s", getStr1, configString);
540 DPRINTF(LOG_DEBUG,
"camera configuration string: \n%s", cameraRequest);
541 camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest);
542 DPRINTF(LOG_DEBUG,
"return from CameraOpenSocketAndIssueAuthorizedRequest %i", camSock);
545 success = CameraSkipUntilEmptyLine(camSock);
546 success = CameraReadLine(camSock, cameraResponse, 1024,
true);
547 DPRINTF(LOG_DEBUG,
"succcess from CameraReadLine: %i", success);
548 DPRINTF(LOG_DEBUG,
"line read from camera \n%s", cameraResponse);
549 DPRINTF (LOG_INFO,
"\nGetCameraSetting ENDING success = %i\n", success );
563 int GetImageSetting(
char *configString,
char *cameraResponse){
564 const char *serverName =
"192.168.0.90";
569 const char *getStr1 =
"GET /axis-cgi/admin/param.cgi?action=list&group=Image.I0.Appearance.";
570 char cameraRequest[strlen(getStr1) + strlen(configString)];
571 sprintf (cameraRequest,
"%s%s", getStr1, configString);
572 DPRINTF(LOG_DEBUG,
"camera configuration string: \n%s", cameraRequest);
573 camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest);
574 DPRINTF(LOG_DEBUG,
"return from CameraOpenSocketAndIssueAuthorizedRequest %i", camSock);
577 success = CameraSkipUntilEmptyLine(camSock);
578 success = CameraReadLine(camSock, cameraResponse, 1024,
true);
579 DPRINTF(LOG_DEBUG,
"succcess from CameraReadLine: %i", success);
580 DPRINTF(LOG_DEBUG,
"line read from camera \n%s", cameraResponse);
581 DPRINTF (LOG_INFO,
"\nGetCameraSetting ENDING success = %i\n", success );
589 #define MEASURE_SOCKET_TIME 1
599 int cameraJPEGServer(
int frames,
int compression, ImageResolution resolution, ImageRotation rotation)
601 char funcName[]=
"cameraJPEGServer";
602 char serverName[] =
"192.168.0.90";
605 int printCounter = 0;
607 int authorizeCount = 0;
608 int authorizeConfirmed = 0;
609 static const int authenticationStringsCount = 3;
610 static const char* authenticationStrings[] = {
616 DPRINTF (LOG_DEBUG,
"cameraJPEGServer" );
618 struct sockaddr_in cameraAddr;
623 switch (resolution) {
624 case k640x480: { sprintf(resStr,
"640x480");
break; }
625 case k320x240: { sprintf(resStr,
"320x240");
break; }
626 case k160x120: { sprintf(resStr,
"160x120");
break; }
627 default: {DPRINTF (LOG_DEBUG,
"code error - resolution input" );
break; }
633 const char * getStr1 =
634 "GET /axis-cgi/mjpg/video.cgi?showlength=1&camera=1&";
637 sprintf (insertStr,
"des_fps=%i&compression=%i&resolution=%s&rotation=%i",
638 frames, compression, resStr, (
int)rotation);
640 const char * getStr2 =
" HTTP/1.1\n\
641 User-Agent: HTTPStreamClient\n\
642 Host: 192.150.1.100\n\
643 Connection: Keep-Alive\n\
644 Cache-Control: no-cache\n\
645 Authorization: Basic %s;\n\n";
647 char getStr[strlen(getStr1) + strlen(insertStr) + strlen(getStr2)];
648 sprintf (getStr,
"%s:%s%s", getStr1, insertStr, getStr2);
650 DPRINTF(LOG_DEBUG,
"revised camera string: \n%s", getStr);
652 char tempBuffer[1024];
656 while (globalCamera.acquire == 0) Wait(0.1);
658 if (!authorizeConfirmed){
659 if (authorizeCount < authenticationStringsCount){
660 sprintf (tempBuffer, getStr, authenticationStrings[authorizeCount]);
662 imaqSetError(ERR_CAMERA_AUTHORIZATION_FAILED, funcName);
663 fprintf(stderr,
"Camera authorization failed ... Incorrect password on camera!!");
670 globalCamera.cameraMetrics[CAM_SOCKET_INIT_ATTEMPTS]++;
673 DPRINTF (LOG_DEBUG,
"creating camSock" );
674 if ((camSock = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) {
675 imaqSetError(ERR_CAMERA_SOCKET_CREATE_FAILED, funcName);
676 perror(
"Failed to create socket");
681 sockAddrSize =
sizeof (
struct sockaddr_in);
682 bzero ((
char *) &cameraAddr, sockAddrSize);
683 cameraAddr.sin_family = AF_INET;
684 cameraAddr.sin_len = (u_char) sockAddrSize;
685 cameraAddr.sin_port = htons (CAMERA_PORT);
687 DPRINTF (LOG_DEBUG,
"getting IP" );
688 if (( (
int)(cameraAddr.sin_addr.s_addr = inet_addr (serverName) ) == ERROR) &&
689 ( (
int)(cameraAddr.sin_addr.s_addr = hostGetByName (serverName) ) == ERROR))
691 CameraCloseSocket(
"Failed to get IP, check hostname or IP", camSock);
695 DPRINTF (LOG_INFO,
"Attempting to connect to camSock" );
696 if (connect (camSock, (
struct sockaddr *) &cameraAddr, sockAddrSize) == ERROR) {
697 imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName);
698 CameraCloseSocket(
"Failed to connect to camera - check network", camSock);
702 #if MEASURE_SOCKET_SETUP
703 socketEndTime = GetTime();
704 setupTime = socketEndTime - socketStartTime;
705 printf(
"\n***socket setup time = %g\n", setupTime );
708 globalCamera.cameraMetrics[CAM_SOCKET_OPEN]++;
712 DPRINTF (LOG_DEBUG,
"writing GET request to camSock" );
713 if (write (camSock, tempBuffer , strlen(tempBuffer) ) == ERROR) {
714 return CameraCloseSocket(
"Failed to send GET request", camSock);
720 const char* contentString =
"Content-Length: ";
721 const char* authorizeString =
"200 OK";
723 #define MEASURE_TIME 0
726 double loopStartTime = 0.0;
727 double loopEndTime = 0.0;
728 double cameraStartTime = 0.0;
729 double cameraEndTime = 0.0;
730 double previousStartTime = 0.0;
731 int performanceLoopCounter = 0;
737 previousStartTime = loopStartTime;
738 loopStartTime = GetTime();
744 if (globalCamera.index == 0)
751 char initialReadBuffer[DEFAULT_PACKET_SIZE] =
"";
752 char intermediateBuffer[1];
753 char *trailingPtr = initialReadBuffer;
754 int trailingCounter = 0;
758 cameraStartTime = GetTime();
762 if (read (camSock, intermediateBuffer, 1) <= 0) {
763 CameraCloseSocket(
"Failed to read image header", camSock);
764 globalCamera.cameraMetrics[ERR_CAMERA_HEADER_ERROR]++;
768 strncat(initialReadBuffer, intermediateBuffer, 1);
769 if (NULL != strstr(trailingPtr,
"\r\n\r\n")) {
771 if (!authorizeConfirmed){
773 if (strstr(initialReadBuffer, authorizeString))
775 authorizeConfirmed = 1;
777 globalCamera.cameraReady = 1;
781 CameraCloseSocket(
"Not authorized to connect to camera", camSock);
788 if (++trailingCounter >= 4) {
794 char *contentLength = strstr(initialReadBuffer, contentString);
795 if (contentLength == NULL) {
796 globalCamera.cameraMetrics[ERR_CAMERA_HEADER_ERROR]++;
797 CameraCloseSocket(
"No content-length token found in packet", camSock);
801 contentLength = contentLength + strlen(contentString);
802 globalCamera.data[writeIndex].cameraImageSize = atol (contentLength);
804 if(globalCamera.data[writeIndex].cameraImage)
805 free(globalCamera.data[writeIndex].cameraImage);
807 globalCamera.data[writeIndex].cameraImage = (
char*)malloc(globalCamera.data[writeIndex].cameraImageSize);
808 if (NULL == globalCamera.data[writeIndex].cameraImage) {
809 return CameraCloseSocket(
"Failed to allocate space for imageString", camSock);
811 globalCamera.cameraMetrics[CAM_BUFFERS_WRITTEN]++;
818 int bytesRead = fioRead (camSock, (
char *)globalCamera.data[writeIndex].cameraImage,
819 globalCamera.data[writeIndex].cameraImageSize);
822 cameraEndTime = GetTime();
826 if (bytesRead <= 0) {
827 CameraCloseSocket(
"Failed to read image data", camSock);
829 }
else if (bytesRead != globalCamera.data[writeIndex].cameraImageSize){
830 fprintf(stderr,
"ERROR: Failed to read entire image: readLength does not match bytes read");
831 globalCamera.cameraMetrics[CAM_BAD_IMAGE_SIZE]++;
834 if (globalCamera.decode) {
835 if(globalCamera.data[writeIndex].decodedImage)
836 frcDispose(globalCamera.data[writeIndex].decodedImage);
837 globalCamera.data[writeIndex].decodedImage = frcCreateImage(IMAQ_IMAGE_HSL);
838 if (! Priv_ReadJPEGString_C(globalCamera.data[writeIndex].decodedImage,
839 (
const unsigned char *)globalCamera.data[writeIndex].cameraImage,
840 globalCamera.data[writeIndex].cameraImageSize) ) {
841 DPRINTF (LOG_DEBUG,
"failure creating Image");
846 globalCamera.data[writeIndex].timestamp = GetTime();
847 globalCamera.index = writeIndex;
850 if (globalCamera.readerPID) {
851 if (taskKill (globalCamera.readerPID,SIGUSR1) == OK)
853 DPRINTF (LOG_DEBUG,
"SIGNALING PID= %i", globalCamera.readerPID);
857 globalCamera.cameraMetrics[CAM_PID_SIGNAL_ERR]++;
858 DPRINTF (LOG_DEBUG,
"ERROR SIGNALING PID= %i", globalCamera.readerPID);
862 globalCamera.cameraMetrics[CAM_NUM_IMAGE]++;
864 if (printCounter == 1000) {
865 DPRINTF (LOG_DEBUG,
"imageCounter = %i", globalCamera.cameraMetrics[CAM_NUM_IMAGE]);
872 loopEndTime = GetTime();
873 performanceLoopCounter++;
874 if (performanceLoopCounter <= maxCount) {
875 DPRINTF (LOG_DEBUG,
"%i DONE!!!: loop = ,%g, camera = ,%g, difference = ,%g, loopRate= ,%g,",
876 performanceLoopCounter, loopEndTime-loopStartTime, cameraEndTime-cameraStartTime,
877 (loopEndTime-loopStartTime) - (cameraEndTime-cameraStartTime),
878 loopStartTime-previousStartTime);
886 DPRINTF (LOG_INFO,
"\nJPEG SERVER ENDING errorCode = %i\n", errorCode );
895 void StartImageSignal(
int taskId)
896 { globalCamera.readerPID = taskId; }
901 void StartImageAcquisition()
903 globalCamera.cameraMetrics[CAM_STARTS]++;
904 globalCamera.acquire = 1;
905 DPRINTF(LOG_DEBUG,
"starting acquisition");
912 void StopImageAcquisition()
913 { globalCamera.cameraMetrics[CAM_STOPS]++; globalCamera.acquire = 0; }
925 static int initCamera(
int frames,
int compression, ImageResolution resolution, ImageRotation rotation)
929 DPRINTF(LOG_DEBUG,
"\n+++++ camera task starting: rotation = %i", (
int)rotation);
935 bzero ((
char *)&globalCamera,
sizeof(globalCamera));
936 globalCamera.index = -1;
937 globalCamera.decode = 1;
940 Priv_SetWriteFileAllowed(1);
943 StartImageAcquisition();
946 DPRINTF (LOG_DEBUG,
"calling cameraJPEGServer" );
947 errorCode = cameraJPEGServer(frames, compression, resolution, rotation);
948 DPRINTF (LOG_INFO,
"errorCode from cameraJPEGServer = %i\n", errorCode );
952 Task g_axisCameraTask(
"Camera", (FUNCPTR)initCamera);
962 int StartCameraTask()
964 return StartCameraTask(10, 0, k160x120, ROT_0);
966 int StartCameraTask(
int frames,
int compression, ImageResolution resolution, ImageRotation rotation)
968 char funcName[]=
"startCameraTask";
969 DPRINTF(LOG_DEBUG,
"starting camera");
971 int cameraTaskID = 0;
974 if (frames < 1) frames = 1;
975 else if (frames > 30) frames = 30;
976 if (compression < 0) compression = 0;
977 else if (compression > 100) compression = 100;
983 bool started = g_axisCameraTask.
Start(frames, compression, resolution, rotation);
984 cameraTaskID = g_axisCameraTask.
GetID();
985 DPRINTF(LOG_DEBUG,
"spawned task id %i", cameraTaskID);
988 DPRINTF(LOG_DEBUG,
"camera task failed to start");
989 imaqSetError(ERR_CAMERA_TASK_SPAWN_FAILED, funcName);
1001 std::string taskName(
"FRC_Camera");
1003 int oldTaskID = taskNameToId(const_cast<char*>(taskName.c_str()));
1004 if(oldTaskID != ERROR) { taskDelete(oldTaskID); }
1015 int AxisCamera_StartupLibraryInit();
1019 { StartCameraTask();}
1022 int AxisCamera_StartupLibraryInit()
1023 { RunProgram();
return 0; }
bool Start(uint32_t arg0=0, uint32_t arg1=0, uint32_t arg2=0, uint32_t arg3=0, uint32_t arg4=0, uint32_t arg5=0, uint32_t arg6=0, uint32_t arg7=0, uint32_t arg8=0, uint32_t arg9=0)