Salut,
bon là j'ai un vrai clavier, mais pas trop le temps d'écrire un roman
tu as déjà fait de la programmation orientée objet ?
le C n'est pas orienté objet (c'est justement la différence entre C et C++), mais on peut reprendre pas mal des principes de l'objet en l'écrivant explicitement :
En objet, on ferait une classe PID comme ca (les méthodes sont bidons, mais c'est pour l'exemple) :
public class PID
{
public PID(int kp, int ki, int kd)
{
m_kp = kp;
m_kd = kd;
m_ki = ki;
m_position = 0;
m_lastdelta = 0;
m_lastint = 0;
}
public int Target
{
get
{
return m_target;
}
set
{
m_target = value;
m_lastdelta = 0;
m_lastint = 0;
}
}
public void UpdatePosition()
{
// mettre ici le code qui gère l'encodeur
}
public int Step(int timeElapsed)
{
// calcul le PID :
int erreur = m_target - m_position;
int derive = (erreur - m_lastdelta) / timeElapsed;
int integr = m_lastint + erreur * timeElapsed;
int result =
m_kp * erreur +
m_kd * derive +
m_ki * integr;
m_lastdelta = erreur;
m_lastint = integr;
return result;
}
private int m_kp; // coef kp
private int m_kd; // coef kd
private int m_kd; // coef kd
private int m_target; // la position voulue
private int m_position; // position actuelle
private int m_lastdelta; // dernière erreur de position
private int m_lastint; // dernière intégration de l'erreur
}
Voilà pour l'objet, dans les grandes lignes (désolé s'il y a des erreurs, j'ai pas de visual studio sous la main ...)
(pour info, c'est du code C# que j'ai écrit).
Comment reprendre les mêmes grandes lignes en C :
On commence par décrire une structure avec les champs :
struct PID
{
int m_kp; // coef kp
int m_kd; // coef kd
int m_kd; // coef kd
int m_target; // la position voulue
int m_position; // position actuelle
int m_lastdelta; // dernière erreur de position
int m_lastint; // dernière intégration de l'erreur
}
et ensuite on définit les "méthodes" en explicitant "this" :
void PIDConstructor(PID this, int kp, int ki, int kd)
{
this.m_kp = kp;
this.m_kd = kd;
this.m_ki = ki;
this.m_position = 0;
this.m_lastdelta = 0;
this.m_lastint = 0;
}
int PIDStep(PID this, int timeElapsed)
{
// je réécrit pas tout le code, mais suffit de mettre this. devant les noms de variables ...
}
etc ...
Par contre je te conseille vivement de passer la structure PID par référence et pas par valeur (en fait c'est même obligé) pour des raisons de perfs (et parce que sinon le PID ne se met jamais à jour, c'est la copie qui est mise à jour ...).
Gros avantage de cette méthode ... tu peux très simplement utiliser la sortie d'un PID comme étant l'entrée d'un autre PID, et les imbriquer comme ca (ca permet de faire de l'asservissement de position ET de vitesse ET d'accélération ...).
Bien entendu, c'est un premier jet et il faudrait affiner tout ca, mais l'idée est là.
Et après ta boucle principale devient :
main()
{
PID my_pid;
PIDConstructor(my_pid, 1, 2, 3);
// ici tu lance un timer
while(true)
{
PIDUpdatePosition(my_pid);
int timeElapsed = timer.value;
timer.value = 0;
mavaleurdePWM = PIDStep(my_pid, timeElapsed);
// et ici tu met n'importe quel code pour faire autre chose, gérer un écran LCD, un clavier, s'en fout ... c'est le principe d'un micro OS en temps partagé.
}
}
Si j'ai un peu de temps (et de courage) je ferais le programme C pour PIC33, il me faudrait juste un étage de puissance basique et un moteur avec encodeur pour faire les tests (j'ai une carte Explorer 16 et un ICD2).
++
[EDIT] j'ai dis une betise, j'ai des moteurs avec encodeurs qui vienne de mes années robotique, il me faudrait donc juste un étage de puissance pas trop dégueu genre L6203. Si quelqu'un a ca en stock ... une fois que ca marche, un petit coup de protel pour faire le pcb, un coup de fil à euro-circuit pour faire quelques exemplaire, qq1 qui les soude, les programme, et hop c'est parti ...