Il y a un ordinateur embarqué dans tirobot et un microcontrôleur pour l'interface des senseurs et le contrôle des moteurs. Ici, on pourrait dire que le cerveau est le Raspberry Pi et le
cervelet c'est le Arduino. Ce qui est bien, les deux peuvent se parler via USB, ce qui fourni aussi le courant au Arduino. Cependant, le Raspberry Pi sera programmé en Python et c'est du
code C qui est compilé pour le Arduino. Il faut donc écrire un mini protocole de communication entre le deux. Tant qu'à ce définir un protocole, vaut mieux le développer tout de suite en introduisant les contraintes auxquels ont risque de faire face durant le développement et pourquoi pas penser au future avec des ajout possible.
Le format est que j'ai implémenté est assez simple:
- 2 octets pour le numéro de la commande
- 1 octet pour la taille complète de la commande incluant sont numéro et l'octet de la taille ( valeur minimum de 3 finalement).
- Liste de paramètre étant soit un octet signé ou non, 2 octet signé, 4 octets signé ou un virgule flottant sur 4 octet ( float).
Pour ne pas avoir à trop coder pour chaque commande, je me suis défini un format bien simple pour décrire les commandes. J'utilise un classeur sous Google Drive que j'exporte en .CSV et j'ai du code Python qui transforme le fichier .CSV en code python et arduino capable de décoder et encoder en binaire la commande en plus de générer le squelettes des méthodes de traitement des commandes. Par exemple:
1 | Avance | Avance le robot de x unites | 2 | a | Unite | i16 | Vitesse | u8 |
La commande numéro 1, dont le nom est "Avance" ayant comme description "Avance le robot de x unites" a deux paramètres. Cette commande est envoyée vers le arduino ( "a" signifie arduino et "p" pour le code python et il est possible d'inscrire les deux). Le premier paramètre se nomme "Unite" et est un entier signé sur 2 octet ( int 16 bit ) et le deuxième paramètre se nomme "Vitesse" et est un entier non signé d'un octet ( unsigned byte ).
Le générateur de code a comme sortie deux fichier, un étant le code arduino et l'autre le code python.
Le fichier .CSV suivant:
1,Avance,Avance le robot de x unite,2,a,Unite,i16,Vitesse,u8,,
2,Tourne,Fait tourné le robot sur x degree,2,a,Degree,i16,Vitesse,u8,,
Permet d'avoir le code suivant en python:
## Avance le robot de x unite
class AvanceCommand( BaseCommand ):
""" Avance le robot de x unite """
def __init__(self):
CommID = 1
nbrParam = 2
Unite = 0 #BaseInitType
Vitesse = 0 #BaseInitType
def decode(self, bytearray ):
Unite = bytearray[0] #BaseInitType
Vitesse = bytearray[1] #BaseInitType
def encode(self, bytearray ):
Unite = 0 #BaseInitType
Vitesse = 0 #BaseInitType
## Fait tourné le robot sur x degree
class TourneCommand( BaseCommand ):
""" Fait tourné le robot sur x degree """
def __init__(self):
CommID = 2
nbrParam = 2
Degree = 0 #BaseInitType
Vitesse = 0 #BaseInitType
def decode(self, bytearray ):
Degree = bytearray[0] #BaseInitType
Vitesse = bytearray[1] #BaseInitType
def encode(self, bytearray ):
Degree = 0 #BaseInitType
Vitesse = 0 #BaseInitType
def HandleDecodeCommand( bytearray, commID ):
retcomm = None
if commID = 1:
retcomm = AvanceCommand()
retcomm.decode(byteArray)
elif commID = 2:
retcomm = TourneCommand()
retcomm.decode(byteArray)
return retcomm
Et celui-ci pour le arduino:
int DecodeAndHandleCommand(commID, char* databuffer)
{
switch (commID){
1: // Decode commande Avance
{
// Unite int
// Vitesse int
Avance(*(int*)&databuff[0], (int)databuff[2]);
}
break;
2: // Decode commande Tourne
{
// Degree int
// Vitesse int
Tourne(*(int*)&databuff[0], (int)databuff[2]);
}
break;
}
}
int Avance(int Unite, int Vitesse)
{
// Avance le robot de x unite
}
int Tourne(int Degree, int Vitesse)
{
// Fait tourné le robot sur x degree
}
Il ne reste que le code de gestion des ports séries et l'implémentation interne des commandes à écrire, le reste se génère seul. Possiblement que j'augmenterai le générateur avec d'autres fonctions tel la gestion d'enum ou encore de constante. Mais pour le moment c'est déjà un minimum intéressant, et pas débogué ni terminé en passant! Le code python n'est pas encore fonctionnel.