71 lines
2.6 KiB
Lua
71 lines
2.6 KiB
Lua
|
local CONTROL_BASE_RPM = 16
|
||
|
local CONTROL_MAX_RPM = 256
|
||
|
|
||
|
-- Converts an RPM speed to a blocks-per-second speed.
|
||
|
local function rpmToBps(rpm)
|
||
|
return (10 / 256) * rpm
|
||
|
end
|
||
|
|
||
|
-- Computes a series of keyframes describing the linear motion of the elevator.
|
||
|
local function computeLinearMotion(distance)
|
||
|
local preFrames = {}
|
||
|
local postFrames = {}
|
||
|
local intervalDuration = 0.5
|
||
|
|
||
|
-- Linear motion calculation
|
||
|
local v1Dist = 2 * intervalDuration * rpmToBps(CONTROL_BASE_RPM)
|
||
|
local v2Dist = 2 * intervalDuration * rpmToBps(CONTROL_BASE_RPM * 2)
|
||
|
local v3Dist = 2 * intervalDuration * rpmToBps(CONTROL_BASE_RPM * 4)
|
||
|
local v4Dist = 2 * intervalDuration * rpmToBps(CONTROL_BASE_RPM * 8)
|
||
|
|
||
|
local distanceToCover = distance
|
||
|
local rpmFactor = 1
|
||
|
while rpmFactor * CONTROL_BASE_RPM < CONTROL_MAX_RPM do
|
||
|
print("Need to cover " .. distanceToCover .. " more meters.")
|
||
|
local rpm = CONTROL_BASE_RPM * rpmFactor
|
||
|
local potentialDistanceCovered = 2 * intervalDuration * rpmToBps(rpm)
|
||
|
local nextRpmFactorDuration = (distanceToCover - potentialDistanceCovered) / rpmToBps(CONTROL_BASE_RPM * (rpmFactor + 1))
|
||
|
print("We'd cover " .. potentialDistanceCovered .. " by moving at " .. rpm .. " rpm for " .. intervalDuration .. " seconds twice.")
|
||
|
if potentialDistanceCovered <= distanceToCover and nextRpmFactorDuration >= 2 then
|
||
|
local frame = {
|
||
|
rpm = rpm,
|
||
|
duration = intervalDuration
|
||
|
}
|
||
|
table.insert(preFrames, frame)
|
||
|
table.insert(postFrames, 1, frame)
|
||
|
distanceToCover = distanceToCover - potentialDistanceCovered
|
||
|
rpmFactor = rpmFactor * 2
|
||
|
elseif nextRpmFactorDuration < 2 then
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Cover the remaining distance with the next rpmFactor.
|
||
|
local finalRpm = CONTROL_BASE_RPM * rpmFactor
|
||
|
local finalDuration = distanceToCover / rpmToBps(finalRpm)
|
||
|
local finalFrame = {
|
||
|
rpm = finalRpm,
|
||
|
duration = finalDuration
|
||
|
}
|
||
|
local frames = {}
|
||
|
for _, frame in pairs(preFrames) do table.insert(frames, frame) end
|
||
|
table.insert(frames, finalFrame)
|
||
|
for _, frame in pairs(postFrames) do table.insert(frames, frame) end
|
||
|
return frames
|
||
|
end
|
||
|
|
||
|
local function printFrames(frames)
|
||
|
for _, frame in pairs(frames) do
|
||
|
print("Frame: rpm = " .. tostring(frame.rpm) .. ", duration = " .. tostring(frame.duration))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local frames = computeLinearMotion(5)
|
||
|
printFrames(frames)
|
||
|
local dist = 0
|
||
|
for _, frame in pairs(frames) do
|
||
|
dist = dist + rpmToBps(frame.rpm) * frame.duration
|
||
|
end
|
||
|
print(dist)
|
||
|
|
||
|
print(0.15 % 0.05 == 0)
|