Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / libwireless / lib / sensor_matrix.c @ 343

History | View | Annotate | Download (7.57 KB)

1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

    
26
/**
27
 * @file sensor_matrix.c
28
 * @brief Sensor Matrix implementation
29
 *
30
 * Implementation of a sensor matrix for storing localization implementation.
31
 *
32
 * @author Brian Coltin, Colony Project, CMU Robotics Club
33
 **/
34

    
35
#include <stdlib.h>
36
#include <stdio.h>
37
#include <wl_defs.h>
38

    
39
#include "sensor_matrix.h"
40

    
41
#define DEFAULT_SENSOR_MATRIX_SIZE 20
42

    
43
/*Sensor Matrix Functions*/
44
void sensor_matrix_expand(SensorMatrix* m, int nextSize);
45

    
46
/**
47
 * Initializes the sensor matrix.
48
 *
49
 * @return the newly created sensor matrix
50
 **/
51
SensorMatrix* sensor_matrix_create() {
52
  SensorMatrix* m;
53
  int i;
54
        
55
  m = (SensorMatrix*)malloc(sizeof(SensorMatrix));
56
  if (!m)        {
57
    WL_DEBUG_PRINT("Out of memory - create sensor matrix.\r\n");
58
    return NULL;
59
  }
60
  m->size = DEFAULT_SENSOR_MATRIX_SIZE;
61
  m->matrix = (int**)malloc(m->size * sizeof(int*));
62
  if (!(m->matrix)) {
63
    WL_DEBUG_PRINT("Out of memory - allocating memory for matrix.\r\n");
64
    free(m);
65
    return NULL;
66
  }
67
  m->joined = (int*)malloc(m->size * sizeof(int));
68
  if (!(m->joined)) {
69
    WL_DEBUG_PRINT("Out of memory - allocating memory for joined.\r\n");
70
    free(m->matrix);
71
    free(m);
72
    return NULL;
73
  }
74
  m->numJoined = 0;
75
  if (!(m->matrix) || !(m->joined)) {
76
    WL_DEBUG_PRINT("Out of memory - create sensor matrix 2.\r\n");
77
    return NULL;
78
  }
79
        
80
  for (i = 0; i < m->size; i++) {
81
    m->matrix[i] = NULL;
82
    m->joined[i] = 0;
83
  }
84
  return m;
85
}
86

    
87
/**
88
 * Deletes and frees memory from the sensor matrix.
89
 *
90
 * @param m the sensor matrix to delete
91
 **/
92
void sensor_matrix_destroy(SensorMatrix* m) {
93
  int i;
94
  for (i = 0; i < m->size; i++)
95
    if (m->matrix[i] != NULL)
96
      free(m->matrix[i]);
97
  free(m->matrix);
98
  free(m->joined);
99
  free(m);
100
}
101

    
102
/**
103
 * Adds robot with XBee id id to the sensor matrix.
104
 * 
105
 * @param m the sensor matrix
106
 * @param id the XBee ID of the robot to add
107
 **/
108
void sensor_matrix_add_robot(SensorMatrix* m, int id) {
109
  int i;
110
  if (id >= m->size)
111
    sensor_matrix_expand(m, id + 1);
112
  if (m->matrix[id] != NULL)
113
    return;
114
        
115
  m->matrix[id] = (int*)malloc(m->size * sizeof(int));
116
  if (!(m->matrix[id])) {
117
    WL_DEBUG_PRINT("Out of memory - add robot.\r\n");
118
    return;
119
  }
120

    
121
  for (i = 0; i < m->size; i++)
122
    if (m->matrix[i] != NULL)
123
      m->matrix[i][id] = -1;
124
}
125

    
126
/**
127
 * Removes robot with id from the sensor matrix, and removes
128
 * all sensor information regarding the robot.
129
 *
130
 * @param m the sensor matrix
131
 * @param id the XBee ID of the robot to remove
132
 **/
133
void sensor_matrix_remove_robot(SensorMatrix* m, int id) {
134
  int i;
135

    
136
  if (id >= m->size || m->matrix[id] == NULL) {
137
    WL_DEBUG_PRINT("Removing robot not added to matrix.\r\n");
138
    return;
139
  }
140
        
141
  free(m->matrix[id]);
142
  m->matrix[id] = NULL;
143
        
144
  for (i = 0 ; i < m->size; i++)
145
    if (m->matrix[i] != NULL)
146
      m->matrix[i][id] = -1;
147
        
148
  m->joined[id] = 0;
149
}
150

    
151
/**
152
 * Expands the size of the sensor matrix if an id number we attempt
153
 * to add is too large.
154
 *
155
 * @param m the sensor matrix to expand
156
 * @param size the new size of the sensor matrix
157
 **/
158
//Note: this has probably not been tested, hopefully it works
159
void sensor_matrix_expand(SensorMatrix* m, int nextSize) {
160
  int i, j;
161
  WL_DEBUG_PRINT("Expanding sensor matrix.\r\n");
162
        
163
  int** tempMatrix = (int**)malloc(nextSize * sizeof(int*));
164
  if (!tempMatrix) {
165
    WL_DEBUG_PRINT("Out of memory - expand matrix.\r\n");
166
    return;
167
  }
168
        
169
  for (i = 0; i < nextSize; i++)
170
    tempMatrix[i] = NULL;
171
        
172
  //copy over old sensor data
173
  for (i = 0; i < m->size; i++)
174
    if (m->matrix[i] != NULL) {
175
      tempMatrix[i] = (int *)malloc(nextSize * sizeof(int));
176
      if (!tempMatrix[i]) {
177
        WL_DEBUG_PRINT("Out of memory - expand matrix 2.\r\n");
178
        return;
179
      }
180
      for (j = 0; j < m->size; j++)
181
        tempMatrix[i][j] = m->matrix[i][j];
182
      for (j = m->size; j < nextSize; j++)
183
        tempMatrix[i][j] = -1;
184
                        
185
      free(m->matrix[i]);
186
    }
187
        
188
  free(m->matrix);
189
  m->matrix = tempMatrix;
190
  m->size = nextSize;
191

    
192
  //expand the size of joined
193
  int* tempJoined = (int *)malloc(nextSize * sizeof(int));
194
  if (!tempJoined) {
195
    WL_DEBUG_PRINT("Out of memory - expand matrix 3.\r\n");
196
    return;
197
  }
198
        
199
  for (i = 0; i < m->size; i++)
200
    tempJoined[i] = m->joined[i];
201
  for (i = m->size; i < nextSize; i++)
202
    tempJoined[i] = 0;
203
        
204
  free(m->joined);
205
  m->joined = tempJoined;
206
}
207

    
208
/**
209
 * Sets the sensor reading for robot robot to reading.
210
 * 
211
 * @param m the sensor matrix to set the reading for
212
 * @param observer the id of the robot who made the reading
213
 * @param robot the id of the robot who the reading is for
214
 * @param reading the BOM reading from observer to robot
215
 */
216
void sensor_matrix_set_reading(SensorMatrix* m, int observer, int robot, int reading) {
217
  if (robot >= m->size || observer >= m->size || m->matrix[observer] == NULL)
218
    sensor_matrix_add_robot(m, observer);
219
  m->matrix[observer][robot] = reading;
220
}
221

    
222
/**
223
 * Gets the sensor reading for a robot to another robot.
224
 *
225
 * @param m the sensor matrix
226
 * @param observer the robot whose reading we check
227
 * @param robot the robot who we are checking the reading to
228
 *
229
 * @return the observer's BOM reading for robot
230
 **/
231
int sensor_matrix_get_reading(SensorMatrix* m, int observer, int robot) {
232
  if (observer >= m->size || robot >= m->size)
233
    return -1;
234
  return m->matrix[observer][robot];
235
}
236

    
237
/**
238
 * Sets whether or not the given robot is part of the token ring.
239
 *
240
 * @param m the sensor matrix
241
 * @param robot the robot to set as a member / nonmember of the token ring
242
 * @param in 1 if the robot is in the token ring, 0 otherwise
243
 **/
244
void sensor_matrix_set_in_ring(SensorMatrix* m, int robot, int in) {
245
  if (robot >= m->size)
246
    sensor_matrix_expand(m, robot + 1);
247
  if (in == 1)
248
    sensor_matrix_add_robot(m, robot);
249
  if (in == 1 && m->joined[robot] == 0)
250
    m->numJoined++;
251
  if (in == 0 && m->joined[robot] == 1)
252
    m->numJoined--;
253
  m->joined[robot] = in;
254
}
255

    
256
/**
257
 * Checks if the given robot is in the token ring.
258
 * 
259
 * @param m the sensor matrix
260
 * @param robot the ID of the robot to check
261
 *
262
 * @return 1 if the robot is in the token ring, 0 otherwise
263
 **/
264
int sensor_matrix_get_in_ring(SensorMatrix* m, int robot) {
265
  if (robot >= m->size)
266
    return -1;
267
  return m->joined[robot];
268
}
269

    
270
/**
271
 * Returns the size of the sensor matrix.
272
 *
273
 * @param m the sensor matrix
274
 * 
275
 * @return the size of the sensor matrix
276
 **/
277
int sensor_matrix_get_size(SensorMatrix* m) {
278
  return m->size;
279
}
280

    
281
/**
282
 * Returns the number of robots which have joined the
283
 * token ring.
284
 *
285
 * @param m the sensor matrix
286
 *
287
 * @return the number of robots in the token ring
288
 **/
289
int sensor_matrix_get_joined(SensorMatrix* m) {
290
  return m->numJoined;
291
}
292