Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / server / PositionMonitor.cpp @ 764

History | View | Annotate | Download (6.3 KB)

1 436 jknichel
/**
2
 * @file PositionMonitor.cpp
3
 *
4
 * @author Jason Knichel
5
 *
6
 * @date 2/4/08
7
 */
8
9 627 emarinel
#include <assert.h>
10 550 emarinel
#include <map>
11 443 emarinel
#include <PositionMonitor.h>
12 550 emarinel
#include <stdio.h>
13 436 jknichel
#include <stdlib.h>
14
#include <vision.h>
15
16 449 jknichel
using namespace std;
17
18 550 emarinel
#define MAX_POSITIONS 20
19 710 gtress
#define SAME_ROBOT_DISTANCE_THRESHOLD 15
20 550 emarinel
#define ROBOT_DELETE_BUFFER 10
21
#define CAM_UPDATE_PERIOD 100000
22
23 655 jknichel
/**
24
 * @brief Constructor for the PositionMonitor class
25
 */
26 436 jknichel
PositionMonitor::PositionMonitor() {
27
  //TODO: don't hardcode this file name
28
  //TODO: check for error returned from init
29
  vision_init("/var/www/colonet.jpg");
30 466 emarinel
  newIdToAssign = -1;
31 710 gtress
32 508 emarinel
  pthread_mutex_init(&position_map_lock, NULL);
33 436 jknichel
}
34
35 655 jknichel
/**
36
 * @brief Destructor for the PositionMonitor class
37
 */
38 436 jknichel
PositionMonitor::~PositionMonitor() {
39
}
40
41 655 jknichel
/**
42
 * @brief This function updates the positions of things in the image
43
 *
44
 * @return Void
45
 */
46 508 emarinel
void PositionMonitor::run() {
47
  while (1) {
48 627 emarinel
    if (updatePositions() == -1) {
49
      fprintf(stderr, "updatePositions failed.\n");
50
    }
51
52 550 emarinel
    usleep(CAM_UPDATE_PERIOD);
53 508 emarinel
  }
54 436 jknichel
}
55
56 655 jknichel
/**
57
 * @brief This function asks the vision code for the position of things it identifies
58
 */
59 447 emarinel
int PositionMonitor::updatePositions() {
60 627 emarinel
  VisionPosition* positions = NULL;
61
  int numPositions = vision_get_robot_positions(&positions);
62 436 jknichel
63 655 jknichel
  //debug output code
64 710 gtress
  /*
65
  printf("\nnumPositions is %d\n", numPositions);
66 467 emarinel
  for (int i = 0; i < numPositions; i++) {
67
    printf("{%d,%d} ", positions[i].x, positions[i].y);
68
  }
69
  printf("\n");
70 581 jknichel
  */
71 436 jknichel
72 627 emarinel
  if (numPositions == -1) {
73
    fprintf(stderr, "%s: vision_get_robot_positions failed.\n", __FUNCTION__);
74
    return -1;
75
  } else {
76
    map<int, VisionPosition> newPositionMap;
77 467 emarinel
78 627 emarinel
    pthread_mutex_lock(&position_map_lock);
79 509 emarinel
80 655 jknichel
    //go through each of the positions the vision system identified
81 627 emarinel
    for (int i = 0; i < numPositions; i++) {
82
      VisionPosition newPos = positions[i];
83
      map<int, VisionPosition>::iterator iter;
84 710 gtress
85 655 jknichel
      //go through all the positions we currently have in the position map
86 627 emarinel
      for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
87
        VisionPosition oldPos = iter->second;
88 449 jknichel
89 655 jknichel
        //figure out if the new point is probably the same robot as one of the old positions
90 627 emarinel
        if (isProbablySameRobot(newPos, oldPos)) {
91 710 gtress
          //DEBUG
92
          //printf("probably same robot: new = (%d, %d), old = (%d, %d)\n", newPos.x, newPos.y, oldPos.x, oldPos.y);
93
94 655 jknichel
          //if the new positions is the same robot as an old one, insert this new position into the new map
95 627 emarinel
          newPositionMap.insert(make_pair(iter->first, newPos));
96 655 jknichel
97
          //erase this robot from the map that is used to smooth over several frames in case of problems identifying robots
98 627 emarinel
          deleteBufferMap.erase(iter->first);
99 655 jknichel
          //insert this robot back into the map in order to refresh its delete buffer
100 627 emarinel
          deleteBufferMap.insert(make_pair(iter->first, ROBOT_DELETE_BUFFER));
101
          break;
102
        }
103 458 jknichel
      }
104 466 emarinel
105 627 emarinel
      if (iter == positionMap.end()) {
106 710 gtress
        //a position was found that probably isn't a known
107 627 emarinel
        //  robot so add it in case a new robot entered the field
108
        printf("Inserting new robot: %d (%d,%d)\n", newIdToAssign, newPos.x, newPos.y);
109 710 gtress
110 627 emarinel
        //a position was found that probably isn't a known robot so add it in case a new robot entered the field
111
        newPositionMap.insert(make_pair(newIdToAssign, newPos));
112
        deleteBufferMap.insert(make_pair(newIdToAssign, ROBOT_DELETE_BUFFER));
113
        newIdToAssign--;
114
      }
115 458 jknichel
    }
116
117 710 gtress
118 627 emarinel
    map<int, VisionPosition>::iterator iter2;
119
    for (iter2 = positionMap.begin(); iter2 != positionMap.end(); iter2++) {
120
      int currId = iter2->first;
121
      map<int, VisionPosition>::iterator checkContains = newPositionMap.find(currId);
122
      if (checkContains == newPositionMap.end()) {
123
        int bufferValue = deleteBufferMap[iter2->first];
124
        bufferValue--;
125
        if (bufferValue > 0) {
126
          newPositionMap.insert(make_pair(currId, iter2->second));
127
          deleteBufferMap.erase(currId);
128
          deleteBufferMap.insert(make_pair(currId, bufferValue));
129
        } else {
130
          deleteBufferMap.erase(currId);
131
        }
132 534 jknichel
      }
133
    }
134
135 627 emarinel
    positionMap = newPositionMap;
136 468 jknichel
137 627 emarinel
    /*
138 710 gtress
    //DEBUG PRINT STATEMENTS
139
    printf("positionMap size is %d and deleteBufferMap size is %d\n", positionMap.size(), deleteBufferMap.size());
140 627 emarinel
    map<int, VisionPosition>::iterator iter;
141
    for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
142 710 gtress
      printf("%d has position (%d, %d) with delete buffer %d\n", iter->first, iter->second.x, iter->second.y, deleteBufferMap[iter->first]);
143 627 emarinel
    }
144
    */
145 509 emarinel
146 581 jknichel
147 627 emarinel
    pthread_mutex_unlock(&position_map_lock);
148 509 emarinel
149 627 emarinel
    assert(positions != NULL);
150 449 jknichel
    free(positions);
151 627 emarinel
152
    return 0;
153 509 emarinel
  }
154 436 jknichel
}
155 443 emarinel
156 455 emarinel
int PositionMonitor::assignRealId(int old_id, int real_id) {
157
  printf("assigning real_id %d to old_id %d\n", real_id, old_id);
158
159 509 emarinel
  pthread_mutex_lock(&position_map_lock);
160
161 455 emarinel
  map<int,VisionPosition>::iterator iter = positionMap.find(old_id);
162
163
  if (iter == positionMap.end()) {
164
    fprintf(stderr, "assignRealId: old_id not found\n");
165 520 emarinel
    pthread_mutex_unlock(&position_map_lock);
166 455 emarinel
    return -1;
167
  }
168
169
  positionMap.insert(make_pair(real_id, iter->second));
170
  positionMap.erase(old_id);
171 534 jknichel
  int oldDeleteBuffer = deleteBufferMap[old_id];
172
  deleteBufferMap.insert(make_pair(real_id, oldDeleteBuffer));
173
  deleteBufferMap.erase(old_id);
174 455 emarinel
175 509 emarinel
  pthread_mutex_unlock(&position_map_lock);
176
177 455 emarinel
  return 0;
178
}
179
180 447 emarinel
map<int, VisionPosition> PositionMonitor::getAllRobotPositions() {
181 509 emarinel
  // TODO return a copy instead of the actual map for synch purposes
182 447 emarinel
  return positionMap;
183
}
184
185 518 emarinel
int PositionMonitor::getNumVisibleRobots() {
186
  return positionMap.size();
187
}
188
189
VisionPosition PositionMonitor::getFirstPosition(void) {
190
  return positionMap.begin()->second;
191
}
192
193 443 emarinel
int PositionMonitor::getRobotPosition(int robot_id, int* xbuf, int* ybuf) {
194 449 jknichel
  //TODO: figure out what a map returns if the element doesn't exist
195 513 emarinel
196 509 emarinel
  pthread_mutex_lock(&position_map_lock);
197
198 451 jknichel
  if (positionMap.find(robot_id) == positionMap.end()){
199 710 gtress
    pthread_mutex_unlock(&position_map_lock);
200 449 jknichel
    return -1;
201 518 emarinel
  } else {
202
    VisionPosition pos = positionMap[robot_id];
203 449 jknichel
204 518 emarinel
    pthread_mutex_unlock(&position_map_lock);
205 455 emarinel
206 518 emarinel
    *xbuf = pos.x;
207
    *ybuf = pos.y;
208 509 emarinel
209 518 emarinel
    return 0;
210
  }
211 443 emarinel
}
212 458 jknichel
213
bool PositionMonitor::isProbablySameRobot(VisionPosition p1, VisionPosition p2) {
214
  int xDiff = p1.x - p2.x;
215
  int yDiff = p1.y - p2.y;
216 513 emarinel
  return (xDiff*xDiff + yDiff*yDiff < SAME_ROBOT_DISTANCE_THRESHOLD*SAME_ROBOT_DISTANCE_THRESHOLD);
217 458 jknichel
}