Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (6.2 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
#define MAX_POSITIONS 20
19
#define SAME_ROBOT_DISTANCE_THRESHOLD 150
20
#define ROBOT_DELETE_BUFFER 10
21
#define CAM_UPDATE_PERIOD 100000
22

    
23
/**
24
 * @brief Constructor for the PositionMonitor class
25
 */
26
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
  newIdToAssign = -1;
31
  
32
  pthread_mutex_init(&position_map_lock, NULL);
33
}
34

    
35
/**
36
 * @brief Destructor for the PositionMonitor class
37
 */
38
PositionMonitor::~PositionMonitor() {
39
}
40

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

    
52
    usleep(CAM_UPDATE_PERIOD);
53
  }
54
}
55

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

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

    
72
  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

    
78
    pthread_mutex_lock(&position_map_lock);
79

    
80
    //go through each of the positions the vision system identified
81
    for (int i = 0; i < numPositions; i++) {
82
      VisionPosition newPos = positions[i];
83
      map<int, VisionPosition>::iterator iter;
84
      //go through all the positions we currently have in the position map
85
      for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
86
        VisionPosition oldPos = iter->second;
87

    
88
        //figure out if the new point is probably the same robot as one of the old positions
89
        if (isProbablySameRobot(newPos, oldPos)) {
90
          //if the new positions is the same robot as an old one, insert this new position into the new map
91
          newPositionMap.insert(make_pair(iter->first, newPos));
92

    
93
          //erase this robot from the map that is used to smooth over several frames in case of problems identifying robots
94
          deleteBufferMap.erase(iter->first);
95
          //insert this robot back into the map in order to refresh its delete buffer
96
          deleteBufferMap.insert(make_pair(iter->first, ROBOT_DELETE_BUFFER));
97
          break;
98
        }
99
      }
100

    
101
      if (iter == positionMap.end()) {
102
        //a position was found that probably isn't a known 
103
        //  robot so add it in case a new robot entered the field
104
        printf("Inserting new robot: %d (%d,%d)\n", newIdToAssign, newPos.x, newPos.y);
105
      
106
        //a position was found that probably isn't a known robot so add it in case a new robot entered the field
107
        newPositionMap.insert(make_pair(newIdToAssign, newPos));
108
        deleteBufferMap.insert(make_pair(newIdToAssign, ROBOT_DELETE_BUFFER));
109
        newIdToAssign--;
110
      }
111
    }
112

    
113
    
114
    map<int, VisionPosition>::iterator iter2;
115
    for (iter2 = positionMap.begin(); iter2 != positionMap.end(); iter2++) {
116
      int currId = iter2->first;
117
      map<int, VisionPosition>::iterator checkContains = newPositionMap.find(currId);
118
      if (checkContains == newPositionMap.end()) {
119
        int bufferValue = deleteBufferMap[iter2->first];
120
        bufferValue--;
121
        if (bufferValue > 0) {
122
          newPositionMap.insert(make_pair(currId, iter2->second));
123
          deleteBufferMap.erase(currId);
124
          deleteBufferMap.insert(make_pair(currId, bufferValue));
125
        } else {
126
          deleteBufferMap.erase(currId);
127
        }
128
      }
129
    }
130

    
131
    positionMap = newPositionMap;
132

    
133
    //  printf("\npositionMap size is %d and deleteBufferMap size is %d\n", positionMap.size(), deleteBufferMap.size());
134

    
135
    /*
136
    //TODO: remove this debug information
137
    map<int, VisionPosition>::iterator iter;
138
    for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
139
    printf("%d has position (%d, %d) with delete buffer %d\n", iter->first, iter->second.x, iter->second.y, deleteBufferMap[iter->first]);
140
    }
141
    */
142

    
143

    
144
    pthread_mutex_unlock(&position_map_lock);
145

    
146
    assert(positions != NULL);
147
    free(positions);
148

    
149
    return 0;
150
  }
151
}
152

    
153
int PositionMonitor::assignRealId(int old_id, int real_id) {
154
  printf("assigning real_id %d to old_id %d\n", real_id, old_id);
155

    
156
  pthread_mutex_lock(&position_map_lock);
157

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

    
160
  if (iter == positionMap.end()) {
161
    fprintf(stderr, "assignRealId: old_id not found\n");
162
    pthread_mutex_unlock(&position_map_lock);
163
    return -1;
164
  }
165

    
166
  positionMap.insert(make_pair(real_id, iter->second));
167
  positionMap.erase(old_id);
168
  int oldDeleteBuffer = deleteBufferMap[old_id];
169
  deleteBufferMap.insert(make_pair(real_id, oldDeleteBuffer));
170
  deleteBufferMap.erase(old_id);
171

    
172
  pthread_mutex_unlock(&position_map_lock);
173

    
174
  return 0;
175
}
176

    
177
map<int, VisionPosition> PositionMonitor::getAllRobotPositions() {
178
  // TODO return a copy instead of the actual map for synch purposes
179
  return positionMap;
180
}
181

    
182
int PositionMonitor::getNumVisibleRobots() {
183
  return positionMap.size();
184
}
185

    
186
VisionPosition PositionMonitor::getFirstPosition(void) {
187
  return positionMap.begin()->second;
188
}
189

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

    
193
  pthread_mutex_lock(&position_map_lock);
194

    
195
  if (positionMap.find(robot_id) == positionMap.end()){
196
    pthread_mutex_unlock(&position_map_lock);    
197
    return -1;
198
  } else {
199
    VisionPosition pos = positionMap[robot_id];
200

    
201
    pthread_mutex_unlock(&position_map_lock);
202

    
203
    *xbuf = pos.x;
204
    *ybuf = pos.y;
205

    
206
    return 0;
207
  }
208
}
209

    
210
bool PositionMonitor::isProbablySameRobot(VisionPosition p1, VisionPosition p2) {
211
  int xDiff = p1.x - p2.x;
212
  int yDiff = p1.y - p2.y;
213
  return (xDiff*xDiff + yDiff*yDiff < SAME_ROBOT_DISTANCE_THRESHOLD*SAME_ROBOT_DISTANCE_THRESHOLD);
214
}