I am having trouble understanding some PID code on an FPGA that is posted on github, by David Paquette.
I will paste it in at the bottom of the post.
It looks very compact and neat, and I understand the concept behind it, but I don't understand why the Kp, Ki and Kd constants are negative numbers. Kp as -300 and Ki as -2 for example.
Suppose I have two questions regarding this:
Why the negative numbers? I am thinking it gives a broader spectrum to work with error values, as the output is capped at zero if the output calculates as a negative.
I am assuming the hardware requires integers of 100, i.e. whatever sensor or motor pwm frequency, but what would the reasoning be behind the 1000 and 10000 integer sizes for the variables?
----------------------------------------------------------------------------------
-- Company:
-- Engineer: David Paquette
--
-- Create Date: 16:49:31 11/19/2015
-- Design Name:
-- Module Name: PIDController - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity PIDController is
Port ( samplingRateClock : in std_logic;
reset : in std_logic;
setpoint: in integer range 0 to 100;
sensorFeedbackValue : in integer range 0 to 100;
controlOutput : out integer range 0 to 100
);
end PIDController;
architecture Behavioral of PIDController is
signal controllerOutput : integer range 0 to 100:=0;
constant kp : integer range -1000 to 0:=-300;
constant ki : integer range -1000 to 0:=-2;
constant kd : integer range -1000 to 0:=0;
begin
process(samplingRateClock, reset)
variable error : integer range -1000 to 1000:=0;
variable previousError : integer range -1000 to 1000:=0;
variable errorSum: integer range -100000 to 100000:=0;
variable errorChange: integer range -1000 to 1000:=0;
variable output: integer range -1000 to 1000:=0;
begin
if(reset='0') then
error:=0;
previousError:=0;
errorSum:=0;
errorChange:=0;
output:=0;
controllerOutput<= 0;
elsif(samplingRateClock'event and samplingRateClock='1') then
error := (setpoint - sensorFeedbackValue);
errorSum := errorSum + error;
if(errorSum > 10000) then
errorSum := 10000;
elsif(errorSum < -10000) then
errorSum := -10000;
end if;
errorChange := error - previousError;
output := (kp*error + ki*errorSum + kd*errorChange)/100;
previousError := error;
if(output>100) then
output := 100;
elsif(output<0)then
output:=0;
end if;
controllerOutput<= output;
end if;
end process;
controlOutput<=controllerOutput;
end Behavioral;
```
errorSum := errorSum + error;
can couses its value is higher than 100 because its a Sum incresing in every function call until it reaches demanded output. It can be probably rewritten better (smaller variable types) if the PID function call is less offen, i.e. higher iteration step or another words slower response regulation. \$\endgroup\$