Project

General

Profile

Statistics
| Revision:

root / branches / lemmings / code / behaviors / lemmings / lemmings.c @ 232

History | View | Annotate | Download (5.98 KB)

1
#include <dragonfly_lib.h>
2
#include <wl_defs.h>
3
#include <wireless.h>
4
#include <wl_token_ring.h>
5
#include "smart_run_around_fsm.h"
6
#include "lemmings.h"
7

    
8
/*A simple behavior for following the leader.
9
  SINGLE_FILE pattern not implemented yet
10
*/
11

    
12
//The States:
13
#define LEAD         1        // move around randomly, leading a chain
14
#define FOLLOW         2        // follow another bot
15

    
16
#define FOLLOW_MULTI_DEFAULT 1 // set default multi-following pattern
17
#define CRAZY_MAX 200       // The number of counts between "crazy moments"
18

    
19
/* Globals */
20
int cur_state;                 // current state
21
int crazy_count;    // Counter for a random behavior
22
int follow_bot;                // follow this bot (-1 if leader)
23
int follow_direction; // follow in this direction
24
int follow_multi;                // set to 0 for single-file following, 1 for tree following
25

    
26
/* Prototypes */
27
static void lemmings_set_pattern(int pattern);
28
static void lemmings_Prims(void);
29
static int lemmings_get_edge_weight(int robot1, int robot2);
30
static void lemmings_evaluate_state(void);
31

    
32
void lemmings_init() {
33
//  dragonfly_init(ALL_ON);
34
//  analog_init();
35
//  motors_init();
36
//  range_init();
37
//  orb_init();
38
//  orb_enable();
39
//  usb_init();
40

    
41
  run_around_init(); // prepare for moving
42

    
43
  /*Start in the default state, LEAD*/
44
  cur_state = LEAD;
45
  /*Set timers to their maximum values.*/
46
  crazy_count = CRAZY_MAX;
47

    
48
  // set to default state
49
  follow_bot = -1;
50
  cur_state = LEAD;
51

    
52
  usb_puts("init_following: robot #");
53
  usb_puti(follow_bot);
54

    
55
  // set pattern
56
  lemmings_set_pattern(FOLLOW_MULTI_DEFAULT);
57
}
58

    
59
// set the following pattern
60
// SINGLE_FILE if pattern <= 0
61
// TREE        if pattern >= 1
62
static void lemmings_set_pattern(int pattern) {
63
  if (pattern <= 0) {
64
    follow_multi = 0;
65
  } else {
66
    follow_multi = 1;
67
  }
68

    
69
  orb_set_color(ORANGE);
70
}
71

    
72
/*The main function, call this to update states as frequently as possible.*/
73
void lemmings_FSM(void) {
74
  int bom = -1;
75
  int i = 0;
76
  int old_follow_bot;
77

    
78
  orb_set_color(WHITE);
79
  if (follow_bot < 0) {
80
    lemmings_Prims(); // if we are not following, then attempt to follow
81
  }
82

    
83
  // if we are following a bot, make sure we can still see it
84
  old_follow_bot = follow_bot;
85
  for (i=0;follow_bot>=0&&i<10;i++) {
86
    bom = wl_token_get_sensor_reading(wl_get_xbee_id(),follow_bot);
87
    if (bom < 0) {
88
      // get new bot to follow
89
      lemmings_Prims();
90
      if (old_follow_bot == follow_bot)
91
        break; // some sort of error
92
      continue;
93
    } else {
94
      cur_state = FOLLOW; // set to follow state
95

    
96
      switch(bom) {
97
      case 0:
98
      case 15:
99
      case 14:
100
      case 13:
101
      case 12:
102
        follow_direction = 255;
103
        break;
104
      case 1:
105
        follow_direction = 150;
106
        break;
107
      case 2:
108
        follow_direction = 100;
109
        break;
110
      case 3:
111
        follow_direction = 50;
112
        break;
113
      case 4:
114
        follow_direction = 0;
115
        break;
116
      case 5:
117
        follow_direction = -50;
118
        break;
119
      case 6:
120
        follow_direction = -100;
121
        break;
122
      case 7:
123
        follow_direction = -150;
124
        break;
125
      case 8:
126
      case 9:
127
      case 10:
128
      case 11:
129
        follow_direction = -255;
130
        break;
131
      default:
132
        follow_direction = 0;
133
        break;
134
      }
135
      break; // break from loop
136
    }
137
  }
138

    
139
  /*If the crazy count is in it's >>3 range, and we are currently a follower, be a leader.*/
140
  /* CURRENTLY DISABLED
141
  if(cur_state == FOLLOW && crazy_count<=(CRAZY_MAX>>3)) {
142
    cur_state = LEAD;
143
  }*/
144

    
145
  usb_puts("following: ");
146
  usb_puti(follow_bot);
147
  usb_puts("bom: ");
148
  usb_puti(bom);
149
  usb_puts("\n\r");
150

    
151
  lemmings_evaluate_state(); // evaluate state
152
}
153

    
154
// create connected components and pick a leader for each chain
155
// use modified Prim's alogrithm to find local spanning tree
156
// CURRENTLY JUST LOOKS FOR CLOSEST ROBOT TO FOLLOW
157
static void lemmings_Prims(void) {
158

    
159
  int nodeA = wl_get_xbee_id(); // get id of current robot
160
  int nodeB = -1;
161
  int cur_weight = -1;
162
  int best_weight = 1000; // set to infinity initially
163
  int best_node = -1;
164
  int i = 0;
165
  orb_set_color(BLUE);
166

    
167
  // iterate through token ring
168
  wl_token_iterator_begin();
169

    
170
  for(i=0; wl_token_iterator_has_next() && i<10; i++) {
171
    nodeB = wl_token_iterator_next();
172
    usb_puts("botB: ");
173
    usb_puti(nodeB);
174
    usb_puts("\n\r");
175
    if (nodeB < 0) {
176
      break; // no more bots
177
    } else if (nodeB == nodeA) {
178
      continue; // can't follow self
179
    }
180

    
181
    cur_weight = lemmings_get_edge_weight(nodeA,nodeB);
182
    usb_puts("weight: ");
183
    usb_puti(cur_weight);
184
    usb_puts("\n\r");
185

    
186
    if (cur_weight >= 0 && cur_weight < best_weight) {
187
      // this is new best node, so save values
188
      best_weight = cur_weight;
189
      best_node = nodeB;
190
    }
191
  }
192

    
193
  if (best_node == -1 || (best_weight > 5 && nodeA < nodeB)) {
194
    // no robots to follow, or choosing to be a leader
195
    cur_state = LEAD;
196
    follow_bot = -1;
197
  } else {
198
    // follow bot
199
    cur_state = FOLLOW;
200
    follow_bot = nodeB;
201
  }
202
}
203

    
204
// get edge weight of sensor matrix
205
// add in BOM range data when BOM 1.5 comes out
206
static int lemmings_get_edge_weight(int robot1, int robot2) {
207
  int weight = -1;
208
  int bom = wl_token_get_sensor_reading(robot1,robot2);
209
  // since we only have positioning data, give better weight to
210
  // bots in from of us
211
  switch(bom) {
212
  case 12:
213
    weight++;
214
  case 13:
215
  case 11:
216
    weight++;
217
  case 14:
218
  case 10:
219
    weight++;
220
  case 15:
221
  case 9:
222
    weight++;
223
  case 0:
224
  case 8:
225
    weight++;
226
  case 1:
227
  case 7:
228
    weight++;
229
  case 2:
230
  case 6:
231
    weight++;
232
  case 3:
233
  case 5:
234
    weight++;
235
  case 4:
236
    break;
237
  default:
238
    weight = -1;
239
    break;
240
  }
241
  return weight;
242
}
243

    
244
//Acts on state change.
245
static void lemmings_evaluate_state() {
246
  usb_puts("state: ");
247
  usb_puti(cur_state);
248
  usb_puts("\n\r");
249

    
250
  switch(cur_state){
251
  case(LEAD):
252
    //move_avoid(200,0,50);
253
    //orb_set_color(GREEN);
254
    run_around_FSM(); // do random run around
255
    break;
256

    
257
  case(FOLLOW):
258
    move(200,follow_direction); // move in direction of bot
259
    orb_set_color(RED);
260
    break;
261

    
262
  default:
263
    /*Should never get here, go strait.*/
264
          move(200,0);
265
          orb_set_color(BLUE);
266
          break;
267
        }
268
}