Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (9.66 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

    
44
//TODO: can a robot ever have more than one sensor matrix?
45
// Can there ever be more than one sensor matrix object in existance at one time?
46
// If not, then why not make a global sensor matrix variable.  Then you don't have
47
// to pass the sensor matrix into each of these functions.
48
// Not passing in the sensor matrix object into all these functions will save a
49
// couple ops before each call to one of these functions because it will no longer have
50
// to set up passing this as a parameter.  However, with a global variable, the
51
// function must, at some point, load the address of the global variable into a register
52
// so this may or may not actually save code space.
53

    
54

    
55
/*Sensor Matrix Functions*/
56
static void sensor_matrix_expand(SensorMatrix* m, int nextSize);
57

    
58
/**
59
 * Initializes the sensor matrix.
60
 *
61
 * @return the newly created sensor matrix
62
 **/
63
SensorMatrix* sensor_matrix_create()
64
{
65
        SensorMatrix* m;
66
        int i;
67

    
68
  //TODO: shouldn't use malloc on embedded systems if avoidable
69
  // Using malloc may save us SRAM usage because you don't need to allocate the second
70
  // dimension unless needed, but it increases the code size because of the malloc
71
  // code and introduces possibilities of memory leaks.  Making a static 2 dimensional array
72
  // will increase sram usage but simplify code.  The size of this matrix can be set low to
73
  // reduce memory consumption and increased (and code recompiled) as more robots are constructed
74
  // and need to be used
75
        m = (SensorMatrix*)malloc(sizeof(SensorMatrix));
76
        if (!m)
77
        {
78
                WL_DEBUG_PRINT("Out of memory - create sensor matrix.\r\n");
79
                return NULL;
80
        }
81
        m->size = DEFAULT_SENSOR_MATRIX_SIZE;
82
        m->matrix = (int**)malloc(m->size * sizeof(int*));
83
        if (!(m->matrix)) {
84
          WL_DEBUG_PRINT("Out of memory - allocating memory for matrix.\r\n");
85
          free(m);
86
          return NULL;
87
        }
88
        m->joined = (int*)malloc(m->size * sizeof(int));
89
        if (!(m->joined)) {
90
          WL_DEBUG_PRINT("Out of memory - allocating memory for joined.\r\n");
91
          free(m->matrix);
92
          free(m);
93
          return NULL;
94
        }
95
        m->numJoined = 0;
96
        if (!(m->matrix) || !(m->joined))
97
        {
98
                WL_DEBUG_PRINT("Out of memory - create sensor matrix 2.\r\n");
99
                return NULL;
100
        }
101

    
102
        for (i = 0; i < m->size; i++)
103
        {
104
                m->matrix[i] = NULL;
105
                m->joined[i] = 0;
106
        }
107
        return m;
108
}
109

    
110
/**
111
 * Deletes and frees memory from the sensor matrix.
112
 *
113
 * @param m the sensor matrix to delete
114
 **/
115
void sensor_matrix_destroy(SensorMatrix* m)
116
{
117
        int i;
118
        for (i = 0; i < m->size; i++)
119
                if (m->matrix[i] != NULL)
120
                        free(m->matrix[i]);
121
        free(m->matrix);
122
        free(m->joined);
123
        free(m);
124
}
125

    
126
/**
127
 * Adds robot with XBee id id to the sensor matrix.
128
 *
129
 * @param m the sensor matrix
130
 * @param id the XBee ID of the robot to add
131
 **/
132
void sensor_matrix_add_robot(SensorMatrix* m, int id)
133
{
134
        int i;
135

    
136
  //TODO: instead of expanding the sensor matrix, since this is a memory constrained system
137
  // devise a new way such that the size of the matrix is independent of the id values
138
        if (id >= m->size) {
139
                sensor_matrix_expand(m, id + 1);
140
        }
141

    
142
        if (m->matrix[id] != NULL) {
143
                return;
144
        }
145

    
146
        m->matrix[id] = (int*)malloc(m->size * sizeof(int));
147
        if (!(m->matrix[id]))
148
        {
149
                WL_DEBUG_PRINT("Out of memory - add robot.\r\n");
150
                return;
151
        }
152

    
153
        for (i = 0; i < m->size; i++) {
154
                if (m->matrix[i] != NULL) {
155
                        m->matrix[i][id] = -1;
156
                }
157
        }
158
}
159

    
160
/**
161
 * Removes robot with id from the sensor matrix, and removes
162
 * all sensor information regarding the robot.
163
 *
164
 * @param m the sensor matrix
165
 * @param id the XBee ID of the robot to remove
166
 **/
167
void sensor_matrix_remove_robot(SensorMatrix* m, int id)
168
{
169
        int i;
170

    
171
        if (id >= m->size || m->matrix[id] == NULL)
172
        {
173
                WL_DEBUG_PRINT("Removing robot not added to matrix.\r\n");
174
                return;
175
        }
176

    
177
        free(m->matrix[id]);
178
        m->matrix[id] = NULL;
179

    
180
        for (i = 0 ; i < m->size; i++)
181
                if (m->matrix[i] != NULL)
182
                        m->matrix[i][id] = -1;
183

    
184
        m->joined[id] = 0;
185
}
186

    
187
/**
188
 * Expands the size of the sensor matrix if an id number we attempt
189
 * to add is too large.
190
 *
191
 * @param m the sensor matrix to expand
192
 * @param size the new size of the sensor matrix
193
 **/
194
//TODO: remove this method when the SensorMatrix is made a static array and doesn't use malloc anymore
195
// and after it has been changed so the size of the matrix does not depend on the values of the ids of
196
// the robots.
197
//Note: this has probably not been tested, hopefully it works
198
static void sensor_matrix_expand(SensorMatrix* m, int nextSize)
199
{
200
        int i, j;
201
        WL_DEBUG_PRINT("Expanding sensor matrix.\r\n");
202

    
203
        int** tempMatrix = (int**)malloc(nextSize * sizeof(int*));
204
        if (!tempMatrix)
205
        {
206
                WL_DEBUG_PRINT("Out of memory - expand matrix.\r\n");
207
                return;
208
        }
209

    
210
  //TODO: using memset here instead of this loop, *might* be less instructions and *might* reduce code size but not sure
211
        for (i = 0; i < nextSize; i++)
212
                tempMatrix[i] = NULL;
213

    
214
        //copy over old sensor data
215
        for (i = 0; i < m->size; i++)
216
                if (m->matrix[i] != NULL)
217
                {
218
                  tempMatrix[i] = (int *)malloc(nextSize * sizeof(int));
219
                        if (!tempMatrix[i])
220
                        {
221
                                WL_DEBUG_PRINT("Out of memory - expand matrix 2.\r\n");
222
                                return;
223
                        }
224
                        for (j = 0; j < m->size; j++) {
225
                                tempMatrix[i][j] = m->matrix[i][j];
226
                        }
227

    
228
                        for (j = m->size; j < nextSize; j++) {
229
                                tempMatrix[i][j] = -1;
230
                        }
231

    
232
                        free(m->matrix[i]);
233
                }
234

    
235
        free(m->matrix);
236
        m->matrix = tempMatrix;
237
        m->size = nextSize;
238

    
239
        //expand the size of joined
240
        int* tempJoined = (int *)malloc(nextSize * sizeof(int));
241
        if (!tempJoined)
242
        {
243
                WL_DEBUG_PRINT("Out of memory - expand matrix 3.\r\n");
244
                return;
245
        }
246

    
247
        for (i = 0; i < m->size; i++) {
248
                tempJoined[i] = m->joined[i];
249
        }
250

    
251
        for (i = m->size; i < nextSize; i++) {
252
                tempJoined[i] = 0;
253
        }
254

    
255
        free(m->joined);
256
        m->joined = tempJoined;
257
}
258

    
259
/**
260
 * Sets the sensor reading for robot robot to reading.
261
 *
262
 * @param m the sensor matrix to set the reading for
263
 * @param observer the id of the robot who made the reading
264
 * @param robot the id of the robot who the reading is for
265
 * @param reading the BOM reading from observer to robot
266
 */
267
void sensor_matrix_set_reading(SensorMatrix* m, int observer, int robot, int reading)
268
{
269
        if (robot >= m->size || observer >= m->size || m->matrix[observer] == NULL) {
270
                sensor_matrix_add_robot(m, observer);
271
        }
272

    
273
        m->matrix[observer][robot] = reading;
274
}
275

    
276
/**
277
 * Gets the sensor reading for a robot to another robot.
278
 *
279
 * @param m the sensor matrix
280
 * @param observer the robot whose reading we check
281
 * @param robot the robot who we are checking the reading to
282
 *
283
 * @return the observer's BOM reading for robot
284
 **/
285
int sensor_matrix_get_reading(SensorMatrix* m, int observer, int robot)
286
{
287
        if (observer >= m->size || robot >= m->size) {
288
                return -1;
289
        }
290

    
291
        return m->matrix[observer][robot];
292
}
293

    
294
/**
295
 * Sets whether or not the given robot is part of the token ring.
296
 *
297
 * @param m the sensor matrix
298
 * @param robot the robot to set as a member / nonmember of the token ring
299
 * @param in 1 if the robot is in the token ring, 0 otherwise
300
 **/
301
//TODO: add comments inside this function
302
void sensor_matrix_set_in_ring(SensorMatrix* m, int robot, int in)
303
{
304
        if (robot >= m->size) {
305
                sensor_matrix_expand(m, robot + 1);
306
        }
307

    
308
        if (in == 1) {
309
                sensor_matrix_add_robot(m, robot);
310
        }
311

    
312
  //TODO: does this mean you are adding the robot?
313
        if (in == 1 && m->joined[robot] == 0) {
314
                m->numJoined++;
315
        }
316

    
317
  //TODO: does this mean you are removing the robot?
318
        if (in == 0 && m->joined[robot] == 1) {
319
                m->numJoined--;
320
        }
321

    
322
        m->joined[robot] = in;
323
}
324

    
325
/**
326
 * Checks if the given robot is in the token ring.
327
 *
328
 * @param m the sensor matrix
329
 * @param robot the ID of the robot to check
330
 *
331
 * @return 1 if the robot is in the token ring, 0 otherwise
332
 **/
333
int sensor_matrix_get_in_ring(SensorMatrix* m, int robot)
334
{
335
        if (robot >= m->size) {
336
                return -1;
337
        }
338

    
339
        return m->joined[robot];
340
}
341

    
342
/**
343
 * Returns the size of the sensor matrix.
344
 *
345
 * @param m the sensor matrix
346
 *
347
 * @return the size of the sensor matrix
348
 **/
349
//TODO: this function is so simple, it *may* be beneficial to inline this function.  testing of if
350
// it reduces code size or not should be done to be sure.
351
int sensor_matrix_get_size(SensorMatrix* m)
352
{
353
        return m->size;
354
}
355

    
356
/**
357
 * Returns the number of robots which have joined the
358
 * token ring.
359
 *
360
 * @param m the sensor matrix
361
 *
362
 * @return the number of robots in the token ring
363
 **/
364
//TODO: this function is so simple, it *may* be beneficial to inline this function.  testing of if
365
// it reduces code size or not should be done to be sure.
366
int sensor_matrix_get_joined(SensorMatrix* m)
367
{
368
        return m->numJoined;
369
}