Railway Challenge
/
challenge
Uncommenting of part that allow supercaps to charge up from the batteries
challenge.cpp@15:4976d145fbd9, 2022-04-27 (annotated)
- Committer:
- jamesmcildowietfl
- Date:
- Wed Apr 27 20:28:28 2022 +0000
- Revision:
- 15:4976d145fbd9
- Parent:
- 13:a9793222af20
- Child:
- 18:d28d458824d4
Re-commented old autostop code, as it wouldn't let me compile on site due to undeclared variable. ; ; Added Chai's code for the braking when at 0 speed & 0 throttle, moved to a different area.; ; Commented lines for park brake, needs testing.
Who changed what in which revision?
User | Revision | Line number | New 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 | 15:4976d145fbd9 | 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 | } |