Library for the PsiSwarm Robot - Version 0.7

Dependents:   PsiSwarm_V7_Blank

Fork of PsiSwarmLibrary by James Hilder

Committer:
jah128
Date:
Sat Oct 15 13:51:39 2016 +0000
Revision:
6:b340a527add9
Parent:
5:3cdd1a37cdd7
Added Apache license to files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jah128 0:d6269d17c8cf 1 /* University of York Robotics Laboratory PsiSwarm Library: PsiSwarm Core Source File
jah128 6:b340a527add9 2 *
jah128 6:b340a527add9 3 * Copyright 2016 University of York
jah128 6:b340a527add9 4 *
jah128 6:b340a527add9 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
jah128 6:b340a527add9 6 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
jah128 6:b340a527add9 7 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS
jah128 6:b340a527add9 8 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
jah128 6:b340a527add9 9 * See the License for the specific language governing permissions and limitations under the License.
jah128 1:060690a934a9 10 *
jah128 0:d6269d17c8cf 11 * File: psiswarm.cpp
jah128 0:d6269d17c8cf 12 *
jah128 0:d6269d17c8cf 13 * (C) Dept. Electronics & Computer Science, University of York
jah128 0:d6269d17c8cf 14 * James Hilder, Alan Millard, Alexander Horsfield, Homero Elizondo, Jon Timmis
jah128 0:d6269d17c8cf 15 *
jah128 5:3cdd1a37cdd7 16 * PsiSwarm Library Version: 0.7
jah128 0:d6269d17c8cf 17 *
jah128 5:3cdd1a37cdd7 18 * October 2016
jah128 0:d6269d17c8cf 19 *
jah128 0:d6269d17c8cf 20 *
jah128 1:060690a934a9 21 */
jah128 0:d6269d17c8cf 22
jah128 0:d6269d17c8cf 23 #include "psiswarm.h"
jah128 0:d6269d17c8cf 24
jah128 0:d6269d17c8cf 25 //Setup MBED connections to PsiSwarm Robot
jah128 0:d6269d17c8cf 26 Serial pc(USBTX,USBRX);
jah128 0:d6269d17c8cf 27 I2C primary_i2c (p9, p10);
jah128 0:d6269d17c8cf 28 InterruptIn gpio_interrupt (p12);
jah128 0:d6269d17c8cf 29 Serial bt(p13, p14);
jah128 0:d6269d17c8cf 30 AnalogIn vin_current(p15);
jah128 0:d6269d17c8cf 31 AnalogIn vin_battery(p16);
jah128 0:d6269d17c8cf 32 AnalogIn vin_dc(p17);
jah128 0:d6269d17c8cf 33 PwmOut motor_left_f (p21);
jah128 0:d6269d17c8cf 34 PwmOut motor_left_r (p22);
jah128 0:d6269d17c8cf 35 PwmOut motor_right_f(p23);
jah128 0:d6269d17c8cf 36 PwmOut motor_right_r(p24);
jah128 0:d6269d17c8cf 37 PwmOut center_led_red(p25);
jah128 0:d6269d17c8cf 38 PwmOut center_led_green(p26);
jah128 0:d6269d17c8cf 39 Display display; //Connects to i2c(p28,p27), reset(p29), backlight(p30)
jah128 0:d6269d17c8cf 40 DigitalOut mbed_led1(LED1);
jah128 0:d6269d17c8cf 41 DigitalOut mbed_led2(LED2);
jah128 0:d6269d17c8cf 42 DigitalOut mbed_led3(LED3);
jah128 0:d6269d17c8cf 43 DigitalOut mbed_led4(LED4);
jah128 0:d6269d17c8cf 44
jah128 0:d6269d17c8cf 45
jah128 0:d6269d17c8cf 46 float center_led_brightness;
jah128 0:d6269d17c8cf 47 float backlight_brightness;
jah128 0:d6269d17c8cf 48
jah128 0:d6269d17c8cf 49 Ticker event_handler;
jah128 0:d6269d17c8cf 50 Timer uptime;
jah128 0:d6269d17c8cf 51 Timeout pause_usercode_timeout;
jah128 0:d6269d17c8cf 52 Ticker ultrasonic_ticker;
jah128 0:d6269d17c8cf 53 Timeout ultrasonic_timeout;
jah128 0:d6269d17c8cf 54 int timer_minute_count;
jah128 0:d6269d17c8cf 55 Ticker timer_ticker;
jah128 0:d6269d17c8cf 56
jah128 0:d6269d17c8cf 57 float firmware_version;
jah128 1:060690a934a9 58 float pcb_version;
jah128 1:060690a934a9 59 float serial_number;
jah128 1:060690a934a9 60
jah128 1:060690a934a9 61 char has_compass=0;
jah128 1:060690a934a9 62 char has_side_ir=1;
jah128 1:060690a934a9 63 char has_base_ir=1;
jah128 1:060690a934a9 64 char has_base_colour_sensor=0;
jah128 1:060690a934a9 65 char has_top_colour_sensor=0;
jah128 1:060690a934a9 66 char has_wheel_encoders=0;
jah128 1:060690a934a9 67 char has_audio_pic=0;
jah128 1:060690a934a9 68 char has_ultrasonic_sensor=0;
jah128 1:060690a934a9 69 char has_temperature_sensor=0;
jah128 1:060690a934a9 70 char has_recharging_circuit=0;
jah128 1:060690a934a9 71 char has_433_radio=0;
jah128 1:060690a934a9 72
jah128 0:d6269d17c8cf 73 char robot_id;
jah128 0:d6269d17c8cf 74 char previous_robot_id;
jah128 0:d6269d17c8cf 75
jah128 0:d6269d17c8cf 76 char wheel_encoder_byte;
jah128 0:d6269d17c8cf 77 char previous_wheel_encoder_byte;
jah128 0:d6269d17c8cf 78 signed int left_encoder;
jah128 0:d6269d17c8cf 79 signed int right_encoder;
jah128 0:d6269d17c8cf 80
jah128 0:d6269d17c8cf 81 char time_based_motor_action = 0;
jah128 0:d6269d17c8cf 82
jah128 0:d6269d17c8cf 83 char testing_voltage_regulators_flag = 1;
jah128 0:d6269d17c8cf 84 char power_good_motor_left = 2;
jah128 0:d6269d17c8cf 85 char power_good_motor_right = 2;
jah128 0:d6269d17c8cf 86 char power_good_infrared = 2;
jah128 0:d6269d17c8cf 87 char status_dc_in = 2;
jah128 0:d6269d17c8cf 88 char status_charging = 2;
jah128 0:d6269d17c8cf 89
jah128 0:d6269d17c8cf 90 char switch_byte;
jah128 0:d6269d17c8cf 91 char previous_switch_byte;
jah128 0:d6269d17c8cf 92
jah128 4:1c621cb8cf0d 93
jah128 4:1c621cb8cf0d 94 char use_motor_calibration = USE_MOTOR_CALIBRATION;
jah128 4:1c621cb8cf0d 95 char motor_calibration_set;
jah128 4:1c621cb8cf0d 96 float left_motor_calibration_value = 1.0;
jah128 4:1c621cb8cf0d 97 float right_motor_calibration_value = 1.0;
jah128 4:1c621cb8cf0d 98
jah128 0:d6269d17c8cf 99 char debug_mode = DEBUG_MODE;
jah128 0:d6269d17c8cf 100 char debug_output = DEBUG_OUTPUT_STREAM;
jah128 1:060690a934a9 101
jah128 0:d6269d17c8cf 102 char firmware_bytes[21];
jah128 0:d6269d17c8cf 103
jah128 0:d6269d17c8cf 104 int base_colour_sensor_raw_values [4];
jah128 0:d6269d17c8cf 105 int top_colour_sensor_raw_values [4];
jah128 0:d6269d17c8cf 106
jah128 0:d6269d17c8cf 107 char waiting_for_ultrasonic = 0;
jah128 0:d6269d17c8cf 108 int ultrasonic_distance = 0;
jah128 0:d6269d17c8cf 109 char ultrasonic_distance_updated = 0;
jah128 0:d6269d17c8cf 110
jah128 0:d6269d17c8cf 111
jah128 0:d6269d17c8cf 112 float line_position = 0;
jah128 0:d6269d17c8cf 113 char line_found = 0;
jah128 0:d6269d17c8cf 114
jah128 0:d6269d17c8cf 115 unsigned short background_ir_values [8];
jah128 0:d6269d17c8cf 116 unsigned short illuminated_ir_values [8];
jah128 0:d6269d17c8cf 117 float reflected_ir_distances [8];
jah128 0:d6269d17c8cf 118 char ir_values_stored = 0;
jah128 0:d6269d17c8cf 119 unsigned short background_base_ir_values [5];
jah128 0:d6269d17c8cf 120 unsigned short illuminated_base_ir_values [5];
jah128 0:d6269d17c8cf 121 char base_ir_values_stored = 0;
jah128 0:d6269d17c8cf 122
jah128 0:d6269d17c8cf 123 float motor_left_speed;
jah128 0:d6269d17c8cf 124 float motor_right_speed;
jah128 0:d6269d17c8cf 125 char motor_left_brake;
jah128 0:d6269d17c8cf 126 char motor_right_brake;
jah128 0:d6269d17c8cf 127
jah128 0:d6269d17c8cf 128 char demo_on = 0;
jah128 0:d6269d17c8cf 129 char event = 0;
jah128 0:d6269d17c8cf 130 char change_id_event = 0;
jah128 0:d6269d17c8cf 131 char encoder_event = 0;
jah128 0:d6269d17c8cf 132 char switch_event = 0;
jah128 0:d6269d17c8cf 133 char user_code_running = 0;
jah128 0:d6269d17c8cf 134 char user_code_restore_mode = 0;
jah128 0:d6269d17c8cf 135 char system_warnings = 0;
jah128 0:d6269d17c8cf 136
jah128 0:d6269d17c8cf 137
jah128 0:d6269d17c8cf 138 vector<string> basic_filenames; //filenames are stored in a vector string
jah128 0:d6269d17c8cf 139 char psi_basic_file_count = 0;
jah128 0:d6269d17c8cf 140 char use_flash_basic = 0;
jah128 0:d6269d17c8cf 141 char file_transfer_mode = 0;
jah128 0:d6269d17c8cf 142
jah128 0:d6269d17c8cf 143 int ir_pulse_delay = DEFAULT_IR_PULSE_DELAY;
jah128 0:d6269d17c8cf 144 int base_ir_pulse_delay = DEFAULT_BASE_IR_PULSE_DELAY;
jah128 0:d6269d17c8cf 145
jah128 0:d6269d17c8cf 146
jah128 1:060690a934a9 147
jah128 1:060690a934a9 148
jah128 0:d6269d17c8cf 149 /**
jah128 0:d6269d17c8cf 150 * init()
jah128 0:d6269d17c8cf 151 *
jah128 0:d6269d17c8cf 152 * Main initialisation routine for the PsiSwarm robot
jah128 0:d6269d17c8cf 153 *
jah128 0:d6269d17c8cf 154 * Set up the GPIO expansion ICs, launch demo mode if button is held
jah128 0:d6269d17c8cf 155 */
jah128 0:d6269d17c8cf 156 void init()
jah128 0:d6269d17c8cf 157 {
jah128 0:d6269d17c8cf 158 firmware_version=0;
jah128 0:d6269d17c8cf 159 timer_minute_count = 0;
jah128 0:d6269d17c8cf 160 timer_ticker.attach(&IF_update_minutes, 300);
jah128 0:d6269d17c8cf 161 uptime.start();
jah128 0:d6269d17c8cf 162 primary_i2c.frequency(400000);
jah128 0:d6269d17c8cf 163 IF_setup_serial_interfaces();
jah128 0:d6269d17c8cf 164 debug("PsiSwarm Robot Library %1.2f\n\n",SOFTWARE_VERSION_CODE);
jah128 0:d6269d17c8cf 165 debug("- Setting up serial interface\n");
jah128 0:d6269d17c8cf 166 debug("- Reading firmware: ");
jah128 1:060690a934a9 167 if(read_firmware() == 1) {
jah128 1:060690a934a9 168 debug("Version %3.2f\n",firmware_version);
jah128 1:060690a934a9 169 IF_get_hardware_description();
jah128 4:1c621cb8cf0d 170 if(use_motor_calibration){
jah128 4:1c621cb8cf0d 171 if(!motor_calibration_set){
jah128 4:1c621cb8cf0d 172 if(firmware_version < 1.1){
jah128 4:1c621cb8cf0d 173 debug("- WARNING: This firmware is incompatible with motor calibration");
jah128 4:1c621cb8cf0d 174 debug("- WARNING: Please update the firmware to use this feature.");
jah128 4:1c621cb8cf0d 175 use_motor_calibration = 0;
jah128 4:1c621cb8cf0d 176 }
jah128 4:1c621cb8cf0d 177 else {
jah128 4:1c621cb8cf0d 178 debug("- WARNING: Motor calibration values have not been stored in firmware");
jah128 4:1c621cb8cf0d 179 debug("- WARNING: Run calibration routine to use this feature.");
jah128 4:1c621cb8cf0d 180 use_motor_calibration = 0;
jah128 4:1c621cb8cf0d 181 }
jah128 4:1c621cb8cf0d 182 }
jah128 4:1c621cb8cf0d 183 else {
jah128 4:1c621cb8cf0d 184 debug("- Motor calibration in use [LEFT:%0.4f RIGHT:%0.4f]",left_motor_calibration_value,right_motor_calibration_value);
jah128 4:1c621cb8cf0d 185 }
jah128 4:1c621cb8cf0d 186 }
jah128 1:060690a934a9 187 } else {
jah128 1:060690a934a9 188 debug("INVALID\n");
jah128 1:060690a934a9 189 debug("- WARNING: Check firmware to enable robot features");
jah128 1:060690a934a9 190 }
jah128 1:060690a934a9 191 if(ENABLE_BASIC == 1) {
jah128 1:060690a934a9 192 read_list_of_file_names();
jah128 1:060690a934a9 193 if(psi_basic_file_count == 0) {
jah128 1:060690a934a9 194 debug("- No PsiBasic files found\n");
jah128 1:060690a934a9 195 } else use_flash_basic = 1;
jah128 0:d6269d17c8cf 196 }
jah128 0:d6269d17c8cf 197 debug("- Setting up PIC microcontroller\n");
jah128 0:d6269d17c8cf 198 // IF_check_pic_firmware();
jah128 0:d6269d17c8cf 199 debug("- Setting up LED drivers\n");
jah128 1:060690a934a9 200 IF_init_leds();
jah128 0:d6269d17c8cf 201 if(IF_setup_led_expansion_ic() != 0) {
jah128 1:060690a934a9 202 debug("- WARNING: No I2C acknowledge for LED driver\n");
jah128 1:060690a934a9 203 system_warnings += 1;
jah128 0:d6269d17c8cf 204 }
jah128 0:d6269d17c8cf 205 debug("- Setting up motor drivers\n");
jah128 1:060690a934a9 206 IF_init_motors();
jah128 0:d6269d17c8cf 207 debug("- Setting up GPIO expansion\n");
jah128 0:d6269d17c8cf 208 reset_encoders();
jah128 0:d6269d17c8cf 209 IF_setup_gpio_expansion_ic();
jah128 1:060690a934a9 210 if(has_temperature_sensor) {
jah128 1:060690a934a9 211 debug("- Setting up temperature sensor\n");
jah128 1:060690a934a9 212 IF_setup_temperature_sensor();
jah128 1:060690a934a9 213 }
jah128 1:060690a934a9 214 if(has_base_colour_sensor) {
jah128 1:060690a934a9 215 debug("- Setting up base colour sensor\n");
jah128 1:060690a934a9 216 IF_check_base_colour_sensor();
jah128 1:060690a934a9 217 }
jah128 1:060690a934a9 218 if(has_ultrasonic_sensor) {
jah128 1:060690a934a9 219 debug("- Setting up ultrasonic sensor\n");
jah128 1:060690a934a9 220 //enable_ultrasonic_ticker();
jah128 1:060690a934a9 221 }
jah128 1:060690a934a9 222
jah128 0:d6269d17c8cf 223 debug("- Robot ID: %d\n",robot_id);
jah128 1:060690a934a9 224 char switchstate = IF_get_switch_state();
jah128 0:d6269d17c8cf 225 debug("- Switch State : %d\n",switchstate);
jah128 0:d6269d17c8cf 226 debug("- Battery Voltage: %1.3fV\n",get_battery_voltage());
jah128 0:d6269d17c8cf 227 debug("- DC Voltage : %1.3fV\n",get_dc_voltage());
jah128 0:d6269d17c8cf 228 debug("- Current Draw : %1.3fA\n",get_current());
jah128 1:060690a934a9 229 if(has_temperature_sensor){
jah128 0:d6269d17c8cf 230 debug("- Temperature : %1.3fC\n",get_temperature());
jah128 1:060690a934a9 231 }
jah128 0:d6269d17c8cf 232 char demo = 0;
jah128 0:d6269d17c8cf 233 if(ENABLE_DEMO == 1 && switchstate > 0) demo=1;
jah128 0:d6269d17c8cf 234 display.init_display(demo);
jah128 0:d6269d17c8cf 235 event_handler.attach_us(&IF_handle_events, 1000);
jah128 1:060690a934a9 236 if(demo > 0) {
jah128 0:d6269d17c8cf 237 debug("- Demo mode button is pressed\n");
jah128 0:d6269d17c8cf 238 wait(1.0);
jah128 0:d6269d17c8cf 239 demo = IF_get_switch_state();
jah128 0:d6269d17c8cf 240 if(demo > 0) demo_mode();
jah128 1:060690a934a9 241 display.init_display(0);
jah128 0:d6269d17c8cf 242 }
jah128 0:d6269d17c8cf 243 }
jah128 0:d6269d17c8cf 244
jah128 1:060690a934a9 245 void IF_update_minutes()
jah128 1:060690a934a9 246 {
jah128 0:d6269d17c8cf 247 uptime.reset();
jah128 0:d6269d17c8cf 248 timer_minute_count += 5;
jah128 0:d6269d17c8cf 249 }
jah128 0:d6269d17c8cf 250
jah128 0:d6269d17c8cf 251 void IF_handle_events()
jah128 0:d6269d17c8cf 252 {
jah128 0:d6269d17c8cf 253 // This is the main 'operating system' thread that handles events from robot stimuli
jah128 0:d6269d17c8cf 254 // By default it is run every 1ms and checks if there are events to handle
jah128 1:060690a934a9 255 if(event > 0) {
jah128 0:d6269d17c8cf 256 // There are some events to handle. We don't handle all events in every loop to keep the system responsive, instead they are priorised.
jah128 1:060690a934a9 257 if(encoder_event == 1) {
jah128 0:d6269d17c8cf 258 // The encoders have changed; update the encoder values
jah128 0:d6269d17c8cf 259 IF_update_encoders();
jah128 1:060690a934a9 260 encoder_event = 0;
jah128 1:060690a934a9 261 event--;
jah128 0:d6269d17c8cf 262 } else {
jah128 1:060690a934a9 263 if(switch_event == 1) {
jah128 1:060690a934a9 264 IF_update_switch();
jah128 1:060690a934a9 265 switch_event = 0;
jah128 1:060690a934a9 266 event--;
jah128 0:d6269d17c8cf 267 }
jah128 1:060690a934a9 268 if(change_id_event == 1) {
jah128 0:d6269d17c8cf 269 // The user ID for the robot has been changed
jah128 0:d6269d17c8cf 270 IF_update_user_id();
jah128 0:d6269d17c8cf 271 change_id_event = 0;
jah128 0:d6269d17c8cf 272 event--;
jah128 0:d6269d17c8cf 273 }
jah128 0:d6269d17c8cf 274 }
jah128 1:060690a934a9 275 }
jah128 0:d6269d17c8cf 276 }
jah128 0:d6269d17c8cf 277
jah128 0:d6269d17c8cf 278 void IF_update_encoders()
jah128 0:d6269d17c8cf 279 {
jah128 0:d6269d17c8cf 280 char rwep = previous_wheel_encoder_byte >> 2;
jah128 0:d6269d17c8cf 281 char rwe = wheel_encoder_byte >> 2;
jah128 0:d6269d17c8cf 282 char lwep = previous_wheel_encoder_byte % 4;
jah128 0:d6269d17c8cf 283 char lwe = wheel_encoder_byte % 4;
jah128 0:d6269d17c8cf 284 //pc.printf("L:%d P:%d R:%d P:%d \n",lwe,lwep,rwe,rwep);
jah128 0:d6269d17c8cf 285 if(lwe == 0 && lwep==1) left_encoder++;
jah128 0:d6269d17c8cf 286 if(lwe == 0 && lwep==2) left_encoder--;
jah128 0:d6269d17c8cf 287 if(rwe == 0 && rwep==1) right_encoder++;
jah128 0:d6269d17c8cf 288 if(rwe == 0 && rwep==2) right_encoder--;
jah128 0:d6269d17c8cf 289 if(left_encoder % 100 == 0) pc.printf("L:%d\n",left_encoder);
jah128 0:d6269d17c8cf 290 }
jah128 0:d6269d17c8cf 291
jah128 0:d6269d17c8cf 292 void IF_update_user_id()
jah128 0:d6269d17c8cf 293 {
jah128 0:d6269d17c8cf 294 }
jah128 0:d6269d17c8cf 295
jah128 0:d6269d17c8cf 296 void IF_update_switch()
jah128 0:d6269d17c8cf 297 {
jah128 0:d6269d17c8cf 298 // The user switch has changed state
jah128 0:d6269d17c8cf 299 // In this implementation we will only act on positive changes (rising edges)
jah128 0:d6269d17c8cf 300 // Subtracting new_state from (new_state & old_state) gives the positive changes
jah128 0:d6269d17c8cf 301 char positive_change = switch_byte - (switch_byte & previous_switch_byte);
jah128 0:d6269d17c8cf 302 if(demo_on) demo_handle_switch_event(positive_change);
jah128 0:d6269d17c8cf 303 else handle_switch_event(positive_change);
jah128 0:d6269d17c8cf 304 }
jah128 0:d6269d17c8cf 305
jah128 0:d6269d17c8cf 306 void reset_encoders()
jah128 0:d6269d17c8cf 307 {
jah128 0:d6269d17c8cf 308 left_encoder = 0;
jah128 1:060690a934a9 309 right_encoder = 0;
jah128 0:d6269d17c8cf 310 }
jah128 0:d6269d17c8cf 311
jah128 1:060690a934a9 312 void debug(const char* format, ...)
jah128 0:d6269d17c8cf 313 {
jah128 1:060690a934a9 314 char buffer[256];
jah128 1:060690a934a9 315 if (debug_mode) {
jah128 1:060690a934a9 316 va_list vl;
jah128 1:060690a934a9 317 va_start(vl, format);
jah128 1:060690a934a9 318 vsprintf(buffer,format,vl);
jah128 1:060690a934a9 319 if(debug_output & 2) bt.printf("%s", buffer);
jah128 1:060690a934a9 320 if(debug_output & 1) pc.printf("%s", buffer);
jah128 1:060690a934a9 321 if(debug_output & 4) display.debug_page(buffer,strlen(buffer));
jah128 1:060690a934a9 322 va_end(vl);
jah128 1:060690a934a9 323 }
jah128 0:d6269d17c8cf 324 }
jah128 0:d6269d17c8cf 325
jah128 0:d6269d17c8cf 326 float get_uptime(void)
jah128 0:d6269d17c8cf 327 {
jah128 1:060690a934a9 328 return uptime.read() + (timer_minute_count * 60);
jah128 0:d6269d17c8cf 329 }
jah128 0:d6269d17c8cf 330
jah128 1:060690a934a9 331 void pause_user_code(float period)
jah128 1:060690a934a9 332 {
jah128 0:d6269d17c8cf 333 user_code_restore_mode = user_code_running;
jah128 0:d6269d17c8cf 334 user_code_running = 0;
jah128 0:d6269d17c8cf 335 pause_usercode_timeout.attach(&IF_end_pause_user_code, period);
jah128 0:d6269d17c8cf 336 }
jah128 0:d6269d17c8cf 337
jah128 1:060690a934a9 338 void IF_end_pause_user_code()
jah128 1:060690a934a9 339 {
jah128 1:060690a934a9 340 user_code_running = user_code_restore_mode;
jah128 1:060690a934a9 341 }
jah128 1:060690a934a9 342
jah128 1:060690a934a9 343 void IF_get_hardware_description()
jah128 1:060690a934a9 344 {
jah128 1:060690a934a9 345 debug("- Robot serial number %1.2f\n",serial_number);
jah128 1:060690a934a9 346 debug("- PCB version %1.2f\n",pcb_version);
jah128 1:060690a934a9 347 debug("- Hardware: ");
jah128 1:060690a934a9 348 if(has_compass) debug("COMPASS, ");
jah128 1:060690a934a9 349 if(has_side_ir) debug("SIDE IR, ");
jah128 1:060690a934a9 350 if(has_base_ir) debug("BASE IR, ");
jah128 1:060690a934a9 351 if(has_base_colour_sensor) debug("BASE COLOUR, ");
jah128 1:060690a934a9 352 if(has_top_colour_sensor) debug("TOP COLOUR, ");
jah128 1:060690a934a9 353 if(has_wheel_encoders) debug("WHEEL ENC., ");
jah128 1:060690a934a9 354 if(has_audio_pic) debug("AUDIO, ");
jah128 1:060690a934a9 355 if(has_ultrasonic_sensor) debug("ULTRASONIC, ");
jah128 1:060690a934a9 356 if(has_temperature_sensor) debug("TEMPERATURE, ");
jah128 1:060690a934a9 357 if(has_recharging_circuit) debug("RECHARGING, ");
jah128 1:060690a934a9 358 if(has_433_radio) debug("433 RADIO.");
jah128 1:060690a934a9 359 debug("\n");
jah128 0:d6269d17c8cf 360 }