SHOW:
|
|
- or go back to the newest paste.
| 1 | --Automated Cruise Control v2 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 | local glassesTerminal = require("component").glasses
| |
| 12 | local event = require("event")
| |
| 13 | local modem = component.modem | |
| 14 | ||
| 15 | local ATC = false | |
| 16 | local RUNNING = true | |
| 17 | local MODE = 0 -- 0 SET, 1 RAMP, | |
| 18 | local sleep = 1 -- seconds | |
| 19 | local display = false | |
| 20 | local iteration = 1 | |
| 21 | local timer = nil | |
| 22 | - | local CONFIG_FILE = "/home/Waypoints.cfg" |
| 22 | + | |
| 23 | local CONFIG_FILE = "/home/CMD.dat" | |
| 24 | - | local DEFAULT_CONFIG = {
|
| 24 | + | |
| 25 | - | array = {
|
| 25 | + | local DEFAULT_CONFIG = {}
|
| 26 | - | {
|
| 26 | + | |
| 27 | - | waypoint = "Station 1", |
| 27 | + | |
| 28 | - | speed = 0, |
| 28 | + | |
| 29 | - | radius = 10, |
| 29 | + | |
| 30 | - | x = 1180, |
| 30 | + | |
| 31 | - | z = -333, |
| 31 | + | |
| 32 | - | mode = "wait", |
| 32 | + | |
| 33 | - | data = 20 |
| 33 | + | |
| 34 | - | }, |
| 34 | + | |
| 35 | - | {
|
| 35 | + | |
| 36 | - | waypoint = "Waypoint 2", |
| 36 | + | |
| 37 | - | speed = 10, |
| 37 | + | |
| 38 | - | radius = 10, |
| 38 | + | |
| 39 | - | x = 1180, |
| 39 | + | |
| 40 | - | z = -333, |
| 40 | + | |
| 41 | - | mode = nil, |
| 41 | + | |
| 42 | - | data = nil |
| 42 | + | |
| 43 | - | }, |
| 43 | + | |
| 44 | - | {
|
| 44 | + | |
| 45 | - | waypoint = "Waypoint 3", |
| 45 | + | |
| 46 | - | speed = 5, |
| 46 | + | |
| 47 | - | radius = 10, |
| 47 | + | |
| 48 | - | x = 1136, |
| 48 | + | |
| 49 | - | z = -333, |
| 49 | + | |
| 50 | - | mode = nil, |
| 50 | + | |
| 51 | - | data = nil |
| 51 | + | |
| 52 | - | } |
| 52 | + | |
| 53 | - | } |
| 53 | + | |
| 54 | - | } |
| 54 | + | |
| 55 | ||
| 56 | local function loadConfig() -- Adapted from HandieAndy's code | |
| 57 | local f = io.open(CONFIG_FILE, "r") | |
| 58 | if f == nil then | |
| 59 | --print("Could not open " .. CONFIG_FILE .. ".")
| |
| 60 | --print("Loading default config")
| |
| 61 | --saveConfig(CONFIG_FILE, DEFAULT_CONFIG) | |
| 62 | return DEFAULT_CONFIG | |
| 63 | else | |
| 64 | local config = serial.unserialize(f:read("*a"))
| |
| 65 | f:close() | |
| 66 | return config | |
| 67 | end | |
| 68 | end | |
| 69 | ||
| 70 | function helpdisplay() | |
| 71 | print("AutomaticTrainControl v1")
| |
| 72 | print("Commands:")
| |
| 73 | print("'Any number' - Changes set speed")
| |
| 74 | print("'+' - Displays additional information")
| |
| 75 | print("'-' - Hides additional information")
| |
| 76 | print("'ramp' - Changes to ramp mode, requires further input")
| |
| 77 | print("'idle' - Pauses train control")
| |
| 78 | print("'auto' - Automatic control")
| |
| 79 | print("'stop' - Ends program")
| |
| 80 | end | |
| 81 | ||
| 82 | function GetTrainPos() | |
| 83 | positions = entity.getLocation() | |
| 84 | xpos = positions.getX() | |
| 85 | ypos = positions.getY() | |
| 86 | zpos = positions.getZ() | |
| 87 | print("X: ", xpos)
| |
| 88 | - | print("Could not open " .. CONFIG_FILE .. ".")
|
| 88 | + | |
| 89 | - | print("Loading default config")
|
| 89 | + | |
| 90 | - | saveConfig(CONFIG_FILE, DEFAULT_CONFIG) |
| 90 | + | |
| 91 | function GetTrainSpeed() | |
| 92 | speed = entity.getCurrentSpeed() | |
| 93 | return speed | |
| 94 | end | |
| 95 | ||
| 96 | function GetUUID() | |
| 97 | uuid = entity.getUUID() | |
| 98 | return uuid | |
| 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 | - | print("'save' - Saves config file")
|
| 107 | + | |
| 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 == "auto" then | |
| 135 | MODE = 3 | |
| 136 | end | |
| 137 | if user == "ramp" then | |
| 138 | print("Start Speed (type 'x' for current setpoint):")
| |
| 139 | c = io.read() | |
| 140 | if c == "x" then | |
| 141 | c = setpoint | |
| 142 | end | |
| 143 | print("End Speed:")
| |
| 144 | rampStart = c | |
| 145 | c = io.read() | |
| 146 | print("Ramp Time (seconds):")
| |
| 147 | rampEnd = c | |
| 148 | c = io.read() | |
| 149 | rampTime = c | |
| 150 | rampDiff = rampEnd - rampStart | |
| 151 | rampCount = math.floor(rampTime/sleep) | |
| 152 | rampInc = rampDiff / rampCount | |
| 153 | PID:SetPoint(rampStart) | |
| 154 | setpoint = rampStart | |
| 155 | MODE = 1 | |
| 156 | end | |
| 157 | if user == "+" then | |
| 158 | display = true | |
| 159 | term.clear() | |
| 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 | ||
| 178 | local function main() | |
| 179 | while RUNNING do | |
| 180 | input = GetTrainSpeed() | |
| 181 | if MODE ~= 2 then | |
| 182 | - | if user == "save" then |
| 182 | + | |
| 183 | - | saveConfig(CONFIG_FILE, CONFIG) |
| 183 | + | |
| 184 | rampCount = rampCount - 1 | |
| 185 | setpoint = setpoint + rampInc | |
| 186 | PID:SetPoint(setpoint) | |
| 187 | if rampCount == 0 then | |
| 188 | setpoint = rampEnd | |
| 189 | PID:SetPoint(rampEnd) | |
| 190 | end | |
| 191 | else | |
| 192 | Mode = 0 | |
| 193 | end | |
| 194 | end | |
| 195 | if MODE == 3 then | |
| 196 | CONFIG = loadConfig() | |
| 197 | if CONFIG[uuid] ~= nil then | |
| 198 | print(CONFIG[uuid].setspeed) | |
| 199 | setpoint = CONFIG[uuid].setspeed | |
| 200 | PID:SetPoint(setpoint) | |
| 201 | - | -- run through array |
| 201 | + | end |
| 202 | - | function getDistance() |
| 202 | + | end |
| 203 | - | --active = CONFIG.array[iteration] |
| 203 | + | |
| 204 | - | x1 = active.x |
| 204 | + | |
| 205 | - | z1 = active.z |
| 205 | + | |
| 206 | - | positions = entity.getLocation() |
| 206 | + | |
| 207 | - | y1 = positions.getY() |
| 207 | + | |
| 208 | - | x = positions.getDistanceToCoordinates(x1,y1,z1) |
| 208 | + | |
| 209 | - | return x |
| 209 | + | |
| 210 | if display then | |
| 211 | print("CurrentSpeed: ", input)
| |
| 212 | if MODE ~= 2 then | |
| 213 | print("SetPoint: ", setpoint)
| |
| 214 | end | |
| 215 | - | array = CONFIG.array |
| 215 | + | |
| 216 | - | active = CONFIG.array[iteration] |
| 216 | + | |
| 217 | - | distance = getDistance() |
| 217 | + | |
| 218 | - | if distance < active.radius or timer ~= nil then |
| 218 | + | |
| 219 | - | setpoint = active.speed |
| 219 | + | |
| 220 | - | PID:SetPoint(setpoint) |
| 220 | + | |
| 221 | - | if active.mode == "wait" then |
| 221 | + | |
| 222 | - | if timer == nil then |
| 222 | + | |
| 223 | - | timer = active.data |
| 223 | + | |
| 224 | end | |
| 225 | - | if timer > 0 then |
| 225 | + | |
| 226 | - | timer = timer - 1 |
| 226 | + | |
| 227 | - | else |
| 227 | + | |
| 228 | - | timer = nil |
| 228 | + | |
| 229 | - | if iteration >= #array then |
| 229 | + | |
| 230 | - | iteration = 1 |
| 230 | + | |
| 231 | - | else |
| 231 | + | if MODE == 3 then |
| 232 | - | iteration = iteration + 1 |
| 232 | + | |
| 233 | - | end |
| 233 | + | |
| 234 | end | |
| 235 | - | else |
| 235 | + | |
| 236 | - | if iteration >= #array then |
| 236 | + | |
| 237 | - | iteration = 1 |
| 237 | + | |
| 238 | - | else |
| 238 | + | |
| 239 | - | iteration = iteration + 1 |
| 239 | + | |
| 240 | ||
| 241 | function inbounds(x0, y0, x1, y1, x2, y2) | |
| 242 | local output = false | |
| 243 | - | |
| 243 | + | |
| 244 | if y0 > y1 then | |
| 245 | if x0 < x2 then | |
| 246 | if y0 < y2 then | |
| 247 | output = true | |
| 248 | end | |
| 249 | end | |
| 250 | end | |
| 251 | end | |
| 252 | return output | |
| 253 | end | |
| 254 | ||
| 255 | function pullOverlay() | |
| 256 | while RUNNING do | |
| 257 | EVENT, ID, USER, X, Y, BUTTON = event.pull("interact_overlay")
| |
| 258 | if inbounds(X,Y,0,0,41,7) then | |
| 259 | if ATC == true then | |
| 260 | MODE = 2 | |
| 261 | else | |
| 262 | MODE = 3 | |
| 263 | PID:SetPoint(setpoint) | |
| 264 | end | |
| 265 | elseif inbounds(X,Y,0,11,20,16) then | |
| 266 | setpoint = setpoint + 10 | |
| 267 | PID:SetPoint(setpoint) | |
| 268 | elseif inbounds(X,Y,0,19,20,24) then | |
| 269 | setpoint = setpoint - 10 | |
| 270 | PID:SetPoint(setpoint) | |
| 271 | - | print("Waypoint: ",active.waypoint)
|
| 271 | + | |
| 272 | - | print("Distance: ",distance)
|
| 272 | + | |
| 273 | - | print("Timer: ",timer)
|
| 273 | + | |
| 274 | ||
| 275 | local function handleMessage(host, msg) | |
| 276 | local packet = serial.unserialize(msg) | |
| 277 | if packet == nil then | |
| 278 | print("nil packet")
| |
| 279 | return | |
| 280 | end | |
| 281 | if packet.t == "STATUS" then | |
| 282 | print(packet.v) | |
| 283 | saveConfig(CONFIG_FILE, packet.v) | |
| 284 | else | |
| 285 | print("unknown command")
| |
| 286 | end | |
| 287 | end | |
| 288 | ||
| 289 | function start() | |
| 290 | - | if MODE == 0 then |
| 290 | + | modem.open(54421) |
| 291 | while RUNNING do | |
| 292 | local eventName, p1, p2, p3, p4, p5 = event.pull() | |
| 293 | if eventName == "modem_message" then | |
| 294 | print("recv")
| |
| 295 | handleMessage(p2, p5) | |
| 296 | end | |
| 297 | end | |
| 298 | modem.close(54421) | |
| 299 | end | |
| 300 | ||
| 301 | ----------- Main loop ------------ | |
| 302 | ||
| 303 | term.clear() | |
| 304 | CONFIG = loadConfig() | |
| 305 | setpoint = 0 | |
| 306 | PID:new(0.01, 0.5, 0.0001, 0) | |
| 307 | PID:SetInput((GetTrainSpeed())) | |
| 308 | PID:SetOutput(0) | |
| 309 | PID:SetPoint(setpoint) | |
| 310 | PID:SetOutputLimits(-1, 1) | |
| 311 | PID:SetMode(1) | |
| 312 | ||
| 313 | helpdisplay() | |
| 314 | uuid = GetUUID() | |
| 315 | ||
| 316 | local tb = thread.create(main) | |
| 317 | local ta = thread.create(reads) | |
| 318 | local tc = thread.create(pullOverlay) | |
| 319 | local td = thread.create(start) | |
| 320 | tb:join() | |
| 321 | - | MODE = 0 |
| 321 | + | |
| 322 | tc:join() | |
| 323 | td:join() | |
| 324 | term.clear() |