Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (4.04 KB)

1
/**
2
 */
3

    
4
#include "dragonfly_lib.h"
5
#include "smart_run_around_fsm.h"
6

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

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

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

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

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

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

    
31
int backup_count;        /*Counter for backup duration.*/
32
int pControl;                /*Proportional control variable, determines turn direction.*/
33
int d1,d2,d3,d4,d5;        /*The five distances taken in by IR.*/
34

    
35

    
36
static void evaluate_state(void);
37

    
38
void run_around_init(void)
39
{
40
  range_init();
41
  analog_init();
42
  motors_init();
43
  orb_init();
44
  orb_enable();
45
  usb_init();
46
 
47
  /*Start in the default state, MOVING*/ 
48
  avoid_state=MOVING;
49
  /*Set timers to their maximum values.*/
50
  crazy_count=CRAZY_MAX;
51
  backup_count=0; 
52
  pControl=0;
53
  
54
  /*Initialize distances to zero.*/ 
55
  d1=0; d2=0; d3=0; d4=0; d5=0;
56
  
57
  orb_set_color(GREEN);
58

    
59
}
60

    
61
/*The main function, call this to update states as frequently as possible.*/
62
void run_around_FSM(void) {
63
  /*Default to moving.*/ 
64
  avoid_state=MOVING;
65
  
66
  /*The following lines ensure that undefined (-1) values
67
  will not update the distances.*/ 
68
  int temp;
69
  
70
  temp=range_read_distance(IR1);
71
  d1=(temp == -1) ? d1 : temp;
72
  
73
  temp=range_read_distance(IR2);
74
  d2=(temp == -1) ? d2 : temp;
75
  
76
  temp=range_read_distance(IR3);
77
  d3=(temp == -1) ? d3 : temp;
78
  
79
  temp=range_read_distance(IR4);
80
  d4=(temp == -1) ? d4 : temp;
81
  
82
  temp=range_read_distance(IR5);
83
  d5=(temp == -1) ? d5 : temp;
84
  
85
  /*If the crazy count is in it's >>3 range, it acts crazy.*/
86
  if(crazy_count<=(CRAZY_MAX>>3))
87
  {
88
    avoid_state=CRAZY;
89
    crazy_count--;
90
    
91
    if(crazy_count<0) crazy_count=CRAZY_MAX;
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((d2!=-1)&&(d2 < 150)){
99
      backup_count=BACKUP_MAX;
100
      avoid_state=BACKWARDS;
101
      evaluate_state();
102
      return;
103
  }
104
  /*
105
  if(d1 < 120 || d3 < 120) {
106
                avoid_state = BACKWARDS;
107
                backup_count = BACKUP_MAX;
108
                evaluate_state();
109
                return;
110
  }
111
  */
112
  if(backup_count<BACKUP_MAX){
113
    avoid_state=BACKWARDS; 
114
    if(backup_count<0)
115
      backup_count=BACKUP_MAX;
116
    evaluate_state();
117
    return;
118
  }
119
  
120
  /*Should evaluate an expression from -255 to 255 to pass to move.*/
121
  pControl= ((d3-d1) + (d4-d5)) >> TURN_CONSTANT;
122
  
123
  if(pControl>PCONTROL_CRAZY_LIMIT || pControl<-PCONTROL_CRAZY_LIMIT) crazy_count--;
124
  /*i.e. if you really want to turn for an extended period of time...you're probably stuck.*/
125

    
126
  /*Debug stuff:*/
127
  /*usb_puts("pControl evaluating: ");
128
  usb_puti(pControl);
129
  usb_puts("\n\r");
130
  usb_puts("IR1: ");
131
  usb_puti(d1);
132
  usb_puts(" IR2: ");
133
  usb_puti(d2);
134
  usb_puts(" IR3: ");
135
  usb_puti(d3);
136
  usb_puts(" IR4: ");
137
  usb_puti(d4);
138
  usb_puts(" IR5: ");
139
  usb_puti(d5);
140
  usb_puts("\n\r");*/
141
  
142
  evaluate_state();
143
}
144

    
145

    
146
//Acts on state change.
147
static void evaluate_state(){
148
    switch(avoid_state){
149
    case(MOVING): orb_set_color(GREEN);
150
      move(STRAIT_SPEED,-pControl);
151
      break;
152
    
153
    case(BACKWARDS): orb_set_color(ORANGE);
154
      move(-STRAIT_SPEED,0);
155
      break;
156
      
157
    case(CRAZY): orb_set_color(RED);
158
      /*TODO: Implement a crazy state.*/
159
      move(STRAIT_SPEED,-pControl);
160
      break;
161
      
162
    default:
163
      /*Should never get here, go strait.*/
164
      move(100,0); orb_set_color(BLUE);
165
      break;
166
  }
167
}
168

    
169