-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRomi
More file actions
216 lines (170 loc) · 6.74 KB
/
Romi
File metadata and controls
216 lines (170 loc) · 6.74 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
* It is recommended: *
* - You keep this sequence of setup calls if you are to use all the devices. *
* - Comment out those you will not use. *
* - Insert new setup code after the below sequence. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void setup()
{
// These two function set up the pin
// change interrupts for the encoders.
setupLeftEncoder();
setupRightEncoder();
startTimer();
//Set speed control maximum outputs to match motor
LeftSpeedControl.setMax(100);
RightSpeedControl.setMax(100);
// For this example, we'll calibrate only the
// centre sensor. You may wish to use more.
LineCentre.calibrate();
//Setup RFID card
setupRFID();
// These functions calibrate the IMU and Magnetometer
// The magnetometer calibration routine require you to move
// your robot around in space.
// The IMU calibration requires the Romi does not move.
// See related lab sheets for more information.
/*
Wire.begin();
Mag.init();
Mag.calibrate();
Imu.init();
Imu.calibrate();
*/
// Set the random seed for the random number generator
// from A0, which should itself be quite random.
randomSeed(analogRead(A0));
// Initialise Serial communication
Serial.begin( BAUD_RATE );
delay(1000);
Serial.println("Board Reset");
// Romi will wait for you to press a button and then print
// the current map.
//
// !!! A second button press will erase the map !!!
ButtonB.waitForButton();
Map.printMap();
// Watch for second button press, then begin autonomous mode.
ButtonB.waitForButton();
Serial.println("Map Erased - Mapping Started");
Map.resetMap();
// Your extra setup code is best placed here:
// ...
// ...
// but not after the following:
// Because code flow has been blocked, we need to reset the
// last_time variable of the PIDs, otherwise we update the
// PID with a large time elapsed since the class was
// initialised, which will cause a big intergral term.
// If you don't do this, you'll see the Romi accelerate away
// very fast!
LeftSpeedControl.reset();
RightSpeedControl.reset();
left_speed_demand = -5;
right_speed_demand = -5;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* This loop() demonstrates all devices being used in a basic sequence.
* The Romi should:
* - move forwards with random turns
* - log lines, RFID and obstacles to the map.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void loop() {
// Remember to always update kinematics!!
Pose.update();
doMovement();
doMapping();
delay(2);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* We have implemented a random walk behaviour for you
* with a *very* basic obstacle avoidance behaviour.
* It is enough to get the Romi to drive around. We
* expect that in your first week, should should get a
* better obstacle avoidance behaviour implemented for
* your Experiment Day 1 baseline test.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void doMovement() {
// Static means this variable will keep
// its value on each call from loop()
static unsigned long walk_update = millis();
// used to control the forward and turn
// speeds of the robot.
float forward_bias;
float turn_bias;
// Check if we are about to collide. If so,
// zero forward speed
if( DistanceSensor.getDistanceRaw() > 450 ) {
forward_bias = 0;
} else {
forward_bias = 5;
}
// Periodically set a random turn.
// Here, gaussian means we most often drive
// forwards, and occasionally make a big turn.
if( millis() - walk_update > 500 ) {
walk_update = millis();
// randGaussian(mean, sd). utils.h
turn_bias = randGaussian(0, 6.5 );
// Setting a speed demand with these variables
// is automatically captured by a speed PID
// controller in timer3 ISR. Check interrupts.h
// for more information.
left_speed_demand = forward_bias + turn_bias;
right_speed_demand = forward_bias - turn_bias;
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* This function groups up our sensor checks, and then
* encodes into the map. To get you started, we are
* simply placing a character into the map. However,
* you might want to look using a bitwise scheme to
* encode more information. Take a look at mapping.h
* for more information on how we are reading and
* writing to eeprom memory.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void doMapping() {
// Read the IR Sensor and determine distance in
// mm. Make sure you calibrate your own code!
// We threshold a reading between 40mm and 12mm.
// The rationale being:
// We can't trust very close readings or very far.
// ...but feel free to investigate this.
float distance = DistanceSensor.getDistanceInMM();
if( distance < 160 && distance > 90 ) {
// We know the romi has the sensor mounted
// to the front of the robot. Therefore, the
// sensor faces along Pose.Theta.
// We also add on the distance of the
// sensor away from the centre of the robot.
distance += 80;
// Here we calculate the actual position of the obstacle we have detected
float projected_x = Pose.getX() + ( distance * cos( Pose.getThetaRadians() ) );
float projected_y = Pose.getY() + ( distance * sin( Pose.getThetaRadians() ) );
Map.updateMapFeature( (byte)'O', projected_x, projected_y );
}
// Check RFID scanner.
// Look inside RF_interface.h for more info.
if( checkForRFID() ) {
// Add card to map encoding.
Map.updateMapFeature( (byte)'R', Pose.getY(), Pose.getX() );
// you can check the position reference and
// bearing information of the RFID Card in
// the following way:
// serialToBearing( rfid.serNum[0] );
// serialToXPos( rfid.serNum[0] );
// serialToYPos( rfid.serNum[0] );
//
// Note, that, you will need to set the x,y
// and bearing information in rfid.h for your
// experiment setup. For the experiment days,
// we will tell you the serial number and x y
// bearing information for the cards in use.
}
// Basic uncalibrated check for a line.
// Students can do better than this after CW1 ;)
if( LineCentre.readRaw() > 580 ) {
Map.updateMapFeature( (byte)'L', Pose.getY(), Pose.getX() );
}
}