Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (6.41 KB)

1
/**
2
 * @file PositionMonitor.cpp
3
 *
4
 * @author Jason Knichel
5
 *
6
 * @date 2/4/08
7
 */
8

    
9
#include <assert.h>
10
#include <map>
11
#include <PositionMonitor.h>
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <vision.h>
15

    
16
using namespace std;
17

    
18
//Based on 640x480 resolution
19
//TODO: Change detection constants to be dependent on resolution
20
#define MAX_POSITIONS 20
21
#define SAME_ROBOT_DISTANCE_THRESHOLD 60
22
#define ROBOT_DELETE_BUFFER 10
23
#define CAM_UPDATE_PERIOD 100000
24

    
25
/**
26
 * @brief Constructor for the PositionMonitor class
27
 */
28
PositionMonitor::PositionMonitor() {
29
  //TODO: don't hardcode this file name
30
  //TODO: check for error returned from init
31
  vision_init(/*"/var/www/colonet.jpg"*/);
32
  newIdToAssign = -1;
33

    
34
  pthread_mutex_init(&position_map_lock, NULL);
35
}
36

    
37
/**
38
 * @brief Destructor for the PositionMonitor class
39
 */
40
PositionMonitor::~PositionMonitor() {
41
  vision_close();
42
}
43

    
44
/**
45
 * @brief This function updates the positions of things in the image
46
 *
47
 * @return Void
48
 */
49
void PositionMonitor::run() {
50
  while (1) {
51
    if (updatePositions() == -1) {
52
      fprintf(stderr, "updatePositions failed.\n");
53
    }
54

    
55
    usleep(CAM_UPDATE_PERIOD);
56
  }
57
}
58

    
59
/**
60
 * @brief This function asks the vision code for the position of things it identifies
61
 */
62
int PositionMonitor::updatePositions() {
63
  VisionPosition* positions = NULL;
64
  int numPositions = vision_get_robot_positions(&positions);
65

    
66
  //debug output code
67
  /*
68
  printf("\nnumPositions is %d\n", numPositions);
69
  for (int i = 0; i < numPositions; i++) {
70
    printf("{%d,%d} ", positions[i].x, positions[i].y);
71
  }
72
  printf("\n");
73
  */
74

    
75
  if (numPositions == -1) {
76
    fprintf(stderr, "%s: vision_get_robot_positions failed.\n", __FUNCTION__);
77
    return -1;
78
  } else {
79
    map<int, VisionPosition> newPositionMap;
80

    
81
    pthread_mutex_lock(&position_map_lock);
82

    
83
    //go through each of the positions the vision system identified
84
    for (int i = 0; i < numPositions; i++) {
85
      VisionPosition newPos = positions[i];
86
      map<int, VisionPosition>::iterator iter;
87

    
88
      //go through all the positions we currently have in the position map
89
      for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
90
        VisionPosition oldPos = iter->second;
91

    
92
        //figure out if the new point is probably the same robot as one of the old positions
93
        if (isProbablySameRobot(newPos, oldPos)) {
94
          //DEBUG
95
          //printf("probably same robot: new = (%d, %d), old = (%d, %d)\n", newPos.x, newPos.y, oldPos.x, oldPos.y);
96

    
97
          //if the new positions is the same robot as an old one, insert this new position into the new map
98
          newPositionMap.insert(make_pair(iter->first, newPos));
99

    
100
          //erase this robot from the map that is used to smooth over several frames in case of problems identifying robots
101
          deleteBufferMap.erase(iter->first);
102
          //insert this robot back into the map in order to refresh its delete buffer
103
          deleteBufferMap.insert(make_pair(iter->first, ROBOT_DELETE_BUFFER));
104
          break;
105
        }
106
      }
107

    
108
      if (iter == positionMap.end()) {
109
        //a position was found that probably isn't a known
110
        //  robot so add it in case a new robot entered the field
111
        printf("Inserting new robot: %d (%d,%d)\n", newIdToAssign, newPos.x, newPos.y);
112

    
113
        //a position was found that probably isn't a known robot so add it in case a new robot entered the field
114
        newPositionMap.insert(make_pair(newIdToAssign, newPos));
115
        deleteBufferMap.insert(make_pair(newIdToAssign, ROBOT_DELETE_BUFFER));
116
        newIdToAssign--;
117
      }
118
    }
119

    
120

    
121
    map<int, VisionPosition>::iterator iter2;
122
    for (iter2 = positionMap.begin(); iter2 != positionMap.end(); iter2++) {
123
      int currId = iter2->first;
124
      map<int, VisionPosition>::iterator checkContains = newPositionMap.find(currId);
125
      if (checkContains == newPositionMap.end()) {
126
        int bufferValue = deleteBufferMap[iter2->first];
127
        bufferValue--;
128
        if (bufferValue > 0) {
129
          newPositionMap.insert(make_pair(currId, iter2->second));
130
          deleteBufferMap.erase(currId);
131
          deleteBufferMap.insert(make_pair(currId, bufferValue));
132
        } else {
133
          deleteBufferMap.erase(currId);
134
        }
135
      }
136
    }
137

    
138
    positionMap = newPositionMap;
139

    
140
    /*
141
    //DEBUG PRINT STATEMENTS
142
    printf("positionMap size is %d and deleteBufferMap size is %d\n", positionMap.size(), deleteBufferMap.size());
143
    map<int, VisionPosition>::iterator iter;
144
    for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
145
      printf("%d has position (%d, %d) with delete buffer %d\n", iter->first, iter->second.x, iter->second.y, deleteBufferMap[iter->first]);
146
    }
147
    */
148

    
149

    
150
    pthread_mutex_unlock(&position_map_lock);
151

    
152
    assert(positions != NULL);
153
    free(positions);
154

    
155
    return 0;
156
  }
157
}
158

    
159
int PositionMonitor::assignRealId(int old_id, int real_id) {
160
  printf("assigning real_id %d to old_id %d\n", real_id, old_id);
161

    
162
  pthread_mutex_lock(&position_map_lock);
163

    
164
  map<int,VisionPosition>::iterator iter = positionMap.find(old_id);
165

    
166
  if (iter == positionMap.end()) {
167
    fprintf(stderr, "assignRealId: old_id not found\n");
168
    pthread_mutex_unlock(&position_map_lock);
169
    return -1;
170
  }
171

    
172
  positionMap.insert(make_pair(real_id, iter->second));
173
  positionMap.erase(old_id);
174
  int oldDeleteBuffer = deleteBufferMap[old_id];
175
  deleteBufferMap.insert(make_pair(real_id, oldDeleteBuffer));
176
  deleteBufferMap.erase(old_id);
177

    
178
  pthread_mutex_unlock(&position_map_lock);
179

    
180
  return 0;
181
}
182

    
183
map<int, VisionPosition> PositionMonitor::getAllRobotPositions() {
184
  // TODO return a copy instead of the actual map for synch purposes
185
  return positionMap;
186
}
187

    
188
int PositionMonitor::getNumVisibleRobots() {
189
  return positionMap.size();
190
}
191

    
192
VisionPosition PositionMonitor::getFirstPosition(void) {
193
  return positionMap.begin()->second;
194
}
195

    
196
int PositionMonitor::getRobotPosition(int robot_id, int* xbuf, int* ybuf) {
197
  //TODO: figure out what a map returns if the element doesn't exist
198

    
199
  pthread_mutex_lock(&position_map_lock);
200

    
201
  if (positionMap.find(robot_id) == positionMap.end()){
202
    pthread_mutex_unlock(&position_map_lock);
203
    return -1;
204
  } else {
205
    VisionPosition pos = positionMap[robot_id];
206

    
207
    pthread_mutex_unlock(&position_map_lock);
208

    
209
    *xbuf = pos.x;
210
    *ybuf = pos.y;
211

    
212
    return 0;
213
  }
214
}
215

    
216
bool PositionMonitor::isProbablySameRobot(VisionPosition p1, VisionPosition p2) {
217
  int xDiff = p1.x - p2.x;
218
  int yDiff = p1.y - p2.y;
219
  return (xDiff*xDiff + yDiff*yDiff < SAME_ROBOT_DISTANCE_THRESHOLD*SAME_ROBOT_DISTANCE_THRESHOLD);
220
}