Bluetooth communication for flocking.

Dependencies:   mbed

Fork of BeautifulMemeProject by James Hilder

Committer:
jah128
Date:
Thu Oct 22 00:46:14 2015 +0000
Revision:
6:ff3c66f7372b
Parent:
3:cd048f6e544e
Child:
7:ef9ab01b9e26
Initial version: beacon detection and sync. code, bearing estimation.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jah128 0:8a5497a2e366 1 /* University of York Robotics Laboratory PsiSwarm Library: Sensor Functions Source File
jah128 0:8a5497a2e366 2 *
jah128 0:8a5497a2e366 3 * File: sensors.cpp
jah128 0:8a5497a2e366 4 *
jah128 6:ff3c66f7372b 5 * (C) Dept. Electronics & Computer Science, University of York
jah128 6:ff3c66f7372b 6 * James Hilder, Alan Millard, Homero Elizondo, Jon Timmis
jah128 0:8a5497a2e366 7 *
jah128 6:ff3c66f7372b 8 * Sensor bearing code by Alan Millard
jah128 0:8a5497a2e366 9 *
jah128 6:ff3c66f7372b 10 * PsiSwarm Library Version: 0.3
jah128 6:ff3c66f7372b 11 *
jah128 6:ff3c66f7372b 12 * October 2015
jah128 0:8a5497a2e366 13 *
jah128 0:8a5497a2e366 14 */
jah128 0:8a5497a2e366 15
jah128 0:8a5497a2e366 16 #include "psiswarm.h"
jah128 0:8a5497a2e366 17
jah128 0:8a5497a2e366 18 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jah128 0:8a5497a2e366 19 // Ultrasonic Sensor (SRF02) Functions
jah128 0:8a5497a2e366 20 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jah128 0:8a5497a2e366 21
jah128 0:8a5497a2e366 22 // The ultrasonic sensor needs a start command to be sent: this is done by calling update_ultrasonic_measure().
jah128 0:8a5497a2e366 23 // It can be set to automatically refresh at 10Hz by called enable_ultrasonic_ticker and disable with disabled_ultrasonic_ticker
jah128 0:8a5497a2e366 24
jah128 0:8a5497a2e366 25 void enable_ultrasonic_ticker(){
jah128 0:8a5497a2e366 26 ultrasonic_ticker.attach_us(update_ultrasonic_measure,100000);
jah128 0:8a5497a2e366 27 }
jah128 0:8a5497a2e366 28
jah128 0:8a5497a2e366 29 void disable_ultrasonic_ticker(){
jah128 0:8a5497a2e366 30 ultrasonic_ticker.detach();
jah128 0:8a5497a2e366 31 }
jah128 0:8a5497a2e366 32
jah128 0:8a5497a2e366 33 void update_ultrasonic_measure(){
jah128 0:8a5497a2e366 34 if(waiting_for_ultrasonic == 0){
jah128 0:8a5497a2e366 35 waiting_for_ultrasonic = 1;
jah128 0:8a5497a2e366 36
jah128 0:8a5497a2e366 37 char command[2];
jah128 0:8a5497a2e366 38 command[0] = 0x00; // Set the command register
jah128 0:8a5497a2e366 39 command[1] = 0x51; // Get result is centimeters
jah128 0:8a5497a2e366 40 primary_i2c.write(ULTRASONIC_ADDRESS, command, 2); // Send the command to start a ranging burst
jah128 0:8a5497a2e366 41
jah128 0:8a5497a2e366 42 ultrasonic_timeout.attach_us(IF_read_ultrasonic_measure,70000);
jah128 0:8a5497a2e366 43 }else{
jah128 0:8a5497a2e366 44 debug("WARNING: Ultrasonic sensor called too frequently.\n");
jah128 0:8a5497a2e366 45 }
jah128 0:8a5497a2e366 46 }
jah128 0:8a5497a2e366 47
jah128 0:8a5497a2e366 48 void IF_read_ultrasonic_measure(){
jah128 0:8a5497a2e366 49 char command[1];
jah128 0:8a5497a2e366 50 char result[2];
jah128 0:8a5497a2e366 51 command[0] = 0x02; // The start address of measure result
jah128 0:8a5497a2e366 52 primary_i2c.write(ULTRASONIC_ADDRESS, command, 1, 1); // Send address to read a measure
jah128 0:8a5497a2e366 53 primary_i2c.read(ULTRASONIC_ADDRESS, result, 2); // Read two byte of measure
jah128 0:8a5497a2e366 54 ultrasonic_distance = (result[0]<<8)+result[1];
jah128 0:8a5497a2e366 55 ultrasonic_distance_updated = 1;
jah128 0:8a5497a2e366 56 waiting_for_ultrasonic = 0;
jah128 0:8a5497a2e366 57 debug("US:%d cm\n",ultrasonic_distance);
jah128 0:8a5497a2e366 58 }
jah128 0:8a5497a2e366 59
jah128 0:8a5497a2e366 60 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jah128 0:8a5497a2e366 61 // Additional Sensing Functions
jah128 0:8a5497a2e366 62 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jah128 0:8a5497a2e366 63
jah128 0:8a5497a2e366 64 float get_temperature(){
jah128 0:8a5497a2e366 65 return IF_read_from_temperature_sensor();
jah128 0:8a5497a2e366 66 }
jah128 0:8a5497a2e366 67
jah128 0:8a5497a2e366 68 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jah128 0:8a5497a2e366 69 // Voltage Sensing Functions
jah128 0:8a5497a2e366 70 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jah128 0:8a5497a2e366 71
jah128 0:8a5497a2e366 72 float get_battery_voltage (){
jah128 0:8a5497a2e366 73 float raw_value = vin_battery.read();
jah128 0:8a5497a2e366 74 return raw_value * 4.95;
jah128 0:8a5497a2e366 75 }
jah128 0:8a5497a2e366 76
jah128 0:8a5497a2e366 77 float get_current (){
jah128 0:8a5497a2e366 78 // Device uses a INA211 current sense monitor measuring voltage drop across a 2mOhm resistor
jah128 0:8a5497a2e366 79 // Device gain = 500
jah128 0:8a5497a2e366 80 float raw_value = vin_current.read();
jah128 0:8a5497a2e366 81 return raw_value * 3.3;
jah128 0:8a5497a2e366 82 }
jah128 0:8a5497a2e366 83
jah128 0:8a5497a2e366 84 float get_dc_voltage (){
jah128 0:8a5497a2e366 85 float raw_value = vin_dc.read();
jah128 0:8a5497a2e366 86 return raw_value * 6.6;
jah128 0:8a5497a2e366 87 }
jah128 0:8a5497a2e366 88
jah128 0:8a5497a2e366 89 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jah128 0:8a5497a2e366 90 // IR Sensor Functions
jah128 0:8a5497a2e366 91 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jah128 0:8a5497a2e366 92
jah128 0:8a5497a2e366 93 // Estimates the distance to an obstacle from one of the IR sensors, defined by index (range 0-7).
jah128 0:8a5497a2e366 94 // The value is converted to an approximate distance in millimetres, or 100.0 if no obstacle found.
jah128 0:8a5497a2e366 95 // NB This function is preserved for code-compatability and cases where only a single reading is needed
jah128 0:8a5497a2e366 96 // In many cases it is preferable to call store_reflected_ir_distances() to save all 8 values then read using get_reflected_ir_distance()
jah128 0:8a5497a2e366 97 float read_reflected_ir_distance ( char index ){
jah128 0:8a5497a2e366 98 // Sanity check
jah128 0:8a5497a2e366 99 if(index>7) return 0.0;
jah128 0:8a5497a2e366 100
jah128 0:8a5497a2e366 101 //1. Read the ADC value without IR emitter on; store in the background_ir_values[] array
jah128 0:8a5497a2e366 102 background_ir_values [index] = IF_read_IR_adc_value(1, index );
jah128 0:8a5497a2e366 103
jah128 0:8a5497a2e366 104 //2. Enable the relevant IR emitter by turning on its pulse output
jah128 0:8a5497a2e366 105 switch(index){
jah128 0:8a5497a2e366 106 case 0: case 1: case 6: case 7:
jah128 0:8a5497a2e366 107 IF_set_IR_emitter_output(0, 1);
jah128 0:8a5497a2e366 108 break;
jah128 0:8a5497a2e366 109 case 2: case 3: case 4: case 5:
jah128 0:8a5497a2e366 110 IF_set_IR_emitter_output(1, 1);
jah128 0:8a5497a2e366 111 break;
jah128 0:8a5497a2e366 112 }
jah128 0:8a5497a2e366 113 wait_us(ir_pulse_delay);
jah128 0:8a5497a2e366 114
jah128 0:8a5497a2e366 115 //3. Read the ADC value now IR emitter is on; store in the illuminated_ir_values[] array
jah128 0:8a5497a2e366 116 illuminated_ir_values [index] = IF_read_IR_adc_value (1, index );
jah128 0:8a5497a2e366 117
jah128 0:8a5497a2e366 118 //4. Turn off IR emitter
jah128 0:8a5497a2e366 119 switch(index){
jah128 0:8a5497a2e366 120 case 0: case 1: case 6: case 7:
jah128 0:8a5497a2e366 121 IF_set_IR_emitter_output(0, 0);
jah128 0:8a5497a2e366 122 break;
jah128 0:8a5497a2e366 123 case 2: case 3: case 4: case 5:
jah128 0:8a5497a2e366 124 IF_set_IR_emitter_output(1, 0);
jah128 0:8a5497a2e366 125 break;
jah128 0:8a5497a2e366 126 }
jah128 0:8a5497a2e366 127
jah128 0:8a5497a2e366 128 //5. Estimate distance based on 2 values using calculate_reflected_distances(); store in reflected_ir_distances()
jah128 0:8a5497a2e366 129 reflected_ir_distances [index] = calculate_reflected_distance( background_ir_values [index], illuminated_ir_values [index]);
jah128 0:8a5497a2e366 130 ir_values_stored = 1;
jah128 0:8a5497a2e366 131 return reflected_ir_distances [index];
jah128 0:8a5497a2e366 132 }
jah128 0:8a5497a2e366 133
jah128 0:8a5497a2e366 134
jah128 0:8a5497a2e366 135 // Returns the stored value of the reflected obstacle based on last call of either read_reflected_ir_distance or store_reflected_distances
jah128 0:8a5497a2e366 136 float get_reflected_ir_distance ( char index ){
jah128 0:8a5497a2e366 137 // Sanity check: check range of index and that values have been stored
jah128 0:8a5497a2e366 138 if (index>7 || ir_values_stored == 0) return 0.0;
jah128 0:8a5497a2e366 139 return reflected_ir_distances[index];
jah128 0:8a5497a2e366 140 }
jah128 0:8a5497a2e366 141
jah128 0:8a5497a2e366 142 // Returns the stored value of the non-illuminated sensor based on last call of store_background_raw_ir_values
jah128 0:8a5497a2e366 143 unsigned short get_background_raw_ir_value ( char index ){
jah128 0:8a5497a2e366 144 // Sanity check: check range of index and that values have been stored
jah128 0:8a5497a2e366 145 if (index>7 || ir_values_stored == 0) return 0.0;
jah128 0:8a5497a2e366 146 return background_ir_values[index];
jah128 0:8a5497a2e366 147 }
jah128 0:8a5497a2e366 148
jah128 0:8a5497a2e366 149 // Returns the stored value of the illuminated sensor based on last call of store_illuminated_raw_ir_values
jah128 0:8a5497a2e366 150 unsigned short get_illuminated_raw_ir_value ( char index ){
jah128 0:8a5497a2e366 151 // Sanity check: check range of index and that values have been stored
jah128 0:8a5497a2e366 152 if (index>7 || ir_values_stored == 0) return 0.0;
jah128 0:8a5497a2e366 153 return illuminated_ir_values[index];
jah128 0:8a5497a2e366 154 }
jah128 0:8a5497a2e366 155
jah128 0:8a5497a2e366 156 // Stores the reflected distances for all 8 IR sensors
jah128 0:8a5497a2e366 157 void store_reflected_ir_distances ( void ){
jah128 0:8a5497a2e366 158 store_ir_values();
jah128 0:8a5497a2e366 159 for(int i=0;i<8;i++){
jah128 0:8a5497a2e366 160 reflected_ir_distances [i] = calculate_reflected_distance( background_ir_values [i], illuminated_ir_values [i]);
jah128 0:8a5497a2e366 161 }
jah128 0:8a5497a2e366 162 }
jah128 0:8a5497a2e366 163
jah128 0:8a5497a2e366 164 // Stores the rbackground and illuminated values for all 8 IR sensors
jah128 0:8a5497a2e366 165 void store_ir_values ( void ){
jah128 0:8a5497a2e366 166 store_background_raw_ir_values();
jah128 0:8a5497a2e366 167 store_illuminated_raw_ir_values();
jah128 0:8a5497a2e366 168 }
jah128 0:8a5497a2e366 169
jah128 0:8a5497a2e366 170 // Stores the raw ADC values for all 8 IR sensors without enabling IR emitters
jah128 0:8a5497a2e366 171 void store_background_raw_ir_values ( void ){
jah128 0:8a5497a2e366 172 ir_values_stored = 1;
jah128 0:8a5497a2e366 173 for(int i=0;i<8;i++){
jah128 0:8a5497a2e366 174 background_ir_values [i] = IF_read_IR_adc_value(1,i);
jah128 0:8a5497a2e366 175 }
jah128 0:8a5497a2e366 176 }
jah128 0:8a5497a2e366 177
jah128 0:8a5497a2e366 178 // Stores the raw ADC values for all 8 IR sensors with a 500us emitter pulse
jah128 0:8a5497a2e366 179 void store_illuminated_raw_ir_values ( void ){
jah128 0:8a5497a2e366 180 //1. Enable the front IR emitters and store the values
jah128 0:8a5497a2e366 181 IF_set_IR_emitter_output(0, 1);
jah128 0:8a5497a2e366 182 wait_us(ir_pulse_delay);
jah128 0:8a5497a2e366 183 illuminated_ir_values [0] = IF_read_IR_adc_value(1,0);
jah128 0:8a5497a2e366 184 illuminated_ir_values [1] = IF_read_IR_adc_value(1,1);
jah128 0:8a5497a2e366 185 illuminated_ir_values [6] = IF_read_IR_adc_value(1,6);
jah128 0:8a5497a2e366 186 illuminated_ir_values [7] = IF_read_IR_adc_value(1,7);
jah128 0:8a5497a2e366 187 IF_set_IR_emitter_output(0, 0);
jah128 0:8a5497a2e366 188
jah128 0:8a5497a2e366 189 //2. Enable the rear+side IR emitters and store the values
jah128 0:8a5497a2e366 190 IF_set_IR_emitter_output(1, 1);
jah128 0:8a5497a2e366 191 wait_us(ir_pulse_delay);
jah128 0:8a5497a2e366 192 illuminated_ir_values [2] = IF_read_IR_adc_value(1,2);
jah128 0:8a5497a2e366 193 illuminated_ir_values [3] = IF_read_IR_adc_value(1,3);
jah128 0:8a5497a2e366 194 illuminated_ir_values [4] = IF_read_IR_adc_value(1,4);
jah128 0:8a5497a2e366 195 illuminated_ir_values [5] = IF_read_IR_adc_value(1,5);
jah128 0:8a5497a2e366 196 IF_set_IR_emitter_output(1, 0);
jah128 0:8a5497a2e366 197 }
jah128 0:8a5497a2e366 198
jah128 0:8a5497a2e366 199 // Converts a background and illuminated value into a distance
jah128 0:8a5497a2e366 200 float calculate_reflected_distance ( unsigned short background_value, unsigned short illuminated_value ){
jah128 0:8a5497a2e366 201 float approximate_distance = 4000 + background_value - illuminated_value;
jah128 0:8a5497a2e366 202 if(approximate_distance < 0) approximate_distance = 0;
jah128 0:8a5497a2e366 203
jah128 0:8a5497a2e366 204 // Very approximate: root value, divide by 2, approx distance in mm
jah128 0:8a5497a2e366 205 approximate_distance = sqrt (approximate_distance) / 2.0;
jah128 0:8a5497a2e366 206
jah128 0:8a5497a2e366 207 // Then add adjustment value if value >27
jah128 0:8a5497a2e366 208 if(approximate_distance > 27) {
jah128 0:8a5497a2e366 209 float shift = pow(approximate_distance - 27,3);
jah128 0:8a5497a2e366 210 approximate_distance += shift;
jah128 0:8a5497a2e366 211 }
jah128 0:8a5497a2e366 212 if(approximate_distance > 90) approximate_distance = 100.0;
jah128 0:8a5497a2e366 213 return approximate_distance;
jah128 0:8a5497a2e366 214 }
jah128 0:8a5497a2e366 215
jah128 0:8a5497a2e366 216 // Returns the illuminated raw sensor value for the IR sensor defined by index (range 0-7); turns on the emitters for a 500us pulse
jah128 0:8a5497a2e366 217 unsigned short read_illuminated_raw_ir_value ( char index ){
jah128 0:8a5497a2e366 218 //This function reads the IR strength when illuminated - used for PC system debugging purposes
jah128 0:8a5497a2e366 219 //1. Enable the relevant IR emitter by turning on its pulse output
jah128 0:8a5497a2e366 220 switch(index){
jah128 0:8a5497a2e366 221 case 0: case 1: case 6: case 7:
jah128 0:8a5497a2e366 222 IF_set_IR_emitter_output(0, 1);
jah128 0:8a5497a2e366 223 break;
jah128 0:8a5497a2e366 224 case 2: case 3: case 4: case 5:
jah128 0:8a5497a2e366 225 IF_set_IR_emitter_output(1, 1);
jah128 0:8a5497a2e366 226 break;
jah128 0:8a5497a2e366 227 }
jah128 0:8a5497a2e366 228 wait_us(ir_pulse_delay);
jah128 0:8a5497a2e366 229 //2. Read the ADC value now IR emitter is on
jah128 0:8a5497a2e366 230 unsigned short strong_value = IF_read_IR_adc_value( 1,index );
jah128 0:8a5497a2e366 231 //3. Turn off IR emitter
jah128 0:8a5497a2e366 232 switch(index){
jah128 0:8a5497a2e366 233 case 0: case 1: case 6: case 7:
jah128 0:8a5497a2e366 234 IF_set_IR_emitter_output(0, 0);
jah128 0:8a5497a2e366 235 break;
jah128 0:8a5497a2e366 236 case 2: case 3: case 4: case 5:
jah128 0:8a5497a2e366 237 IF_set_IR_emitter_output(1, 0);
jah128 0:8a5497a2e366 238 break;
jah128 0:8a5497a2e366 239 }
jah128 0:8a5497a2e366 240 return strong_value;
jah128 0:8a5497a2e366 241 }
jah128 0:8a5497a2e366 242
jah128 0:8a5497a2e366 243 // Base IR sensor functions
jah128 0:8a5497a2e366 244
jah128 0:8a5497a2e366 245
jah128 0:8a5497a2e366 246 // Returns the stored value of the non-illuminated sensor based on last call of store_background_base_ir_values
jah128 0:8a5497a2e366 247 unsigned short get_background_base_ir_value ( char index ){
jah128 0:8a5497a2e366 248 // Sanity check: check range of index and that values have been stored
jah128 0:8a5497a2e366 249 if (index>4 || base_ir_values_stored == 0) return 0.0;
jah128 0:8a5497a2e366 250 return background_base_ir_values[index];
jah128 0:8a5497a2e366 251 }
jah128 0:8a5497a2e366 252
jah128 0:8a5497a2e366 253 // Returns the stored value of the illuminated sensor based on last call of store_illuminated_base_ir_values
jah128 0:8a5497a2e366 254 unsigned short get_illuminated_base_ir_value ( char index ){
jah128 0:8a5497a2e366 255 // Sanity check: check range of index and that values have been stored
jah128 0:8a5497a2e366 256 if (index>4 || base_ir_values_stored == 0) return 0.0;
jah128 0:8a5497a2e366 257 return illuminated_base_ir_values[index];
jah128 0:8a5497a2e366 258 }
jah128 0:8a5497a2e366 259
jah128 0:8a5497a2e366 260 // Stores the reflected distances for all 5 base IR sensors
jah128 0:8a5497a2e366 261 void store_base_ir_values ( void ){
jah128 0:8a5497a2e366 262 store_background_base_ir_values();
jah128 0:8a5497a2e366 263 store_illuminated_base_ir_values();
jah128 0:8a5497a2e366 264 //for(int i=0;i<5;i++){
jah128 0:8a5497a2e366 265 // reflected_ir_distances [i] = calculate_reflected_distance( background_base_ir_values [i], illuminated_base_ir_values [i]);
jah128 0:8a5497a2e366 266 //}
jah128 0:8a5497a2e366 267 }
jah128 0:8a5497a2e366 268
jah128 0:8a5497a2e366 269 // Stores the raw ADC values for all 5 base IR sensors without enabling IR emitters
jah128 0:8a5497a2e366 270 void store_background_base_ir_values ( void ){
jah128 0:8a5497a2e366 271 base_ir_values_stored = 1;
jah128 0:8a5497a2e366 272 for(int i=0;i<5;i++){
jah128 0:8a5497a2e366 273 background_base_ir_values [i] = IF_read_IR_adc_value(2,i);
jah128 0:8a5497a2e366 274 }
jah128 0:8a5497a2e366 275 }
jah128 0:8a5497a2e366 276
jah128 0:8a5497a2e366 277 // Stores the raw ADC values for all 5 base IR sensors with a 500us emitter pulse
jah128 0:8a5497a2e366 278 void store_illuminated_base_ir_values ( void ){
jah128 0:8a5497a2e366 279 //1. Enable the base IR emitters and store the values
jah128 0:8a5497a2e366 280 IF_set_IR_emitter_output(2, 1);
jah128 0:8a5497a2e366 281 wait_us(base_ir_pulse_delay);
jah128 0:8a5497a2e366 282 for(int i=0;i<5;i++){
jah128 0:8a5497a2e366 283 illuminated_base_ir_values [i] = IF_read_IR_adc_value(2,i);
jah128 0:8a5497a2e366 284 }
jah128 0:8a5497a2e366 285
jah128 0:8a5497a2e366 286 IF_set_IR_emitter_output(2, 0);
jah128 0:8a5497a2e366 287 }
jah128 0:8a5497a2e366 288
jah128 2:a6214fd156ff 289 // Routine to store detected line position in a similar format to the used on 3Pi\m3Pi\PiSwarm
jah128 3:cd048f6e544e 290 void store_line_position ( ){
jah128 2:a6214fd156ff 291 // Store background and reflected base IR values
jah128 2:a6214fd156ff 292 store_base_ir_values();
jah128 3:cd048f6e544e 293 int h_value[5];
jah128 3:cd048f6e544e 294 int line_threshold = 1000;
jah128 3:cd048f6e544e 295 int line_threshold_hi = 2000;
jah128 3:cd048f6e544e 296 char count = 0;
jah128 3:cd048f6e544e 297 line_found = 0;
jah128 3:cd048f6e544e 298 line_position = 0;
jah128 3:cd048f6e544e 299 for(int i=0;i<5;i++){
jah128 3:cd048f6e544e 300 if(get_background_base_ir_value(i) > get_illuminated_base_ir_value(i)) h_value[i]=0;
jah128 3:cd048f6e544e 301 else h_value[i] = get_illuminated_base_ir_value(i) - get_background_base_ir_value(i);
jah128 3:cd048f6e544e 302 if(h_value[i] < line_threshold) count++;
jah128 3:cd048f6e544e 303 }
jah128 3:cd048f6e544e 304 if(count == 1){
jah128 3:cd048f6e544e 305 line_found = 1;
jah128 3:cd048f6e544e 306 if(h_value[0] < line_threshold) {
jah128 3:cd048f6e544e 307 line_position = -1;
jah128 3:cd048f6e544e 308 if(h_value[1] < line_threshold_hi) line_position = -0.8;
jah128 3:cd048f6e544e 309 }
jah128 3:cd048f6e544e 310
jah128 3:cd048f6e544e 311 if (h_value[1] < line_threshold) {
jah128 3:cd048f6e544e 312 line_position = -0.5 + (0.00005 * h_value[0]) - (0.0001 * h_value[2]);;
jah128 3:cd048f6e544e 313 }
jah128 3:cd048f6e544e 314 if(h_value[2] < line_threshold) {
jah128 3:cd048f6e544e 315 line_position = (0.00005 * h_value[1]) - (0.0001 * h_value[3]);
jah128 3:cd048f6e544e 316 }
jah128 3:cd048f6e544e 317 if(h_value[3] < line_threshold) {
jah128 3:cd048f6e544e 318 line_position = 0.5 + (0.00005 * h_value[2]) - (0.0001 * h_value[4]);;
jah128 3:cd048f6e544e 319 }
jah128 3:cd048f6e544e 320 if(h_value[4] < line_threshold) {
jah128 3:cd048f6e544e 321 line_position = 1;
jah128 3:cd048f6e544e 322 if(h_value[3] < line_threshold_hi) line_position = 0.8;
jah128 3:cd048f6e544e 323 }
jah128 3:cd048f6e544e 324 }
jah128 3:cd048f6e544e 325 if(count == 2){
jah128 3:cd048f6e544e 326 if(h_value[0] && h_value[1] < line_threshold){
jah128 3:cd048f6e544e 327 line_found = 1;
jah128 3:cd048f6e544e 328 line_position = -0.6;
jah128 3:cd048f6e544e 329 }
jah128 3:cd048f6e544e 330
jah128 3:cd048f6e544e 331 if(h_value[1] && h_value[2] < line_threshold){
jah128 3:cd048f6e544e 332 line_found = 1;
jah128 3:cd048f6e544e 333 line_position = -0.4;
jah128 3:cd048f6e544e 334 }
jah128 3:cd048f6e544e 335
jah128 3:cd048f6e544e 336 if(h_value[2] && h_value[3] < line_threshold){
jah128 3:cd048f6e544e 337 line_found = 1;
jah128 3:cd048f6e544e 338 line_position = 0.4;
jah128 3:cd048f6e544e 339 }
jah128 3:cd048f6e544e 340
jah128 3:cd048f6e544e 341 if(h_value[3] && h_value[4] < line_threshold){
jah128 3:cd048f6e544e 342 line_found = 1;
jah128 3:cd048f6e544e 343 line_position = 0.6;
jah128 3:cd048f6e544e 344 }
jah128 3:cd048f6e544e 345 }
jah128 2:a6214fd156ff 346 }
jah128 2:a6214fd156ff 347
jah128 2:a6214fd156ff 348
jah128 3:cd048f6e544e 349
jah128 0:8a5497a2e366 350 void calibrate_base_ir_sensors (void) {
jah128 0:8a5497a2e366 351 short white_background[5];
jah128 0:8a5497a2e366 352 short white_active[5];
jah128 0:8a5497a2e366 353 short black_background[5];
jah128 0:8a5497a2e366 354 short black_active[5];
jah128 0:8a5497a2e366 355 for(int k=0;k<5;k++){
jah128 0:8a5497a2e366 356 white_background[k]=0;
jah128 0:8a5497a2e366 357 black_background[k]=0;
jah128 0:8a5497a2e366 358 white_active[k]=0;
jah128 0:8a5497a2e366 359 black_active[k]=0;
jah128 0:8a5497a2e366 360 }
jah128 0:8a5497a2e366 361 pc.printf("Base IR Calibration\n");
jah128 0:8a5497a2e366 362 display.clear_display();
jah128 0:8a5497a2e366 363 display.write_string("Calibrating base");
jah128 0:8a5497a2e366 364 display.set_position(1,0);
jah128 0:8a5497a2e366 365 display.write_string("IR sensor");
jah128 0:8a5497a2e366 366 wait(0.5);
jah128 0:8a5497a2e366 367 display.clear_display();
jah128 0:8a5497a2e366 368 display.write_string("Place robot on");
jah128 0:8a5497a2e366 369 display.set_position(1,0);
jah128 0:8a5497a2e366 370 display.write_string("white surface");
jah128 0:8a5497a2e366 371 wait(3);
jah128 0:8a5497a2e366 372 display.clear_display();
jah128 0:8a5497a2e366 373 display.write_string("Calibrating base");
jah128 0:8a5497a2e366 374 display.set_position(1,0);
jah128 0:8a5497a2e366 375 display.write_string("IR sensor");
jah128 0:8a5497a2e366 376 wait(0.5);
jah128 0:8a5497a2e366 377 pc.printf("\nWhite Background Results:\n");
jah128 0:8a5497a2e366 378
jah128 0:8a5497a2e366 379 for(int i=0;i<5;i++){
jah128 0:8a5497a2e366 380 wait(0.2);
jah128 0:8a5497a2e366 381 store_background_base_ir_values();
jah128 0:8a5497a2e366 382
jah128 0:8a5497a2e366 383 display.set_position(1,9);
jah128 0:8a5497a2e366 384 display.write_string(".");
jah128 0:8a5497a2e366 385 wait(0.2);
jah128 0:8a5497a2e366 386 store_illuminated_base_ir_values();
jah128 0:8a5497a2e366 387 for(int k=0;k<5;k++){
jah128 0:8a5497a2e366 388 white_background[k]+= get_background_base_ir_value(k);
jah128 0:8a5497a2e366 389 white_active[k] += get_illuminated_base_ir_value(k);
jah128 0:8a5497a2e366 390 }
jah128 0:8a5497a2e366 391 pc.printf("Sample %d 1: %04d-%04d 2: %04d-%04d 3: %04d-%04d 4: %04d-%04d 5: %04d-%04d\n", (i+1),
jah128 0:8a5497a2e366 392 get_background_base_ir_value(0), get_illuminated_base_ir_value(0),
jah128 0:8a5497a2e366 393 get_background_base_ir_value(1), get_illuminated_base_ir_value(1),
jah128 0:8a5497a2e366 394 get_background_base_ir_value(2), get_illuminated_base_ir_value(2),
jah128 0:8a5497a2e366 395 get_background_base_ir_value(3), get_illuminated_base_ir_value(3),
jah128 0:8a5497a2e366 396 get_background_base_ir_value(4), get_illuminated_base_ir_value(4));
jah128 0:8a5497a2e366 397 }
jah128 0:8a5497a2e366 398 for(int k=0;k<5;k++){
jah128 0:8a5497a2e366 399 white_background[k]/=5;
jah128 0:8a5497a2e366 400 white_active[k]/=5;
jah128 0:8a5497a2e366 401 }
jah128 0:8a5497a2e366 402 pc.printf("Mean results 1: %04d-%04d 2: %04d-%04d 3: %04d-%04d 4: %04d-%04d 5: %04d-%04d\n",
jah128 0:8a5497a2e366 403 white_background[0], white_active[0],
jah128 0:8a5497a2e366 404 white_background[1], white_active[1],
jah128 0:8a5497a2e366 405 white_background[2], white_active[2],
jah128 0:8a5497a2e366 406 white_background[3], white_active[3],
jah128 0:8a5497a2e366 407 white_background[4], white_active[4]);
jah128 0:8a5497a2e366 408
jah128 0:8a5497a2e366 409 display.clear_display();
jah128 0:8a5497a2e366 410 display.write_string("Place robot on");
jah128 0:8a5497a2e366 411 display.set_position(1,0);
jah128 0:8a5497a2e366 412 display.write_string("black surface");
jah128 0:8a5497a2e366 413 wait(3);
jah128 0:8a5497a2e366 414
jah128 0:8a5497a2e366 415 display.clear_display();
jah128 0:8a5497a2e366 416 display.write_string("Calibrating base");
jah128 0:8a5497a2e366 417 display.set_position(1,0);
jah128 0:8a5497a2e366 418 display.write_string("IR sensor");
jah128 0:8a5497a2e366 419 wait(0.5);
jah128 0:8a5497a2e366 420 pc.printf("\nBlack Background Results:\n");
jah128 0:8a5497a2e366 421
jah128 0:8a5497a2e366 422 for(int i=0;i<5;i++){
jah128 0:8a5497a2e366 423 wait(0.2);
jah128 0:8a5497a2e366 424
jah128 0:8a5497a2e366 425 store_background_base_ir_values();
jah128 0:8a5497a2e366 426 display.set_position(1,9);
jah128 0:8a5497a2e366 427 display.write_string(".");
jah128 0:8a5497a2e366 428 wait(0.2);
jah128 0:8a5497a2e366 429 store_illuminated_base_ir_values();
jah128 0:8a5497a2e366 430 for(int k=0;k<5;k++){
jah128 0:8a5497a2e366 431 black_background[k]+= get_background_base_ir_value(k);
jah128 0:8a5497a2e366 432 black_active[k] += get_illuminated_base_ir_value(k);
jah128 0:8a5497a2e366 433 }
jah128 0:8a5497a2e366 434 pc.printf("Sample %d 1: %04d-%04d 2: %04d-%04d 3: %04d-%04d 4: %04d-%04d 5: %04d-%04d\n", (i+1),
jah128 0:8a5497a2e366 435 get_background_base_ir_value(0), get_illuminated_base_ir_value(0),
jah128 0:8a5497a2e366 436 get_background_base_ir_value(1), get_illuminated_base_ir_value(1),
jah128 0:8a5497a2e366 437 get_background_base_ir_value(2), get_illuminated_base_ir_value(2),
jah128 0:8a5497a2e366 438 get_background_base_ir_value(3), get_illuminated_base_ir_value(3),
jah128 0:8a5497a2e366 439 get_background_base_ir_value(4), get_illuminated_base_ir_value(4));
jah128 0:8a5497a2e366 440 }
jah128 0:8a5497a2e366 441 for(int k=0;k<5;k++){
jah128 0:8a5497a2e366 442 black_background[k]/=5;
jah128 0:8a5497a2e366 443 black_active[k]/=5;
jah128 0:8a5497a2e366 444 }
jah128 0:8a5497a2e366 445 pc.printf("Mean results 1: %04d-%04d 2: %04d-%04d 3: %04d-%04d 4: %04d-%04d 5: %04d-%04d\n",
jah128 0:8a5497a2e366 446 black_background[0], black_active[0],
jah128 0:8a5497a2e366 447 black_background[1], black_active[1],
jah128 0:8a5497a2e366 448 black_background[2], black_active[2],
jah128 0:8a5497a2e366 449 black_background[3], black_active[3],
jah128 0:8a5497a2e366 450 black_background[4], black_active[4]);
jah128 0:8a5497a2e366 451
jah128 6:ff3c66f7372b 452 }
jah128 6:ff3c66f7372b 453
jah128 6:ff3c66f7372b 454
jah128 6:ff3c66f7372b 455 int get_bearing_from_ir_array (unsigned short * ir_sensor_readings){
jah128 6:ff3c66f7372b 456 float degrees_per_radian = 57.295779513;
jah128 6:ff3c66f7372b 457
jah128 6:ff3c66f7372b 458 // sin(IR sensor angle) and cos(IR sensor angle) LUT, for all 8 sensors
jah128 6:ff3c66f7372b 459 float ir_sensor_sin[8] = {0.382683432, 0.923879533, 0.923879533, 0.382683432, -0.382683432, -0.923879533, -0.923879533, -0.382683432};
jah128 6:ff3c66f7372b 460 float ir_sensor_cos[8] = {0.923879533, 0.382683432, -0.382683432, -0.923879533, -0.923879533, -0.382683432, 0.382683432, 0.923879533};
jah128 6:ff3c66f7372b 461
jah128 6:ff3c66f7372b 462 float sin_sum = 0;
jah128 6:ff3c66f7372b 463 float cos_sum = 0;
jah128 6:ff3c66f7372b 464
jah128 6:ff3c66f7372b 465 for(int i = 0; i < 8; i++)
jah128 6:ff3c66f7372b 466 {
jah128 6:ff3c66f7372b 467 // Use IR sensor reading to weight bearing vector
jah128 6:ff3c66f7372b 468 sin_sum += ir_sensor_sin[i] * ir_sensor_readings[i];
jah128 6:ff3c66f7372b 469 cos_sum += ir_sensor_cos[i] * ir_sensor_readings[i];
jah128 6:ff3c66f7372b 470 }
jah128 6:ff3c66f7372b 471
jah128 6:ff3c66f7372b 472 float bearing = atan2(sin_sum, cos_sum); // Calculate vector towards IR light source
jah128 6:ff3c66f7372b 473 bearing *= degrees_per_radian; // Convert to degrees
jah128 6:ff3c66f7372b 474
jah128 6:ff3c66f7372b 475 return (int) bearing;
jah128 6:ff3c66f7372b 476 }
jah128 6:ff3c66f7372b 477