Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- hi! i spent about four hours writing and
- adjusting everything.
- at first i thought this would be impossible,
- then too easy, then it turned out really difficult.
- oh well.
- i spent this summer pretty mindlessly,
- so this is the first time i put enough comments
- into my code to help me think more about what
- i'm doing.
- cheers to desmos and wolframalpha.
- pona tawa sina.
- u/Bright-Historian-216
- ]]
- local SAVEFILE = ".solarPanelDeg"
- local CTR = "Create_RotationSpeedController_2"
- local SWIVEL = "front" -- used for error correction
- local c = peripheral.wrap(CTR)
- c.setTargetSpeed(0)
- local s = peripheral.wrap(SWIVEL)
- local function optimalAngle(time)
- --[[
- return 0 at 6:00, 90 at 12:00 and 180 at 18:00.
- at a given time the sun is at
- x: cos(pi(n-6)/12)
- y: sin(pi(n-6)/12)
- using arccos or arcsin a position can be turned
- into an angle;
- arccos(cos(x)) = x
- thus i only need to convert pi(n-6)/12 to degrees
- pi(n-6)/12 * (180/pi) = (n-6)*15 = 15n-90.
- ]]
- return 15*time-90
- end
- local function saveDeg(d)
- local f = fs.open(SAVEFILE,"w")
- f.write(tostring(d))
- f.close()
- end
- local function loadDeg(d) -- nil or number
- local f = fs.open(SAVEFILE,"r")
- if f==nil then return nil end
- local n = tonumber(f.readAll())
- f.close()
- return n
- end
- local swivelError = loadDeg()
- local function getActualDeg()
- return -s.getTargetAngle()-swivelError
- end
- local panelDeg = swivelError
- local function moveTowards(angle)
- -- 200 rpm on control = 10 rpm on panel = 60 deg/s
- -- trialed and errored (and errored a lot)
- local rpm = 200
- local sleepTime = (angle-panelDeg)/60
- local degError=1
- if sleepTime<0 then
- sleepTime=-sleepTime
- rpm=-rpm
- degError=-degError
- end
- -- used in the past for predicting error; i wonder if it does anything now?
- local timeError = sleepTime%0.05
- if sleepTime>0.05 then
- c.setTargetSpeed(rpm)
- sleep(sleepTime-timeError)
- c.setTargetSpeed(0)
- panelDeg = getActualDeg()
- panelDeg=panelDeg%360
- saveDeg(swivelError)
- end
- end
- local function adjustRotation()
- local t = os.time()
- if t>18 or t<6 then return end
- local optimalDeg = optimalAngle(t)
- moveTowards(optimalDeg)
- end
- local args = {...}
- if args[1] == "help" then
- print("solarpanel reset - manually reset known rotation")
- print("solarpanel debug <angle> - measure error")
- print("solarpanel install - set as startup")
- print("solarpanel invert - use if your panels are upside down for whatever reason")
- return
- end
- if args[1] == "debug" then
- if s==nil then
- print("Place swivel bearing ("..SWIVEL..") and try again")
- return
- end
- print("use reset subcommand after finishing debug")
- panelDeg = 0
- s.disassemble()
- moveTowards(args[2]+0)
- local actualDeg = -s.getTargetAngle()
- print(panelDeg,actualDeg)
- print("error: "..panelDeg-actualDeg.."; "..(actualDeg/panelDeg-1)*100 .."%")
- return
- end
- if args[1] == "install" then
- if args[2]~="force" and (fs.exists("startup") or fs.exists("startup.lua")) then
- print("You already have a startup script! Use install force to overwrite it.")
- return
- end
- fs.delete("startup")
- fs.delete("startup.lua")
- local f=fs.open("startup","w")
- f.write("print('Starting up solar panels...')\nshell.run('"..shell.resolve("solarpanel").."')")
- f.close()
- return
- end
- if args[1] == "invert" then
- saveDeg(panelDeg+180)
- return
- end
- if panelDeg==nil or args[1]=="reset" then
- c.setTargetSpeed(0)
- s.disassemble()
- print("disassemble panel bearing, then enter position number:")
- print("1. facing east (to sunrise)\n2. panel facing up\n3. facing west (to sunset)\n4. facing down")
- panelDeg = (read()-1)*90
- swivelError = -panelDeg
- end
- while true do
- adjustRotation()
- sleep(0.05)
- end
Advertisement
Add Comment
Please, Sign In to add comment