Project

General

Profile

Revision 1094

Added by Rich Hong about 15 years ago

simulating rangefinder and smart run around

changed the position of IR sensors defined in libsim
libsim and libdragonfly use different numbering for IRs (#418, #419)
added smart_run_around to template, right now it just hits wall, backs
up then segfaults

View differences:

branches/simulator/projects/simulator/libsim/rangefinder.c
56 56
#define MIN_IR_ADC8 20
57 57
#define MAX_IR_ADC8 133
58 58

  
59
// hacky conversion
60
#define IR_MAX 800
61
#define IR_MIN 100
62
#define IR_CONVERSION_FACTOR 2.0
63

  
59 64
void range_init(void)
60 65
{
61 66
	/* simulator does not need this */
62 67
}
63 68

  
69
// should return value between 101 and 800
64 70
int range_read_distance (int range_id)
65 71
{
66
	int temp=0;
72
	short temp;
73
	short ir_value; // simulate what libdragonfly rangefiner returns
67 74
	/* read from array in shared memory, if valid */
68
	if (range_id > 0 && range_id < 6) {
69
		temp = (shared_state->ranges).d[range_id];
70
		if (temp < 0 || temp > 1000)
71
			return -1;
72
		else
73
			return temp;
75
	/* TODO: fix numbering in libdragonfly then fix it here */
76
	switch (range_id) {
77
	case IR1:
78
		temp = (shared_state->ranges).d[0];
79
		break;
80
	case IR2:
81
		temp = (shared_state->ranges).d[1];
82
		break;
83
	case IR3:
84
		temp = (shared_state->ranges).d[2];
85
		break;
86
	case IR4:
87
		temp = (shared_state->ranges).d[3];
88
		break;
89
	case IR5:
90
		temp = (shared_state->ranges).d[4];
91
		break;
74 92
	}
93
	ir_value = ((temp / IR_CONVERSION_FACTOR) + IR_MIN);
94
	ir_value = ir_value > IR_MAX ? IR_MAX : ir_value;
95
	printf("[%d]: %d\n", range_id, ir_value);
96
	if (temp >= 0 && temp <= 1000) return ir_value;
75 97
	return -1;
76 98
}
77 99

  
branches/simulator/projects/simulator/simulator/core/motion.c
10 10
#define TIME 1 /*sec*/
11 11
#define ROBOT_WIDTH 131 /*mm*/
12 12

  
13
#define MOTOR_CONVERSION_FACTOR 1000.0
13
#define MOTOR_CONVERSION_FACTOR 10.0
14 14

  
15 15
#define FUDGE 10 /* minimum rangefinder distance until collision */
16 16

  
......
23 23
 **/
24 24
int move_robot(Robot* r)
25 25
{
26
    printf("Called motion\n");
27 26
	Pose old_pose = r->pose;
28 27
	
29 28
	short speed1 = r->shared->motor1;
......
50 49
	  r->pose.y += sin(theta) * speed1 / MOTOR_CONVERSION_FACTOR;
51 50
	  for (divide = 0; divide < 5; divide++) {
52 51
	    /* Lets just call this a collision... */
53
	    printf("%d: %d\n",divide,r->shared->ranges.d[divide]);
52
	    //printf("%d: %d\n",divide,r->shared->ranges.d[divide]);
54 53
	    if (r->shared->ranges.d[divide] < FUDGE) {
55 54
		/* Restore x,y, but allow rotation */
56 55
		r->pose.x = old_pose.x;
......
60 59
		update_rangefinders(r);
61 60
		return 0;
62 61
	    }
63
	}
62
		}
64 63
	  return 0;
65 64
	}
66 65
	radius = ROBOT_WIDTH * speed1 / (speed1 - speed2);
......
84 83
	update_rangefinders(r);
85 84
	for (divide = 0; divide < 5; divide++) {
86 85
	    /* Lets just call this a collision... */
87
	    printf("%d: %d\n",divide,r->shared->ranges.d[divide]);
86
	    //printf("%d: %d\n",divide,r->shared->ranges.d[divide]);
88 87
	    if (r->shared->ranges.d[divide] < FUDGE) {
89 88
		/* Restore x,y, but allow rotation */
90 89
		r->pose.x = old_pose.x;
branches/simulator/projects/simulator/simulator/core/rangefinders.c
6 6
#include "world.h"
7 7

  
8 8
//TODO: These need to be measured...
9
double rf_thetas[5] = {0.0, 2*M_PI/5, 4*M_PI/5, 6*M_PI/5, 8*M_PI/5};
9
double rf_thetas[5] = {8*M_PI/5, 0.0, 2*M_PI/5, 4*M_PI/5, 6*M_PI/5};
10 10
//double rf_thetas[5] = {0.0, 0.0, M_PI/2, M_PI, 3*M_PI/2};
11 11

  
12 12
void update_rangefinders(Robot *bot)
......
24 24
    {
25 25
	rf.d = theta + rf_thetas[ir];
26 26
	x = collide_world(&rf);
27
	//printf("@(%g) - [%d] = %g --> %d\n",rf.d, ir, x, (short)x);
27
	// printf("@(%g) - [%d] = %g --> %d\n",rf.d, ir, x, (short)x);
28 28
	bot->shared->ranges.d[ir] = x;
29 29
    }
30 30
}
branches/simulator/projects/simulator/test/world.txt
4 4
POLYGON 4 CONNECTED -999 1000 -999 999 999 999 999 1000
5 5
POLYGON 4 CONNECTED 1000 -1000 1000 1000 999 1000 999 -1000
6 6

  
7
POLYGON 4 CONNECTED -20 -20 -20 20 20 20 20 -20
7
#POLYGON 4 CONNECTED -20 -20 -20 20 20 20 20 -20
8
POLYGON 4 CONNECTED -100 -500 -100 500 -80 500 -80 -500
8 9

  
branches/simulator/projects/template/main.c
1 1
#include <dragonfly_lib.h>
2
#include "smart_run_around_fsm.h"
2 3

  
3 4
int main(void)
4 5
{
5 6
	dragonfly_init(ALL_ON);
6
	bom_leds_on(BOM_ALL);
7
	motor1_set(1, 200);
8
	motor2_set(1, 150);
7
	//bom_leds_on(BOM_ALL);
8
	//motor1_set(1, 210);
9
	//motor2_set(1, 200);
10
	run_around_init();
9 11
	while(1){
10
       simulator_do();
11
  }
12
		run_around_FSM();
13
       		simulator_do();
14
  	}
12 15
	return 0;
13 16
}
14 17

  
branches/simulator/projects/template/smart_run_around_fsm.c
1
#include "dragonfly_lib.h"
2
#include "smart_run_around_fsm.h"
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
void run_around_init(void)
12
{
13
  range_init();
14
 
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
  
25
}
26

  
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
  printf("d2: %d\n",d2);
65
  if((d2!=-1)&&(d2 < 150)){
66
      backup_count=BACKUP_MAX;
67
      avoid_state=BACKWARDS;
68
      evaluate_state();
69
      return;
70
  }
71
  /*
72
  if(d1 < 120 || d3 < 120) {
73
		avoid_state = BACKWARDS;
74
		backup_count = BACKUP_MAX;
75
		evaluate_state();
76
		return;
77
  }
78
  */
79
  if(backup_count<BACKUP_MAX){
80
    avoid_state=BACKWARDS; 
81
    if(backup_count<0)
82
      backup_count=BACKUP_MAX;
83
    evaluate_state();
84
    return;
85
  }
86
  
87
  /*Should evaluate an expression from -255 to 255 to pass to move.*/
88
  pControl= ((d3-d1) + (d4-d5)) >> TURN_CONSTANT;
89
  
90
  if(pControl>PCONTROL_CRAZY_LIMIT || pControl<-PCONTROL_CRAZY_LIMIT) crazy_count--;
91
  /*i.e. if you really want to turn for an extended period of time...you're probably stuck.*/
92

  
93
  /*Debug stuff:*/
94
  /*usb_puts("pControl evaluating: ");
95
  usb_puti(pControl);
96
  usb_puts("\n\r");
97
  usb_puts("IR1: ");
98
  usb_puti(d1);
99
  usb_puts(" IR2: ");
100
  usb_puti(d2);
101
  usb_puts(" IR3: ");
102
  usb_puti(d3);
103
  usb_puts(" IR4: ");
104
  usb_puti(d4);
105
  usb_puts(" IR5: ");
106
  usb_puti(d5);
107
  usb_puts("\n\r");*/
108
  
109
  evaluate_state();
110
}
111

  
112

  
113
//Acts on state change.
114
void evaluate_state(){
115
    switch(avoid_state){
116
    case(MOVING):
117
      move(STRAIT_SPEED,-pControl);
118
      break;
119
    
120
    case(BACKWARDS):
121
      move(-STRAIT_SPEED-50,0);
122
      break;
123
      
124
    case(CRAZY):
125
      /*TODO: Implement a crazy state.*/
126
      move(STRAIT_SPEED,-pControl);
127
      break;
128
      
129
    default:
130
      /*Should never get here, go strait.*/
131
      move(100,0);
132
      break;
133
  }
134
}
135

  
136

  
branches/simulator/projects/template/smart_run_around_fsm.h
1
//Obstacle Avoid Numbers
2

  
3

  
4
#ifndef _RUN_AROUND_FSM_H_
5
#define _RUN_AROUND_FSM_H_
6

  
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.)
12

  
13
#define LEFT 37             //Left
14
#define RIGHT 39            //Right
15

  
16
#define BACKUP_MAX 60
17
#define CRAZY_MAX 200       //The number of counts between "crazy moments"
18
#define STRAIT_SPEED 185    //The speed when going strait or backing up.
19
#define TURN_CONSTANT 2
20
#define PCONTROL_CRAZY_LIMIT 80
21

  
22
int avoid_state;
23
int prev_state;    /*State machine variable.*/
24
int crazy_count;    /*Counter for a 'get unstuck' behavior.*/
25

  
26
int backup_count;	/*Counter for backup duration.*/
27
int pControl;		/*Proportional control variable, determines turn direction.*/
28
int d1,d2,d3,d4,d5;	/*The five distances taken in by IR.*/
29

  
30
void run_around_init(void);
31
void run_around_FSM(void);
32
void evaluate_state(void);
33

  
34
#endif

Also available in: Unified diff