Talking especifically of PSO:
PSO is a good method for PID tuning, as you state. This algo is based particles that help find the absolute minimum. Let's think that you tune to get the no overshot.
If you tune a PID you must have a 3 dimension PSO algo, if you tune a PD just two. And for each dimension you can have any amount of particles as you want. In my case, in Scilab 5.4 I tune PD with PSO with 10 or 15 particles and converge quite fast, in a pair of minutes.
A particle represents a Kp value, for instance. If you have 10 particles for each dimension, you will be able to test your Kp with 10 different values at once. Then, the best particle will reveal, and will tell the other nine particles to adapt their value towards that local best particle, and Kp values will readapt till you find the local minimum Kp value that gets the lowest overshot.
Before tuning a PID, I suggest you to try to find the lowest point in a U letter with PSO. My code with Scilab is next:
N=10;
weight=1; //weight of the PSO algorithm
const_c1=2; //constant of the velocity algorithm.
const_c2=2; //constant of the velocity algorithm.
Number_Iter=300; //number of iterations
dim=1; // dimension
//Initialize the parameter
fitness=zeros(N,Number_Iter);
R1=rand(dim,N); //Random numbers [0 1]
R2=rand(dim,N); //Random numbers [0 1]
current_fitness=zeros(N,1); /
//initializing swarm and velocities and position
current_position=2*(rand(dim,N));/
velocity=3*rand(dim,N);
local_best_position = current_position;
//evaluate initial population
x1=current_position;
y=x1^2;
current_fitness=y;
local_best_fitness = current_fitness;
global_best_fitness=min(local_best_fitness);
for i=1:N
g=find(current_fitness==min(current_fitness));
global_best_position(:,i)=local_best_position(:,g);
end
//velocity update
velocity = weight*velocity + const_c1*(R1.*(local_best_position-current_position)) + const_c2*(R2.*(global_best_position - current_position));
//swarm update
current_position = current_position + velocity;
//evaluate a new swarm
iter=0;
while(iter < = Number_Iter)
iter = iter + 1;
x1=current_position;
y= x1^2;
current_fitness=y;
disp(iter); disp(i);
for var = 1 : N
if current_fitness(var) < local_best_fitness(var) then
local_best_fitness(var) = current_fitness(var);
local_best_position(var) = current_position(var);
end
end
current_glob_bestfitness = min(local_best_fitness);
if (current_glob_bestfitness < global_best_fitness)
global_best_fitness = current_glob_bestfitness;
for var2=1:N
g=find(current_fitness==min(current_fitness));
global_best_position(var2)=local_best_position(g);
end
end
velocity = weight * velocity + const_c1*(R1.*(local_best_position - current_position)) + const_c2*(R2.*(global_best_position - current_position));
current_position = current_position + velocity;
plot(x1,y,'or');
y1=min(y);
end