-
Notifications
You must be signed in to change notification settings - Fork 1
/
follow_the_leader.c
160 lines (135 loc) · 3.56 KB
/
follow_the_leader.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <kilolib.h>
// this program tests an algorithm for following the leader.
// define states
#define WAIT 0
#define MOVE 1
// define movements
typedef enum {
STRAIGHT,
LEFT,
RIGHT,
STOP
} motion_dir;
// declare variables
uint8_t state = WAIT; // all kilobots start in WAIT mode
uint8_t ftl_id = 0; // ID for following the leader
uint8_t front_id = 0; // store ID of bot in front
uint8_t front_state = 0; // store state of bot in front
uint8_t front_dist = 0; // store distance to bot in front
uint8_t behind_id = 0; // store ID of bot behind
uint8_t behind_state = 0; // store state of bot behind
uint8_t behind_dist = 0; // store distance to bot behind
uint8_t dist = 0; // var to hold calculated distance
uint8_t new_message = 0; // new message flag
//uint32_t clock_time = 0;
// declare structs
message_t msg;
distance_measurement_t d_measure;
// simplify updating the motors
void update_motors(motion_dir direction) {
static motion_dir previous_dir = STOP;
if (direction != previous_dir) {
previous_dir = direction;
switch(direction) {
case STRAIGHT:
spinup_motors();
set_motors(kilo_straight_left, kilo_straight_right);
break;
case LEFT:
spinup_motors();
set_motors(kilo_turn_left,0);
break;
case RIGHT:
spinup_motors();
set_motors(0,kilo_turn_right);
break;
case STOP:
set_motors(0,0);
break;
}
}
}
// message transmission callback
message_t *message_tx() {
return &msg;
}
// message receival callback
void message_rx(message_t *m, distance_measurement_t *d) {
// set new message flag and calculate distance
new_message = 1;
d_measure = *d;
dist = estimate_distance(&d_measure);
// store message data for later
if (m->data[0] == front_id) {
front_dist = dist;
front_state = m->data[1];
} else if (m->data[0] == behind_id) {
behind_dist = dist;
behind_state = m->data[1];
}
}
void update_state() {
msg.data[1] = state;
msg.crc = message_crc(&msg);
}
void move() {
state = MOVE;
update_state();
update_motors(STRAIGHT);
set_color(RGB(0,1,0));
}
void wait() {
state = WAIT;
update_state();
update_motors(STOP);
set_color(RGB(1,0,0));
}
void setup() {
ftl_id = kilo_uid / 1000;
// initialize message with bot's ID
msg.type = NORMAL;
msg.data[0] = ftl_id;
msg.crc = message_crc(&msg);
front_id = ftl_id - 1;
behind_id = ftl_id + 1;
// odd-numbered bots move first
if (ftl_id % 2 == 1) {
move();
} else {
wait();
}
}
void loop() {
if (new_message) {
new_message = 0;
if (ftl_id == 1) {
if (behind_state == WAIT && behind_dist < 40) {
move();
} else {
wait();
}
} else if (ftl_id == 3) {
if (front_state == WAIT && front_dist > 40) {
move();
} else {
wait();
}
} else {
if (front_state == WAIT && behind_state == WAIT && front_dist > 40) {
move();
} else {
wait();
}
}
}
}
int main() {
// initialize hardware
kilo_init();
// initialize callbacks
kilo_message_tx = message_tx;
kilo_message_rx = message_rx;
// start program
kilo_start(setup, loop);
return 0;
}