Drone PID Balance Issues

I have a system using PIDs to tilt my drone to cancel out any lateral movement it creates using the upward thrust I have on the drone and redirecting some of it in a given direction. The problem arises when my drone tilts to cancel the lateral movement out and it does successfully but it doesn’t take into account that it is still tilted and moves itself the other direction. It then tries to correct the lateral movement in the other way that it created itself and rinse and repeat till it crashes. I am wondering how I would go about making the tilt 0 as the lateral velocity also reaches zero. I am using torque to control the tilt of the drone. The code I use to achieve this is shown below

Video: https://gyazo.com/2b36021b0150be85fd9ffe6f6a69a609

local PID = require(RS.Modules.PID)
-- From https://github.com/Sleitnick/AeroGameFramework/blob/master/src/StarterPlayer/StarterPlayerScripts/Aero/Modules/PID.lua

local XRotTorque = PID.new(-1,1,100,200,0)

function Update(dt)
	
	local ObjectRot = script.Parent.Engine.CFrame:VectorToObjectSpace(script.Parent.Engine.Orientation)
	local ObjectVelocity = script.Parent.Engine.CFrame:VectorToObjectSpace(script.Parent.Engine.AssemblyLinearVelocity)
	
	local XRotValue = XRotTorque:Calculate(dt,0,ObjectVelocity.Z)
	
	script.Parent.Engine.Torque.Torque = Vector3.new(XRotValue/10,YRotValue * 3,0)
	
end

RunService.Heartbeat:Connect(Update)

Uh, tweak your PID values until it works? That’s sort of the point of PIDs :slight_smile:

Aside from needing to tune the PID you should correct the inputs of the setpoint (The current point) and process variable (goal), which were mixed up. Here is an example:

--PID:Calculate(Deltatime, Setpoint, ProcessVariable)
local XRotValue = XRotTorque:Calculate(dt, -ObjectVelocity.Z, 0)

Additionally, you may want to modify Sleitnick’s PID module script and add integral anti-windup if you have constant overshooting. Related information here. The following example can be done on line 59 of the PID module script.

--self._integral += (err * dt)
self._integral += math.clamp((err * dt), self._min, self._max) --anti-windup