SHOW:
|
|
- or go back to the newest paste.
| 1 | --Automated Train Control v1 by Gazer29 | |
| 2 | --Uses Automation mod version: Beta 1 | |
| 3 | ||
| 4 | local component = require("component")
| |
| 5 | local term = require ("term")
| |
| 6 | local entity = component.entity_link.getAPI("immersiverailroading:locomotivediesel")
| |
| 7 | local thread = require("thread")
| |
| 8 | require("PIDController")
| |
| 9 | local serial = require("serialization")
| |
| 10 | local fs = require("filesystem")
| |
| 11 | ||
| 12 | local RUNNING = true | |
| 13 | local MODE = 0 -- 0 SET, 1 RAMP, | |
| 14 | local sleep = 1 -- seconds | |
| 15 | local display = false | |
| 16 | local iteration = 1 | |
| 17 | local timer = nil | |
| 18 | ||
| 19 | local CONFIG_FILE = "/home/Waypoints.cfg" | |
| 20 | local CONFIG = nil | |
| 21 | local DEFAULT_CONFIG = {
| |
| 22 | array = {
| |
| 23 | {
| |
| 24 | waypoint = "Station 1", | |
| 25 | speed = 0, | |
| 26 | radius = 10, | |
| 27 | x = 1180, | |
| 28 | z = -333, | |
| 29 | mode = "wait", | |
| 30 | data = 20 | |
| 31 | }, | |
| 32 | {
| |
| 33 | waypoint = "Waypoint 2", | |
| 34 | speed = 10, | |
| 35 | radius = 10, | |
| 36 | x = 1180, | |
| 37 | z = -333, | |
| 38 | mode = nil, | |
| 39 | data = nil | |
| 40 | }, | |
| 41 | {
| |
| 42 | waypoint = "Waypoint 3", | |
| 43 | speed = 5, | |
| 44 | radius = 10, | |
| 45 | x = 1136, | |
| 46 | z = -333, | |
| 47 | mode = nil, | |
| 48 | data = nil | |
| 49 | } | |
| 50 | } | |
| 51 | } | |
| 52 | ||
| 53 | local function saveConfig(file, cfg) -- Adapted from HandieAndy's code | |
| 54 | local f = io.open(file, "w") | |
| 55 | if f == nil then error("Couldn't open " .. file .. " to write config.") end
| |
| 56 | f:write(serial.serialize(cfg, 100000)) | |
| 57 | f:close() | |
| 58 | print("Saved to file: ", CONFIG_FILE)
| |
| 59 | end | |
| 60 | ||
| 61 | local function loadConfig() -- Adapted from HandieAndy's code | |
| 62 | local f = io.open(CONFIG_FILE, "r") | |
| 63 | if f == nil then | |
| 64 | print("Could not open " .. CONFIG_FILE .. ".")
| |
| 65 | print("Loading default config")
| |
| 66 | saveConfig(CONFIG_FILE, DEFAULT_CONFIG) | |
| 67 | return DEFAULT_CONFIG | |
| 68 | else | |
| 69 | local config = serial.unserialize(f:read("*a"))
| |
| 70 | f:close() | |
| 71 | return config | |
| 72 | end | |
| 73 | end | |
| 74 | ||
| 75 | function helpdisplay() | |
| 76 | print("AutomaticTrainControl v1")
| |
| 77 | print("Commands:")
| |
| 78 | print("'Any number' - Changes set speed")
| |
| 79 | print("'+' - Displays additional information")
| |
| 80 | print("'-' - Hides additional information")
| |
| 81 | print("'ramp' - Changes to ramp mode, requires further input")
| |
| 82 | print("'idle' - Pauses train control")
| |
| 83 | print("'save' - Saves config file")
| |
| 84 | print("'stop' - Ends program")
| |
| 85 | end | |
| 86 | ||
| 87 | function GetTrainPos() | |
| 88 | positions = entity.getLocation() | |
| 89 | xpos = positions.getX() | |
| 90 | ypos = positions.getY() | |
| 91 | zpos = positions.getZ() | |
| 92 | print("X: ", xpos)
| |
| 93 | print("Z: ", zpos)
| |
| 94 | end | |
| 95 | ||
| 96 | function GetTrainSpeed() | |
| 97 | speed = entity.getCurrentSpeed() | |
| 98 | return speed | |
| 99 | end | |
| 100 | ||
| 101 | function setThrottle(x) | |
| 102 | if 0 >= x then x = 0 end | |
| 103 | if 1 <= x then x = 1 end | |
| 104 | entity.setThrottleLevel(x) | |
| 105 | if display then | |
| 106 | print("Throttle: ", x)
| |
| 107 | end | |
| 108 | end | |
| 109 | ||
| 110 | function setBrake(x) | |
| 111 | if 0 >= x then x = 0 end | |
| 112 | if 1 <= x then x = 1 end | |
| 113 | entity.setAirBrakeLevel(x) | |
| 114 | if display then | |
| 115 | print("Brake: ", x)
| |
| 116 | end | |
| 117 | end | |
| 118 | ||
| 119 | local function reads() | |
| 120 | while RUNNING do | |
| 121 | user = nil | |
| 122 | user = io.read() | |
| 123 | if user == "stop" then | |
| 124 | print("STOPPING...")
| |
| 125 | os.sleep(1) | |
| 126 | stop() | |
| 127 | end | |
| 128 | if user == "." then | |
| 129 | term.clear() | |
| 130 | end | |
| 131 | if user == "idle" then | |
| 132 | MODE = 2 | |
| 133 | end | |
| 134 | if user == "ramp" then | |
| 135 | print("Start Speed (type 'x' for current setpoint):")
| |
| 136 | c = io.read() | |
| 137 | if c == "x" then | |
| 138 | c = setpoint | |
| 139 | end | |
| 140 | print("End Speed:")
| |
| 141 | rampStart = c | |
| 142 | c = io.read() | |
| 143 | print("Ramp Time (seconds):")
| |
| 144 | rampEnd = c | |
| 145 | c = io.read() | |
| 146 | rampTime = c | |
| 147 | rampDiff = rampEnd - rampStart | |
| 148 | rampCount = math.floor(rampTime/sleep) | |
| 149 | rampInc = rampDiff / rampCount | |
| 150 | PID:SetPoint(rampStart) | |
| 151 | setpoint = rampStart | |
| 152 | MODE = 1 | |
| 153 | end | |
| 154 | if user == "+" then | |
| 155 | display = true | |
| 156 | term.clear() | |
| 157 | end | |
| 158 | if user == "save" then | |
| 159 | saveConfig(CONFIG_FILE, CONFIG) | |
| 160 | end | |
| 161 | if user == "-" then | |
| 162 | display = false | |
| 163 | term.clear() | |
| 164 | os.sleep(1) | |
| 165 | helpdisplay() | |
| 166 | end | |
| 167 | if nil ~= tonumber(user) then | |
| 168 | MODE = 0 | |
| 169 | PID:SetPoint(user) | |
| 170 | setpoint = user | |
| 171 | print("Setting Speed: ", user)
| |
| 172 | end | |
| 173 | os.sleep(1) | |
| 174 | end | |
| 175 | end | |
| 176 | ||
| 177 | -- run through array | |
| 178 | function getDistance() | |
| 179 | --active = CONFIG.array[iteration] | |
| 180 | x1 = active.x | |
| 181 | z1 = active.z | |
| 182 | positions = entity.getLocation() | |
| 183 | y1 = positions.getY() | |
| 184 | x = positions.getDistanceToCoordinates(x1,y1,z1) | |
| 185 | return x | |
| 186 | end | |
| 187 | ||
| 188 | ||
| 189 | local function main() | |
| 190 | while RUNNING do | |
| 191 | array = CONFIG.array | |
| 192 | active = CONFIG.array[iteration] | |
| 193 | distance = getDistance() | |
| 194 | if distance < active.radius or timer ~= nil then | |
| 195 | setpoint = active.speed | |
| 196 | PID:SetPoint(setpoint) | |
| 197 | if active.mode == "wait" then | |
| 198 | if timer == nil then | |
| 199 | timer = active.data | |
| 200 | end | |
| 201 | if timer > 0 then | |
| 202 | timer = timer - 1 | |
| 203 | else | |
| 204 | timer = nil | |
| 205 | if iteration >= #array then | |
| 206 | iteration = 1 | |
| 207 | else | |
| 208 | iteration = iteration + 1 | |
| 209 | end | |
| 210 | end | |
| 211 | else | |
| 212 | if iteration >= #array then | |
| 213 | iteration = 1 | |
| 214 | else | |
| 215 | iteration = iteration + 1 | |
| 216 | end | |
| 217 | end | |
| 218 | end | |
| 219 | ||
| 220 | input = GetTrainSpeed() | |
| 221 | if MODE ~= 2 then | |
| 222 | if MODE == 1 then | |
| 223 | if rampCount > 0 then | |
| 224 | rampCount = rampCount - 1 | |
| 225 | setpoint = setpoint + rampInc | |
| 226 | PID:SetPoint(setpoint) | |
| 227 | if rampCount == 0 then | |
| 228 | setpoint = rampEnd | |
| 229 | PID:SetPoint(rampEnd) | |
| 230 | end | |
| 231 | else | |
| 232 | Mode = 0 | |
| 233 | end | |
| 234 | end | |
| 235 | PID:SetInput(input) | |
| 236 | PID:Compute() | |
| 237 | output = PID:GetOutput() | |
| 238 | BrakeOut = output * -1 | |
| 239 | setThrottle(output) | |
| 240 | setBrake(BrakeOut) | |
| 241 | end | |
| 242 | if display then | |
| 243 | print("CurrentSpeed: ", input)
| |
| 244 | if MODE ~= 2 then | |
| 245 | print("SetPoint: ", setpoint)
| |
| 246 | end | |
| 247 | print("Waypoint: ",active.waypoint)
| |
| 248 | print("Distance: ",distance)
| |
| 249 | print("Timer: ",timer)
| |
| 250 | GetTrainPos() | |
| 251 | print("----")
| |
| 252 | os.sleep(sleep) | |
| 253 | term.clear() | |
| 254 | else | |
| 255 | os.sleep(sleep) | |
| 256 | end | |
| 257 | ||
| 258 | end | |
| 259 | end | |
| 260 | ||
| 261 | function stop() | |
| 262 | RUNNING = false | |
| 263 | end | |
| 264 | ||
| 265 | ----------- Main loop ------------ | |
| 266 | ||
| 267 | term.clear() | |
| 268 | CONFIG = loadConfig() | |
| 269 | setpoint = 0 | |
| 270 | PID:new(0.01, 0.5, 0.0001, 0) | |
| 271 | PID:SetInput((GetTrainSpeed())) | |
| 272 | PID:SetOutput(0) | |
| 273 | PID:SetPoint(setpoint) | |
| 274 | PID:SetOutputLimits(-1, 1) | |
| 275 | PID:SetMode(1) | |
| 276 | ||
| 277 | helpdisplay() | |
| 278 | ||
| 279 | local tb = thread.create(main) | |
| 280 | local ta = thread.create(reads) | |
| 281 | tb:join() | |
| 282 | ta:join() | |
| 283 | term.clear() |