Project

General

Profile

Statistics
| Revision:

root / branches / analog / trunk / code / projects / libdragonfly / bom.c @ 335

History | View | Annotate | Download (8.64 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
/**
28
 * @file bom.c
29
 * @brief Implementation for using the BOM
30
 *
31
 * Contains functions for using the Bearing and Orientation Module (BOM)
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

    
36
#include <dragonfly_lib.h>
37
#include "bom.h"
38
#include "dio.h"
39
#include "analog.h"
40

    
41
//constants
42
static const char lookup[16] = {7,6,5,0xe,1,4,3,2,0xf,0,0xd,8,0xc,0xb,9,0xa};
43

    
44
// internal function prototypes
45
static void output_high(which);
46
static void output_low(which);
47
static void bom_select(char which);
48

    
49
/*
50
 Bk R Y (Analog)
51
---------
52
 Green
53
 Blue
54
 White
55
---------
56
 Blue
57
 White
58
*/
59

    
60

    
61
/*
62
the analog pin definitions from dio.h DO NOT work here,
63
so we must use PF0 from avrgcc (as opposed to _PIN_F0).
64
BUT the dio pin definitions from dio.h must be used (no PE...).
65

66
also, _PIN_E2 is initialized to high for some reason,
67
which turns the BOM on when the robot is turned on.
68
WORK-AROUND: call digital_output(_PIN_E2,0) at some point.
69

70
*/
71

    
72
#define MONKI PF0         //analog (yellow)
73
//------------------------//
74
#define MONKL _PIN_E2     //green
75
#define MONK1 _PIN_E3     //blue
76
#define MONK0 _PIN_E4     //white
77
//------------------------//
78
#define MONK3 _PIN_E6     //blue
79
#define MONK2 _PIN_E7     //white
80

    
81
#define BOM_VALUE_THRESHOLD 200
82
#define NUM_BOM_LEDS 16
83

    
84

    
85
/**
86
 * @defgroup bom BOM (Bearing and Orientation Module)
87
 * @brief Functions for dealing with the BOM.
88
 *
89
 * The Bearing and Orientation Module / Barrel of Monkeys / BOM
90
 * is a custom sensor designed and built by the Colony Project.
91
 * It consists of a ring of 16 IR emitters and 16 IR detectors.
92
 * The BOM is most often use to determine the direction of other
93
 * robots. This module contains functions for controlling the BOM.
94
 *
95
 * Include bom.h to access these functions.
96
 *
97
 * @{
98
 **/
99

    
100
static unsigned int bom_val[NUM_BOM_LEDS];
101
static char bom_type = BOM;
102
  
103
/**
104
 * Initializes the BOM.
105
 * Call bom_init before reading bom values or turning bom leds.
106
 *
107
 * @bugs INCOMPLETE - need to fill in init routine for BOM15
108
 * 
109
 * @see bom_refresh, bom_leds_on, bom_leds_off
110
 **/
111
void bom_init(char type) {
112
    bom_type = type;
113
    
114
    switch(bom_type) {
115
    case BOM:
116
        break;
117
    case BOM15:
118
        break;
119
    case RBOM:
120
        break;
121
    default:
122
    }
123
}
124

    
125
/**
126
 * Iterates through each bit in the bit_field. For each set bit, sets the corresponding bom select bits
127
 *    and updates the corresponding bom value with an analog_get8 reading.  analog_init and bom_init
128
 *    must be called for this to work.
129
 *
130
 *
131
 * @param bit_field specifies which elements in bom_val[] should be updated. Use BOM_ALL to refresh all values.
132
 *    Ex. if 0x0003 is passed, bom_val[0] and bom_val[1] will be updated.
133
 *
134
 * @see bom_get
135
 **/
136
void bom_refresh(int bit_field) {
137
    int i;
138
    
139
    analog_stop_loop();
140
    
141
    for(i = 0; i < NUM_BOM_LEDS; i++) {
142
        if(bit_field & 0x1) {
143
            bom_select(i);
144
            bom_val[i] = analog_get8(MONKI);
145
        }
146
        bit_field = bitfield >> 1;
147
    }
148
    
149
    analog_start_loop();
150
}
151

    
152
/**
153
 * Gets the bom reading from bom_val[which].  Call bom_refresh beforehand to read new bom values.
154
 *
155
 * @param which which bom value to return
156
 *
157
 * @return the bom value
158
 *
159
 * see bom_refresh
160
 **/
161
int bom_get(char which) {
162
    return bom_val[which];
163
}
164

    
165
/** 
166
 * Compares all the values in bom_val[] and returns the index to the lowest (max) value element.
167
 *
168
 * @return index to the lowest (max) bom value element.  -1 if no value is lower than
169
 *    BOM_VALUE_THRESHOLD
170
 **/
171
int bom_get_max(void) {
172
    int i, lowest_val, lowest_i;
173
    
174
    lowest_val = bom_val[0];
175
    lowest_i = 0;
176
    for(i = 1; i < NUM_BOM_LEDS; i++) {
177
        if(bom_val[i] < lowest) {
178
            lowest_val = bom_val[i];
179
            lowest_i = i;
180
        }
181
    }
182
    
183
    if(lowest_val < BOM_VALUE_THRESHOLD)
184
        return lowest_i;
185
    else
186
        return -1;
187
}
188

    
189
/**
190
 * Iterates through each bit in the bit_field. For each set bit, turns on the corresponding bom led.
191
 *    bom_init must be called for this to work. Only works with BOM_ALL if using the original bom.
192
 *
193
 * @param bit_field specifies which leds should be turned on.  Use BOM_ALL to turn on all bom leds.
194
 *    Ex. if 0x0005 is passed, leds 0 and 2 will be turned on.
195
 **/
196
void bom_leds_on(int bit_field) {
197
    switch(bom_type) {
198
    case BOM:
199
        if(bit_field == BOM_ALL) {
200
            digital_output(MONKL, 1);
201
        }
202
        break;
203
    case BOM15:
204
        //add bom 1.5 code here
205
        break;
206
    case RBOM:
207
        //add rbom code here
208
        break;
209
}
210

    
211
/**
212
 * Iterates through each bit in the bit_field. For each set bit, turns off the corresponding bom led.
213
 *    bom_init must be called for this to work. Only works with BOM_ALL if using the original bom.
214
 *
215
 * @param bit_field specifies which leds should be turned off.  Use BOM_ALL to turn off all bom leds.
216
 *    Ex. if 0x000B is passed, leds 0 and 3 will be turned off.
217
 **/
218
void bom_leds_off(int bit_field) {
219
    switch(bom_type) {
220
    case BOM:
221
        if(bit_field == BOM_ALL) {
222
            digital_output(MONKL, 0);
223
        }
224
        break;
225
    case BOM15:
226
        //add bom 1.5 code here
227
        break;
228
    case RBOM:
229
        //add rbom code here
230
        break;
231
}
232

    
233

    
234
/**
235
 * (DEPRECATED) Returns the direction of the maximum BOM reading,
236
 * as an integer in the range 0-15. 0 indicates to the
237
 * robot's right, while the rest of the sensors are
238
 * numbered counterclockwise. This is useful for determining
239
 * the direction of a robot flashing its BOM, of only one
240
 * robot is currently doing so. analog_init must be called
241
 * before this function can be used.
242
 *
243
 * @return the direction of the maximum BOM reading
244
 *
245
 * @see analog_init
246
 **/
247
int get_max_bom(void) {
248
        int max_bom_temp = 0;
249
        int a, i, j, h;
250
    h = 255;
251

    
252
        //Turn off the loop so that we can actually use analog8 correctly
253
        analog_stop_loop();
254

    
255
        //Iterate through through each LED
256
    for (j = 0; j < 16; j++)
257
    {
258
      i = lookup[j];
259

    
260
      if (i&8)
261
        output_high(MONK3);
262
      else
263
        output_low(MONK3);
264

    
265
      if (i&4)
266
        output_high(MONK2);
267
      else
268
        output_low(MONK2);
269

    
270
      if (i&2)
271
        output_high(MONK1);
272
      else
273
        output_low(MONK1);
274

    
275
      if (i&1)
276
        output_high(MONK0);
277
      else
278
        output_low(MONK0);
279

    
280
      a = analog_get8(MONKI);
281
              
282
      if (a < h)
283
      {
284
        h = a;
285
        max_bom_temp = j;
286
      }
287

    
288
    }
289
        
290
        //Restart loop now that we are done using analog8
291
        analog_start_loop();
292

    
293
        //threshold on the bom analog value.
294
        //defined in bom.h
295
        // if the analog value read is above the threshold, we cannot see a robot
296
        // (remember, low means higher intensity).
297
        if(h < BOM_VALUE_THRESHOLD) {
298
                return max_bom_temp;
299
        }
300
        else
301
                return -1;
302
}
303

    
304
/**
305
 * (DEPRECATED) Turns on all bom leds.
306
 * 
307
 * @see bom_off
308
 **/
309
void bom_on(void)
310
{
311
  output_high(MONKL);
312
}
313

    
314
/**
315
 * (DEPRECATED) Turns off all bom leds.
316
 * 
317
 * @see bom_on
318
 **/
319
void bom_off(void)
320
{
321
  output_low(MONKL);
322
}
323

    
324
/** @} **/ //end group
325

    
326
void output_high(int which) {
327
        digital_output(which, 1);
328
}
329

    
330
void output_low(int which) {
331
        digital_output(which, 0);
332
}
333

    
334
static void bom_select(char which) {
335
      if (which&8)
336
        digital_output(MONK3, 1);
337
      else
338
        digital_output(MONK3, 0);
339

    
340
      if (which&4)
341
        digital_output(MONK2, 1);
342
      else
343
        digital_output(MONK2, 0);
344

    
345
      if (which&2)
346
        digital_output(MONK1, 1);
347
      else
348
        digital_output(MONK1, 0);
349

    
350
      if (which&1)
351
        digital_output(MONK0, 1);
352
      else
353
        digital_output(MONK0, 0);
354
}