Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (7.52 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
static 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
{
53
        SensorMatrix* m;
54
        int i;
55

    
56
        m = (SensorMatrix*)malloc(sizeof(SensorMatrix));
57
        if (!m)
58
        {
59
                WL_DEBUG_PRINT("Out of memory - create sensor matrix.\r\n");
60
                return NULL;
61
        }
62
        m->size = DEFAULT_SENSOR_MATRIX_SIZE;
63
        m->matrix = (int**)malloc(m->size * sizeof(int*));
64
        if (!(m->matrix)) {
65
          WL_DEBUG_PRINT("Out of memory - allocating memory for matrix.\r\n");
66
          free(m);
67
          return NULL;
68
        }
69
        m->joined = (int*)malloc(m->size * sizeof(int));
70
        if (!(m->joined)) {
71
          WL_DEBUG_PRINT("Out of memory - allocating memory for joined.\r\n");
72
          free(m->matrix);
73
          free(m);
74
          return NULL;
75
        }
76
        m->numJoined = 0;
77
        if (!(m->matrix) || !(m->joined))
78
        {
79
                WL_DEBUG_PRINT("Out of memory - create sensor matrix 2.\r\n");
80
                return NULL;
81
        }
82

    
83
        for (i = 0; i < m->size; i++)
84
        {
85
                m->matrix[i] = NULL;
86
                m->joined[i] = 0;
87
        }
88
        return m;
89
}
90

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

    
107
/**
108
 * Adds robot with XBee id id to the sensor matrix.
109
 *
110
 * @param m the sensor matrix
111
 * @param id the XBee ID of the robot to add
112
 **/
113
void sensor_matrix_add_robot(SensorMatrix* m, int id)
114
{
115
        int i;
116
        if (id >= m->size) {
117
                sensor_matrix_expand(m, id + 1);
118
        }
119

    
120
        if (m->matrix[id] != NULL) {
121
                return;
122
        }
123

    
124
        m->matrix[id] = (int*)malloc(m->size * sizeof(int));
125
        if (!(m->matrix[id]))
126
        {
127
                WL_DEBUG_PRINT("Out of memory - add robot.\r\n");
128
                return;
129
        }
130

    
131
        for (i = 0; i < m->size; i++) {
132
                if (m->matrix[i] != NULL) {
133
                        m->matrix[i][id] = -1;
134
                }
135
        }
136
}
137

    
138
/**
139
 * Removes robot with id from the sensor matrix, and removes
140
 * all sensor information regarding the robot.
141
 *
142
 * @param m the sensor matrix
143
 * @param id the XBee ID of the robot to remove
144
 **/
145
void sensor_matrix_remove_robot(SensorMatrix* m, int id)
146
{
147
        int i;
148

    
149
        if (id >= m->size || m->matrix[id] == NULL)
150
        {
151
                WL_DEBUG_PRINT("Removing robot not added to matrix.\r\n");
152
                return;
153
        }
154

    
155
        free(m->matrix[id]);
156
        m->matrix[id] = NULL;
157

    
158
        for (i = 0 ; i < m->size; i++)
159
                if (m->matrix[i] != NULL)
160
                        m->matrix[i][id] = -1;
161

    
162
        m->joined[id] = 0;
163
}
164

    
165
/**
166
 * Expands the size of the sensor matrix if an id number we attempt
167
 * to add is too large.
168
 *
169
 * @param m the sensor matrix to expand
170
 * @param size the new size of the sensor matrix
171
 **/
172
//Note: this has probably not been tested, hopefully it works
173
static void sensor_matrix_expand(SensorMatrix* m, int nextSize)
174
{
175
        int i, j;
176
        WL_DEBUG_PRINT("Expanding sensor matrix.\r\n");
177

    
178
        int** tempMatrix = (int**)malloc(nextSize * sizeof(int*));
179
        if (!tempMatrix)
180
        {
181
                WL_DEBUG_PRINT("Out of memory - expand matrix.\r\n");
182
                return;
183
        }
184

    
185
        for (i = 0; i < nextSize; i++)
186
                tempMatrix[i] = NULL;
187

    
188
        //copy over old sensor data
189
        for (i = 0; i < m->size; i++)
190
                if (m->matrix[i] != NULL)
191
                {
192
                  tempMatrix[i] = (int *)malloc(nextSize * sizeof(int));
193
                        if (!tempMatrix[i])
194
                        {
195
                                WL_DEBUG_PRINT("Out of memory - expand matrix 2.\r\n");
196
                                return;
197
                        }
198
                        for (j = 0; j < m->size; j++) {
199
                                tempMatrix[i][j] = m->matrix[i][j];
200
                        }
201

    
202
                        for (j = m->size; j < nextSize; j++) {
203
                                tempMatrix[i][j] = -1;
204
                        }
205

    
206
                        free(m->matrix[i]);
207
                }
208

    
209
        free(m->matrix);
210
        m->matrix = tempMatrix;
211
        m->size = nextSize;
212

    
213
        //expand the size of joined
214
        int* tempJoined = (int *)malloc(nextSize * sizeof(int));
215
        if (!tempJoined)
216
        {
217
                WL_DEBUG_PRINT("Out of memory - expand matrix 3.\r\n");
218
                return;
219
        }
220

    
221
        for (i = 0; i < m->size; i++) {
222
                tempJoined[i] = m->joined[i];
223
        }
224

    
225
        for (i = m->size; i < nextSize; i++) {
226
                tempJoined[i] = 0;
227
        }
228

    
229
        free(m->joined);
230
        m->joined = tempJoined;
231
}
232

    
233
/**
234
 * Sets the sensor reading for robot robot to reading.
235
 *
236
 * @param m the sensor matrix to set the reading for
237
 * @param observer the id of the robot who made the reading
238
 * @param robot the id of the robot who the reading is for
239
 * @param reading the BOM reading from observer to robot
240
 */
241
void sensor_matrix_set_reading(SensorMatrix* m, int observer, int robot, int reading)
242
{
243
        if (robot >= m->size || observer >= m->size || m->matrix[observer] == NULL) {
244
                sensor_matrix_add_robot(m, observer);
245
        }
246

    
247
        m->matrix[observer][robot] = reading;
248
}
249

    
250
/**
251
 * Gets the sensor reading for a robot to another robot.
252
 *
253
 * @param m the sensor matrix
254
 * @param observer the robot whose reading we check
255
 * @param robot the robot who we are checking the reading to
256
 *
257
 * @return the observer's BOM reading for robot
258
 **/
259
int sensor_matrix_get_reading(SensorMatrix* m, int observer, int robot)
260
{
261
        if (observer >= m->size || robot >= m->size) {
262
                return -1;
263
        }
264

    
265
        return m->matrix[observer][robot];
266
}
267

    
268
/**
269
 * Sets whether or not the given robot is part of the token ring.
270
 *
271
 * @param m the sensor matrix
272
 * @param robot the robot to set as a member / nonmember of the token ring
273
 * @param in 1 if the robot is in the token ring, 0 otherwise
274
 **/
275
void sensor_matrix_set_in_ring(SensorMatrix* m, int robot, int in)
276
{
277
        if (robot >= m->size) {
278
                sensor_matrix_expand(m, robot + 1);
279
        }
280

    
281
        if (in == 1) {
282
                sensor_matrix_add_robot(m, robot);
283
        }
284

    
285
        if (in == 1 && m->joined[robot] == 0) {
286
                m->numJoined++;
287
        }
288

    
289
        if (in == 0 && m->joined[robot] == 1) {
290
                m->numJoined--;
291
        }
292

    
293
        m->joined[robot] = in;
294
}
295

    
296
/**
297
 * Checks if the given robot is in the token ring.
298
 *
299
 * @param m the sensor matrix
300
 * @param robot the ID of the robot to check
301
 *
302
 * @return 1 if the robot is in the token ring, 0 otherwise
303
 **/
304
int sensor_matrix_get_in_ring(SensorMatrix* m, int robot)
305
{
306
        if (robot >= m->size) {
307
                return -1;
308
        }
309

    
310
        return m->joined[robot];
311
}
312

    
313
/**
314
 * Returns the size of the sensor matrix.
315
 *
316
 * @param m the sensor matrix
317
 *
318
 * @return the size of the sensor matrix
319
 **/
320
int sensor_matrix_get_size(SensorMatrix* m)
321
{
322
        return m->size;
323
}
324

    
325
/**
326
 * Returns the number of robots which have joined the
327
 * token ring.
328
 *
329
 * @param m the sensor matrix
330
 *
331
 * @return the number of robots in the token ring
332
 **/
333
int sensor_matrix_get_joined(SensorMatrix* m)
334
{
335
        return m->numJoined;
336
}