]> rtime.felk.cvut.cz Git - eurobot/public.git/commitdiff
"Averaging" results - rozkuk now keeps a number of results in memory, finds the most...
authorPetr Kubiznak <kubizpet@fel.cvut.cz>
Wed, 26 May 2010 17:16:41 +0000 (19:16 +0200)
committerPetr Kubiznak <kubizpet@fel.cvut.cz>
Wed, 26 May 2010 17:16:41 +0000 (19:16 +0200)
src/camera/rozkuk/Makefile.omk
src/camera/rozkuk/rozkuk.cxx
src/camera/rozkuk/t_decision_box.cxx [new file with mode: 0644]
src/camera/rozkuk/t_decision_box.h [new file with mode: 0644]

index 754631478fd4b1c9b7055bd6fdff4c18fb7cc87b..f35ae9647609ac8ef1a4f9c2c110846c3be6dfb6 100644 (file)
@@ -4,11 +4,11 @@
 INCLUDES += -I /usr/local/include
 LDFLAGS += -L /usr/local/lib
 
-bin_PROGRAMS = rozkuk camgrab #v4l-info
+bin_PROGRAMS = rozkuk #v4l-info
 
 #v4l-info_SOURCES = v4l-info.c struct-dump.c struct-v4l.c struct-v4l2.c
 
-rozkuk_SOURCES = rozkuk.cxx clr2float.cxx
+rozkuk_SOURCES = rozkuk.cxx clr2float.cxx t_decision_box.cxx
 rozkuk_LIBS = robodim pthread roboorte robottype orte cv highgui cxcore rt z jpeg
 
 ifeq ($(CROSS_COMPILE),)
@@ -20,9 +20,6 @@ maskgen_SOURCES = maskgen.cxx
 maskgen_LIBS = cv highgui
 endif
 
-camgrab_SOURCES = camgrab.c camera.c
-camgrab_LIBS = v4lconvert
-
 ifneq ($(wildcard $(OUTPUT_DIR)/_compiled/bin/maskgen),)
 binary-pass_HOOKS = masks.stamp
 
index 4c5ccc4cac9f9bfdb4de30bc5fe59f71af101f8b..5926232df5dc0706b5bd013e91a991ad135f83ae 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "clr2float.h"
 #include "masks_globals.h"
+#include "t_decision_box.h"
 
 extern "C" {
 #include <roboorte_robottype.h>
@@ -97,6 +98,16 @@ extern "C" {
 #define MASK_CENTER_SHIFT 4
 #define MASK_CENTER       (0x03 << 4)
 
+//number of results to select the most probable one from
+#define DECISION_BOX_SIZE 5
+
+//camera control system (if true, rozkuk recognizes, else it waits)
+#ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
+#define ORTE_CAMERA_CONTROL 1
+#else                     /******************** PPC *******************/
+#define ORTE_CAMERA_CONTROL orte.camera_control.on
+#endif                    /*------------------------------------------*/
+
 /******************************************************************************/
 
 // function declarations
@@ -267,11 +278,13 @@ int modeRecognize(CvCapture* capture) {
        CvMat *floatMat = NULL;                               // float <-1,1> image of the frame
        int sideConfig, centerConfig;                         // indices of recognized configurations
        double sideDist, centerDist;                          // distances between the best and second best results
+       TDecisionBox sideBox(DECISION_BOX_SIZE, SIDEMASKSCNT);     // side solutions "averaging" decision box
+       TDecisionBox centerBox(DECISION_BOX_SIZE, CENTERMASKSCNT); // center solutions "averaging" decision box
 #ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
        int framesPassed = PASS_FRAMES;                       // number of passed frames before refresh
        int pause=0;                                          // set pause=1 to pause processing
 #endif                    /*----------- DEBUG SESSION ONLY -----------*/
-       while(orte.camera_control.on) {
+       while(ORTE_CAMERA_CONTROL) {
 
 #ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
                /* keyboard events handeling */
@@ -333,16 +346,22 @@ int modeRecognize(CvCapture* capture) {
                // convert to float
                int threshold = countThreshold(frame);
                clr2float(frame, &floatMat, threshold, SATURATION, thresFrame); // get float representation (in DEBUG session, thresholded image is stored to thresFrame)
-               //recognize side and center layouts
+               //recognize side and center configurations
                sideConfig = recognize(floatMat, sideMasks, SIDEMASKSCNT, &sideDist);
                centerConfig = recognize(floatMat, centerMasks, CENTERMASKSCNT, &centerDist);
+               fprintf(stderr, "SINGLE:   thr: %3d, side: %d (%f), center: %d (%f)\n", threshold, sideConfig, sideDist, centerConfig, centerDist);
+               //push the results to the decision box and get "averaged" solutions from it
+               sideBox.insertItem(sideConfig, sideDist);
+               centerBox.insertItem(centerConfig, centerDist);
+               sideBox.decide(&sideConfig, &sideDist);
+               centerBox.decide(&centerConfig, &centerDist);
                //publish results
-               fprintf(stderr, "thr: %d, side: %d (%f), center: %d (%f)\n", threshold, sideConfig, sideDist, centerConfig, centerDist);
                orte.camera_result.side = sideConfig;
                orte.camera_result.center = centerConfig;
                orte.camera_result.sideDist = sideDist;
                orte.camera_result.centerDist = centerDist;
                ORTEPublicationSend(orte.publication_camera_result);
+               fprintf(stderr, "ORTE:               side: %d (%f), center: %d (%f)\n", sideConfig, sideDist, centerConfig, centerDist);
                
 #ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
                displayProduct(floatMat, sideConfig, centerConfig);
@@ -372,7 +391,7 @@ int modeRecognize(CvCapture* capture) {
   * @param capture Pointer to a camera capture.
   * @return Code of mode to switch to. */
 int modeWait(CvCapture *capture) {
-       while(!orte.camera_control.on) {
+       while(!ORTE_CAMERA_CONTROL) {
 #ifdef ROZKUK_DEBUG       /************ DEBUG SESSION ONLY ************/
                //process keyboard events
                switch(cvWaitKey(10) & 0xFF) {                      // wait 10ms for an event
diff --git a/src/camera/rozkuk/t_decision_box.cxx b/src/camera/rozkuk/t_decision_box.cxx
new file mode 100644 (file)
index 0000000..cb67a51
--- /dev/null
@@ -0,0 +1,91 @@
+#include <cstddef>
+#include <cstdio>
+#include "t_decision_box.h"
+using namespace std;
+
+/******************************************************************************/
+
+void TDecisionBox::countDistances(void) {
+       for(int i=0; i<=maxVal; i++) optionsWeights[i] = 0;
+       
+       Configuration *token = head;
+       while(token) {
+               optionsWeights[token->number] += token->distance;
+               token = token->next;
+       }
+}
+
+/******************************************************************************/
+/******************************************************************************/
+
+TDecisionBox::TDecisionBox(int size, int maxVal) {
+       this->size = (size<1 ? 1 : size);
+       this->count = 0;
+       this->maxVal = (maxVal<1 ? 0 : maxVal);
+       this->optionsWeights = new double [this->maxVal+1];
+       this->head = this->tail = NULL;
+}
+
+/******************************************************************************/
+
+TDecisionBox::~TDecisionBox(void) {
+       delete [] optionsWeights;
+       while(head) {
+               Configuration *item = head;
+               head = head->next;
+               delete item;
+       }
+}
+
+/******************************************************************************/
+
+bool TDecisionBox::insertItem(int number, double distance) {
+       if((number<0)||(number>maxVal)) return false;
+
+       Configuration *conf = new Configuration;
+       conf->number = number;
+       conf->distance = distance;
+       conf->next = head;
+       conf->prev = NULL;
+       
+       if(head) head->prev = conf;
+       head = conf;
+       if(!tail) tail = conf;
+       
+       // delete the last item
+       if(count>=size) {
+               Configuration *last = tail;
+               if(tail) {
+                       tail = tail->prev;
+                       tail->next = NULL;
+               }
+               delete last;
+       } else ++count;
+
+       return true;
+}
+
+/******************************************************************************/
+
+void TDecisionBox::decide(int *configuration, double *distance) {
+       double maxValue;
+       int maxIndex=0;
+       
+       //refresh table of distances
+       countDistances();
+       
+       // find highest distance
+       maxValue=optionsWeights[0];
+       for(int i=1; i<=maxVal; i++) {
+               if(optionsWeights[i] > maxValue) {
+                       maxValue = optionsWeights[i];
+                       maxIndex = i;
+               }
+       }
+       
+       if(configuration) *configuration = maxIndex;
+       if(distance) *distance = maxValue / count;            //average distance
+}
+
+/******************************************************************************/
+
diff --git a/src/camera/rozkuk/t_decision_box.h b/src/camera/rozkuk/t_decision_box.h
new file mode 100644 (file)
index 0000000..7ed2c8d
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 
+ * TDecisionBox - Class implementing box selecting most probable solution,
+ *  i.e. performs weighted selection on input objects.
+ *
+ * Created for Eurobot 2010 competition.
+ *
+ * Petr Kubizňák (kubiznak.petr@gmail.com), 2010
+ * 
+ ******************************************************************************/
+
+#ifndef __T_DECISION_BOX_H__
+#define __T_DECISION_BOX_H__
+
+/******************************************************************************/
+
+struct Configuration {
+       int number;
+       double distance;
+       Configuration *next;
+       Configuration *prev;
+};
+
+/******************************************************************************/
+
+class TDecisionBox {
+protected:
+       /** Capacity of the box. */
+       int size;
+       /** Actual number of items in the box. */
+       int count;
+       /** Maximal value of result. */
+       int maxVal;
+       /** Table of weights of each option. */
+       double *optionsWeights;
+       /** First and last item in the box. */
+       Configuration *head, *tail;
+       
+       /** Refreshes the optionsWeights table. */
+       void countDistances(void);
+       
+public:
+       TDecisionBox(int size, int maxVal);
+       ~TDecisionBox(void);
+       
+       /** Inserts solution properties as one item in the box.
+         * @return False if (number) is invalid value, else true. */
+       bool insertItem(int number, double distance);
+       /** Finds the most supported solution and sets it to (configuration),
+            distance is stored to (distance). */
+       void decide(int *configuration, double *distance);
+};
+
+/******************************************************************************/
+
+#endif /* T_DECISION_BOX */
+