Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (9.11 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
//TODO: DELETE THIS
42
void printi(int i)
43
{
44
    char c3 = (i % 10) + '0';
45
    i /= 10;
46
    char c2 = (i % 10) + '0';
47
    i /= 10;
48
    char c1 = (i % 10) + '0';
49
    if (c1 == '0')
50
    {
51
        c1 = ' ';
52
        if (c2 == '0')
53
            c2 = ' ';
54
    }
55
    usb_putc(c1);
56
    usb_putc(c2);
57
    usb_putc(c3);
58
}
59

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

    
63
// internal function prototypes
64
static void output_high(which);
65
static void output_low(which);
66
static void bom_select(char which);
67

    
68
/*
69
 Bk R Y (Analog)
70
---------
71
 Green
72
 Blue
73
 White
74
---------
75
 Blue
76
 White
77
*/
78

    
79

    
80
/*
81
the analog pin definitions from dio.h DO NOT work here,
82
so we must use PF0 from avrgcc (as opposed to _PIN_F0).
83
BUT the dio pin definitions from dio.h must be used (no PE...).
84

85
also, _PIN_E2 is initialized to high for some reason,
86
which turns the BOM on when the robot is turned on.
87
WORK-AROUND: call digital_output(_PIN_E2,0) at some point.
88

89
*/
90

    
91
#define MONKI PF0         //analog (yellow)
92
//------------------------//
93
#define MONKL _PIN_E2     //green
94
#define MONK1 _PIN_E3     //blue
95
#define MONK0 _PIN_E4     //white
96
//------------------------//
97
#define MONK3 _PIN_E6     //blue
98
#define MONK2 _PIN_E7     //white
99

    
100
#define BOM_VALUE_THRESHOLD 200
101
#define NUM_BOM_LEDS 16
102

    
103

    
104
/**
105
 * @defgroup bom BOM (Bearing and Orientation Module)
106
 * @brief Functions for dealing with the BOM.
107
 *
108
 * The Bearing and Orientation Module / Barrel of Monkeys / BOM
109
 * is a custom sensor designed and built by the Colony Project.
110
 * It consists of a ring of 16 IR emitters and 16 IR detectors.
111
 * The BOM is most often use to determine the direction of other
112
 * robots. This module contains functions for controlling the BOM.
113
 *
114
 * Include bom.h to access these functions.
115
 *
116
 * @{
117
 **/
118

    
119
static unsigned int bom_val[NUM_BOM_LEDS];
120
static char bom_type = BOM;
121
  
122
/**
123
 * Initializes the BOM.
124
 * Call bom_init before reading bom values or turning bom leds.
125
 *
126
 * @bugs INCOMPLETE - need to fill in init routine for BOM15
127
 * 
128
 * @see bom_refresh, bom_leds_on, bom_leds_off
129
 **/
130
void bom_init(char type) {
131
    bom_type = type;
132
    
133
    switch(bom_type) {
134
    case BOM:
135
        break;
136
    case BOM15:
137
        break;
138
    case RBOM:
139
        break;
140
    //default:
141
    }
142
}
143

    
144
/**
145
 * Iterates through each bit in the bit_field. For each set bit, sets the corresponding bom select bits
146
 *    and updates the corresponding bom value with an analog_get8 reading.  analog_init and bom_init
147
 *    must be called for this to work.
148
 *
149
 *
150
 * @param bit_field specifies which elements in bom_val[] should be updated. Use BOM_ALL to refresh all values.
151
 *    Ex. if 0x0003 is passed, bom_val[0] and bom_val[1] will be updated.
152
 *
153
 * @see bom_get
154
 **/
155
void bom_refresh(int bit_field) {
156
    int i;
157
    
158
    analog_stop_loop();
159
    
160
    for(i = 0; i < NUM_BOM_LEDS; i++) {
161
        if(bit_field & 0x1) {
162
            bom_select(lookup[i]);
163
            bom_val[i] = analog_get8(MONKI);
164
        }
165
        bit_field = bit_field >> 1;
166
    }
167
    
168
    analog_start_loop();
169
}
170

    
171
/**
172
 * Gets the bom reading from bom_val[which].  Call bom_refresh beforehand to read new bom values.
173
 *
174
 * @param which which bom value to return
175
 *
176
 * @return the bom value
177
 *
178
 * see bom_refresh
179
 **/
180
int bom_get(char which) {
181
    return bom_val[which];
182
}
183

    
184
/** 
185
 * Compares all the values in bom_val[] and returns the index to the lowest (max) value element.
186
 *
187
 * @return index to the lowest (max) bom value element.  -1 if no value is lower than
188
 *    BOM_VALUE_THRESHOLD
189
 **/
190
int bom_get_max(void) {
191
    int i, lowest_val, lowest_i;
192
    
193
    lowest_val = 255;
194
    for(i = 0; i < NUM_BOM_LEDS; i++) {
195
        printi(bom_val[i]);
196
        usb_puts(" ");
197
        if(bom_val[i] < lowest_val) {
198
            lowest_val = bom_val[i];
199
            lowest_i = i;
200
        }
201
    }
202
    usb_puts("<<< BOM_GET_MAX\n\r");
203
    
204
    if(lowest_val < BOM_VALUE_THRESHOLD)
205
        return lowest_i;
206
    else
207
        return -1;
208
}
209

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

    
233
/**
234
 * Iterates through each bit in the bit_field. For each set bit, turns off the corresponding bom led.
235
 *    bom_init must be called for this to work. Only works with BOM_ALL if using the original bom.
236
 *
237
 * @param bit_field specifies which leds should be turned off.  Use BOM_ALL to turn off all bom leds.
238
 *    Ex. if 0x000B is passed, leds 0 and 3 will be turned off.
239
 **/
240
void bom_leds_off(int bit_field) {
241
    switch(bom_type) {
242
    case BOM:
243
        if(bit_field == BOM_ALL) {
244
            digital_output(MONKL, 0);
245
        }
246
        break;
247
    case BOM15:
248
        //add bom 1.5 code here
249
        break;
250
    case RBOM:
251
        //add rbom code here
252
        break;
253
    }
254
}
255

    
256

    
257
/**
258
 * (DEPRECATED) Returns the direction of the maximum BOM reading,
259
 * as an integer in the range 0-15. 0 indicates to the
260
 * robot's right, while the rest of the sensors are
261
 * numbered counterclockwise. This is useful for determining
262
 * the direction of a robot flashing its BOM, of only one
263
 * robot is currently doing so. analog_init must be called
264
 * before this function can be used.
265
 *
266
 * @return the direction of the maximum BOM reading
267
 *
268
 * @see analog_init
269
 **/
270
int get_max_bom(void) {
271
        int max_bom_temp = 0;
272
        int a, i, j, h;
273
    h = 255;
274

    
275
        //Turn off the loop so that we can actually use analog8 correctly
276
        analog_stop_loop();
277

    
278
        //Iterate through through each LED
279
    for (j = 0; j < 16; j++)
280
    {
281
      i = lookup[j];
282

    
283
      if (i&8)
284
        output_high(MONK3);
285
      else
286
        output_low(MONK3);
287

    
288
      if (i&4)
289
        output_high(MONK2);
290
      else
291
        output_low(MONK2);
292

    
293
      if (i&2)
294
        output_high(MONK1);
295
      else
296
        output_low(MONK1);
297

    
298
      if (i&1)
299
        output_high(MONK0);
300
      else
301
        output_low(MONK0);
302

    
303
      a = analog_get8(MONKI);
304
      printi(a);
305
      usb_puts(" ");
306
              
307
      if (a < h)
308
      {
309
        h = a;
310
        max_bom_temp = j;
311
      }
312

    
313
    }
314
        usb_puts("\n\r");
315
        //Restart loop now that we are done using analog8
316
        analog_start_loop();
317

    
318
        //threshold on the bom analog value.
319
        //defined in bom.h
320
        // if the analog value read is above the threshold, we cannot see a robot
321
        // (remember, low means higher intensity).
322
        if(h < BOM_VALUE_THRESHOLD) {
323
                return max_bom_temp;
324
        }
325
        else
326
                return -1;
327
}
328

    
329
/**
330
 * (DEPRECATED) Turns on all bom leds.
331
 * 
332
 * @see bom_off
333
 **/
334
void bom_on(void)
335
{
336
  output_high(MONKL);
337
}
338

    
339
/**
340
 * (DEPRECATED) Turns off all bom leds.
341
 * 
342
 * @see bom_on
343
 **/
344
void bom_off(void)
345
{
346
  output_low(MONKL);
347
}
348

    
349
/** @} **/ //end group
350

    
351
void output_high(int which) {
352
        digital_output(which, 1);
353
}
354

    
355
void output_low(int which) {
356
        digital_output(which, 0);
357
}
358

    
359
static void bom_select(char which) {
360
      if (which&8)
361
        digital_output(MONK3, 1);
362
      else
363
        digital_output(MONK3, 0);
364

    
365
      if (which&4)
366
        digital_output(MONK2, 1);
367
      else
368
        digital_output(MONK2, 0);
369

    
370
      if (which&2)
371
        digital_output(MONK1, 1);
372
      else
373
        digital_output(MONK1, 0);
374

    
375
      if (which&1)
376
        digital_output(MONK0, 1);
377
      else
378
        digital_output(MONK0, 0);
379
}