Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (5.15 KB)

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

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

    
15
using namespace std;
16

    
17
#define MAX_POSITIONS 20
18
#define SAME_ROBOT_DISTANCE_THRESHOLD 110
19
#define ROBOT_DELETE_BUFFER 10
20
#define CAM_UPDATE_PERIOD 100000
21

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

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

    
34
void PositionMonitor::run() {
35
  while (1) {
36
    updatePositions();
37
    usleep(CAM_UPDATE_PERIOD);
38
  }
39
}
40

    
41
int PositionMonitor::updatePositions() {
42
  VisionPosition * positions = NULL;
43

    
44
  //TODO: check for error returned
45
  int numPositions = vision_get_robot_positions(&positions);
46
  /*  
47
      printf("numPositions is %d\n", numPositions);
48
  for (int i = 0; i < numPositions; i++) {
49
    printf("{%d,%d} ", positions[i].x, positions[i].y);
50
  }
51
  printf("\n");
52
  */
53

    
54
  map<int, VisionPosition> newPositionMap;
55

    
56
  pthread_mutex_lock(&position_map_lock);
57

    
58
  //TODO: also remove robots that might have disappeared
59
  int i;
60
  for (i = 0; i < numPositions; i++) {
61
    VisionPosition newPos = positions[i];
62
    map<int, VisionPosition>::iterator iter;
63
    for (iter = positionMap.begin(); iter != positionMap.end(); iter++) {
64
      VisionPosition oldPos = iter->second;
65

    
66
      if (isProbablySameRobot(newPos, oldPos)) {
67
        //TODO: is this the right use of an iterator?
68
        newPositionMap.insert(make_pair(iter->first, newPos));
69
        deleteBufferMap.erase(iter->first);
70
        deleteBufferMap.insert(make_pair(iter->first, ROBOT_DELETE_BUFFER));
71
        break;
72
      }
73
    }
74

    
75
    if (iter == positionMap.end()) {
76
      //a position was found that probably isn't a known 
77
      //  robot so add it in case a new robot entered the field
78
      printf("Inserting new robot: %d (%d,%d)", newIdToAssign, newPos.x, newPos.y);
79
      
80
      //a position was found that probably isn't a known robot so add it in case a new robot entered the field
81
      newPositionMap.insert(make_pair(newIdToAssign, newPos));
82
      deleteBufferMap.insert(make_pair(newIdToAssign, ROBOT_DELETE_BUFFER));
83
      newIdToAssign--;
84
    }
85
  }
86

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

    
104
  positionMap = newPositionMap;
105

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

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

    
116

    
117
  pthread_mutex_unlock(&position_map_lock);
118

    
119
  if (positions) {
120
    free(positions);
121
  }
122

    
123
  return 0;
124
}
125

    
126
int PositionMonitor::assignRealId(int old_id, int real_id) {
127
  printf("assigning real_id %d to old_id %d\n", real_id, old_id);
128

    
129
  pthread_mutex_lock(&position_map_lock);
130

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

    
133
  if (iter == positionMap.end()) {
134
    fprintf(stderr, "assignRealId: old_id not found\n");
135
    pthread_mutex_unlock(&position_map_lock);
136
    return -1;
137
  }
138

    
139
  positionMap.insert(make_pair(real_id, iter->second));
140
  positionMap.erase(old_id);
141
  int oldDeleteBuffer = deleteBufferMap[old_id];
142
  deleteBufferMap.insert(make_pair(real_id, oldDeleteBuffer));
143
  deleteBufferMap.erase(old_id);
144

    
145
  pthread_mutex_unlock(&position_map_lock);
146

    
147
  return 0;
148
}
149

    
150
map<int, VisionPosition> PositionMonitor::getAllRobotPositions() {
151
  // TODO return a copy instead of the actual map for synch purposes
152
  return positionMap;
153
}
154

    
155
int PositionMonitor::getNumVisibleRobots() {
156
  return positionMap.size();
157
}
158

    
159
VisionPosition PositionMonitor::getFirstPosition(void) {
160
  return positionMap.begin()->second;
161
}
162

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

    
166
  pthread_mutex_lock(&position_map_lock);
167

    
168
  if (positionMap.find(robot_id) == positionMap.end()){
169
    pthread_mutex_unlock(&position_map_lock);    
170
    return -1;
171
  } else {
172
    VisionPosition pos = positionMap[robot_id];
173

    
174
    pthread_mutex_unlock(&position_map_lock);
175

    
176
    *xbuf = pos.x;
177
    *ybuf = pos.y;
178

    
179
    return 0;
180
  }
181
}
182

    
183
bool PositionMonitor::isProbablySameRobot(VisionPosition p1, VisionPosition p2) {
184
  int xDiff = p1.x - p2.x;
185
  int yDiff = p1.y - p2.y;
186
  return (xDiff*xDiff + yDiff*yDiff < SAME_ROBOT_DISTANCE_THRESHOLD*SAME_ROBOT_DISTANCE_THRESHOLD);
187
}