Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Pi_Swarm_Blank by
main.cpp@17:4fa7c9e1b512, 2015-08-25 (annotated)
- Committer:
- homero
- Date:
- Tue Aug 25 17:49:16 2015 +0000
- Revision:
- 17:4fa7c9e1b512
- Parent:
- 16:a32ee9ed15c4
revision tested
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
re633 | 11:c5094a68283f | 1 | /* |
re633 | 11:c5094a68283f | 2 | * Software License Agreement (BSD License) |
re633 | 11:c5094a68283f | 3 | * |
re633 | 11:c5094a68283f | 4 | * Copyright (c) 2015, University of York Robotics Laboratory (YRL). |
re633 | 11:c5094a68283f | 5 | * All rights reserved. |
re633 | 11:c5094a68283f | 6 | * |
re633 | 11:c5094a68283f | 7 | * Redistribution and use in source and binary forms, with or without |
re633 | 11:c5094a68283f | 8 | * modification, are permitted provided that the following conditions |
re633 | 11:c5094a68283f | 9 | * are met: |
re633 | 11:c5094a68283f | 10 | * |
re633 | 11:c5094a68283f | 11 | * * Redistributions of source code must retain the above copyright |
re633 | 11:c5094a68283f | 12 | * notice, this list of conditions and the following disclaimer. |
re633 | 11:c5094a68283f | 13 | * * Redistributions in binary form must reproduce the above |
re633 | 11:c5094a68283f | 14 | * copyright notice, this list of conditions and the following |
re633 | 11:c5094a68283f | 15 | * disclaimer in the documentation and/or other materials provided |
re633 | 11:c5094a68283f | 16 | * with the distribution. |
re633 | 11:c5094a68283f | 17 | * |
re633 | 11:c5094a68283f | 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
re633 | 11:c5094a68283f | 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
re633 | 11:c5094a68283f | 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
re633 | 11:c5094a68283f | 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
re633 | 11:c5094a68283f | 22 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
re633 | 11:c5094a68283f | 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
re633 | 11:c5094a68283f | 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
re633 | 11:c5094a68283f | 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
re633 | 11:c5094a68283f | 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
re633 | 11:c5094a68283f | 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
re633 | 11:c5094a68283f | 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
re633 | 11:c5094a68283f | 29 | * POSSIBILITY OF SUCH DAMAGE. |
re633 | 11:c5094a68283f | 30 | */ |
re633 | 11:c5094a68283f | 31 | /** |
re633 | 11:c5094a68283f | 32 | * @file main.cpp |
re633 | 11:c5094a68283f | 33 | * @brief The Ticker fucntion for gaining sensor data and the main function for the PRGP Pi-Swarm Controllers. |
re633 | 11:c5094a68283f | 34 | * @details In this file the main function for the Pi-Swarm Controller is defined. |
re633 | 11:c5094a68283f | 35 | * @version 1.0 |
homero | 13:c18d82f62d38 | 36 | * @author Robert Evans |
re633 | 11:c5094a68283f | 37 | * @date 24/07/15 |
homero | 13:c18d82f62d38 | 38 | * @version 2.0 |
homero | 13:c18d82f62d38 | 39 | * @author Homero Silva |
homero | 13:c18d82f62d38 | 40 | * @date 16/08/15 |
homero | 13:c18d82f62d38 | 41 | * @ultrasonic sensor added |
homero | 15:f7a8989a3cd3 | 42 | * @version 3.0 |
homero | 13:c18d82f62d38 | 43 | * @author Robert Evans |
homero | 13:c18d82f62d38 | 44 | * @date 17/08/15 |
homero | 13:c18d82f62d38 | 45 | * @communication added |
re633 | 11:c5094a68283f | 46 | */ |
jah128 | 3:1aa1de26966a | 47 | #include "main.h" // Certain parameters can be set by changing the defines in piswarm.h |
homero | 14:fc406dfff94f | 48 | #include "pi_swarm_functions.h" |
homero | 13:c18d82f62d38 | 49 | #include "hcsr04.h" |
jah128 | 0:46cd1498a39a | 50 | |
jah128 | 1:37502eb3b70f | 51 | PiSwarm piswarm; |
jah128 | 1:37502eb3b70f | 52 | Serial pc (USBTX,USBRX); |
homero | 13:c18d82f62d38 | 53 | HCSR04 usensor(p30,p14); |
jah128 | 0:46cd1498a39a | 54 | |
re633 | 9:ef0907fda2f1 | 55 | //Tickers |
homero | 14:fc406dfff94f | 56 | Ticker ticker_25ms; //Ticker used to periodically obtain new IR readings. |
homero | 14:fc406dfff94f | 57 | Ticker ticker_ultrasonic50ms; //Ticker used to periodically obtain a new ultrasonic reading. |
homero | 13:c18d82f62d38 | 58 | |
homero | 13:c18d82f62d38 | 59 | //Timeouts |
homero | 14:fc406dfff94f | 60 | Timeout tickChangeTimeout; //Timeout used to adjust IR read ticker phase to enable to beacon syncronisation. |
homero | 14:fc406dfff94f | 61 | Timeout broadcastTimeout; //Timeout used for broadcasting messages multiple times with a set interval. |
homero | 17:4fa7c9e1b512 | 62 | Timeout stopSearchTimeout; |
homero | 13:c18d82f62d38 | 63 | |
homero | 13:c18d82f62d38 | 64 | //Timers |
homero | 14:fc406dfff94f | 65 | Timer turn_timer; //Timer used to turn a user specified number of degrees. |
homero | 14:fc406dfff94f | 66 | Timer levy_timer; //Timer used to control time between levy walk steps. |
homero | 17:4fa7c9e1b512 | 67 | Timer back_move_timer; //Timer used to make the piswarm move back and turn periodically in case it is stuck moving to the beacon. |
re633 | 9:ef0907fda2f1 | 68 | |
re633 | 9:ef0907fda2f1 | 69 | //Global Variables |
homero | 14:fc406dfff94f | 70 | |
homero | 14:fc406dfff94f | 71 | //Individucal Pi-Swarm variables: speed and motor trim etc |
homero | 14:fc406dfff94f | 72 | float BASE_SPEED = 0.6; //The input to the motor functions when the robot is moving forward and does not detect obstacles. |
homero | 14:fc406dfff94f | 73 | float r_mot_scaler = 1; //This variable is allows particular pi swarms to be adjusted to travel in a straight line. |
homero | 14:fc406dfff94f | 74 | float l_mot_scaler = 1; //This variable is allows particular pi swarms to be adjusted to travel in a straight line. |
homero | 14:fc406dfff94f | 75 | uint16_t at_beacon_threshold = 3800; //A raw IR reading greater than this value indicates the robot is at a beacon. |
homero | 14:fc406dfff94f | 76 | int16_t g_currentHeading = 0; //The current heading of the Pi-swarm relative to the IR beacon. |
homero | 14:fc406dfff94f | 77 | uint8_t robot_id; //The id unique to each Pi-Swarm robot |
homero | 14:fc406dfff94f | 78 | |
homero | 14:fc406dfff94f | 79 | //Finite state machine information |
homero | 14:fc406dfff94f | 80 | uint8_t volatile gv_state = States::READY_TO_START; //This is the current state of the finite state machine |
homero | 14:fc406dfff94f | 81 | int8_t g_obstacle_type = 0; //The Pi-Swarm will perform different obstacle avoidance behaviours depending on which sensors detect obstacles. This variable is used to note which sensor detected the obstacle. |
homero | 17:4fa7c9e1b512 | 82 | uint8_t consecutive_turn_count = 0; |
homero | 17:4fa7c9e1b512 | 83 | uint8_t volatile stop_search_flag = 0; //Set to one ten seconds after command five received. Means stop searching for target beacon. |
homero | 17:4fa7c9e1b512 | 84 | uint8_t volatile sync_attempt_count = 0; |
homero | 14:fc406dfff94f | 85 | |
homero | 14:fc406dfff94f | 86 | //IR Readings + beacon syncronisation variables |
re633 | 9:ef0907fda2f1 | 87 | uint8_t const IR_READ_PER_BEAC = 20; //The number of IR readings between beacon flashes |
re633 | 9:ef0907fda2f1 | 88 | uint16_t volatile gv_IRVals[IR_READ_PER_BEAC][8] = {0}; //The passive IR values each are stored in this array every 25ms for the last 0.5 seconds |
homero | 14:fc406dfff94f | 89 | int16_t volatile gv_IRValDiffs[IR_READ_PER_BEAC][8] = {0};//The difference between consective IR readings. |
homero | 14:fc406dfff94f | 90 | int16_t volatile gv_IRValDiffsTwo[IR_READ_PER_BEAC][8] = {0};//The difference between IR readings seperated by two ticks |
homero | 14:fc406dfff94f | 91 | uint8_t volatile beacon_detected[8] = {0}; //An IR sensor is judged to have a detected the beacon in a valid way the corresponding array variable will be set to 1, else 0. |
re633 | 9:ef0907fda2f1 | 92 | int8_t volatile gv_counter25ms = 0; //This counter is increased every 25ms and resets to zero after one second. (It is signed because 1 is subtracted from it in ReadIRs) |
homero | 14:fc406dfff94f | 93 | int8_t g_beaconOn = 100; //The first tick at which the beacon is illuminated |
homero | 13:c18d82f62d38 | 94 | uint8_t const BEACON_SUSPECTED = 20; //Value by which consecutive IR sensor readings need to jump by for in order to cause beacon to be suspected. |
homero | 14:fc406dfff94f | 95 | uint8_t volatile gv_IRDistances[8]; //Using the custom distance function the active IR readings are converted to distances and stored here every 25ms. |
re633 | 11:c5094a68283f | 96 | int8_t volatile tick_beacon_suspected = 100; //Is set to the tick value within the period between beacon flashes that the beacon flash is suspected to begin at |
re633 | 11:c5094a68283f | 97 | int8_t tick_beacon_period_check = 100; //Is used to temporarily store the value of tick_beacon_suspected |
homero | 14:fc406dfff94f | 98 | uint8_t beacon_syncronised_flag = 0; //Set to one when the robot is synchronised with the beacon |
homero | 14:fc406dfff94f | 99 | uint8_t volatile beacon_illuminated_flag = 0; //Should be 1 when beacon is illuminated otherwise 0 |
homero | 14:fc406dfff94f | 100 | |
homero | 14:fc406dfff94f | 101 | //Ultrasonic Readings |
homero | 14:fc406dfff94f | 102 | float volatile distance_ultrasonic_sensor = 1000; //Here is stored the latest reading from the ultrasonic sensor in mm from 1 -800. 1000 is an error value. |
homero | 14:fc406dfff94f | 103 | |
homero | 14:fc406dfff94f | 104 | //Levy walk variables |
homero | 14:fc406dfff94f | 105 | uint32_t levy_target_time_us = 0; //The amount of time in micro seconds by which the robot needs to move in order to reach the distance required in next section of the levy walk. |
homero | 14:fc406dfff94f | 106 | uint8_t g_back_count = 0; //After a set number of Levy walk turns the robot will move backward. This variable monitors how many Levy turns since the last backward move. |
homero | 14:fc406dfff94f | 107 | uint8_t set_new_levy_time_flag = 1; //Must start as 1. If fwd move state is entered following a levy turn the flag will be 1 indicating a new time should be set. |
homero | 14:fc406dfff94f | 108 | |
homero | 14:fc406dfff94f | 109 | |
homero | 15:f7a8989a3cd3 | 110 | //Communication |
homero | 14:fc406dfff94f | 111 | uint8_t broadcasted_flag = 1; //Set to one when a message has been broadcast. 0 when about to broadcast a new message |
homero | 14:fc406dfff94f | 112 | uint8_t broadcasted_count = 0; //The number of messages that have been broadcasted in one batch |
homero | 17:4fa7c9e1b512 | 113 | int8_t volatile start_flag = 0; //Set to 1 on receiving a command by RF. Indicates robot can start searching for target beacon. |
homero | 14:fc406dfff94f | 114 | int8_t volatile back_flag = 0; //Set to 1 on receiving a command by RF. Indicates robot can start searching for home beacon, unless it is at the target beacon. |
homero | 14:fc406dfff94f | 115 | int8_t volatile return_flag = 0; //Set to 1 on receiving a command by RF. Indicates all robots now start or continue searching for home beacon. |
homero | 13:c18d82f62d38 | 116 | |
re633 | 9:ef0907fda2f1 | 117 | //Ticker Function************************************************************************************* |
re633 | 9:ef0907fda2f1 | 118 | //This function is called by a ticker every 25ms |
re633 | 9:ef0907fda2f1 | 119 | //The function firstly stores the background IRS values. |
re633 | 9:ef0907fda2f1 | 120 | //Secondly if beacon is off it uses illuminated IR sensors to estimate distances |
re633 | 9:ef0907fda2f1 | 121 | //Each second it will update when it believes beacon illumination time to be |
re633 | 9:ef0907fda2f1 | 122 | //It will work out which sensors spotted then beacon and will illuminate the Leds accordingly |
homero | 15:f7a8989a3cd3 | 123 | void readIRs() |
homero | 15:f7a8989a3cd3 | 124 | { |
homero | 15:f7a8989a3cd3 | 125 | |
re633 | 9:ef0907fda2f1 | 126 | //Fistly update the beaconVisable flag if possible |
homero | 15:f7a8989a3cd3 | 127 | if(gv_counter25ms == mod8((g_beaconOn - 1), IR_READ_PER_BEAC)) { |
homero | 14:fc406dfff94f | 128 | beacon_illuminated_flag = 1; |
re633 | 9:ef0907fda2f1 | 129 | } |
homero | 15:f7a8989a3cd3 | 130 | |
homero | 15:f7a8989a3cd3 | 131 | if(gv_counter25ms == mod8((g_beaconOn + 2), IR_READ_PER_BEAC)) { |
homero | 14:fc406dfff94f | 132 | beacon_illuminated_flag = 0; |
re633 | 9:ef0907fda2f1 | 133 | } |
re633 | 9:ef0907fda2f1 | 134 | //Firstly store background values |
re633 | 9:ef0907fda2f1 | 135 | //Also make a note of which point in the second did the values change most. |
re633 | 9:ef0907fda2f1 | 136 | //For which sensor specifically did the values change the most |
re633 | 9:ef0907fda2f1 | 137 | //That sensor will be used to estimate the beacon start time if a threshold value is met |
re633 | 9:ef0907fda2f1 | 138 | piswarm.store_background_raw_ir_values(); |
re633 | 9:ef0907fda2f1 | 139 | int16_t IRchange = 0; |
homero | 13:c18d82f62d38 | 140 | int16_t IRchange2 = 0; |
re633 | 9:ef0907fda2f1 | 141 | uint8_t loopCounter = 0; |
re633 | 9:ef0907fda2f1 | 142 | //In this loop the raw IR values are read. |
re633 | 9:ef0907fda2f1 | 143 | //If the points where the IR values have increased by the greatest amount are noted as this indicates a beacon illumination |
re633 | 9:ef0907fda2f1 | 144 | for(loopCounter = 0; loopCounter < 8; loopCounter++) { |
re633 | 9:ef0907fda2f1 | 145 | gv_IRVals[gv_counter25ms][loopCounter] = piswarm.get_background_raw_ir_value(loopCounter); |
homero | 15:f7a8989a3cd3 | 146 | |
homero | 13:c18d82f62d38 | 147 | IRchange = gv_IRVals[gv_counter25ms][loopCounter]-gv_IRVals[mod8((gv_counter25ms-1),IR_READ_PER_BEAC)][loopCounter]; |
homero | 13:c18d82f62d38 | 148 | IRchange2 = gv_IRVals[gv_counter25ms][loopCounter]-gv_IRVals[mod8((gv_counter25ms-2),IR_READ_PER_BEAC)][loopCounter]; |
re633 | 9:ef0907fda2f1 | 149 | gv_IRValDiffs[gv_counter25ms][loopCounter] = IRchange; |
homero | 13:c18d82f62d38 | 150 | gv_IRValDiffsTwo[gv_counter25ms][loopCounter] = IRchange2; |
homero | 15:f7a8989a3cd3 | 151 | |
re633 | 9:ef0907fda2f1 | 152 | //printf("change %d count %d\n",IRchange); |
re633 | 9:ef0907fda2f1 | 153 | //If difference is greater than a threshold value then the beacon is suspected. This will be confirmed depending on the robots state of movement. |
homero | 15:f7a8989a3cd3 | 154 | if (IRchange > BEACON_SUSPECTED) { |
re633 | 11:c5094a68283f | 155 | tick_beacon_suspected = gv_counter25ms; |
re633 | 9:ef0907fda2f1 | 156 | piswarm.cls(); |
re633 | 11:c5094a68283f | 157 | piswarm.printf("%d",tick_beacon_suspected); |
homero | 15:f7a8989a3cd3 | 158 | } |
re633 | 9:ef0907fda2f1 | 159 | } |
homero | 15:f7a8989a3cd3 | 160 | |
re633 | 9:ef0907fda2f1 | 161 | //Now store the illuminated values if the beacon is not illuminated- |
re633 | 9:ef0907fda2f1 | 162 | piswarm.store_illuminated_raw_ir_values(); |
homero | 15:f7a8989a3cd3 | 163 | |
homero | 15:f7a8989a3cd3 | 164 | //In this loop convert each raw active IR reading into a distance estimate |
re633 | 9:ef0907fda2f1 | 165 | for(loopCounter = 0; loopCounter < 8; loopCounter++) { |
homero | 15:f7a8989a3cd3 | 166 | |
re633 | 9:ef0907fda2f1 | 167 | //Specific sensor readings converted to distances |
re633 | 9:ef0907fda2f1 | 168 | float temp = piswarm.get_illuminated_raw_ir_value(loopCounter); |
homero | 13:c18d82f62d38 | 169 | //if(gv_counter25ms == 1) pc.printf("sen %d :%f\n", loopCounter,temp); |
homero | 15:f7a8989a3cd3 | 170 | if(gv_counter25ms == 0) { |
homero | 13:c18d82f62d38 | 171 | pc.printf("sen %d raw: %f",loopCounter,temp); |
homero | 13:c18d82f62d38 | 172 | } |
homero | 15:f7a8989a3cd3 | 173 | if(temp>3500) { |
homero | 15:f7a8989a3cd3 | 174 | temp = 3500; |
homero | 15:f7a8989a3cd3 | 175 | } else if (temp < 97) { |
homero | 15:f7a8989a3cd3 | 176 | temp = 97; |
re633 | 9:ef0907fda2f1 | 177 | } |
homero | 15:f7a8989a3cd3 | 178 | //#put this into a function |
re633 | 9:ef0907fda2f1 | 179 | //Switch case for robot 5 |
homero | 15:f7a8989a3cd3 | 180 | switch(robot_id) { |
homero | 13:c18d82f62d38 | 181 | case 9: |
homero | 15:f7a8989a3cd3 | 182 | switch(loopCounter) { |
homero | 13:c18d82f62d38 | 183 | case 0: |
homero | 13:c18d82f62d38 | 184 | temp = 1643 * sqrt(1/(temp-190))-35; |
homero | 15:f7a8989a3cd3 | 185 | break; |
homero | 13:c18d82f62d38 | 186 | case 1: |
homero | 13:c18d82f62d38 | 187 | temp = 1097 * sqrt(1/(temp-190))-24; |
homero | 15:f7a8989a3cd3 | 188 | break; |
homero | 13:c18d82f62d38 | 189 | case 2: |
homero | 13:c18d82f62d38 | 190 | temp = 838 * sqrt(1/(temp-120))-17; |
homero | 13:c18d82f62d38 | 191 | break; |
homero | 13:c18d82f62d38 | 192 | case 3: |
homero | 13:c18d82f62d38 | 193 | temp = 1017 * sqrt(1/(temp-175))-22; |
homero | 13:c18d82f62d38 | 194 | break; |
homero | 13:c18d82f62d38 | 195 | case 4: |
homero | 13:c18d82f62d38 | 196 | temp = 777 * sqrt(1/(temp-130))-16; |
homero | 13:c18d82f62d38 | 197 | break; |
homero | 13:c18d82f62d38 | 198 | case 5: |
homero | 13:c18d82f62d38 | 199 | temp = 765 * sqrt(1/(temp-115))-11; |
homero | 13:c18d82f62d38 | 200 | break; |
homero | 13:c18d82f62d38 | 201 | case 6: |
homero | 13:c18d82f62d38 | 202 | temp = 1086 * sqrt(1/(temp-150))-17; |
homero | 13:c18d82f62d38 | 203 | break; |
homero | 13:c18d82f62d38 | 204 | case 7: |
homero | 13:c18d82f62d38 | 205 | temp = 1578 * sqrt(1/(temp-220))-24; |
homero | 13:c18d82f62d38 | 206 | break; |
homero | 13:c18d82f62d38 | 207 | } |
re633 | 9:ef0907fda2f1 | 208 | break; |
homero | 13:c18d82f62d38 | 209 | case 12: |
homero | 15:f7a8989a3cd3 | 210 | switch(loopCounter) { |
homero | 13:c18d82f62d38 | 211 | case 0: |
homero | 13:c18d82f62d38 | 212 | temp = 877 * sqrt(1/(temp-80))-13; |
homero | 15:f7a8989a3cd3 | 213 | break; |
homero | 13:c18d82f62d38 | 214 | case 1: |
homero | 13:c18d82f62d38 | 215 | temp = 887 * sqrt(1/(temp-110))-13; |
homero | 15:f7a8989a3cd3 | 216 | break; |
homero | 13:c18d82f62d38 | 217 | case 2: |
homero | 13:c18d82f62d38 | 218 | temp = 744 * sqrt(1/(temp-90))-8; |
homero | 13:c18d82f62d38 | 219 | break; |
homero | 13:c18d82f62d38 | 220 | case 3: |
homero | 13:c18d82f62d38 | 221 | temp = 816 * sqrt(1/(temp-105))-17; |
homero | 13:c18d82f62d38 | 222 | break; |
homero | 13:c18d82f62d38 | 223 | case 4: |
homero | 13:c18d82f62d38 | 224 | temp = 821 * sqrt(1/(temp-125))-7; |
homero | 13:c18d82f62d38 | 225 | break; |
homero | 13:c18d82f62d38 | 226 | case 5: |
homero | 13:c18d82f62d38 | 227 | temp = 741 * sqrt(1/(temp-110))-7; |
homero | 13:c18d82f62d38 | 228 | break; |
homero | 13:c18d82f62d38 | 229 | case 6: |
homero | 13:c18d82f62d38 | 230 | temp = 1000 * sqrt(1/(temp-95))-18; |
homero | 13:c18d82f62d38 | 231 | break; |
homero | 13:c18d82f62d38 | 232 | case 7: |
homero | 13:c18d82f62d38 | 233 | temp = 924 * sqrt(1/(temp-115))-12; |
homero | 13:c18d82f62d38 | 234 | break; |
homero | 13:c18d82f62d38 | 235 | } |
re633 | 9:ef0907fda2f1 | 236 | break; |
homero | 13:c18d82f62d38 | 237 | default: |
homero | 15:f7a8989a3cd3 | 238 | temp = 662 * sqrt(1/(temp-152)); |
homero | 13:c18d82f62d38 | 239 | |
re633 | 9:ef0907fda2f1 | 240 | } |
homero | 15:f7a8989a3cd3 | 241 | |
homero | 15:f7a8989a3cd3 | 242 | if(gv_counter25ms == 0) { |
homero | 15:f7a8989a3cd3 | 243 | pc.printf("sen %d dist:%f\n",loopCounter,temp); |
homero | 13:c18d82f62d38 | 244 | } |
homero | 15:f7a8989a3cd3 | 245 | if (temp > 130) { |
re633 | 9:ef0907fda2f1 | 246 | temp = 130; |
re633 | 9:ef0907fda2f1 | 247 | } |
homero | 15:f7a8989a3cd3 | 248 | gv_IRDistances[loopCounter] = temp; |
re633 | 9:ef0907fda2f1 | 249 | |
homero | 13:c18d82f62d38 | 250 | } |
homero | 15:f7a8989a3cd3 | 251 | |
re633 | 9:ef0907fda2f1 | 252 | //reset counter after 1 second (beacon period) |
re633 | 9:ef0907fda2f1 | 253 | gv_counter25ms = mod8(gv_counter25ms + 1,IR_READ_PER_BEAC); |
re633 | 9:ef0907fda2f1 | 254 | } |
re633 | 9:ef0907fda2f1 | 255 | |
homero | 15:f7a8989a3cd3 | 256 | //Get the distance of the ultrsonic sensor in cm |
homero | 15:f7a8989a3cd3 | 257 | void get_ultrasonic_readings() |
homero | 15:f7a8989a3cd3 | 258 | { |
homero | 13:c18d82f62d38 | 259 | float old_dist = distance_ultrasonic_sensor; |
homero | 15:f7a8989a3cd3 | 260 | int static count = 0; |
homero | 13:c18d82f62d38 | 261 | distance_ultrasonic_sensor = usensor.get_dist_mm(); |
homero | 15:f7a8989a3cd3 | 262 | if(count <100) { |
homero | 17:4fa7c9e1b512 | 263 | //pc.printf("US: %.1f, %d\n",distance_ultrasonic_sensor, count); |
homero | 13:c18d82f62d38 | 264 | count ++; |
homero | 15:f7a8989a3cd3 | 265 | } else { |
homero | 13:c18d82f62d38 | 266 | count =0; |
homero | 13:c18d82f62d38 | 267 | } |
homero | 15:f7a8989a3cd3 | 268 | |
homero | 15:f7a8989a3cd3 | 269 | if(distance_ultrasonic_sensor <= 0 || distance_ultrasonic_sensor == 1000) { |
homero | 13:c18d82f62d38 | 270 | distance_ultrasonic_sensor = old_dist; |
homero | 13:c18d82f62d38 | 271 | } |
homero | 13:c18d82f62d38 | 272 | usensor.start(); |
homero | 13:c18d82f62d38 | 273 | } |
homero | 13:c18d82f62d38 | 274 | |
homero | 13:c18d82f62d38 | 275 | //When called the readIRs ticker will be reattached after the specified time. |
homero | 15:f7a8989a3cd3 | 276 | void atTimeout() |
homero | 15:f7a8989a3cd3 | 277 | { |
homero | 13:c18d82f62d38 | 278 | ticker_25ms.attach_us(&readIRs,25000); |
homero | 13:c18d82f62d38 | 279 | } |
homero | 13:c18d82f62d38 | 280 | |
homero | 15:f7a8989a3cd3 | 281 | void atBroadcastTimeout() |
homero | 15:f7a8989a3cd3 | 282 | { |
homero | 13:c18d82f62d38 | 283 | char function; |
homero | 17:4fa7c9e1b512 | 284 | if(robot_id == 1|| robot_id == 9) { |
homero | 13:c18d82f62d38 | 285 | function = 2; |
homero | 17:4fa7c9e1b512 | 286 | } else if(robot_id == 12) { |
homero | 13:c18d82f62d38 | 287 | function = 3; |
homero | 13:c18d82f62d38 | 288 | } |
homero | 15:f7a8989a3cd3 | 289 | |
homero | 13:c18d82f62d38 | 290 | char message[2]; |
homero | 13:c18d82f62d38 | 291 | message[0] = piswarm.get_id()+48; |
homero | 13:c18d82f62d38 | 292 | broadcast_user_rf_command(function,message,1); |
homero | 13:c18d82f62d38 | 293 | broadcasted_count++; |
homero | 13:c18d82f62d38 | 294 | broadcasted_flag = 1; |
homero | 13:c18d82f62d38 | 295 | } |
homero | 17:4fa7c9e1b512 | 296 | |
homero | 17:4fa7c9e1b512 | 297 | void atStopSearchTimeout(){ |
homero | 17:4fa7c9e1b512 | 298 | stop_search_flag = 1; |
homero | 17:4fa7c9e1b512 | 299 | } |
homero | 13:c18d82f62d38 | 300 | //This is a wait function for one |
homero | 13:c18d82f62d38 | 301 | |
re633 | 9:ef0907fda2f1 | 302 | //******************************************************************************************************* |
homero | 15:f7a8989a3cd3 | 303 | //This is where the program code goes. |
homero | 15:f7a8989a3cd3 | 304 | int main() |
homero | 15:f7a8989a3cd3 | 305 | { |
homero | 15:f7a8989a3cd3 | 306 | init(); |
homero | 13:c18d82f62d38 | 307 | robot_id = piswarm.get_id(); |
re633 | 9:ef0907fda2f1 | 308 | //starting point in state 11 |
homero | 15:f7a8989a3cd3 | 309 | //usensor.start(); // get first reading of the ultrasonic sensor required before ticker |
homero | 13:c18d82f62d38 | 310 | //wait_ms(50); |
homero | 15:f7a8989a3cd3 | 311 | |
homero | 15:f7a8989a3cd3 | 312 | |
homero | 13:c18d82f62d38 | 313 | //wait(1); //Wait a second to allow IR array to be filled |
homero | 15:f7a8989a3cd3 | 314 | |
re633 | 9:ef0907fda2f1 | 315 | //Controller is a finite state machine |
homero | 15:f7a8989a3cd3 | 316 | while(1) { |
homero | 15:f7a8989a3cd3 | 317 | |
re633 | 9:ef0907fda2f1 | 318 | //Waiting for signal to begin searching |
homero | 15:f7a8989a3cd3 | 319 | if(gv_state == States::READY_TO_START) { |
homero | 13:c18d82f62d38 | 320 | //pc.printf("%d\n",start_flag); |
homero | 15:f7a8989a3cd3 | 321 | if(start_flag == 1) { |
re633 | 12:118f2b0ed8eb | 322 | //Change state here after recieving a radio command |
homero | 13:c18d82f62d38 | 323 | ticker_25ms.attach_us(&readIRs,25000); |
homero | 15:f7a8989a3cd3 | 324 | |
homero | 15:f7a8989a3cd3 | 325 | if(robot_id == 1) { |
homero | 14:fc406dfff94f | 326 | at_beacon_threshold = 3850; |
homero | 13:c18d82f62d38 | 327 | } |
homero | 15:f7a8989a3cd3 | 328 | |
homero | 15:f7a8989a3cd3 | 329 | else if (robot_id == 9) { |
homero | 17:4fa7c9e1b512 | 330 | at_beacon_threshold = 3925; |
homero | 13:c18d82f62d38 | 331 | } |
homero | 15:f7a8989a3cd3 | 332 | |
homero | 15:f7a8989a3cd3 | 333 | else if (robot_id == 12) { |
homero | 17:4fa7c9e1b512 | 334 | at_beacon_threshold = 3825; |
homero | 17:4fa7c9e1b512 | 335 | r_mot_scaler = 1.03; |
homero | 17:4fa7c9e1b512 | 336 | l_mot_scaler = 0.97; |
homero | 13:c18d82f62d38 | 337 | } |
homero | 15:f7a8989a3cd3 | 338 | |
homero | 15:f7a8989a3cd3 | 339 | else { |
homero | 14:fc406dfff94f | 340 | at_beacon_threshold = 3900; |
homero | 13:c18d82f62d38 | 341 | } |
homero | 15:f7a8989a3cd3 | 342 | |
homero | 15:f7a8989a3cd3 | 343 | usensor.start(); // get first reading of the ultrasonic sensor required before ticker |
homero | 13:c18d82f62d38 | 344 | wait_ms(50); |
homero | 13:c18d82f62d38 | 345 | ticker_ultrasonic50ms.attach_us(&get_ultrasonic_readings,50000); |
homero | 15:f7a8989a3cd3 | 346 | |
homero | 14:fc406dfff94f | 347 | turn_timer.start(); |
homero | 14:fc406dfff94f | 348 | levy_timer.start(); |
homero | 13:c18d82f62d38 | 349 | //pc.printf("why\n"); |
homero | 13:c18d82f62d38 | 350 | changeState(States::SEARCHING_FWD); |
re633 | 10:da62735d6df9 | 351 | } |
homero | 15:f7a8989a3cd3 | 352 | |
homero | 15:f7a8989a3cd3 | 353 | //Searching state |
homero | 15:f7a8989a3cd3 | 354 | } else if (gv_state == States::SEARCHING_FWD || gv_state == States::SEARCHING_TURNING) { |
homero | 15:f7a8989a3cd3 | 355 | |
re633 | 12:118f2b0ed8eb | 356 | //Do something here on receipt of 'function 5' if necessary. |
re633 | 12:118f2b0ed8eb | 357 | //As currently the home beacon will immediately switch on that is not necessary. |
homero | 15:f7a8989a3cd3 | 358 | |
re633 | 12:118f2b0ed8eb | 359 | //Determine if suspected beacon is actually the beacon. |
re633 | 9:ef0907fda2f1 | 360 | //This is done by checking the period between flashes matches the beacon period |
homero | 15:f7a8989a3cd3 | 361 | if(tick_beacon_suspected != 100) { |
re633 | 9:ef0907fda2f1 | 362 | //When the beacon flag is first raised store its value and reset it |
homero | 15:f7a8989a3cd3 | 363 | if(tick_beacon_period_check == 100) { |
re633 | 11:c5094a68283f | 364 | tick_beacon_period_check = tick_beacon_suspected; |
re633 | 11:c5094a68283f | 365 | tick_beacon_suspected = 100; |
homero | 15:f7a8989a3cd3 | 366 | //Check the timing of the latest jump with the last one to see if period matches the Beacon. |
re633 | 9:ef0907fda2f1 | 367 | } else { |
re633 | 9:ef0907fda2f1 | 368 | piswarm.locate(0,1); |
re633 | 11:c5094a68283f | 369 | piswarm.printf("%d %d",tick_beacon_period_check,tick_beacon_suspected); |
re633 | 11:c5094a68283f | 370 | //printf("%d %d *********************************",tick_beacon_period_check,tick_beacon_suspected); |
re633 | 9:ef0907fda2f1 | 371 | //If the two numbers are similar then test will be low. For this to work the period of the ticker and beacon should be the same. |
re633 | 11:c5094a68283f | 372 | int8_t test = (tick_beacon_period_check - tick_beacon_suspected); |
homero | 15:f7a8989a3cd3 | 373 | |
re633 | 9:ef0907fda2f1 | 374 | test = test * test; |
homero | 15:f7a8989a3cd3 | 375 | |
re633 | 9:ef0907fda2f1 | 376 | //if test is low then identify the beacon as the cause of the flags |
homero | 15:f7a8989a3cd3 | 377 | if(test < 2) { |
re633 | 9:ef0907fda2f1 | 378 | //Beacon found change to state 2 |
re633 | 11:c5094a68283f | 379 | g_beaconOn = tick_beacon_period_check; //update the global variable that stores when beacon flashes occur |
homero | 15:f7a8989a3cd3 | 380 | |
homero | 13:c18d82f62d38 | 381 | //wait(2); |
homero | 13:c18d82f62d38 | 382 | changeState(States::MOVING_TO_BEACON); |
re633 | 9:ef0907fda2f1 | 383 | } else { |
re633 | 9:ef0907fda2f1 | 384 | //Reset the flag to try again |
re633 | 11:c5094a68283f | 385 | tick_beacon_period_check = 100; |
re633 | 9:ef0907fda2f1 | 386 | } |
re633 | 9:ef0907fda2f1 | 387 | } |
re633 | 9:ef0907fda2f1 | 388 | } |
homero | 15:f7a8989a3cd3 | 389 | |
homero | 15:f7a8989a3cd3 | 390 | if(gv_state == States::SEARCHING_FWD) { |
homero | 15:f7a8989a3cd3 | 391 | |
homero | 17:4fa7c9e1b512 | 392 | if(stop_search_flag == 1 && back_flag == 0){ |
homero | 17:4fa7c9e1b512 | 393 | piswarm.stop(); |
homero | 17:4fa7c9e1b512 | 394 | piswarm.set_oled_colour(0,255,255); |
homero | 17:4fa7c9e1b512 | 395 | ticker_25ms.detach(); |
homero | 17:4fa7c9e1b512 | 396 | ticker_ultrasonic50ms.detach(); |
homero | 17:4fa7c9e1b512 | 397 | while(back_flag == 0){ |
homero | 17:4fa7c9e1b512 | 398 | |
homero | 17:4fa7c9e1b512 | 399 | } |
homero | 17:4fa7c9e1b512 | 400 | |
homero | 17:4fa7c9e1b512 | 401 | ticker_25ms.attach_us(&readIRs,25000); |
homero | 17:4fa7c9e1b512 | 402 | ticker_ultrasonic50ms.attach_us(&get_ultrasonic_readings,50000); |
homero | 17:4fa7c9e1b512 | 403 | |
homero | 17:4fa7c9e1b512 | 404 | |
homero | 17:4fa7c9e1b512 | 405 | } else if(gv_IRDistances[0] < 100 || gv_IRDistances[1] < 100) { |
re633 | 9:ef0907fda2f1 | 406 | piswarm.stop(); |
homero | 15:f7a8989a3cd3 | 407 | piswarm.cls(); |
re633 | 10:da62735d6df9 | 408 | piswarm.printf("ob R"); |
re633 | 10:da62735d6df9 | 409 | piswarm.play_tune("CC",1); |
homero | 14:fc406dfff94f | 410 | g_obstacle_type = 1; |
homero | 13:c18d82f62d38 | 411 | changeState(States::SEARCHING_TURNING); |
homero | 15:f7a8989a3cd3 | 412 | |
homero | 15:f7a8989a3cd3 | 413 | //Avoid obstacle to the left |
homero | 15:f7a8989a3cd3 | 414 | } else if(gv_IRDistances[6] < 100 || gv_IRDistances[7] < 100) { |
re633 | 9:ef0907fda2f1 | 415 | piswarm.stop(); |
homero | 15:f7a8989a3cd3 | 416 | piswarm.cls(); |
re633 | 10:da62735d6df9 | 417 | piswarm.printf("ob L"); |
re633 | 10:da62735d6df9 | 418 | piswarm.play_tune("CC",1); |
homero | 14:fc406dfff94f | 419 | g_obstacle_type = 2; |
homero | 15:f7a8989a3cd3 | 420 | changeState(States::SEARCHING_TURNING); |
homero | 15:f7a8989a3cd3 | 421 | |
homero | 15:f7a8989a3cd3 | 422 | } else if(distance_ultrasonic_sensor < 70) { |
homero | 13:c18d82f62d38 | 423 | piswarm.stop(); |
homero | 15:f7a8989a3cd3 | 424 | piswarm.cls(); |
homero | 13:c18d82f62d38 | 425 | piswarm.printf("ob F"); |
homero | 13:c18d82f62d38 | 426 | piswarm.play_tune("DD",1); |
homero | 13:c18d82f62d38 | 427 | //wait(0.1); |
homero | 14:fc406dfff94f | 428 | g_obstacle_type = 3; |
homero | 13:c18d82f62d38 | 429 | changeState(States::SEARCHING_TURNING); |
homero | 15:f7a8989a3cd3 | 430 | |
homero | 15:f7a8989a3cd3 | 431 | |
homero | 15:f7a8989a3cd3 | 432 | } else if(distance_ultrasonic_sensor <= 80) { |
homero | 15:f7a8989a3cd3 | 433 | g_obstacle_type = 3; |
homero | 15:f7a8989a3cd3 | 434 | changeState(States::SEARCHING_TURNING); |
homero | 15:f7a8989a3cd3 | 435 | |
homero | 15:f7a8989a3cd3 | 436 | } else if(levy_timer.read_us() > levy_target_time_us) { |
homero | 14:fc406dfff94f | 437 | g_back_count++; |
homero | 14:fc406dfff94f | 438 | set_new_levy_time_flag = 1; |
re633 | 10:da62735d6df9 | 439 | piswarm.play_tune("G",1); |
homero | 13:c18d82f62d38 | 440 | piswarm.set_oled_colour(255,0,0); |
homero | 13:c18d82f62d38 | 441 | changeState(States::SEARCHING_TURNING); |
homero | 15:f7a8989a3cd3 | 442 | } else if(g_back_count >=8) { |
homero | 14:fc406dfff94f | 443 | g_back_count = 0; |
homero | 13:c18d82f62d38 | 444 | piswarm.stop(); |
homero | 13:c18d82f62d38 | 445 | wait_ms(200); |
homero | 13:c18d82f62d38 | 446 | piswarm.left_motor(-0.4*l_mot_scaler); |
homero | 15:f7a8989a3cd3 | 447 | piswarm.right_motor(-0.4*r_mot_scaler); |
homero | 13:c18d82f62d38 | 448 | wait(0.5); |
homero | 13:c18d82f62d38 | 449 | changeState(States::SEARCHING_TURNING); |
homero | 15:f7a8989a3cd3 | 450 | |
homero | 15:f7a8989a3cd3 | 451 | } else if (distance_ultrasonic_sensor <= 800) { |
homero | 17:4fa7c9e1b512 | 452 | consecutive_turn_count = 0; |
homero | 15:f7a8989a3cd3 | 453 | //decrease speed when PiSwarm is getting close to an obstacle |
homero | 15:f7a8989a3cd3 | 454 | float velocity = 0.2; |
homero | 15:f7a8989a3cd3 | 455 | if(distance_ultrasonic_sensor > 100) { |
homero | 15:f7a8989a3cd3 | 456 | velocity = (distance_ultrasonic_sensor*0.00057) + 0.142; |
homero | 15:f7a8989a3cd3 | 457 | } |
homero | 15:f7a8989a3cd3 | 458 | piswarm.left_motor(velocity*l_mot_scaler); |
homero | 15:f7a8989a3cd3 | 459 | piswarm.right_motor(velocity*r_mot_scaler); |
homero | 17:4fa7c9e1b512 | 460 | wait_ms(100); |
homero | 15:f7a8989a3cd3 | 461 | |
homero | 15:f7a8989a3cd3 | 462 | |
homero | 15:f7a8989a3cd3 | 463 | //Otherwise continue moving forward until distance determined by levy algorithm is calculated. |
homero | 15:f7a8989a3cd3 | 464 | |
homero | 15:f7a8989a3cd3 | 465 | |
homero | 13:c18d82f62d38 | 466 | } else { |
homero | 17:4fa7c9e1b512 | 467 | consecutive_turn_count = 0; |
homero | 13:c18d82f62d38 | 468 | piswarm.right_motor(BASE_SPEED*r_mot_scaler); |
homero | 15:f7a8989a3cd3 | 469 | piswarm.left_motor(BASE_SPEED*l_mot_scaler); |
homero | 13:c18d82f62d38 | 470 | } |
homero | 13:c18d82f62d38 | 471 | //wait to get new ultrasound reading |
homero | 15:f7a8989a3cd3 | 472 | //wait_ms(50); |
homero | 15:f7a8989a3cd3 | 473 | |
homero | 15:f7a8989a3cd3 | 474 | |
homero | 15:f7a8989a3cd3 | 475 | } else if(gv_state == States::SEARCHING_TURNING) { |
re633 | 9:ef0907fda2f1 | 476 | piswarm.stop();//Stop the robot. |
re633 | 9:ef0907fda2f1 | 477 | int16_t randomAngle; |
re633 | 9:ef0907fda2f1 | 478 | //If sent here beacuse of obstacle find angle between -180 to -90 and 90 to 180 |
homero | 15:f7a8989a3cd3 | 479 | if(g_obstacle_type == 1) { |
re633 | 10:da62735d6df9 | 480 | randomAngle = rand()%90 - 135; |
homero | 15:f7a8989a3cd3 | 481 | |
homero | 15:f7a8989a3cd3 | 482 | } else if(g_obstacle_type == 2) { |
re633 | 10:da62735d6df9 | 483 | randomAngle = rand()%90 + 45; |
homero | 15:f7a8989a3cd3 | 484 | |
homero | 15:f7a8989a3cd3 | 485 | } else if(g_obstacle_type == 3) { |
homero | 14:fc406dfff94f | 486 | randomAngle = rand()%90 + 45; |
homero | 15:f7a8989a3cd3 | 487 | |
homero | 15:f7a8989a3cd3 | 488 | //Otherwise if here due to levy walk: turn to any random angle |
re633 | 9:ef0907fda2f1 | 489 | } else { |
homero | 15:f7a8989a3cd3 | 490 | randomAngle = rand()%360 - 180; |
re633 | 9:ef0907fda2f1 | 491 | } |
re633 | 9:ef0907fda2f1 | 492 | turnDegrees(randomAngle); //Make the turn |
homero | 14:fc406dfff94f | 493 | g_obstacle_type = 0; |
homero | 13:c18d82f62d38 | 494 | changeState(States::SEARCHING_FWD);//Move back into state 11 |
homero | 15:f7a8989a3cd3 | 495 | |
homero | 16:a32ee9ed15c4 | 496 | } |
homero | 16:a32ee9ed15c4 | 497 | //Beacon found state |
homero | 16:a32ee9ed15c4 | 498 | } else if (gv_state == States::MOVING_TO_BEACON) { |
homero | 16:a32ee9ed15c4 | 499 | |
homero | 16:a32ee9ed15c4 | 500 | //Do something here on receipt of 'function 5' if necessary. |
homero | 16:a32ee9ed15c4 | 501 | //As currently the home beacon will immediately switch on that is not necessary. |
homero | 16:a32ee9ed15c4 | 502 | |
homero | 16:a32ee9ed15c4 | 503 | static int16_t valid_distances[8] = {0}; |
homero | 15:f7a8989a3cd3 | 504 | |
homero | 16:a32ee9ed15c4 | 505 | int16_t maxValue[2] = {0,100}; //Value and sensor position |
homero | 16:a32ee9ed15c4 | 506 | int8_t loopCounter = 0; |
homero | 16:a32ee9ed15c4 | 507 | |
homero | 16:a32ee9ed15c4 | 508 | if(beacon_illuminated_flag == 0) { |
homero | 16:a32ee9ed15c4 | 509 | for(loopCounter = 0; loopCounter < 8; loopCounter++) { |
homero | 16:a32ee9ed15c4 | 510 | valid_distances[loopCounter] = gv_IRDistances[loopCounter]; |
homero | 16:a32ee9ed15c4 | 511 | } |
homero | 16:a32ee9ed15c4 | 512 | } |
re633 | 9:ef0907fda2f1 | 513 | |
homero | 16:a32ee9ed15c4 | 514 | //If beacon visible |
homero | 16:a32ee9ed15c4 | 515 | if(beacon_syncronised_flag == 1) { |
homero | 16:a32ee9ed15c4 | 516 | |
homero | 16:a32ee9ed15c4 | 517 | //Firstly check beacon is still visible |
homero | 16:a32ee9ed15c4 | 518 | beacon_syncronised_flag = 0; |
homero | 16:a32ee9ed15c4 | 519 | //Update array concerning which IRs can see the beacon |
homero | 16:a32ee9ed15c4 | 520 | for(loopCounter = 0; loopCounter<8; loopCounter++) { |
homero | 15:f7a8989a3cd3 | 521 | |
homero | 16:a32ee9ed15c4 | 522 | //Find which sensor has the highest reading |
homero | 16:a32ee9ed15c4 | 523 | if( gv_IRValDiffs[g_beaconOn][loopCounter] > BEACON_SUSPECTED) { |
homero | 16:a32ee9ed15c4 | 524 | if( valid_distances[loopCounter] > 100 && valid_distances[mod8((loopCounter + 1),8)]>100 && valid_distances[mod8((loopCounter - 1),8)]>100) { |
homero | 16:a32ee9ed15c4 | 525 | if(gv_IRVals[g_beaconOn][loopCounter] > maxValue[0]) { |
homero | 16:a32ee9ed15c4 | 526 | maxValue[0] = gv_IRVals[g_beaconOn][loopCounter]; |
homero | 16:a32ee9ed15c4 | 527 | maxValue[1] = loopCounter; |
homero | 16:a32ee9ed15c4 | 528 | beacon_syncronised_flag = 1; //This will remain as one so long as at least on sensor can see beacon |
homero | 16:a32ee9ed15c4 | 529 | } |
homero | 16:a32ee9ed15c4 | 530 | } |
re633 | 9:ef0907fda2f1 | 531 | } |
re633 | 9:ef0907fda2f1 | 532 | } |
homero | 15:f7a8989a3cd3 | 533 | |
homero | 16:a32ee9ed15c4 | 534 | //Only do this if beacon still visible |
homero | 15:f7a8989a3cd3 | 535 | if(beacon_syncronised_flag == 1) { |
homero | 15:f7a8989a3cd3 | 536 | |
homero | 16:a32ee9ed15c4 | 537 | //If the adjacent two sensors are above the threshold too then they can also be marked as illuminated |
homero | 15:f7a8989a3cd3 | 538 | for(loopCounter = 0; loopCounter<8; loopCounter++) { |
re633 | 9:ef0907fda2f1 | 539 | |
homero | 16:a32ee9ed15c4 | 540 | //reset all beacon detected values |
homero | 16:a32ee9ed15c4 | 541 | beacon_detected[loopCounter] = 0; |
homero | 16:a32ee9ed15c4 | 542 | |
homero | 16:a32ee9ed15c4 | 543 | if(abs(maxValue[1] - loopCounter)< 3 || abs(maxValue[1] + 8 - loopCounter)< 3 || abs(maxValue[1] - 8 - loopCounter)< 3) { |
homero | 16:a32ee9ed15c4 | 544 | if(gv_IRValDiffs[g_beaconOn][loopCounter] > BEACON_SUSPECTED) { |
homero | 16:a32ee9ed15c4 | 545 | beacon_detected[loopCounter] = 1; |
re633 | 9:ef0907fda2f1 | 546 | } |
re633 | 9:ef0907fda2f1 | 547 | } |
re633 | 9:ef0907fda2f1 | 548 | } |
homero | 15:f7a8989a3cd3 | 549 | |
homero | 14:fc406dfff94f | 550 | |
homero | 16:a32ee9ed15c4 | 551 | //Update the piswarm LEDS so the ones that can see the beacon are on. |
homero | 16:a32ee9ed15c4 | 552 | piswarm.set_oleds(beacon_detected[0]||beacon_detected[1], |
homero | 16:a32ee9ed15c4 | 553 | beacon_detected[1]||beacon_detected[2], |
homero | 16:a32ee9ed15c4 | 554 | beacon_detected[2], |
homero | 16:a32ee9ed15c4 | 555 | beacon_detected[3], |
homero | 16:a32ee9ed15c4 | 556 | 0, |
homero | 16:a32ee9ed15c4 | 557 | beacon_detected[4], |
homero | 16:a32ee9ed15c4 | 558 | beacon_detected[5], |
homero | 16:a32ee9ed15c4 | 559 | beacon_detected[5]||beacon_detected[6], |
homero | 16:a32ee9ed15c4 | 560 | beacon_detected[6]||beacon_detected[7], |
homero | 16:a32ee9ed15c4 | 561 | beacon_detected[7]||beacon_detected[0]); |
homero | 15:f7a8989a3cd3 | 562 | |
homero | 16:a32ee9ed15c4 | 563 | //If the max IR value is below a threshold then move toward beacon. Else change state |
homero | 16:a32ee9ed15c4 | 564 | if(maxValue[0] < at_beacon_threshold) { |
homero | 16:a32ee9ed15c4 | 565 | |
homero | 16:a32ee9ed15c4 | 566 | //Calculate the heading of Pi-Swarm Relative to beacon |
homero | 16:a32ee9ed15c4 | 567 | calculateNewHeading(); |
homero | 16:a32ee9ed15c4 | 568 | |
homero | 16:a32ee9ed15c4 | 569 | if(g_currentHeading > 5 || g_currentHeading < -5) { |
homero | 16:a32ee9ed15c4 | 570 | turnDegrees(-g_currentHeading); |
re633 | 9:ef0907fda2f1 | 571 | } |
homero | 15:f7a8989a3cd3 | 572 | |
homero | 16:a32ee9ed15c4 | 573 | //If the beacon is not currently on but obstacle detected then do obstacle avoidance |
homero | 16:a32ee9ed15c4 | 574 | int16_t randomAngle; |
homero | 16:a32ee9ed15c4 | 575 | if(beacon_illuminated_flag == 0) { |
homero | 16:a32ee9ed15c4 | 576 | if(gv_IRDistances[0] < 100 || gv_IRDistances[1] < 100) { |
homero | 17:4fa7c9e1b512 | 577 | back_move_timer.reset(); |
homero | 16:a32ee9ed15c4 | 578 | randomAngle = rand()%90 - 135; |
homero | 16:a32ee9ed15c4 | 579 | piswarm.stop(); |
homero | 16:a32ee9ed15c4 | 580 | wait_ms(100); |
homero | 16:a32ee9ed15c4 | 581 | piswarm.backward(0.3); |
homero | 16:a32ee9ed15c4 | 582 | wait_ms(200); |
homero | 16:a32ee9ed15c4 | 583 | turnDegrees(randomAngle); |
homero | 16:a32ee9ed15c4 | 584 | } else if (gv_IRDistances[6] < 100 || gv_IRDistances[7] < 100) { |
homero | 17:4fa7c9e1b512 | 585 | back_move_timer.reset(); |
homero | 16:a32ee9ed15c4 | 586 | randomAngle = rand()%90 + 45; |
homero | 16:a32ee9ed15c4 | 587 | piswarm.stop(); |
homero | 16:a32ee9ed15c4 | 588 | wait_ms(100); |
homero | 16:a32ee9ed15c4 | 589 | piswarm.backward(0.3); |
homero | 16:a32ee9ed15c4 | 590 | wait_ms(200); |
homero | 16:a32ee9ed15c4 | 591 | turnDegrees(randomAngle); |
homero | 16:a32ee9ed15c4 | 592 | } else if ( distance_ultrasonic_sensor < 100) { |
homero | 17:4fa7c9e1b512 | 593 | back_move_timer.reset(); |
homero | 16:a32ee9ed15c4 | 594 | randomAngle = rand()%60 - 30; |
homero | 16:a32ee9ed15c4 | 595 | piswarm.stop(); |
homero | 16:a32ee9ed15c4 | 596 | wait_ms(100); |
homero | 16:a32ee9ed15c4 | 597 | piswarm.backward(0.3); |
homero | 16:a32ee9ed15c4 | 598 | wait_ms(200); |
homero | 16:a32ee9ed15c4 | 599 | turnDegrees(randomAngle); |
homero | 17:4fa7c9e1b512 | 600 | } else if (back_move_timer.read() > 10){ |
homero | 17:4fa7c9e1b512 | 601 | back_move_timer.reset(); |
homero | 17:4fa7c9e1b512 | 602 | randomAngle = rand()%90 + 45; |
homero | 17:4fa7c9e1b512 | 603 | piswarm.stop(); |
homero | 17:4fa7c9e1b512 | 604 | wait_ms(100); |
homero | 17:4fa7c9e1b512 | 605 | piswarm.backward(0.5); |
homero | 17:4fa7c9e1b512 | 606 | wait_ms(200); |
homero | 17:4fa7c9e1b512 | 607 | turnDegrees(randomAngle); |
homero | 15:f7a8989a3cd3 | 608 | } |
homero | 13:c18d82f62d38 | 609 | } |
homero | 16:a32ee9ed15c4 | 610 | piswarm.right_motor(0.3*r_mot_scaler*r_mot_scaler); |
homero | 16:a32ee9ed15c4 | 611 | piswarm.left_motor(0.3*l_mot_scaler*l_mot_scaler); |
homero | 16:a32ee9ed15c4 | 612 | wait_ms(500); |
homero | 16:a32ee9ed15c4 | 613 | //Should be at beacon |
homero | 16:a32ee9ed15c4 | 614 | } else { |
homero | 16:a32ee9ed15c4 | 615 | piswarm.stop(); |
homero | 17:4fa7c9e1b512 | 616 | //homero comment this |
homero | 17:4fa7c9e1b512 | 617 | /* calculateNewHeading(); |
homero | 16:a32ee9ed15c4 | 618 | if(g_currentHeading > 5 || g_currentHeading < -5) { |
homero | 17:4fa7c9e1b512 | 619 | turnDegrees(-g_currentHeading);*/ |
homero | 15:f7a8989a3cd3 | 620 | |
homero | 16:a32ee9ed15c4 | 621 | //If either of these flags is one then the beacon should be the home beacon so change to state 4. |
homero | 16:a32ee9ed15c4 | 622 | if(return_flag == 1 || back_flag == 1) { |
homero | 16:a32ee9ed15c4 | 623 | changeState(States::AT_HOME_BEACON); |
re633 | 12:118f2b0ed8eb | 624 | } else { |
homero | 16:a32ee9ed15c4 | 625 | changeState(States::AT_TARGET_BEACON); |
re633 | 12:118f2b0ed8eb | 626 | } |
re633 | 9:ef0907fda2f1 | 627 | } |
re633 | 9:ef0907fda2f1 | 628 | } |
homero | 16:a32ee9ed15c4 | 629 | //Else need to syncronise with beacon |
homero | 16:a32ee9ed15c4 | 630 | } else { |
homero | 15:f7a8989a3cd3 | 631 | |
homero | 16:a32ee9ed15c4 | 632 | while(beacon_syncronised_flag == 0) { |
homero | 15:f7a8989a3cd3 | 633 | |
homero | 16:a32ee9ed15c4 | 634 | //Sychronise the ticker with the beacon |
homero | 16:a32ee9ed15c4 | 635 | uint8_t testBefore = 0; |
homero | 16:a32ee9ed15c4 | 636 | uint8_t testDuring = 0; |
homero | 16:a32ee9ed15c4 | 637 | uint8_t testAfter = 0; |
homero | 16:a32ee9ed15c4 | 638 | for(loopCounter = 0; loopCounter < 8; loopCounter++) { |
homero | 16:a32ee9ed15c4 | 639 | if (gv_IRValDiffs[mod8((g_beaconOn - 1),IR_READ_PER_BEAC)][loopCounter] > BEACON_SUSPECTED) { |
homero | 16:a32ee9ed15c4 | 640 | testBefore = 1; |
homero | 16:a32ee9ed15c4 | 641 | } |
homero | 16:a32ee9ed15c4 | 642 | if (gv_IRValDiffs[g_beaconOn][loopCounter] > BEACON_SUSPECTED) { |
homero | 16:a32ee9ed15c4 | 643 | testDuring = 1; |
homero | 16:a32ee9ed15c4 | 644 | } |
homero | 16:a32ee9ed15c4 | 645 | if (gv_IRValDiffsTwo[mod8((g_beaconOn + 2),IR_READ_PER_BEAC)][loopCounter] > BEACON_SUSPECTED) { |
homero | 16:a32ee9ed15c4 | 646 | testAfter = 1; |
homero | 16:a32ee9ed15c4 | 647 | } |
homero | 16:a32ee9ed15c4 | 648 | if (gv_IRValDiffsTwo[mod8((g_beaconOn + 2),IR_READ_PER_BEAC)][loopCounter] < -BEACON_SUSPECTED) { |
homero | 16:a32ee9ed15c4 | 649 | testAfter = 2; |
homero | 16:a32ee9ed15c4 | 650 | } |
homero | 16:a32ee9ed15c4 | 651 | } |
homero | 15:f7a8989a3cd3 | 652 | |
homero | 16:a32ee9ed15c4 | 653 | //Firstly if the beacon is not detected by any of the sensors then change state back to search |
homero | 16:a32ee9ed15c4 | 654 | if(testBefore == 0 && testDuring == 0 && testAfter == 0) { |
homero | 16:a32ee9ed15c4 | 655 | changeState(States::SEARCHING_FWD); |
homero | 16:a32ee9ed15c4 | 656 | beacon_syncronised_flag = 1;//to exit while loop |
homero | 16:a32ee9ed15c4 | 657 | |
homero | 16:a32ee9ed15c4 | 658 | //If the tick before g_beaconOn is detecting the change caused by the flash change the value of g_beaconOn |
homero | 16:a32ee9ed15c4 | 659 | } else if(testBefore == 1) { |
homero | 16:a32ee9ed15c4 | 660 | g_beaconOn = g_beaconOn - 1; |
homero | 16:a32ee9ed15c4 | 661 | |
homero | 16:a32ee9ed15c4 | 662 | //If the After Tick does not show a drop in value then it is also occuring within the beacon flash so delay the ticker by 10ms |
homero | 16:a32ee9ed15c4 | 663 | } else if(testBefore == 0 && testDuring == 1 && testAfter == 1) { |
homero | 17:4fa7c9e1b512 | 664 | if(sync_attempt_count > 5){ |
homero | 17:4fa7c9e1b512 | 665 | changeState(States::SEARCHING_FWD); |
homero | 17:4fa7c9e1b512 | 666 | beacon_syncronised_flag = 1;//to exit while loop |
homero | 17:4fa7c9e1b512 | 667 | } |
homero | 17:4fa7c9e1b512 | 668 | else |
homero | 17:4fa7c9e1b512 | 669 | { |
homero | 17:4fa7c9e1b512 | 670 | ticker_25ms.detach(); |
homero | 17:4fa7c9e1b512 | 671 | tickChangeTimeout.attach_us(&atTimeout,7000); |
homero | 17:4fa7c9e1b512 | 672 | wait(1);//Do not delete this wait |
homero | 17:4fa7c9e1b512 | 673 | sync_attempt_count++; |
homero | 17:4fa7c9e1b512 | 674 | } |
homero | 15:f7a8989a3cd3 | 675 | |
homero | 16:a32ee9ed15c4 | 676 | //If successful the set flag |
homero | 16:a32ee9ed15c4 | 677 | } else if (testBefore == 0 && testDuring == 1 && testAfter == 2) { |
homero | 16:a32ee9ed15c4 | 678 | beacon_syncronised_flag = 1; |
homero | 15:f7a8989a3cd3 | 679 | |
homero | 16:a32ee9ed15c4 | 680 | //Error handle. If this happens stop the piswarm |
homero | 16:a32ee9ed15c4 | 681 | } else { |
homero | 16:a32ee9ed15c4 | 682 | piswarm.set_oled_colour(255,255,255); |
homero | 16:a32ee9ed15c4 | 683 | piswarm.set_oleds(1,1,1,1,1,1,1,1,1,1); |
homero | 16:a32ee9ed15c4 | 684 | piswarm.cls(); |
homero | 16:a32ee9ed15c4 | 685 | piswarm.printf("%d %d %d",testBefore, testDuring,testAfter); |
homero | 16:a32ee9ed15c4 | 686 | piswarm.stop(); |
homero | 16:a32ee9ed15c4 | 687 | ticker_25ms.detach(); |
homero | 16:a32ee9ed15c4 | 688 | tickChangeTimeout.attach_us(&atTimeout,10000); |
homero | 16:a32ee9ed15c4 | 689 | wait_ms(500); |
homero | 16:a32ee9ed15c4 | 690 | beacon_syncronised_flag = 1; |
homero | 16:a32ee9ed15c4 | 691 | changeState(States::SEARCHING_FWD); |
re633 | 9:ef0907fda2f1 | 692 | } |
re633 | 9:ef0907fda2f1 | 693 | } |
homero | 16:a32ee9ed15c4 | 694 | } |
homero | 15:f7a8989a3cd3 | 695 | |
homero | 16:a32ee9ed15c4 | 696 | //At target Beacon. |
homero | 16:a32ee9ed15c4 | 697 | //Broadcast target beacon found and wait. |
homero | 16:a32ee9ed15c4 | 698 | } else if (gv_state == States::AT_TARGET_BEACON) { |
homero | 17:4fa7c9e1b512 | 699 | |
homero | 17:4fa7c9e1b512 | 700 | int8_t aligned_to_beacon = 0; |
homero | 16:a32ee9ed15c4 | 701 | piswarm.stop(); |
homero | 16:a32ee9ed15c4 | 702 | piswarm.set_oled_colour(150,255,0); |
homero | 16:a32ee9ed15c4 | 703 | piswarm.set_oleds(1,1,1,1,1,1,1,1,1,1); |
homero | 17:4fa7c9e1b512 | 704 | |
homero | 17:4fa7c9e1b512 | 705 | //to fully aligned when its near to the target beacon |
homero | 17:4fa7c9e1b512 | 706 | calculateNewHeading(); |
homero | 17:4fa7c9e1b512 | 707 | while(aligned_to_beacon == 0){ |
homero | 17:4fa7c9e1b512 | 708 | if(g_currentHeading > 5 || g_currentHeading < -5) { |
homero | 17:4fa7c9e1b512 | 709 | wait(1); |
homero | 17:4fa7c9e1b512 | 710 | turnDegrees(-g_currentHeading); |
homero | 17:4fa7c9e1b512 | 711 | }else{ |
homero | 17:4fa7c9e1b512 | 712 | aligned_to_beacon = 1; |
homero | 17:4fa7c9e1b512 | 713 | } |
homero | 17:4fa7c9e1b512 | 714 | } |
homero | 17:4fa7c9e1b512 | 715 | |
homero | 16:a32ee9ed15c4 | 716 | //Detach tickers before broadcasting and waiting for reply |
homero | 16:a32ee9ed15c4 | 717 | ticker_25ms.detach(); |
homero | 16:a32ee9ed15c4 | 718 | ticker_ultrasonic50ms.detach(); |
homero | 16:a32ee9ed15c4 | 719 | |
homero | 16:a32ee9ed15c4 | 720 | uint8_t const num_to_broadcast = 10; |
homero | 15:f7a8989a3cd3 | 721 | |
homero | 16:a32ee9ed15c4 | 722 | while(back_flag == 0) { |
homero | 16:a32ee9ed15c4 | 723 | if(broadcasted_flag == 1 && broadcasted_count < num_to_broadcast) { |
homero | 16:a32ee9ed15c4 | 724 | broadcastTimeout.attach_us(&atBroadcastTimeout,100000); |
homero | 16:a32ee9ed15c4 | 725 | broadcasted_flag = 0; |
homero | 13:c18d82f62d38 | 726 | } |
re633 | 12:118f2b0ed8eb | 727 | } |
homero | 16:a32ee9ed15c4 | 728 | |
homero | 16:a32ee9ed15c4 | 729 | ticker_25ms.attach_us(&readIRs,25000); |
homero | 16:a32ee9ed15c4 | 730 | ticker_ultrasonic50ms.attach_us(&get_ultrasonic_readings,50000); |
homero | 16:a32ee9ed15c4 | 731 | |
homero | 16:a32ee9ed15c4 | 732 | //Return to beacon search state but now robot is lookling for the home beacon. |
homero | 16:a32ee9ed15c4 | 733 | changeState(States::SEARCHING_FWD); |
homero | 16:a32ee9ed15c4 | 734 | |
homero | 16:a32ee9ed15c4 | 735 | //Back at home area. Stop and wait. |
homero | 16:a32ee9ed15c4 | 736 | } else if (gv_state == States::AT_HOME_BEACON) { |
homero | 16:a32ee9ed15c4 | 737 | piswarm.stop(); |
homero | 16:a32ee9ed15c4 | 738 | piswarm.set_oleds(1,1,1,1,1,1,1,1,1,1); |
homero | 16:a32ee9ed15c4 | 739 | piswarm.play_tune( "T180L8O5EERERCL4EGR<GR",22 ); |
homero | 16:a32ee9ed15c4 | 740 | while(1) { |
homero | 16:a32ee9ed15c4 | 741 | piswarm.set_oled_colour(0,150,0); |
homero | 16:a32ee9ed15c4 | 742 | wait_ms(200); |
homero | 16:a32ee9ed15c4 | 743 | piswarm.set_oled_colour(150,0,0); |
homero | 16:a32ee9ed15c4 | 744 | wait_ms(200); |
homero | 16:a32ee9ed15c4 | 745 | piswarm.set_oled_colour(0,0,150); |
homero | 16:a32ee9ed15c4 | 746 | wait_ms(200); |
homero | 16:a32ee9ed15c4 | 747 | } |
re633 | 9:ef0907fda2f1 | 748 | } |
homero | 15:f7a8989a3cd3 | 749 | } |
jah128 | 7:d03e54d9eb1c | 750 | } |
homero | 16:a32ee9ed15c4 | 751 | |
jah128 | 2:e806b595f9ce | 752 | /*************************************************************************************************************************************** |
jah128 | 2:e806b595f9ce | 753 | * |
jah128 | 4:823174be9a6b | 754 | * Beyond this point, empty code blocks for optional functions is given |
jah128 | 2:e806b595f9ce | 755 | * |
homero | 15:f7a8989a3cd3 | 756 | * These may be left blank if not used, but should not be deleted |
jah128 | 2:e806b595f9ce | 757 | * |
jah128 | 2:e806b595f9ce | 758 | **************************************************************************************************************************************/ |
homero | 15:f7a8989a3cd3 | 759 | |
jah128 | 1:37502eb3b70f | 760 | // Communications |
jah128 | 1:37502eb3b70f | 761 | |
jah128 | 1:37502eb3b70f | 762 | // If using the communication stack (USE_COMMUNICATION_STACK = 1), functionality for handling user RF responses should be added to the following functions |
jah128 | 1:37502eb3b70f | 763 | // If the communication stack is not being used, all radio data is sent to processRawRFData() instead |
jah128 | 1:37502eb3b70f | 764 | |
homero | 15:f7a8989a3cd3 | 765 | void handleUserRFCommand(char sender, char broadcast_message, char request_response, char id, char is_command, char function, char * data, char length) |
homero | 15:f7a8989a3cd3 | 766 | { |
jah128 | 1:37502eb3b70f | 767 | // A 'user' RF Command has been received: write the code here to process it |
jah128 | 1:37502eb3b70f | 768 | // sender = ID of the sender, range 0 to 31 |
jah128 | 1:37502eb3b70f | 769 | // broadcast_message = 1 is message sent to all robots, 0 otherwise |
jah128 | 1:37502eb3b70f | 770 | // request_response = 1 if a response is expected, 0 otherwise |
jah128 | 1:37502eb3b70f | 771 | // id = Message ID, range 0 to 255 |
jah128 | 1:37502eb3b70f | 772 | // is_command = 1 is message is a command, 0 if it is a request. If RF_ALLOW_COMMANDS is not selected, only requests will be sent to this block |
jah128 | 1:37502eb3b70f | 773 | // function = The function identifier. Range 0 to 15 |
jah128 | 1:37502eb3b70f | 774 | // * data = Array containing extra data bytes |
jah128 | 1:37502eb3b70f | 775 | // length = Length of extra data bytes held (range 0 to 57) |
homero | 15:f7a8989a3cd3 | 776 | |
homero | 15:f7a8989a3cd3 | 777 | |
jah128 | 4:823174be9a6b | 778 | //Do something... |
re633 | 12:118f2b0ed8eb | 779 | piswarm.cls(); |
re633 | 12:118f2b0ed8eb | 780 | piswarm.locate(0,0); |
re633 | 12:118f2b0ed8eb | 781 | piswarm.printf("URF:%d",function); |
re633 | 12:118f2b0ed8eb | 782 | if(length > 0) { |
re633 | 12:118f2b0ed8eb | 783 | piswarm.locate(0,1); |
homero | 15:f7a8989a3cd3 | 784 | piswarm.printf("%s",data); |
re633 | 12:118f2b0ed8eb | 785 | } |
re633 | 12:118f2b0ed8eb | 786 | |
homero | 15:f7a8989a3cd3 | 787 | if(function == 1) { |
re633 | 12:118f2b0ed8eb | 788 | start_flag = 1; |
re633 | 12:118f2b0ed8eb | 789 | } |
re633 | 12:118f2b0ed8eb | 790 | |
homero | 15:f7a8989a3cd3 | 791 | if(function == 5) { |
homero | 17:4fa7c9e1b512 | 792 | stopSearchTimeout.attach(&atStopSearchTimeout,6); |
re633 | 12:118f2b0ed8eb | 793 | return_flag = 1; |
re633 | 12:118f2b0ed8eb | 794 | } |
homero | 15:f7a8989a3cd3 | 795 | if(function == 6) { |
re633 | 12:118f2b0ed8eb | 796 | back_flag = 1; |
re633 | 10:da62735d6df9 | 797 | } |
homero | 15:f7a8989a3cd3 | 798 | } |
jah128 | 1:37502eb3b70f | 799 | |
re633 | 12:118f2b0ed8eb | 800 | // This function is used to send the RF message: |
re633 | 12:118f2b0ed8eb | 801 | void broadcast_user_rf_command(int function, char * message, int length) |
re633 | 12:118f2b0ed8eb | 802 | { |
re633 | 12:118f2b0ed8eb | 803 | //This function augments the communications stack |
re633 | 12:118f2b0ed8eb | 804 | //It sends a 'user' RF command to all members (ie target_id = 0) |
re633 | 12:118f2b0ed8eb | 805 | //It sends a 'request', not a 'command', meaning it will still be handled if commands are disabled (RF_ALLOW_COMMANDS set to 0, recommended) |
re633 | 12:118f2b0ed8eb | 806 | //It takes three inputs: |
re633 | 12:118f2b0ed8eb | 807 | // * function (an integer from 0 to 15) |
re633 | 12:118f2b0ed8eb | 808 | // * message (a char array) |
re633 | 12:118f2b0ed8eb | 809 | // * length (length of message in bytes) |
re633 | 12:118f2b0ed8eb | 810 | send_rf_message(0,48+(function % 16),message,length); |
re633 | 12:118f2b0ed8eb | 811 | } |
re633 | 12:118f2b0ed8eb | 812 | |
homero | 15:f7a8989a3cd3 | 813 | void handleUserRFResponse(char sender, char broadcast_message, char success, char id, char is_command, char function, char * data, char length) |
homero | 15:f7a8989a3cd3 | 814 | { |
jah128 | 1:37502eb3b70f | 815 | // A 'user' RF Response has been received: write the code here to process it |
jah128 | 1:37502eb3b70f | 816 | // sender = ID of the sender, range 0 to 31 |
jah128 | 1:37502eb3b70f | 817 | // broadcast_message = 1 is message sent to all robots, 0 otherwise |
jah128 | 1:37502eb3b70f | 818 | // success = 1 if operation successful, 0 otherwise |
jah128 | 1:37502eb3b70f | 819 | // id = Message ID, range 0 to 255 |
jah128 | 1:37502eb3b70f | 820 | // is_command = 1 is message is a command, 0 if it is a request. If RF_ALLOW_COMMANDS is not selected, only requests will be sent to this block |
jah128 | 1:37502eb3b70f | 821 | // function = The function identifier. Range 0 to 15 |
jah128 | 1:37502eb3b70f | 822 | // * data = Array containing extra data bytes |
jah128 | 1:37502eb3b70f | 823 | // length = Length of extra data bytes held (range 0 to 57) |
jah128 | 4:823174be9a6b | 824 | |
homero | 15:f7a8989a3cd3 | 825 | //Do something... |
homero | 15:f7a8989a3cd3 | 826 | } |
jah128 | 1:37502eb3b70f | 827 | |
homero | 15:f7a8989a3cd3 | 828 | void processRawRFData(char * rstring, char cCount) |
homero | 15:f7a8989a3cd3 | 829 | { |
jah128 | 1:37502eb3b70f | 830 | // A raw RF packet has been received: write the code here to process it |
jah128 | 1:37502eb3b70f | 831 | // rstring = The received packet |
jah128 | 1:37502eb3b70f | 832 | // cCount = Packet length |
homero | 15:f7a8989a3cd3 | 833 | |
jah128 | 4:823174be9a6b | 834 | //Do something... |
jah128 | 0:46cd1498a39a | 835 | } |
jah128 | 0:46cd1498a39a | 836 | |
homero | 15:f7a8989a3cd3 | 837 | void switch_pressed() |
homero | 15:f7a8989a3cd3 | 838 | { |
jah128 | 1:37502eb3b70f | 839 | //Switch(es) pressed {1 = Center 2 = Right 4 = Left 8 = Down 16 = Up} |
jah128 | 1:37502eb3b70f | 840 | char switches = piswarm.get_switches(); |
homero | 15:f7a8989a3cd3 | 841 | |
jah128 | 1:37502eb3b70f | 842 | //Do something... |
homero | 13:c18d82f62d38 | 843 | } |