Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (5.44 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 110
20
#define ROBOT_DELETE_BUFFER 10
21
#define CAM_UPDATE_PERIOD 100000
22

    
23
PositionMonitor::PositionMonitor() {
24
  //TODO: don't hardcode this file name
25
  //TODO: check for error returned from init
26
  vision_init("/var/www/colonet.jpg");
27
  newIdToAssign = -1;
28
  
29
  pthread_mutex_init(&position_map_lock, NULL);
30
}
31

    
32
PositionMonitor::~PositionMonitor() {
33
}
34

    
35
void PositionMonitor::run() {
36
  while (1) {
37
    if (updatePositions() == -1) {
38
      fprintf(stderr, "updatePositions failed.\n");
39
    }
40

    
41
    usleep(CAM_UPDATE_PERIOD);
42
  }
43
}
44

    
45
int PositionMonitor::updatePositions() {
46
  VisionPosition* positions = NULL;
47
  int numPositions = vision_get_robot_positions(&positions);
48

    
49
  /*  
50
  printf("numPositions is %d\n", numPositions);
51
  for (int i = 0; i < numPositions; i++) {
52
    printf("{%d,%d} ", positions[i].x, positions[i].y);
53
  }
54
  printf("\n");
55
  */
56

    
57
  if (numPositions == -1) {
58
    fprintf(stderr, "%s: vision_get_robot_positions failed.\n", __FUNCTION__);
59
    return -1;
60
  } else {
61
    map<int, VisionPosition> newPositionMap;
62

    
63
    pthread_mutex_lock(&position_map_lock);
64

    
65
    //TODO: also remove robots that might have disappeared
66
    for (int i = 0; i < numPositions; i++) {
67
      VisionPosition newPos = positions[i];
68
      map<int, VisionPosition>::iterator iter;
69
      for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
70
        VisionPosition oldPos = iter->second;
71

    
72
        if (isProbablySameRobot(newPos, oldPos)) {
73
          //TODO: is this the right use of an iterator?
74
          newPositionMap.insert(make_pair(iter->first, newPos));
75
          deleteBufferMap.erase(iter->first);
76
          deleteBufferMap.insert(make_pair(iter->first, ROBOT_DELETE_BUFFER));
77
          break;
78
        }
79
      }
80

    
81
      if (iter == positionMap.end()) {
82
        //a position was found that probably isn't a known 
83
        //  robot so add it in case a new robot entered the field
84
        printf("Inserting new robot: %d (%d,%d)\n", newIdToAssign, newPos.x, newPos.y);
85
      
86
        //a position was found that probably isn't a known robot so add it in case a new robot entered the field
87
        newPositionMap.insert(make_pair(newIdToAssign, newPos));
88
        deleteBufferMap.insert(make_pair(newIdToAssign, ROBOT_DELETE_BUFFER));
89
        newIdToAssign--;
90
      }
91
    }
92

    
93
    map<int, VisionPosition>::iterator iter2;
94
    for (iter2 = positionMap.begin(); iter2 != positionMap.end(); iter2++) {
95
      int currId = iter2->first;
96
      map<int, VisionPosition>::iterator checkContains = newPositionMap.find(currId);
97
      if (checkContains == newPositionMap.end()) {
98
        int bufferValue = deleteBufferMap[iter2->first];
99
        bufferValue--;
100
        if (bufferValue > 0) {
101
          newPositionMap.insert(make_pair(currId, iter2->second));
102
          deleteBufferMap.erase(currId);
103
          deleteBufferMap.insert(make_pair(currId, bufferValue));
104
        } else {
105
          deleteBufferMap.erase(currId);
106
        }
107
      }
108
    }
109

    
110
    positionMap = newPositionMap;
111

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

    
114
    /*
115
    //TODO: remove this debug information
116
    map<int, VisionPosition>::iterator iter;
117
    for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
118
    printf("%d has position (%d, %d) with delete buffer %d\n", iter->first, iter->second.x, iter->second.y, deleteBufferMap[iter->first]);
119
    }
120
    */
121

    
122

    
123
    pthread_mutex_unlock(&position_map_lock);
124

    
125
    assert(positions != NULL);
126
    free(positions);
127

    
128
    return 0;
129
  }
130
}
131

    
132
int PositionMonitor::assignRealId(int old_id, int real_id) {
133
  printf("assigning real_id %d to old_id %d\n", real_id, old_id);
134

    
135
  pthread_mutex_lock(&position_map_lock);
136

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

    
139
  if (iter == positionMap.end()) {
140
    fprintf(stderr, "assignRealId: old_id not found\n");
141
    pthread_mutex_unlock(&position_map_lock);
142
    return -1;
143
  }
144

    
145
  positionMap.insert(make_pair(real_id, iter->second));
146
  positionMap.erase(old_id);
147
  int oldDeleteBuffer = deleteBufferMap[old_id];
148
  deleteBufferMap.insert(make_pair(real_id, oldDeleteBuffer));
149
  deleteBufferMap.erase(old_id);
150

    
151
  pthread_mutex_unlock(&position_map_lock);
152

    
153
  return 0;
154
}
155

    
156
map<int, VisionPosition> PositionMonitor::getAllRobotPositions() {
157
  // TODO return a copy instead of the actual map for synch purposes
158
  return positionMap;
159
}
160

    
161
int PositionMonitor::getNumVisibleRobots() {
162
  return positionMap.size();
163
}
164

    
165
VisionPosition PositionMonitor::getFirstPosition(void) {
166
  return positionMap.begin()->second;
167
}
168

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

    
172
  pthread_mutex_lock(&position_map_lock);
173

    
174
  if (positionMap.find(robot_id) == positionMap.end()){
175
    pthread_mutex_unlock(&position_map_lock);    
176
    return -1;
177
  } else {
178
    VisionPosition pos = positionMap[robot_id];
179

    
180
    pthread_mutex_unlock(&position_map_lock);
181

    
182
    *xbuf = pos.x;
183
    *ybuf = pos.y;
184

    
185
    return 0;
186
  }
187
}
188

    
189
bool PositionMonitor::isProbablySameRobot(VisionPosition p1, VisionPosition p2) {
190
  int xDiff = p1.x - p2.x;
191
  int yDiff = p1.y - p2.y;
192
  return (xDiff*xDiff + yDiff*yDiff < SAME_ROBOT_DISTANCE_THRESHOLD*SAME_ROBOT_DISTANCE_THRESHOLD);
193
}