Fork with cleaned up main and brakes class. Implementation or regen, friction and emergency stop now in brakes.cpp and called in main

Dependencies:   mbed millis

Committer:
cdevarakonda
Date:
Mon Jun 20 17:12:18 2022 +0000
Revision:
33:9198b292a8eb
Parent:
23:c25af9a7db8d
Energyy Storage code updated, pins changed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rwcjoliver 0:4788e1df7b55 1 #include <mbed.h>
rwcjoliver 0:4788e1df7b55 2 #include "definitions.h"
rwcjoliver 0:4788e1df7b55 3 #include "challenge.h"
rwcjoliver 0:4788e1df7b55 4 #include "remoteControl.h"
rwcjoliver 0:4788e1df7b55 5 #include "dashboard.h"
rwcjoliver 0:4788e1df7b55 6 #include "motor.h"
rwcjoliver 0:4788e1df7b55 7
rwcjoliver 0:4788e1df7b55 8 ChallengeMode::ChallengeMode(InterruptIn& autoStopTrigger, Dashboard& dashboard, Remote& remote, Motor& motor1) :
rwcjoliver 0:4788e1df7b55 9 _autoStopTrigger(autoStopTrigger), _dashboard(dashboard), _remote(remote), _motor1(motor1) {
rwcjoliver 0:4788e1df7b55 10 // CONSTRUCTOR
rwcjoliver 0:4788e1df7b55 11
rwcjoliver 0:4788e1df7b55 12 // ATTACH AUTOSTOP INTERRUPT
rwcjoliver 0:4788e1df7b55 13 _autoStopTrigger.rise(this, &ChallengeMode::autoStopTriggered);
rwcjoliver 0:4788e1df7b55 14
rwcjoliver 0:4788e1df7b55 15 // FUNCTIONS
rwcjoliver 0:4788e1df7b55 16 regenThrottleOff(); // Make sure regen throttle is off
rwcjoliver 0:4788e1df7b55 17 autoStopOff(); // Make sure auto-stop is off
rwcjoliver 0:4788e1df7b55 18 innovationOff(); // make sure innovation (collision detection mode) is off
rwcjoliver 0:4788e1df7b55 19
rwcjoliver 0:4788e1df7b55 20 // VARIABLES
rwcjoliver 0:4788e1df7b55 21
rwcjoliver 0:4788e1df7b55 22 contactBatt = 1;
rwcjoliver 0:4788e1df7b55 23
rwcjoliver 0:4788e1df7b55 24 // Auto-Stop Challenge
rwcjoliver 0:4788e1df7b55 25 autoStopActive = false; // Flag is auto-stop mode is active
rwcjoliver 0:4788e1df7b55 26 autoStopInProgress = false; // Flag if auto-stop track-side sensor has been detected and auto-stop is in progress
rwcjoliver 0:4788e1df7b55 27 autoStopCruiseSpeed = 0; // Speed of loco at time of auto-stop trackside sensor triggering so loco can maintain this speed without operator input
rwcjoliver 0:4788e1df7b55 28 autoStopThrottle = 0; // Throttle rate applied at the time of triggering autostop
rwcjoliver 0:4788e1df7b55 29 targetDistance = 25.00f; // How far in meters to bring the loco to a stop
rwcjoliver 0:4788e1df7b55 30 remainingDistance = targetDistance; // How far the loco has left to go before reaching target distance
rwcjoliver 0:4788e1df7b55 31 decelerationGradient = 0; // Gradient of y=mx+c linear speed-distance curve that is used in this auto-stop version
rwcjoliver 0:4788e1df7b55 32 requiredSpeed = 0; // How fast the loco should be going according to y=mx+c line
rwcjoliver 0:4788e1df7b55 33
rwcjoliver 0:4788e1df7b55 34 // Innovation Challenge
rwcjoliver 0:4788e1df7b55 35 innovationDistanceLimit = 1500; // Stopping distance in mm from IR sensors
rwcjoliver 0:4788e1df7b55 36 stopLoco = false; // Flag to stop the loco when obstacle has been detected
rwcjoliver 0:4788e1df7b55 37
rwcjoliver 0:4788e1df7b55 38 // IR Output voltages at various distances (for calibration purposes)
rwcjoliver 0:4788e1df7b55 39 voltageAt5500 = 0;
rwcjoliver 0:4788e1df7b55 40 voltageAt5000 = 0;
rwcjoliver 0:4788e1df7b55 41 voltageAt4500 = 0;
rwcjoliver 0:4788e1df7b55 42 voltageAt4000 = 0;
rwcjoliver 0:4788e1df7b55 43 voltageAt3500 = 0;
rwcjoliver 0:4788e1df7b55 44 voltageAt3000 = 0;
rwcjoliver 0:4788e1df7b55 45 voltageAt2500 = 0;
rwcjoliver 0:4788e1df7b55 46 voltageAt2000 = 0;
rwcjoliver 0:4788e1df7b55 47 voltageAt1500 = 0;
rwcjoliver 0:4788e1df7b55 48 voltageAt1000 = 2.2f;
rwcjoliver 0:4788e1df7b55 49 voltageAt500 = 3.0f;
rwcjoliver 0:4788e1df7b55 50
rwcjoliver 0:4788e1df7b55 51 } // CONSTRUCTOR
rwcjoliver 0:4788e1df7b55 52
rwcjoliver 0:4788e1df7b55 53 void ChallengeMode::regenThrottleOn() {
rwcjoliver 0:4788e1df7b55 54 // OPEN THE BATTERY CONTACTOR SO POWER IS DELIVERED BY SUPERCAPS
rwcjoliver 0:4788e1df7b55 55
rwcjoliver 0:4788e1df7b55 56 contactCapCharge = 0; // Open supercap charging contactor to prevent charging
rwcjoliver 0:4788e1df7b55 57
rwcjoliver 0:4788e1df7b55 58 contactBatt = 0; // Open battery contactor so all power comes from supercaps
rwcjoliver 0:4788e1df7b55 59 regenThrottleActive = true; // Flag to indicate that regen throttling is on
rwcjoliver 0:4788e1df7b55 60 pc.printf("Regen Throttle On\r\n");
rwcjoliver 0:4788e1df7b55 61 }
rwcjoliver 0:4788e1df7b55 62
rwcjoliver 0:4788e1df7b55 63 void ChallengeMode::regenThrottleOff() {
rwcjoliver 0:4788e1df7b55 64 // CLOSE THE BATTERY CONTACTOR
rwcjoliver 1:ba85dae98035 65 if (regenBrakingActive == false) { // If regen braking is not active and using the supercaps, allow capacitor to pre-charge from batteries
rwcjoliver 1:ba85dae98035 66 contactCapCharge = 1; // Close the supercap charging contactor
rwcjoliver 1:ba85dae98035 67 }
rwcjoliver 0:4788e1df7b55 68
rwcjoliver 0:4788e1df7b55 69 contactBatt = 1; // Close the battery contactor so power comes from batteries
rwcjoliver 0:4788e1df7b55 70 regenThrottleActive = false; // Flag to indicate that regen throttling is off
rwcjoliver 0:4788e1df7b55 71 pc.printf("Regen Throttle Off\r\n");
rwcjoliver 0:4788e1df7b55 72 }
rwcjoliver 0:4788e1df7b55 73
rwcjoliver 0:4788e1df7b55 74 bool ChallengeMode::regenBrakingOn() {
rwcjoliver 0:4788e1df7b55 75 // TURN ON REGEN BRAKING
rwcjoliver 1:ba85dae98035 76 // if (superCapVoltage == 0) { // If super caps are not full
rwcjoliver 1:ba85dae98035 77 // contactCapCharge = 0; // Open the super cap pre-cahrging contactor
rwcjoliver 1:ba85dae98035 78 // contactBatt = 0; // Open battery contactor so all power comes from supercaps
rwcjoliver 0:4788e1df7b55 79 regenBrakingActive = true; // Flag to indicate that regen throttling is on
rwcjoliver 0:4788e1df7b55 80 pc.printf("Regen Braking On\r\n");
rwcjoliver 0:4788e1df7b55 81 return 1; // Return 1 if regen braking switched on
rwcjoliver 1:ba85dae98035 82 // }
rwcjoliver 1:ba85dae98035 83 // else {
rwcjoliver 1:ba85dae98035 84 // return 0; // Return 0 is regen braking didnt turn on due to full supercaps
rwcjoliver 1:ba85dae98035 85 // }
rwcjoliver 0:4788e1df7b55 86 }
rwcjoliver 0:4788e1df7b55 87
rwcjoliver 0:4788e1df7b55 88 void ChallengeMode::regenBrakingOff() {
rwcjoliver 0:4788e1df7b55 89 // TURN OFF REGEN BRAKING
rwcjoliver 0:4788e1df7b55 90 if (regenThrottleActive == false) { // If regen throttle is not active and using the supercaps, allow capacitor to pre-charge from batteries
rwcjoliver 0:4788e1df7b55 91 contactCapCharge = 1; // Close the supercap pre-charge contactor
rwcjoliver 0:4788e1df7b55 92 }
rwcjoliver 0:4788e1df7b55 93 regenBrakingActive = false; // Flag that regen braking is off
rwcjoliver 0:4788e1df7b55 94 contactBatt = 1; // Close battery contactor so all power comes from supercaps
rwcjoliver 0:4788e1df7b55 95 pc.printf("Regen Braking Off\r\n");
rwcjoliver 0:4788e1df7b55 96 }
rwcjoliver 0:4788e1df7b55 97
rwcjoliver 0:4788e1df7b55 98 void ChallengeMode::autoStopOn() {
rwcjoliver 0:4788e1df7b55 99 // TURN ON AUTOSTOP MODE
rwcjoliver 0:4788e1df7b55 100 autoStopActive = true; // Flag that auto-stop mode is on
rwcjoliver 0:4788e1df7b55 101 pc.printf("Auto-Stop On\r\n");
rwcjoliver 0:4788e1df7b55 102 }
rwcjoliver 0:4788e1df7b55 103
rwcjoliver 0:4788e1df7b55 104 void ChallengeMode::autoStopTriggered() {
rwcjoliver 0:4788e1df7b55 105 // INTERRUPT FUNCTION CALLED WHEN TRACK-SIDE TRIGGER HAS BEEN DETECTED
rwcjoliver 0:4788e1df7b55 106 if (autoStopActive == true && autoStopInProgress == false) { // If auto-stop mode is on and signal has not yet been detected
rwcjoliver 0:4788e1df7b55 107 autoStopInProgress = true; // Flag that auto-stop is in progress and fully autonomous
rwcjoliver 0:4788e1df7b55 108 autoStopCruiseSpeed = _dashboard.currentSpeed; // Set the speed the loco was going at the point of triggering
rwcjoliver 0:4788e1df7b55 109 autoStopThrottle = _remote.throttle;
jamesmcildowietfl 23:c25af9a7db8d 110 whistleValve32 = 1;
rwcjoliver 0:4788e1df7b55 111 _dashboard.currentDistance = 0.00f; // Reset the distance-travelled counter to 0
jamesmcildowietfl 15:4976d145fbd9 112 // timeToReachTarget = targetDistance / (autoStopCruiseSpeed * 1000 / 3600); // Time(s) = Distance(m) / Speed(converted to m/s)
rwcjoliver 0:4788e1df7b55 113 decelerationGradient = (autoStopCruiseSpeed - 1) / (targetDistance - 1); // m = y / x → to get to 1kph at 24m, leaving ~ 4 seconds to get to target of 25m
rwcjoliver 0:4788e1df7b55 114 pc.printf("Auto-Stop Triggered\r\n");
rwcjoliver 0:4788e1df7b55 115 }
rwcjoliver 0:4788e1df7b55 116 }
rwcjoliver 0:4788e1df7b55 117
rwcjoliver 0:4788e1df7b55 118 void ChallengeMode::autoStopControl() {
rwcjoliver 0:4788e1df7b55 119 // FUNCTION TO MANAGE THE LOCO THROTTLE AND BRAKING WHEN AUTO-STOPPING
rwcjoliver 0:4788e1df7b55 120 remainingDistance = targetDistance - _dashboard.currentDistance; // Calculate remaining distance from target distance
jamesmcildowietfl 15:4976d145fbd9 121 // timeToReachTarget = int(_dashboard.currentSpeed) > 0 ? remainingDistance / _dashboard.currentSpeed : 999;
rwcjoliver 0:4788e1df7b55 122
rwcjoliver 0:4788e1df7b55 123 // FOLLOWING DECELERATION GRADIENT
rwcjoliver 0:4788e1df7b55 124
rwcjoliver 0:4788e1df7b55 125 if (remainingDistance > 2.0f) { // IF OVER 3M FROM TARGET, CONTROL SPEED (1m + 2m sensor to nose of train)
rwcjoliver 0:4788e1df7b55 126
rwcjoliver 0:4788e1df7b55 127 _motor1.throttle(0.3f); // Apply 30% throttle
rwcjoliver 0:4788e1df7b55 128 //requiredSpeed = (decelerationGradient * _dashboard.currentDistance) + autoStopCruiseSpeed; // (y = mx + c)
rwcjoliver 0:4788e1df7b55 129 //
rwcjoliver 0:4788e1df7b55 130 // if (_dashboard.currentSpeed < requiredSpeed) { // If train is below the speed it should be, apply 30% throttle and no braking
rwcjoliver 0:4788e1df7b55 131 //// _motor1.throttle(0.3f);
rwcjoliver 0:4788e1df7b55 132 //// _motor2.throttle(0.1f);
rwcjoliver 0:4788e1df7b55 133 //// _motor1.brake(0.0f);
rwcjoliver 0:4788e1df7b55 134 //// _motor2.brake(0.0f);
rwcjoliver 0:4788e1df7b55 135 //
rwcjoliver 0:4788e1df7b55 136 // brakeValve32 = 1;
rwcjoliver 0:4788e1df7b55 137 // }
rwcjoliver 0:4788e1df7b55 138 // else { // If loco is going faster than is should be
rwcjoliver 0:4788e1df7b55 139 // int speedDifference = _dashboard.currentSpeed - requiredSpeed; // Work out how much faster it is going and apply a proportional amount of motor braking
rwcjoliver 0:4788e1df7b55 140 //
rwcjoliver 0:4788e1df7b55 141 // _motor1.throttle(0.0f); // Turn off throttle
rwcjoliver 0:4788e1df7b55 142 //// _motor2.throttle(0.0f);
rwcjoliver 0:4788e1df7b55 143 //
rwcjoliver 0:4788e1df7b55 144 // brakeValve32 = 0;
rwcjoliver 0:4788e1df7b55 145 // if (pressureSwitch1.read() == 0) {
rwcjoliver 0:4788e1df7b55 146 // brakeValve22 = 0;
rwcjoliver 0:4788e1df7b55 147 // pc.printf("Pressure 1 Reached");
rwcjoliver 0:4788e1df7b55 148 // }
rwcjoliver 0:4788e1df7b55 149 //
rwcjoliver 0:4788e1df7b55 150 // switch (speedDifference) { // MOTOR BRAKING
rwcjoliver 0:4788e1df7b55 151 // case 1:
rwcjoliver 0:4788e1df7b55 152 // _motor1.brake(0.1f);
rwcjoliver 0:4788e1df7b55 153 //// _motor2.brake(0.1f);
rwcjoliver 0:4788e1df7b55 154 // break;
rwcjoliver 0:4788e1df7b55 155 //
rwcjoliver 0:4788e1df7b55 156 // case 2:
rwcjoliver 0:4788e1df7b55 157 // _motor1.brake(0.2f);
rwcjoliver 0:4788e1df7b55 158 //// _motor2.brake(0.2f);
rwcjoliver 0:4788e1df7b55 159 // break;
rwcjoliver 0:4788e1df7b55 160 //
rwcjoliver 0:4788e1df7b55 161 // case 3:
rwcjoliver 0:4788e1df7b55 162 // _motor1.brake(0.3f);
rwcjoliver 0:4788e1df7b55 163 //// _motor2.brake(0.3f);
rwcjoliver 0:4788e1df7b55 164 // break;
rwcjoliver 0:4788e1df7b55 165 //
rwcjoliver 0:4788e1df7b55 166 // case 4:
rwcjoliver 0:4788e1df7b55 167 // _motor1.brake(0.4f);
rwcjoliver 0:4788e1df7b55 168 //// _motor2.brake(0.4f);
rwcjoliver 0:4788e1df7b55 169 // break;
rwcjoliver 0:4788e1df7b55 170 //
rwcjoliver 0:4788e1df7b55 171 // case 5:
rwcjoliver 0:4788e1df7b55 172 // _motor1.brake(0.5f);
rwcjoliver 0:4788e1df7b55 173 //// _motor2.brake(0.5f);
rwcjoliver 0:4788e1df7b55 174 // break;
rwcjoliver 0:4788e1df7b55 175 //
rwcjoliver 0:4788e1df7b55 176 // case 6:
rwcjoliver 0:4788e1df7b55 177 // _motor1.brake(0.6f);
rwcjoliver 0:4788e1df7b55 178 //// _motor2.brake(0.6f);
rwcjoliver 0:4788e1df7b55 179 // break;
rwcjoliver 0:4788e1df7b55 180 //
rwcjoliver 0:4788e1df7b55 181 // case 7:
rwcjoliver 0:4788e1df7b55 182 // _motor1.brake(0.7f);
rwcjoliver 0:4788e1df7b55 183 //// _motor2.brake(0.7f);
rwcjoliver 0:4788e1df7b55 184 // break;
rwcjoliver 0:4788e1df7b55 185 //
rwcjoliver 0:4788e1df7b55 186 // case 8:
rwcjoliver 0:4788e1df7b55 187 // _motor1.brake(0.8f);
rwcjoliver 0:4788e1df7b55 188 //// _motor2.brake(0.8f);
rwcjoliver 0:4788e1df7b55 189 // break;
rwcjoliver 0:4788e1df7b55 190 //
rwcjoliver 0:4788e1df7b55 191 // case 9:
rwcjoliver 0:4788e1df7b55 192 // _motor1.brake(0.9f);
rwcjoliver 0:4788e1df7b55 193 //// _motor2.brake(0.9f);
rwcjoliver 0:4788e1df7b55 194 // break;
rwcjoliver 0:4788e1df7b55 195 //
rwcjoliver 0:4788e1df7b55 196 // default:
rwcjoliver 0:4788e1df7b55 197 // _motor1.brake(1.0f);
rwcjoliver 0:4788e1df7b55 198 //// _motor2.brake(1.0f);
rwcjoliver 0:4788e1df7b55 199 // break;
rwcjoliver 0:4788e1df7b55 200 // } // switch
rwcjoliver 0:4788e1df7b55 201 // }// else
rwcjoliver 0:4788e1df7b55 202 }// if
rwcjoliver 0:4788e1df7b55 203 else { // IF REACHED STOPPING TARGET AREA
rwcjoliver 0:4788e1df7b55 204 rtc_Trigger = 0; // APPLY EMERGENCY BRAKES
rwcjoliver 0:4788e1df7b55 205 // if (remainingDistance > 0.2f) { // If more than 20cm to go, stay at 1kph
rwcjoliver 0:4788e1df7b55 206 //
rwcjoliver 0:4788e1df7b55 207 // }
rwcjoliver 0:4788e1df7b55 208 // else { // If less than 20cm from target apply full mechanical brakes and turn off throttle
rwcjoliver 0:4788e1df7b55 209 // _motor1.throttle(0.0f);
rwcjoliver 0:4788e1df7b55 210 //// _motor2.throttle(0.0f);
rwcjoliver 0:4788e1df7b55 211 //
rwcjoliver 0:4788e1df7b55 212 // // MECHANICAL BRAKES
rwcjoliver 0:4788e1df7b55 213 // brakeValve32 = 1;
rwcjoliver 0:4788e1df7b55 214 // if (pressureSwitch3 == 0) {
rwcjoliver 0:4788e1df7b55 215 // brakeValve22 = 0;
rwcjoliver 0:4788e1df7b55 216 // }
rwcjoliver 0:4788e1df7b55 217 // else {
rwcjoliver 0:4788e1df7b55 218 // brakeValve22 = 1;
rwcjoliver 0:4788e1df7b55 219 // }
rwcjoliver 0:4788e1df7b55 220 // }
rwcjoliver 0:4788e1df7b55 221 }
rwcjoliver 0:4788e1df7b55 222
rwcjoliver 0:4788e1df7b55 223 pc.printf("remainingDistance %f\r\n", remainingDistance);
rwcjoliver 0:4788e1df7b55 224 // pc.printf("timeToReachTarget %f\r\n", timeToReachTarget);
rwcjoliver 0:4788e1df7b55 225 }
rwcjoliver 0:4788e1df7b55 226
rwcjoliver 0:4788e1df7b55 227 void ChallengeMode::autoStopOff() {
rwcjoliver 0:4788e1df7b55 228 // TURN OFF AUTOSTOP MODE
rwcjoliver 0:4788e1df7b55 229 autoStopActive = false; // CLEAR AUTOSTOP MODE FLAG
rwcjoliver 0:4788e1df7b55 230 autoStopInProgress = false; // CLEAR AUTOSTOPPING
rwcjoliver 0:4788e1df7b55 231 rtc_Trigger = 1;
rwcjoliver 0:4788e1df7b55 232 pc.printf("Auto-Stop Off\r\n");
rwcjoliver 0:4788e1df7b55 233 }
rwcjoliver 0:4788e1df7b55 234
rwcjoliver 0:4788e1df7b55 235 void ChallengeMode::innovationOn() {
rwcjoliver 0:4788e1df7b55 236 // TURN ON INNOVATION MODE
rwcjoliver 0:4788e1df7b55 237 innovationActive = true;
rwcjoliver 0:4788e1df7b55 238 stopLoco = false;
rwcjoliver 0:4788e1df7b55 239 rtc_Trigger = 1;
rwcjoliver 0:4788e1df7b55 240 _motor1.setSpeedMode(1); // SET MOTORS TO INCH FORWARD MODE
rwcjoliver 0:4788e1df7b55 241 // _motor2.setSpeedMode(1);
rwcjoliver 0:4788e1df7b55 242 pc.printf("Innovation On\r\n");
rwcjoliver 0:4788e1df7b55 243 }
rwcjoliver 0:4788e1df7b55 244
rwcjoliver 0:4788e1df7b55 245 void ChallengeMode::innovationOff() {
rwcjoliver 0:4788e1df7b55 246 // TURN OFF INNOVATION MODE
rwcjoliver 0:4788e1df7b55 247 innovationActive = false;
rwcjoliver 0:4788e1df7b55 248 stopLoco = false;
rwcjoliver 0:4788e1df7b55 249 rtc_Trigger = 1;
rwcjoliver 0:4788e1df7b55 250 _motor1.setSpeedMode(3); // SET MOTOR SPEED LIMIT TO MAX
rwcjoliver 0:4788e1df7b55 251 pc.printf("Innovation Off\r\n");
rwcjoliver 0:4788e1df7b55 252 }
rwcjoliver 0:4788e1df7b55 253
rwcjoliver 0:4788e1df7b55 254 int ChallengeMode::innovationControl(int requestedThrottle) {
rwcjoliver 0:4788e1df7b55 255 // CONTROL THE TRAIN THROTTLING AND BRAKING
rwcjoliver 0:4788e1df7b55 256
rwcjoliver 0:4788e1df7b55 257 int count = 0;
rwcjoliver 0:4788e1df7b55 258
rwcjoliver 0:4788e1df7b55 259 if (irSensor_1 > voltageAt1000 / 3.3f) { count++; }
rwcjoliver 0:4788e1df7b55 260 if (irSensor_2 > voltageAt1000 / 3.3f) { count++; }
rwcjoliver 0:4788e1df7b55 261 if (irSensor_3 > voltageAt1000 / 3.3f ) { count++; }
rwcjoliver 0:4788e1df7b55 262
rwcjoliver 0:4788e1df7b55 263 if (count >= 2) {
rwcjoliver 0:4788e1df7b55 264 stopLoco = true;
rwcjoliver 0:4788e1df7b55 265 }
rwcjoliver 0:4788e1df7b55 266
rwcjoliver 0:4788e1df7b55 267
rwcjoliver 0:4788e1df7b55 268 if (stopLoco == true) { // IF SENSORS INDICATE TRAIN SHOULD STOP
rwcjoliver 0:4788e1df7b55 269
rwcjoliver 0:4788e1df7b55 270 // // APPLY MECHANICAL BRAKES
jamesmcildowietfl 15:4976d145fbd9 271 // brakeValve32 = 0;
jamesmcildowietfl 15:4976d145fbd9 272 // brakeValve22 = 1;
rwcjoliver 0:4788e1df7b55 273
rwcjoliver 0:4788e1df7b55 274 // APPLY E-BRAKE
rwcjoliver 0:4788e1df7b55 275 rtc_Trigger = 0;
rwcjoliver 0:4788e1df7b55 276
rwcjoliver 0:4788e1df7b55 277 pc.printf("Obstacle Detected\r\n");
rwcjoliver 0:4788e1df7b55 278
rwcjoliver 0:4788e1df7b55 279 return 0; // RETURN THROTTLE = 0 TO INDICATE TRAIN SHOULD STOP
rwcjoliver 0:4788e1df7b55 280 }
rwcjoliver 0:4788e1df7b55 281 else {
rwcjoliver 0:4788e1df7b55 282 return requestedThrottle; // OTHERWISE THROTTLE = USER REQUEST
rwcjoliver 0:4788e1df7b55 283 }
rwcjoliver 0:4788e1df7b55 284 }