local m={}m.__index=m function m.new(C,r,v,Z,G)local z=setmetatable({},m)z._min=C z._max=r z._kp=v z._kd=Z z._ki=G z._preError=0 z._integral=0 return z end function m.Reset(m)m._preError=0 m._integral=0 end function m.Calculate(v,m,C,r)local Z=C-r local G=v._kp*Z v._integral+=Z*m local z=v._ki*v._integral local Y=(Z-v._preError)/m local y=v._kd*Y local A=math.clamp((G+z)+y,v._min,v._max)v._preError=Z return A end function m.SetMinMax(r,m,C)r._min=m r._max=C end return m



local PID = {}
PID.__index = PID


function PID.new(min, max, kp, kd, ki)
	local self = setmetatable({}, PID)
	self._min = min
	self._max = max
	self._kp = kp
	self._kd = kd
	self._ki = ki
	self._preError = 0
	self._integral = 0
	return self
end


function PID:Reset()
	self._preError = 0
	self._integral = 0
end


function PID:Calculate(dt, setpoint, pv)
	local err = (setpoint - pv)
	local pOut = (self._kp * err)
	self._integral += (err * dt)
	local iOut = (self._ki * self._integral)
	local deriv = ((err - self._preError) / dt)
	local dOut = (self._kd * deriv)
	local output = math.clamp((pOut + iOut + dOut), self._min, self._max)
	self._preError = err
	return output
end


function PID:SetMinMax(min, max)
	self._min = min
	self._max = max
end


return PID
