AdditionalPylons

solarpanel.lua

Aug 17th, 2026
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.96 KB | None | 0 0
  1. --[[
  2. hi! i spent about four hours writing and
  3. adjusting everything.
  4. at first i thought this would be impossible,
  5. then too easy, then it turned out really difficult.
  6. oh well.
  7.  
  8. i spent this summer pretty mindlessly,
  9. so this is the first time i put enough comments
  10. into my code to help me think more about what
  11. i'm doing.
  12.  
  13. cheers to desmos and wolframalpha.
  14.  
  15. pona tawa sina.
  16. u/Bright-Historian-216
  17. ]]
  18. local SAVEFILE = ".solarPanelDeg"
  19. local CTR = "Create_RotationSpeedController_2"
  20. local SWIVEL = "front" -- used for error correction
  21.  
  22. local c = peripheral.wrap(CTR)
  23. c.setTargetSpeed(0)
  24. local s = peripheral.wrap(SWIVEL)
  25.  
  26. local function optimalAngle(time)
  27.     --[[
  28.     return 0 at 6:00, 90 at 12:00 and 180 at 18:00.
  29.     at a given time the sun is at
  30.     x: cos(pi(n-6)/12)
  31.     y: sin(pi(n-6)/12)
  32.  
  33.     using arccos or arcsin a position can be turned
  34.     into an angle;
  35.     arccos(cos(x)) = x
  36.     thus i only need to convert pi(n-6)/12 to degrees
  37.     pi(n-6)/12 * (180/pi) = (n-6)*15 = 15n-90.  
  38.     ]]
  39.     return 15*time-90
  40. end
  41. local function saveDeg(d)
  42.     local f = fs.open(SAVEFILE,"w")
  43.     f.write(tostring(d))
  44.     f.close()
  45. end
  46. local function loadDeg(d) -- nil or number
  47.     local f = fs.open(SAVEFILE,"r")
  48.     if f==nil then return nil end
  49.     local n = tonumber(f.readAll())
  50.     f.close()
  51.     return n
  52. end
  53. local swivelError = loadDeg()
  54. local function getActualDeg()
  55.     return -s.getTargetAngle()-swivelError
  56. end
  57. local panelDeg = swivelError
  58. local function moveTowards(angle)
  59.     -- 200 rpm on control = 10 rpm on panel = 60 deg/s
  60.     -- trialed and errored (and errored a lot)
  61.     local rpm = 200
  62.     local sleepTime = (angle-panelDeg)/60
  63.     local degError=1
  64.    
  65.     if sleepTime<0 then
  66.         sleepTime=-sleepTime
  67.         rpm=-rpm
  68.         degError=-degError
  69.     end
  70.  
  71.     -- used in the past for predicting error; i wonder if it does anything now?
  72.     local timeError = sleepTime%0.05
  73.  
  74.     if sleepTime>0.05 then
  75.         c.setTargetSpeed(rpm)
  76.         sleep(sleepTime-timeError)
  77.         c.setTargetSpeed(0)
  78.  
  79.         panelDeg = getActualDeg()
  80.         panelDeg=panelDeg%360
  81.         saveDeg(swivelError)
  82.     end
  83. end
  84.  
  85. local function adjustRotation()
  86.     local t = os.time()
  87.     if t>18 or t<6 then return end
  88.     local optimalDeg = optimalAngle(t)
  89.     moveTowards(optimalDeg)
  90. end
  91.  
  92. local args = {...}
  93. if args[1] == "help" then
  94.     print("solarpanel reset - manually reset known rotation")
  95.     print("solarpanel debug <angle> - measure error")
  96.     print("solarpanel install - set as startup")
  97.     print("solarpanel invert - use if your panels are upside down for whatever reason")
  98.     return
  99. end
  100. if args[1] == "debug" then
  101.     if s==nil then
  102.         print("Place swivel bearing ("..SWIVEL..") and try again")
  103.         return
  104.     end
  105.     print("use reset subcommand after finishing debug")
  106.     panelDeg = 0
  107.     s.disassemble()
  108.     moveTowards(args[2]+0)
  109.     local actualDeg = -s.getTargetAngle()
  110.     print(panelDeg,actualDeg)
  111.     print("error: "..panelDeg-actualDeg.."; "..(actualDeg/panelDeg-1)*100 .."%")
  112.     return
  113. end
  114. if args[1] == "install" then
  115.     if args[2]~="force" and (fs.exists("startup") or fs.exists("startup.lua")) then
  116.         print("You already have a startup script! Use install force to overwrite it.")
  117.         return
  118.     end
  119.     fs.delete("startup")
  120.     fs.delete("startup.lua")
  121.     local f=fs.open("startup","w")
  122.     f.write("print('Starting up solar panels...')\nshell.run('"..shell.resolve("solarpanel").."')")
  123.     f.close()
  124.     return
  125. end
  126. if args[1] == "invert" then
  127.     saveDeg(panelDeg+180)
  128.     return
  129. end
  130. if panelDeg==nil or args[1]=="reset" then
  131.     c.setTargetSpeed(0)
  132.     s.disassemble()
  133.  
  134.     print("disassemble panel bearing, then enter position number:")
  135.     print("1. facing east (to sunrise)\n2. panel facing up\n3. facing west (to sunset)\n4. facing down")
  136.  
  137.     panelDeg = (read()-1)*90
  138.     swivelError = -panelDeg
  139. end
  140.  
  141. while true do
  142.     adjustRotation()
  143.     sleep(0.05)
  144. end
  145.  
Advertisement
Add Comment
Please, Sign In to add comment