Project

General

Profile

Revision 1201

Changed smart run-around from old version to new version, which seems kind
of silly, since the rangefinder functions didn't actually change.

View differences:

trunk/code/projects/mapping/auto/smart_run_around_fsm.c
1
#include "dragonfly_lib.h"
1
#include <dragonfly_lib.h>
2 2
#include "smart_run_around_fsm.h"
3 3

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

  
7
Latest revision only has two accessible states: move and reverse.
8
*/
9

  
10

  
11 4
void run_around_init(void)
12 5
{
13 6
  range_init();
7
  orb_init();
14 8
 
15
  /*Start in the default state, MOVING*/ 
16
  avoid_state=MOVING;
17
  /*Set timers to their maximum values.*/
18
  crazy_count=CRAZY_MAX;
19
  backup_count=BACKUP_MAX; 
20
  pControl=0;
21
  
22
  /*Initialize distances to zero.*/ 
23
  d1=0; d2=0; d3=0; d4=0; d5=0;
24
  
9
  state = FORWARD;  // start out moving forward
10
  // initialize rangefinder values to 0
11
  d1 = 0, d2 = 0, d3 = 0, d4 = 0, d5 = 0;
25 12
}
26 13

  
27
/*The main function, call this to update states as frequently as possible.*/
28
void run_around_FSM(void) {
29
  /*Default to moving.*/ 
30
  avoid_state=MOVING;
31
  
32
  /*The following lines ensure that undefined (-1) values
33
  will not update the distances.*/ 
34
  int temp;
35
  
36
  temp=range_read_distance(IR1);
37
  d1=(temp == -1) ? d1 : temp;
38
  
39
  temp=range_read_distance(IR2);
40
  d2=(temp == -1) ? d2 : temp;
41
  
42
  temp=range_read_distance(IR3);
43
  d3=(temp == -1) ? d3 : temp;
44
  
45
  temp=range_read_distance(IR4);
46
  d4=(temp == -1) ? d4 : temp;
47
  
48
  temp=range_read_distance(IR5);
49
  d5=(temp == -1) ? d5 : temp;
50
  
51
  /*If the crazy count is in it's >>3 range, it acts crazy.*/
52
  if(crazy_count<=(CRAZY_MAX>>3))
53
  {
54
    avoid_state=CRAZY;
55
    crazy_count--;
56
    
57
    if(crazy_count<0) crazy_count=CRAZY_MAX;
58
    
59
    evaluate_state();
60
    return;
61
  }
62
  
63
  //Checks the forward distance to see if it should back up, if so...state backwards.
64
  if((d2!=-1)&&(d2 < 150)){
65
      backup_count=BACKUP_MAX;
66
      avoid_state=BACKWARDS;
67
      evaluate_state();
68
      return;
69
  }
70
  /*
71
  if(d1 < 120 || d3 < 120) {
72
		avoid_state = BACKWARDS;
73
		backup_count = BACKUP_MAX;
74
		evaluate_state();
75
		return;
76
  }
77
  */
78
  if(backup_count<BACKUP_MAX){
79
    avoid_state=BACKWARDS; 
80
    if(backup_count<0)
81
      backup_count=BACKUP_MAX;
82
    evaluate_state();
83
    return;
84
  }
85
  
86
  /*Should evaluate an expression from -255 to 255 to pass to move.*/
87
  pControl= ((d3-d1) + (d4-d5)) >> TURN_CONSTANT;
14
/* evaluate rangefinder input and update state
15
 * call this function as often as possible to avoid collisions
16
 */
17
void run_around_FSM(void)
18
{
19
    /* TODO: find a better way to handle rangefinder input
20
     * robot should deal with -1s (obstacles too close or too far to detect)
21
     * in a way that keeps it from crashing or driving in circles
22
     */
23
    // do not update distances when rangefinders return -1
24
    // otherwise update distances with new rangefinder values
25
    int16_t temp;
88 26

  
89
  if(pControl > 255)
90
    pControl = 255;
91
  if(pControl < -255)
92
    pControl = -255;
93
  
94
  if(pControl>PCONTROL_CRAZY_LIMIT || pControl<-PCONTROL_CRAZY_LIMIT) crazy_count--;
95
  /*i.e. if you really want to turn for an extended period of time...you're probably stuck.*/
27
    temp = range_read_distance(IR1);
28
    d1 = (temp == -1) ? d1 : temp;
96 29

  
97
  /*Debug stuff:*/
98
  /*usb_puts("pControl evaluating: ");
99
  usb_puti(pControl);
100
  usb_puts("\n\r");
101
  usb_puts("IR1: ");
102
  usb_puti(d1);
103
  usb_puts(" IR2: ");
104
  usb_puti(d2);
105
  usb_puts(" IR3: ");
106
  usb_puti(d3);
107
  usb_puts(" IR4: ");
108
  usb_puti(d4);
109
  usb_puts(" IR5: ");
110
  usb_puti(d5);
111
  usb_puts("\n\r");*/
112
  
113
  evaluate_state();
114
}
30
    temp = range_read_distance(IR2);
31
    d2 = (temp == -1) ? d2 : temp;
115 32

  
33
    temp = range_read_distance(IR3);
34
    d3 = (temp == -1) ? d3 : temp;
116 35

  
117
//Acts on state change.
118
void evaluate_state(){
119
    switch(avoid_state){
120
    case(MOVING):
121
      move(STRAIT_SPEED,-pControl);
122
      break;
123
    
124
    case(BACKWARDS):
125
      move(-STRAIT_SPEED-50,0);
126
      break;
127
      
128
    case(CRAZY):
129
      /*TODO: Implement a crazy state.*/
130
      move(STRAIT_SPEED,-pControl);
131
      break;
132
      
133
    default:
134
      /*Should never get here, go strait.*/
135
      move(100,0);
136
      break;
137
  }
36
    temp = range_read_distance(IR4);
37
    d4 = (temp == -1) ? d4 : temp;
38

  
39
    temp = range_read_distance(IR5);
40
    d5 = (temp == -1) ? d5 : temp;
41

  
42
    // update state based on rangefinder input
43
    if (d2 < IR2_DANGER)    // avoid frontal collision by turning in place
44
	state = SPIN;
45
    /* nowhere to turn, so don't
46
     * will probably need to turn around soon, but not yet
47
     */
48
    else if (d1 < IR13_DANGER && d3 < IR13_DANGER)
49
	state = FORWARD;
50
    else if (d1 < IR13_DANGER)	// avoid left-side collision by turning right
51
	state = RIGHT;
52
    else if (d3 < IR13_DANGER)	// avoid right-side collision by turning left
53
	state = LEFT;
54
    else if (d2 < IR2_INTEREST)	// should turn to avoid obstacle up ahead
55
    {
56
	if (d3 >= d1)	// more room on right
57
	    state = RIGHT;
58
	else	// more room on left
59
	    state = LEFT;
60
    }
61
    else    // no obstacles close by, so keep going straight
62
	state = FORWARD;
63

  
64
    /* Debugging via USB output */
65
    usb_puts("IR1: ");
66
    usb_puti(d1);
67
    usb_puts(" IR2: ");
68
    usb_puti(d2);
69
    usb_puts(" IR3: ");
70
    usb_puti(d3);
71
    usb_puts(" IR4: ");
72
    usb_puti(d4);
73
    usb_puts(" IR5: ");
74
    usb_puti(d5);
75
    usb_puts("\n\r");
76

  
77
    if (button2_read())	// pushing buttons resets robot
78
    	reset();
79

  
80
    evaluate_state();	// take action on updated state
138 81
}
139 82

  
83
// behave according to current state
84
// TODO: adjust speeds after testing
85
void evaluate_state(void)
86
{
87
    switch (state)
88
    {
89
	case FORWARD:
90
	    orb_set_color(GREEN);
91
	    move(FULL_SPD, 0);	// drive straight forward
92
	    break;
93
	case LEFT:
94
	    orbs_set_color(GREEN, YELLOW);  // green on left side
95
	    move(HALF_SPD, NRML_TURN);	// drive forward and to the left
96
	    break;
97
	case RIGHT:
98
	    orbs_set_color(YELLOW, GREEN);  // green on right side
99
	    move(HALF_SPD, -NRML_TURN);	// drive forward and to the right
100
	    break;
101
	case SPIN:
102
	    orb_set_color(RED);
103
	    move(0, NRML_TURN);	// spin CCW without traveling
104
	    break;
105
	default:    // should never reach this
106
	    orb_set_color(PURPLE);
107
	    move(0, 0);	// stop completely
108
    }
109
}
140 110

  
trunk/code/projects/mapping/auto/Makefile
1
########Update This Section########
1
#######Update This Section########
2 2
#
3 3
#
4 4

  
......
14 14
USE_WIRELESS = 1
15 15

  
16 16
# com1 = serial port. Use lpt1 to connect to parallel port.
17
AVRDUDE_PORT = /dev/tty.usbserial-A4001hAS
17
AVRDUDE_PORT = /dev/ttyUSB0
18 18
#
19 19
#
20 20
###################################
trunk/code/projects/mapping/auto/smart_run_around_fsm.h
1
//Obstacle Avoid Numbers
1
// smart_run_around_fsm.h
2
// required to run Smart Run Around functions
3
// declare functions and global variables
2 4

  
3

  
4 5
#ifndef _RUN_AROUND_FSM_H_
5 6
#define _RUN_AROUND_FSM_H_
6 7

  
7
//The States: 
8
#define MOVING 12           //Move strait.
9
#define BACKWARDS 15        //Move backwards. (Front close to wall.)
10
#define STOP 16             //Stop.  The default state, (Something broke).
11
#define CRAZY 40            //Erratic behavior that occurs more often when the robot is frequently trying to turn. (i.e. may be stuck.)
8
// states (robot shall never move in reverse)
9
// these constants may be changed (but can't overlap) without effect
10
#define FORWARD 0   // drive straight forward
11
#define LEFT 1	// drive forward and to the left
12
#define RIGHT 2	// drive forward and to the right
13
#define SPIN 3	// turn without traveling (last resort if otherwise stuck)
12 14

  
13
#define BACKUP_MAX 60
14
#define CRAZY_MAX 200       //The number of counts between "crazy moments"
15
#define STRAIT_SPEED 185    //The speed when going strait or backing up.
16
#define TURN_CONSTANT 2
17
#define PCONTROL_CRAZY_LIMIT 80
15
/* conditions on rangefinders (in mm) informing state changes
16
 * distances are 50 greater than in real life, cannot be smaller than 100
17
 * naming format: SENSOR_URGENCY
18
 * changing these constants affects robot operation
19
 */
20
#define IR2_DANGER 150	// 10 cm: dangerously close to front
21
#define IR13_DANGER 200 // 15 cm: dangerously close to sides (looking ahead)
22
#define IR2_INTEREST 300    // 25 cm: notably close to front
23
#define IR45_DANGER 150	// dangerously close to side (looking sideways)
18 24

  
19
int avoid_state;
20
int prev_state;    /*State machine variable.*/
21
int crazy_count;    /*Counter for a 'get unstuck' behavior.*/
25
uint8_t state;	// current state of FSM: FORWARD, LEFT, RIGHT, SPIN
26
int16_t d1, d2, d3, d4, d5; // values returned by rangefinders
22 27

  
23
int backup_count;	/*Counter for backup duration.*/
24
int pControl;		/*Proportional control variable, determines turn direction.*/
25
int d1,d2,d3,d4,d5;	/*The five distances taken in by IR.*/
28
// initialize rangefinders and global variables
29
void run_around_init(void);
26 30

  
27
void run_around_init(void);
31
/* evaluate rangefinder input and update state
32
 * call this function as often as possible to avoid collisions
33
 */
28 34
void run_around_FSM(void);
35

  
36
// behave according to current state
29 37
void evaluate_state(void);
30 38

  
31 39
#endif
40

  

Also available in: Unified diff