Gazer29

acc_v2

Mar 18th, 2021 (edited)
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.  
  14. local ATC = false
  15. local RUNNING = true
  16. local MODE = 0 -- 0 SET, 1 RAMP,
  17. local sleep = 1 -- seconds
  18. local display = false
  19. local iteration = 1
  20. local timer = nil
  21.  
  22. local CONFIG_FILE = "/home/Waypoints.cfg"
  23. local CONFIG = nil
  24. local DEFAULT_CONFIG = {
  25.   array = {
  26.     {
  27.     waypoint = "Station 1",
  28.     speed = 0,
  29.     radius = 10,
  30.     x = 1180,
  31.     z = -333,
  32.     mode = "wait",
  33.     data = 20
  34.     },
  35.     {
  36.     waypoint = "Waypoint 2",
  37.     speed = 10,
  38.     radius = 10,
  39.     x = 1180,
  40.     z = -333,
  41.     mode = nil,
  42.     data = nil
  43.     },
  44.     {
  45.     waypoint = "Waypoint 3",
  46.     speed = 5,
  47.     radius = 10,
  48.     x = 1136,
  49.     z = -333,
  50.     mode = nil,
  51.     data = nil
  52.     }
  53.   }
  54. }
  55.  
  56. glassesTerminal.removeAll()
  57. atext = glassesTerminal.addText2D()
  58. atext.setText("ATC: OFF") -- no modifier!
  59. atext.setFontSize(42)
  60. atext.addColor(1, 0, 0, 1)
  61. atext.setCondition(atext.addColor(0, 1, 0, 1), "OVERLAY_ACTIVE", true)
  62.  
  63. btext = glassesTerminal.addText2D()
  64. btext.setText("+10")
  65. btext.setFontSize(60)
  66. btext.addColor(1,0,0,1)
  67. btext.addTranslation(0, 10, 0)
  68. btext.setCondition(btext.addColor(0, 1, 0, 1), "OVERLAY_ACTIVE", true)
  69.  
  70. ctext = glassesTerminal.addText2D()
  71. ctext.setText("-10")
  72. ctext.setFontSize(60)
  73. ctext.addColor(1,0,0,1)
  74. ctext.addTranslation(0,18,0)
  75. ctext.setCondition(ctext.addColor(0, 1, 0, 1), "OVERLAY_ACTIVE", true)
  76.  
  77. local function saveConfig(file, cfg) -- Adapted from HandieAndy's code
  78.   local f = io.open(file, "w")
  79.   if f == nil then error("Couldn't open " .. file .. " to write config.") end
  80.   f:write(serial.serialize(cfg, 100000))
  81.   f:close()
  82.   print("Saved to file: ", CONFIG_FILE)
  83. end
  84.  
  85. local function loadConfig() -- Adapted from HandieAndy's code
  86.   local f = io.open(CONFIG_FILE, "r")
  87.   if f == nil then
  88.     print("Could not open " .. CONFIG_FILE .. ".")
  89.     print("Loading default config")
  90.     saveConfig(CONFIG_FILE, DEFAULT_CONFIG)
  91.     return DEFAULT_CONFIG
  92.     else
  93.     local config = serial.unserialize(f:read("*a"))
  94.     f:close()
  95.     return config
  96.     end
  97. end
  98.  
  99. function helpdisplay()
  100.     print("AutomaticTrainControl v1")
  101.     print("Commands:")
  102.     print("'Any number'    - Changes set speed")
  103.     print("'+'      - Displays additional information")
  104.     print("'-'      - Hides additional information")
  105.     print("'ramp'       - Changes to ramp mode, requires further input")
  106.     print("'idle'       - Pauses train control")
  107.     print("'save'       - Saves config file")
  108.     print("'stop'       - Ends program")
  109. end
  110.    
  111. function GetTrainPos()
  112.     positions = entity.getLocation()
  113.     xpos = positions.getX()
  114.     ypos = positions.getY()
  115.     zpos = positions.getZ()
  116.     print("X:   ", xpos)
  117.     print("Z:   ", zpos)
  118. end
  119.  
  120. function GetTrainSpeed()
  121.     speed = entity.getCurrentSpeed()
  122.     return speed
  123. end
  124.  
  125. function setThrottle(x)
  126.     if 0 >= x then x = 0 end
  127.     if 1 <= x then x = 1 end
  128.     entity.setThrottleLevel(x)
  129.     if display then
  130.         print("Throttle: ", x)
  131.         end
  132. end
  133.  
  134. function setBrake(x)
  135.     if 0 >= x then x = 0 end
  136.     if 1 <= x then x = 1 end
  137.     entity.setAirBrakeLevel(x)
  138.     if display then
  139.         print("Brake:   ", x)
  140.         end
  141. end
  142.  
  143. local function reads()
  144.   while RUNNING do
  145.     user = nil
  146.     user = io.read()
  147.     if user == "stop" then 
  148.         print("STOPPING...")
  149.         os.sleep(1)
  150.         stop()
  151.         end
  152.     if user == "." then
  153.         term.clear()
  154.         end
  155.     if user == "idle" then
  156.         MODE = 2
  157.         end
  158.     if user == "ramp" then
  159.         print("Start Speed (type 'x' for current setpoint):")
  160.         c = io.read()
  161.         if c == "x" then
  162.             c = setpoint
  163.             end
  164.         print("End Speed:")
  165.         rampStart = c
  166.         c = io.read()
  167.         print("Ramp Time (seconds):")
  168.         rampEnd = c
  169.         c = io.read()
  170.         rampTime = c
  171.         rampDiff = rampEnd - rampStart
  172.         rampCount = math.floor(rampTime/sleep)
  173.         rampInc = rampDiff / rampCount
  174.         PID:SetPoint(rampStart)
  175.         setpoint = rampStart
  176.         MODE = 1
  177.         end
  178.     if user == "+" then
  179.         display = true
  180.         term.clear()
  181.         end
  182.     if user == "save" then
  183.         saveConfig(CONFIG_FILE, CONFIG)
  184.         end
  185.     if user == "-" then
  186.         display = false
  187.         term.clear()
  188.         os.sleep(1)
  189.         helpdisplay()
  190.         end
  191.     if nil ~= tonumber(user) then
  192.         MODE = 0
  193.         PID:SetPoint(user)
  194.         setpoint = user
  195.         print("Setting Speed: ", user)
  196.         end
  197.     os.sleep(1)
  198.   end
  199. end
  200.  
  201. -- run through array
  202. function getDistance()
  203.     --active = CONFIG.array[iteration]
  204.     x1 = active.x
  205.     z1 = active.z
  206.     positions = entity.getLocation()
  207.     y1 = positions.getY()
  208.     x = positions.getDistanceToCoordinates(x1,y1,z1)
  209.     return x
  210.     end
  211.  
  212.  
  213. local function main()
  214.     while RUNNING do
  215.         array = CONFIG.array
  216.         active = CONFIG.array[iteration]
  217.         distance = getDistance()
  218.         if distance < active.radius or timer ~= nil then
  219.             setpoint = active.speed
  220.             PID:SetPoint(setpoint)
  221.             if active.mode == "wait" then
  222.                 if timer == nil then
  223.                     timer = active.data
  224.                     end
  225.                 if timer > 0 then
  226.                     timer = timer - 1
  227.                     else
  228.                     timer = nil
  229.                     if iteration >= #array then
  230.                         iteration = 1
  231.                         else
  232.                         iteration = iteration + 1
  233.                         end
  234.                     end
  235.                 else
  236.                 if iteration >= #array then
  237.                     iteration = 1
  238.                     else
  239.                     iteration = iteration + 1
  240.                     end
  241.                 end
  242.             end
  243.        
  244.         input = GetTrainSpeed()
  245.         if MODE ~= 2 then
  246.             if MODE == 1 then
  247.                 if rampCount > 0 then
  248.                   rampCount = rampCount - 1
  249.                   setpoint = setpoint + rampInc
  250.                   PID:SetPoint(setpoint)
  251.                   if rampCount == 0 then
  252.                     setpoint = rampEnd
  253.                     PID:SetPoint(rampEnd)
  254.                     end
  255.                   else
  256.                   Mode = 0
  257.                   end
  258.                 end
  259.             PID:SetInput(input)
  260.             PID:Compute()
  261.             output = PID:GetOutput()
  262.             BrakeOut = output * -1
  263.             setThrottle(output)
  264.             setBrake(BrakeOut)
  265.             end
  266.         if display then
  267.             print("CurrentSpeed: ", input)
  268.             if MODE ~= 2 then
  269.                 print("SetPoint: ", setpoint)
  270.                 end
  271.             print("Waypoint: ",active.waypoint)
  272.             print("Distance: ",distance)
  273.             print("Timer:   ",timer)
  274.             GetTrainPos()
  275.             print("----")
  276.             os.sleep(sleep)
  277.             term.clear()
  278.             else
  279.             os.sleep(sleep)
  280.             end
  281.         checkATC()
  282.         end
  283.   end
  284.  
  285. function stop()
  286.   RUNNING = false
  287. end
  288.  
  289. function checkATC()
  290.   if MODE == 0 then
  291.     atext.setText("ATC: "..setpoint.."  Speed: "..(math.floor(input * 1000)/1000))
  292.     ATC = true
  293.     end
  294.   if MODE == 2 then
  295.     atext.setText("ATC: OFF")
  296.     ATC = false
  297.     end
  298. end
  299.  
  300. function inbounds(x0, y0, x1, y1, x2, y2)
  301.   local output = false
  302.   if x0 > x1 then
  303.     if y0 > y1 then
  304.       if x0 < x2 then
  305.         if y0 < y2 then
  306.           output = true
  307.           end
  308.         end
  309.       end
  310.     end
  311.   return output
  312. end    
  313.  
  314. function pullOverlay()
  315. while RUNNING do
  316.   EVENT, ID, USER, X, Y, BUTTON = event.pull("interact_overlay")
  317.   if inbounds(X,Y,0,0,41,7) then
  318.     if ATC == true then
  319.         MODE = 2
  320.         else
  321.         MODE = 0
  322.         PID:SetPoint(setpoint)
  323.         end
  324.   elseif inbounds(X,Y,0,11,20,16) then
  325.     setpoint = setpoint + 10
  326.     PID:SetPoint(setpoint)
  327.   elseif inbounds(X,Y,0,19,20,24) then
  328.     setpoint = setpoint - 10
  329.     PID:SetPoint(setpoint)
  330.     end
  331. end
  332. end
  333.  
  334. ----------- Main loop ------------ 
  335.    
  336. term.clear()
  337. CONFIG = loadConfig()
  338. setpoint = 0
  339. PID:new(0.01, 0.5, 0.0001, 0)
  340. PID:SetInput((GetTrainSpeed()))
  341. PID:SetOutput(0)
  342. PID:SetPoint(setpoint)
  343. PID:SetOutputLimits(-1, 1)
  344. PID:SetMode(1)
  345.  
  346. helpdisplay()
  347.  
  348. local tb = thread.create(main)
  349. local ta = thread.create(reads)
  350. local tc = thread.create(pullOverlay)
  351. tb:join()
  352. ta:join()
  353. tc:join()
  354. term.clear()
Advertisement
Add Comment
Please, Sign In to add comment