Project

General

Profile

Statistics
| Revision:

root / branches / lemmings / code / behaviors / lemmings / smart_run_around_fsm.c @ 332

History | View | Annotate | Download (4.12 KB)

1
/**
2
 */
3

    
4
#include <string.h>
5
#include "dragonfly_lib.h"
6
#include "smart_run_around_fsm.h"
7

    
8
/*A simple behavior for navigating in an environment, i.e. avoiding walls and getting stuck.
9
Could be better at not getting stuck.
10

11
Latest revision only has two accessible states: move and reverse.
12
*/
13

    
14
// FSM states
15
#define MOVING 12           //Move strait.
16
#define BACKWARDS 15        //Move backwards. (Front close to wall.)
17
#define STOP 16             //Stop.  The default state, (Something broke).
18
#define CRAZY 40            //Erratic behavior that occurs more often when the robot is frequently trying to turn. (i.e. may be stuck.)
19

    
20
#define LEFT 37             //Left
21
#define RIGHT 39            //Right
22

    
23
#define BACKUP_MAX 20
24
#define CRAZY_MAX 200       //The number of counts between "crazy moments"
25
#define STRAIT_SPEED 185    //The speed when going strait or backing up.
26
#define TURN_CONSTANT 2
27
#define PCONTROL_CRAZY_LIMIT 80
28

    
29
// Globals
30
int avoid_state;    /*State machine variable.*/
31
int crazy_count;    /*Counter for a 'get unstuck' behavior.*/
32

    
33
int backup_count;        /*Counter for backup duration.*/
34
int pControl;                /*Proportional control variable, determines turn direction.*/
35

    
36
#define NUM_IR_SENSORS 5
37
int dist[NUM_IR_SENSORS];
38

    
39
static void evaluate_state(void);
40

    
41
void run_around_init(void) {
42
/*   range_init(); */
43
/*   analog_init(); */
44
/*   motors_init(); */
45
/*   orb_init(); */
46
/*   orb_enable(); */
47
/*   usb_init(); */
48

    
49
  avoid_state = MOVING;
50

    
51
  /*Set timers to their maximum values.*/
52
  crazy_count = CRAZY_MAX;
53
  backup_count = 0;
54
  pControl = 0;
55

    
56
  /*Initialize distances to zero.*/
57
  memset(dist, 0, NUM_IR_SENSORS * sizeof(int));
58
}
59

    
60
/*The main function, call this to update states as frequently as possible.*/
61
void run_around_FSM(void) {
62
  /*Default to moving.*/
63
  avoid_state=MOVING;
64

    
65
  /*The following lines ensure that undefined (-1) values
66
  will not update the distances.*/
67
  int temp;
68

    
69
  temp = range_read_distance(IR1);
70
  dist[0] = (temp == -1) ? dist[0] : temp;
71

    
72
  temp=range_read_distance(IR2);
73
  dist[1] = (temp == -1) ? dist[1] : temp;
74

    
75
  temp=range_read_distance(IR3);
76
  dist[2] = (temp == -1) ? dist[2] : temp;
77

    
78
  temp=range_read_distance(IR4);
79
  dist[3] = (temp == -1) ? dist[3] : temp;
80

    
81
  temp=range_read_distance(IR5);
82
  dist[4] = (temp == -1) ? dist[4] : temp;
83

    
84
  /*If the crazy count is in it's >>3 range, it acts crazy.*/
85
  if (crazy_count <= (CRAZY_MAX>>3)) {
86
    avoid_state=CRAZY;
87
    crazy_count--;
88

    
89
    if (crazy_count < 0) {
90
      crazy_count=CRAZY_MAX;
91
    }
92

    
93
    evaluate_state();
94
    return;
95
  }
96

    
97
  //Checks the forward distance to see if it should back up, if so...state backwards.
98
  if ((dist[1] != -1) && (dist[1] < 150)){
99
    backup_count=BACKUP_MAX;
100
    avoid_state=BACKWARDS;
101
    evaluate_state();
102
    return;
103
  }
104

    
105
  /*
106
  if(dist[0] < 120 || dist[2] < 120) {
107
                avoid_state = BACKWARDS;
108
                backup_count = BACKUP_MAX;
109
                evaluate_state();
110
                return;
111
  }
112
  */
113

    
114
  if(backup_count<BACKUP_MAX){
115
    avoid_state=BACKWARDS;
116
    if (backup_count<0) {
117
      backup_count = BACKUP_MAX;
118
    }
119

    
120
    evaluate_state();
121
    return;
122
  }
123

    
124
  /*Should evaluate an expression from -255 to 255 to pass to move.*/
125
  pControl= ((dist[2]-dist[0]) + (dist[3]-dist[4])) >> TURN_CONSTANT;
126

    
127
  if(pControl>PCONTROL_CRAZY_LIMIT || pControl<-PCONTROL_CRAZY_LIMIT) crazy_count--;
128
  /*i.e. if you really want to turn for an extended period of time...you're probably stuck.*/
129

    
130
  /*Debug stuff:*/
131
  /*usb_puts("pControl evaluating: ");
132
  usb_puti(pControl);
133
  usb_puts("\n\r");
134
  usb_puts("IR1: ");
135
  usb_puti(dist[0]);
136
  usb_puts(" IR2: ");
137
  usb_puti(dist[1]);
138
  usb_puts(" IR3: ");
139
  usb_puti(dist[2]);
140
  usb_puts(" IR4: ");
141
  usb_puti(dist[3]);
142
  usb_puts(" IR5: ");
143
  usb_puti(dist[4]);
144
  usb_puts("\n\r");*/
145

    
146
  evaluate_state();
147
}
148

    
149
//Acts on state change.
150
static void evaluate_state(){
151
  switch(avoid_state){
152
  case(MOVING): orb_set_color(GREEN);
153
    move(STRAIT_SPEED,-pControl);
154
    break;
155

    
156
  case(BACKWARDS): orb_set_color(ORANGE);
157
    move(-STRAIT_SPEED,0);
158
    break;
159

    
160
  case(CRAZY): orb_set_color(RED);
161
    /*TODO: Implement a crazy state.*/
162
    move(STRAIT_SPEED,-pControl);
163
    break;
164

    
165
  default:
166
    /*Should never get here, go strait.*/
167
    move(100,0); orb_set_color(BLUE);
168
    break;
169
  }
170
}