]> rtime.felk.cvut.cz Git - eurobot/public.git/blob - src/camera/barcam/barcam.cxx
Some minor changes, working on (Canny, Hough) line detection in frame.
[eurobot/public.git] / src / camera / barcam / barcam.cxx
1 /*******************************************************************************
2  * 
3  * barcam - OpenCV based camera recognition program.
4  *
5  * Created for Eurobot 2010 competition.
6  *
7  * Petr Kubizňák (kubiznak.petr@gmail.com), 2010
8  * rewriten by Mihal Vokac (vokac.m@gmail.com), for Eurobot 2011
9  *
10  * This program is used to recognize type of playing elements (pawns, qeens,
11  * kings) in Eurobot 2011 competition. 
12  * Program can switch between several modes, also depending on platform - on PPC,
13  * only modes RECOGNIZE and WAIT are present, on PC, there are also VIDEO and
14  * IMAGE modes. Lets introduce them:
15  *  RECOGNIZE: Camera image is processed and playing element type is recognized.
16  *    The results are published continually using orte. On PC, the result and
17  *    some subresults are displayed graphically.
18  *  WAIT: Program waits until orte.camera_control.on is set to true, or, on PC,
19  *    waiting is interrupted by W key. This is the default mode for PPC.
20  *  VIDEO (PC only): Video from camera is just displayed in a window. Default
21  *    mode for PC. Use R key to switch to RECOGNIZE mode.
22  *  IMAGE (PC only): Pseudo-mode used to analyze *one* image loaded from file.
23  *    Is useful also for finding a good threshold value, using +/- keys. To use
24  *    this mode, start the program with -i argument (see below). There is no way
25  *    to switch from this mode to another one.
26  * 
27  * +++ PC +++
28  * Usage: ./barcam [-i filename]
29  *  -i:
30  *   Start in image mode, load filename to analyze.
31  *
32  * +++ PPC +++
33  * Usage: ./barcam
34  *   No arguments possible.
35  * 
36  ******************************************************************************/
37 #define BARCAM_DEBUG
38
39 #ifdef BARCAM_DEBUG
40 #define WITH_GUI
41 #endif
42
43 /******************************************************************************/
44
45 #include <inttypes.h>
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <sys/stat.h>
49 #include <semaphore.h>
50 #include <getopt.h>
51 #include <unistd.h>
52
53 #include <opencv/cv.h>
54 #include <opencv/highgui.h>
55
56 extern "C" {
57 #include <roboorte_robottype.h>
58 #include <robot.h>
59 }
60
61 /******************************************************************************/
62 /***************************** macro definitions ******************************/
63 /******************************************************************************/
64
65 //uncomment next line to "log" the output frames - save them as pnm to the working directory
66 //#define PPC_DEBUG
67
68 // modes definitions
69 #define MODE_QUIT         0x01
70 #define MODE_VIDEO        0x02
71 #define MODE_RECOGNIZE    0x04
72 #define MODE_WAIT         0x08
73 #define MODE_IMAGE        0x10
74
75 // highgui windows names
76 #define WINDOW_ORIG       "BARCAM original scene"
77 #define WINDOW_ROI        "BARCAM set region of interest"
78 #define WINDOW_PROD       "BARCAM recognition product"
79
80 // size of graphical windows
81 #define WINDOW_WIDTH      640
82 #define WINDOW_HEIGHT     480
83
84 // size of desired region of interest (crop camera view)
85 #define ROI_LU_X      WINDOW_WIDTH/2 - 40 
86 #define ROI_LU_Y      0
87 #define ROI_RL_X      WINDOW_WIDTH/2 + 40
88 #define ROI_RL_Y      WINDOW_HEIGHT - 20 
89
90 // values of keys
91 #define KEY_ESC           0x1B
92 #define KEY_SPACE         0x20
93 #define KEY_O             0x4f
94 #define KEY_P             0x50
95 #define KEY_R             0x52
96 #define KEY_S             0x53
97 #define KEY_V             0x56
98 #define KEY_W             0x57
99 #define KEY_o             0x6f
100 #define KEY_p             0x70
101 #define KEY_r             0x72
102 #define KEY_s             0x73
103 #define KEY_v             0x76
104 #define KEY_w             0x77
105 #define KEY_PLUS          0x2B
106 #define KEY_MINUS         0x2D
107 #define KEY_1             0x31
108 #define KEY_2             0x32
109 #define KEY_3             0x33
110 #define KEY_4             0x34
111 #define KEY_5             0x35
112 #define KEY_6             0x36
113 #define KEY_7             0x37
114 #define KEY_8             0x38
115
116
117 // filename pattern of snapshots (PPC does not support png)
118 #ifdef WITH_GUI
119 #define SNAPSHOTFILENAME  "snapshot%02d.png"
120 #else /* PPC */
121 #define SNAPSHOTFILENAME  "snapshot%02d.pnm"
122 #endif /* WITH_GUI */
123
124
125 /******************************************************************************/
126 /************************** function declarations *****************************/
127 /******************************************************************************/
128
129 /********************** multimode graphical functions *************************/
130 int saveFrame(const CvArr *img);
131 void drawPauseText(IplImage *img);
132 void selectROI(CvCapture* capture, struct roi *roi);
133
134 /******************** multimode computational functions ***********************/
135 int countThreshold(const IplImage *frame);
136 int recognize(const CvMat *frame);
137
138 /********************************** MODE_IMAGE ********************************/
139 int modeImage(char *imageFilename);
140
141 /********************************* MODE_VIDEO *********************************/
142 int modeVideo(CvCapture* capture, struct roi *roi);
143
144 /****************************** MODE_RECOGNIZE ********************************/
145 int recognizeMode_processKeys(IplImage *frame);
146 void displayFrames(IplImage *frame, IplImage **thrFrame, CvMat *fMat,
147                 int cfgSide, int cfgCenter);
148 int modeRecognize(CvCapture* capture, struct roi *roi);
149
150 /********************************* MODE_WAIT **********************************/
151 int waitMode_processKeys(int previousMode);
152 int modeWait(int previousMode);
153
154 /******************************** mode manager ********************************/
155 void setAnalyticWindowsVisible(bool visible);
156 void destroyGUI(void);
157 int modeManager(int defaultMode, char *paramC = NULL);
158
159 /*********************************** orte *************************************/
160 bool getCameraControlOn(void);
161 void send_cmr_res_cb(const ORTESendInfo *info, void *vinstance, void *recvCallBackParam);
162 void rcv_cmr_ctrl_cb(const ORTERecvInfo *info, void *vinstance, void *recvCallBackParam);
163 void rcv_robot_switches_cb(const ORTERecvInfo *info, void *vinstance, void *recvCallBackParam);
164
165 /********************************* application ********************************/
166 int getParamI(int argc, char *argv[], char *imgFilename);
167 int main(int argc, char *argv[]);
168
169
170 /******************************************************************************/
171 /**************************** variable declarations ***************************/
172 /******************************************************************************/
173
174 struct robottype_orte_data orte;
175 bool camera_control_on = false;
176
177 CvFont fontLarge;
178
179 struct roi {
180   CvPoint lu;
181   CvPoint rl;
182 };
183
184
185 /******************************************************************************/
186 /********************** multimode graphical functions *************************/
187 /******************************************************************************/
188
189 /** Saves current image to a new file in the current directory.
190   * @param img Image to save to file.
191   * @return Value returned by cvSaveImage. */
192 int saveFrame(const CvArr *img)
193 {
194         struct stat stFileInfo;
195         char filename[30];
196         int i = 0;
197
198         //find a non-existent filename (e.g. "snapshot13.png")
199         do {
200                 sprintf(filename, SNAPSHOTFILENAME, i++);
201         } while (!stat(filename, &stFileInfo));
202
203         fprintf(stdout, "Saving frame to %s...\n", filename);
204         return cvSaveImage(filename, img);
205 }
206
207 /******************************************************************************/
208
209 /** Writes text "pause" in the CAMERA window.
210   * @param img Frame to display with PAUSE text. */
211 #ifdef WITH_GUI
212 void drawPauseText(IplImage *img)
213 {
214   cvPutText(img, "PAUSE", cvPoint(img->width/2 - 40,img->height - 50),
215             &fontLarge, cvScalar(0,0,255));
216   cvShowImage(WINDOW_ORIG, img);
217 }
218 #else /* PPC */
219
220 void drawPauseText(IplImage *img) {}
221 #endif /* WITH_GUI */
222
223
224 /******************************************************************************/
225
226 /** Setting region of interest in the ROI window.
227   * @param capture Pointer to a camera capture.
228   * @param roi Pointer to ROI structure   */
229 #ifdef WITH_GUI
230 void selectROI(CvCapture* capture, struct roi *roi)
231 {
232   IplImage* frame = NULL;
233   int step = 10;
234   
235   while (1) {
236     // wait 10ms for an event
237     switch(cvWaitKey(10) & 0xFF) {
238       // exit ROI setting
239       case KEY_ESC:
240         cvDestroyWindow(WINDOW_ROI);
241         return;
242         
243       case KEY_PLUS:
244         // increase ROI step
245         step++;
246         break;
247         
248       case KEY_MINUS:
249         // decrease ROI step
250         step--;
251         break;
252         
253       case KEY_R:
254       case KEY_r:
255         // reset ROI to full frame
256         roi->lu.x = 0;
257         roi->lu.y = 0;
258         roi->rl.x = WINDOW_WIDTH;
259         roi->rl.y = WINDOW_HEIGHT;
260         break;
261         
262       case KEY_1:
263         // increase left border
264         roi->lu.x -= step;
265         break;
266         
267       case KEY_2:
268         // decrease left border
269         roi->lu.x += step;
270         break;
271         
272       case KEY_3:
273         // increase upper border
274         roi->lu.y -= step;
275         break;
276         
277       case KEY_4:
278         // decrease upper border
279         roi->lu.y += step;
280         break;
281         
282       case KEY_5:
283         // decrease lower border
284         roi->rl.y -= step;
285         break;
286         
287       case KEY_6:
288         // increase lower border
289         roi->rl.y += step;
290         break;
291         
292       case KEY_7:
293         // decrease right border
294         roi->rl.x -= step;
295         break;
296         
297       case KEY_8:
298         // increase right border
299         roi->rl.x += step;
300         break;
301     }
302     
303     fprintf(stderr, "ROI step: %d left: %d up: %d right: %d down: %d\n",
304             step, roi->lu.x, roi->lu.y, roi->rl.x, roi->rl.y);
305     
306     step = (step < 0 ? 0 : step);
307     
308     frame = cvQueryFrame(capture);
309     
310     cvPutText(frame, "Select ROI", cvPoint(frame->width/2 -60,
311                                            frame->height - 50),
312               &fontLarge, cvScalar(0,0,255));
313     
314     cvRectangle(frame, roi->lu, roi->rl, cvScalar(0,0,255), 2, 8, 0);
315     
316     cvShowImage(WINDOW_ROI, frame);
317       
318   }
319 }
320 #else /* PPC */
321
322 void selectROI(CvCapture *capture, struct roi *roi) {}
323 #endif /* WITH_GUI */
324
325 /******************************************************************************/
326 /******************** multimode computational functions ***********************/
327 /******************************************************************************/
328
329 /** Returns a threshold computed from the frame.
330   * @param frame Frame to compute a threshold from.
331   * @return Mean of all pixels of the frame. */
332 int countThreshold(const IplImage *frame)
333 {
334         return cvAvg(frame).val[0];
335 }
336
337 /******************************************************************************/
338
339 /** Returns an ordinary number of recognized configuration.
340   * @param frame Float representation of frame.
341   * @return  */
342 int recognize(IplImage* roi_frame) {
343   
344   int i,j;
345   
346    /* say you want to set some pixels in the ROI to 0 */
347   for (i = 0; i < roi_frame->height/2; i++) {
348       for (j = 0; j < roi_frame->width/2; j++) {
349           ((uchar*)(roi_frame->imageData + i * roi_frame->widthStep))[j*3] = 0;
350           ((uchar*)(roi_frame->imageData + i * roi_frame->widthStep))[j*3+1] = 0;
351           ((uchar*)(roi_frame->imageData + i * roi_frame->widthStep))[j*3+2] = 0;
352       }
353   } 
354
355 //   IplImage* dst = cvCreateImage( cvGetSize(roi_frame), roi_frame->depth, 1 );
356 //   IplImage* color_dst = cvCreateImage( cvGetSize(roi_frame), roi_frame->depth, roi_frame->nChannels);
357 //   
358 //   CvMemStorage* storage = cvCreateMemStorage(0);
359 //   CvSeq* lines = 0;
360 // 
361
362 //   
363 //         cvCanny(roi_frame, dst, 50, 200, 3 );
364 //         
365 //         cvCvtColor( dst, color_dst, CV_GRAY2BGR );
366 //         
367 //         lines = cvHoughLines2( dst,
368 //                                storage,
369 //                                CV_HOUGH_STANDARD,
370 //                                1,
371 //                                CV_PI/180,
372 //                                100,
373 //                                0,
374 //                                0 );
375 // 
376 //         for( i = 0; i < MIN(lines->total,100); i++ )
377 //         {
378 //             float* line = (float*)cvGetSeqElem(lines,i);
379 //             float rho = line[0];
380 //             float theta = line[1];
381 //             CvPoint pt1, pt2;
382 //             double a = cos(theta), b = sin(theta);
383 //             double x0 = a*rho, y0 = b*rho;
384 //             pt1.x = cvRound(x0 + 1000*(-b));
385 //             pt1.y = cvRound(y0 + 1000*(a));
386 //             pt2.x = cvRound(x0 - 1000*(-b));
387 //             pt2.y = cvRound(y0 - 1000*(a));
388 //             cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
389 //         }
390 // 
391 //         cvNamedWindow( "Hough", 1 );
392 //         cvShowImage( "Hough", color_dst );
393 // 
394 //         cvWaitKey(0);
395     
396
397   
398   return 0;
399 }
400
401
402 /******************************************************************************/
403 /********************************** MODE_IMAGE ********************************/
404 /******************************************************************************/
405
406 /** Simulates MODE_RECOGNIZE over one specified image filename (PC only).
407   * @param imageFilename Image to load and recognize.
408   * @return Code of mode to switch to. */
409 #ifdef WITH_GUI
410 int modeImage(char *imageFilename)
411 {
412   IplImage *frame = NULL;
413   
414   frame = cvLoadImage(imageFilename);
415   
416   if (!frame) {
417     fprintf(stderr, "File %s cannot be loaded as image.\n", imageFilename);
418     return MODE_QUIT;
419   }
420  
421   while (1) {
422
423     //TODO do something useful with the image
424     recognize(frame);
425     
426     // wait infinitely for a keyboard event
427     switch((char)(cvWaitKey(0) & 0xFF)) {
428     // quit
429     case KEY_ESC:
430       goto _modeImage_end;
431       break;
432     }
433   }
434
435 _modeImage_end:
436   cvReleaseImage(&frame);
437   return MODE_QUIT;
438 }
439 #else /* PPC */
440
441 int modeImage(char *imageFilename) {
442   fprintf(stderr, "Image mode is unsupported on PPC.\nTerminating.\n");
443   return MODE_QUIT;
444 }
445 #endif /* WITH_GUI */
446
447 /******************************************************************************/
448 /********************************* MODE_VIDEO *********************************/
449 /******************************************************************************/
450
451 /** Displays just a real video in a window (only on PC).
452   * @param capture Pointer to a camera capture.
453   * @return Code of mode to switch to. */
454 #ifdef WITH_GUI
455 int modeVideo(CvCapture* capture, struct roi *roi)
456 {
457         IplImage *frame = NULL;
458   IplImage *roi_frame = NULL;
459   
460         while (1) {
461                 // wait 10ms for an event
462                 switch(cvWaitKey(10) & 0xFF) {
463       // stop capturing
464       case KEY_ESC:
465         return MODE_QUIT;
466
467       // switch to recognize mode
468       case KEY_R:
469       case KEY_r:
470         return MODE_RECOGNIZE;
471
472       // pause - switch to wait mode
473       case KEY_P:
474       case KEY_p:
475         drawPauseText(roi_frame);
476         return MODE_WAIT;
477
478       // save frame to file
479       case KEY_S:
480       case KEY_s:
481         saveFrame(roi_frame);
482         break;
483         
484       case KEY_O:
485       case KEY_o:
486         cvResetImageROI(frame);
487         selectROI(capture, roi);
488         break;
489       
490                 }
491
492                 // get one frame from camera (do not release it!)
493                 frame = cvQueryFrame(capture);
494     
495     if (!frame) {
496       fprintf(stderr, "NULL frame\n");
497       continue;
498     }
499     
500     cvSetImageROI(frame, cvRect(roi->lu.x, roi->lu.y, roi->rl.x - roi->lu.x,
501                               roi->rl.y - roi->lu.y));
502     
503     roi_frame = cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels);
504   
505     cvCopy(frame, roi_frame, NULL);
506     
507                 cvShowImage(WINDOW_ORIG, roi_frame);
508         }
509         
510         return MODE_QUIT;
511 }
512 #else /* PPC */
513
514 int modeVideo(CvCapture* capture) {
515         fprintf(stderr, "Video mode is unsupported on PPC.\nTerminating.\n");
516         return MODE_QUIT;
517 }
518 #endif /* WITH_GUI */
519
520 /******************************************************************************/
521 /****************************** MODE_RECOGNIZE ********************************/
522 /******************************************************************************/
523
524 /** On PC processes keyboard events, on PPC does nothing.
525   * @param frame Last camera frame.
526   * @return MODE_RECOGNIZE or mode to switch to. */
527 #ifdef WITH_GUI
528 int recognizeMode_processKeys(IplImage *roi_frame)
529 {
530   // wait 10ms for an event
531   switch (cvWaitKey(10) & 0xFF) {
532     // stop capturing
533     case KEY_ESC:
534       return MODE_QUIT;
535
536     // video mode
537     case KEY_V:
538     case KEY_v:
539       return MODE_VIDEO;
540
541     // pause - wait mode
542     case KEY_P:
543     case KEY_p:
544       drawPauseText(roi_frame);
545       camera_control_on = 0;
546       return MODE_WAIT;
547   }
548   return MODE_RECOGNIZE;
549 }
550 #else /* PPC */
551
552 int recognizeMode_processKeys(IplImage *frame)
553 {
554   return MODE_RECOGNIZE;
555 }
556 #endif /* WITH_GUI */
557
558 /******************************************************************************/
559
560 /** Displays analytic frames on screen (on PC), or saves (input) frame to file
561   * (on PPC in debug mode).
562   * @param frame Input frame from camera.
563   * @param thrFrame Thresholded frame.
564   * @param fMat Float representation of frame.
565   * @param cfgSide Index of current side configuration.
566   * @param cfgCenter Index of current center configuration. */
567 #ifdef WITH_GUI
568 void displayFrames(IplImage *roi_frame) {
569   cvShowImage(WINDOW_PROD, roi_frame);
570
571 }
572
573 #else /* PPC */
574
575 void displayFrames(IplImage *frame, IplImage **thrFrame, CvMat *fMat,
576     int cfgSide, int cfgCenter) { /* nothing */ }
577 #endif /* WITH_GUI */
578
579 /******************************************************************************/
580
581 /** Implements the camera recognition of corns configurations.
582  * @param capture Pointer to a camera capture.
583  * @return Code of mode to switch to. */
584 int modeRecognize(CvCapture* capture, struct roi *roi)
585 {
586   int ret;
587   IplImage *frame = NULL;
588   IplImage *roi_frame = NULL;
589  
590   while (camera_control_on) {
591     
592     if ((ret = recognizeMode_processKeys(roi_frame)) != MODE_RECOGNIZE)
593       return ret;
594
595     //get one frame from camera (do not release!)
596     frame = cvQueryFrame(capture);
597     
598     if (!frame) {
599       fprintf(stderr, "NULL frame\n");
600       usleep(100*1000);
601       continue;
602     } //else if(orte.camera_result.error & camera_ERR_NO_FRAME) {
603      // orte.camera_result.error &= ~camera_ERR_NO_FRAME;
604       //ORTEPublicationSend(orte.publication_camera_result);
605    // }
606    
607     cvSetImageROI(frame, cvRect(roi->lu.x, roi->lu.y, roi->rl.x - roi->lu.x,
608                               roi->rl.y - roi->lu.y));
609    
610     roi_frame = cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels);
611   
612     cvCopy(frame, roi_frame, NULL);
613    
614     //TODO call image processing (do something useful with the image, FFT atc.)
615     ret = recognize(roi_frame);
616    
617 #ifdef WITH_GUI
618     cvShowImage(WINDOW_PROD, roi_frame);
619 #endif /* WITH_GUI */
620
621 //     publish results
622 //     orte.camera_result.side = sideConfig;
623 //     orte.camera_result.center = centerConfig;
624 //     orte.camera_result.sideDist = sideDist;
625 //     orte.camera_result.centerDist = centerDist;
626 //     ORTEPublicationSend(orte.publication_camera_result);
627
628   }
629   
630   return MODE_WAIT;  
631 }
632
633
634 /******************************************************************************/
635 /********************************* MODE_WAIT **********************************/
636 /******************************************************************************/
637
638 /** Returns mode to switch to from wait mode. On PC processes keyboard events,
639   * on PPC just tests for orte.camera_control.on value.
640   * @param previousMode Mode to switch to, if no more waiting is needed.
641   * @return Mode to switch to. */
642 #ifdef WITH_GUI
643 int waitMode_processKeys(int previousMode)
644 {
645         // wait 10ms for an event
646         switch(cvWaitKey(10) & 0xFF) {
647     // exit program
648     case KEY_ESC:
649       return MODE_QUIT;
650
651     // stop waiting
652     case KEY_P:
653     case KEY_p:
654       camera_control_on = 1;
655       return previousMode;
656     
657     // continue waiting
658     default:
659       return MODE_WAIT;
660         }
661 }
662 #else /* PPC */
663
664 int waitMode_processKeys(int previousMode) {
665         return (getCameraControlOn() ? previousMode : MODE_WAIT);
666 }
667 #endif /* WITH_GUI */
668
669 /******************************************************************************/
670
671 /** Waits until orte.camera_control.on is set to true or, on PC P-key
672   * is pressed.
673   * @param previousMode Mode to switch to when waiting stops.
674   * @return Code of mode to switch to. */
675 int modeWait(int previousMode)
676 {
677         int mode;
678
679         while((mode = waitMode_processKeys(previousMode)) == MODE_WAIT) {
680                 fprintf(stderr, "waiting...\n");
681                 sleep(1);
682         }
683         
684         return mode;
685 }
686
687
688 /******************************************************************************/
689 /******************************** mode manager ********************************/
690 /******************************************************************************/
691
692 /** Initializes GUI, displays static video window. */
693 #ifdef WITH_GUI
694 void initGUI(void) {
695   cvNamedWindow(WINDOW_ORIG, CV_WINDOW_AUTOSIZE);
696   cvInitFont(&fontLarge, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 2);
697 }
698 #else /* PPC */
699 void initGUI(void) {}
700 #endif /* WITH_GUI */
701
702 /******************************************************************************/
703
704 /** Destroys highgui windows. */
705 #ifdef WITH_GUI
706 void destroyGUI(void)
707 {
708   cvDestroyWindow(WINDOW_ORIG);
709   cvDestroyWindow(WINDOW_PROD);
710   cvDestroyWindow(WINDOW_ROI);
711 }
712 #else /* PPC */
713 void destroyGUI(void) {}
714 #endif /* WITH_GUI */
715
716 /******************************************************************************/
717
718 /** Switches between modes of the program.
719   * @param defaultMode The first mode to run.
720   * @param paramC Used only in MODE_IMAGE mode (store filepath here).
721   * @return Zero on success, error number on fail. */
722 int modeManager(int defaultMode, char *paramC)
723 {
724   int mode = defaultMode;
725   int lastMode = MODE_RECOGNIZE;
726   CvCapture* capture = NULL;
727   struct roi roi;
728
729   roi.lu.x = ROI_LU_X;
730   roi.lu.y = ROI_LU_Y;
731   roi.rl.x = ROI_RL_X;
732   roi.rl.y = ROI_RL_Y;
733
734   if (defaultMode == MODE_IMAGE) {
735     fprintf(stderr, "barcam started in image mode\n");
736   } else {
737     // connect to a camera
738     while (!(capture = cvCaptureFromCAM(-1))) {
739       fprintf(stderr, "NULL capture (is camera connected?)\n");
740       //orte.camera_result.error |= camera_ERR_NO_VIDEO;
741       //ORTEPublicationSend(orte.publication_camera_result);
742       usleep(500*1000);
743     }
744     
745     //orte.camera_result.error &= ~camera_ERR_NO_VIDEO;
746     //ORTEPublicationSend(orte.publication_camera_result);
747     fprintf(stderr, "barcam started, camera connected successfully\n");
748   }
749
750   initGUI();
751
752   while(!(mode & MODE_QUIT)) {
753     switch(mode) {
754
755     case MODE_VIDEO:
756       mode = modeVideo(capture, &roi);
757       lastMode = MODE_VIDEO;
758       break;
759       
760     case MODE_RECOGNIZE:
761       mode = modeRecognize(capture, &roi);
762       lastMode = MODE_RECOGNIZE;
763       break;
764
765     case MODE_WAIT:
766       mode = modeWait(lastMode);
767       break;
768
769     case MODE_IMAGE:
770       mode = modeImage(paramC);
771       lastMode = MODE_IMAGE;
772       break;
773
774     // jump out of the loop
775     default:
776       goto _modeManager_end;
777     }
778   }
779
780 _modeManager_end:
781   cvReleaseCapture(&capture);
782   //destroyGUI();
783   return 0;
784 }
785
786
787 /******************************************************************************/
788 /*********************************** orte *************************************/
789 /******************************************************************************/
790
791 /** Returns actual state of orte.camera_control.on.
792   * If value changed from previous call, informative output is printed. */
793 #ifdef WITH_GUI
794 inline bool getCameraControlOn(void) {
795         return camera_control_on;
796 }
797 #else /* PPC */
798
799 inline bool getCameraControlOn(void) {
800         if(orte.camera_control.on!=camera_control_on) {
801                 camera_control_on = orte.camera_control.on;
802                 fprintf(stderr, "orte: camera_control changed: ctrl %d\n",
803                                 camera_control_on);
804         }
805         return camera_control_on;
806 }
807 #endif /* WITH_GUI */
808
809 /******************************************************************************/
810
811 /** Orte camera result callback function. Does nothing. */
812 void send_cmr_res_cb(const ORTESendInfo *info, void *vinstance,
813                 void *recvCallBackParam) { /* nothing */ }
814
815 /******************************************************************************/
816
817 /** Orte camera control callback function.
818   * Sets actual value of orte.camera_control.on to camera_control_on. */
819 void rcv_cmr_ctrl_cb(const ORTERecvInfo *info, void *vinstance, void *recvCallBackParam) {
820         struct robottype_orte_data *orte_data = (struct robottype_orte_data *)recvCallBackParam;
821
822         switch (info->status) {
823                 case NEW_DATA:
824                         fprintf(stderr, "orte: New camera data: ctrl %d\n",
825                                 orte_data->camera_control.on);
826                         getCameraControlOn();
827                         break;
828                 case DEADLINE:
829                         fprintf(stderr, "ORTE deadline occurred - CMR_CTRL receive\n");
830                         break;
831         }
832 }
833
834
835 /******************************************************************************/
836 /********************************* application ********************************/
837 /******************************************************************************/
838
839 /** If "-i filename" is in argv, filename is stored to imgFilename.
840   * @return Mode to switch to. */
841 #ifdef WITH_GUI
842 int getStartMode(int argc, char *argv[], char *imgFilename) {
843         char opt;
844         
845         // scan for program arguments
846         while((opt = getopt(argc, argv, "i:")) != -1) {
847                 switch (opt) {
848                 //"-i filename"
849                 case 'i':
850                         if(optarg) sprintf(imgFilename, "%s", optarg);
851                         else {
852                                 fprintf(stderr, "Specify image filename to process: barcam -i filename\n");
853                                 return MODE_QUIT;
854                         }
855                         return MODE_IMAGE;
856                         break;
857                 }
858         }
859
860         camera_control_on = true;
861         return MODE_VIDEO;
862 }
863 #else /* PPC */
864
865 int getStartMode(int argc, char *argv[], char *imgFilename) {
866         return MODE_WAIT;
867 }
868 #endif /* WITH_GUI */
869
870 /******************************************************************************/
871
872 /** The program may on PC be called with -i argument followed by an image
873   * filename, i.e. rozkuk -i image.png, then the program runs in image mode.
874   * Else call it without arguments. On PC it starts in video mode, to switch
875   * modes keyboard is used (R-recognize, W-wait, Esc-quit). On PPC only two
876   * modes are available - recognize and wait. Orte's camera_control_on variable
877   * is used to switch between them. */
878 int main(int argc, char *argv[])
879 {  
880         char imgFilename[100];
881         int ret;
882
883         //ret = robottype_roboorte_init(&orte);
884         
885 //   if(ret < 0) {
886 //              fprintf(stderr, "robottype_roboorte_init failed\n");
887 //              return ret;
888 //      }
889 //      
890         
891 //      robottype_publisher_camera_result_create(&orte, send_cmr_res_cb, &orte);
892 //      robottype_subscriber_camera_control_create(&orte, rcv_cmr_ctrl_cb, &orte);
893 //      robottype_subscriber_robot_switches_create(&orte, rcv_robot_switches_cb, &orte);
894    
895   ret = getStartMode(argc, argv, imgFilename);
896   modeManager(ret, imgFilename);
897   
898   //ret = robottype_roboorte_destroy(&orte);
899   return ret;
900   
901 }
902