Asservissement-Positionnement

Usine à Gaz - Fonctionnement interne


Introduction

Une seule remarque ici, il convient de consulter l'historique de cette chose. Après ceci, il est clair que la documentation de la chose n'est pas simple. Il ne s'agit pas d'essayer de décrire tous les éléments, mais plutôt de donner des références pour trouver ce que l'on recherche ....

Documentations

Aucune, le code source.

Code Usine à Gaz - Fichiers

Ce code situé dans ProjetsAjout\Asservissement-balisees\asser_dsp_new\lm629_dsp, est constitué d'une myriade de fichiers :

  • bgenio.c,bgenio.h. Ces 2 fichiers (de mon cru), permettent d'utiliser un driver maison (BGENIO.SYS), pour effectuer des accès sur des ports sous NT (ex écrire dans un registre du port parallèle). Il ne s'agit pas des dernières versions.
  • calcul.c. Ce fichier conserve quelques routines de calcul, utilisées lorsque le LM était relié directement sur le port //
  • calcul.h, en plus des prototypes de calcul.c, contient les premiers ajustages des constantes pour les LM (ancienne base mécanique)
  • carte_chef.c,carte_chef.h, ces 2 fichiers contiennent la gestion de la boite 'carte chef' qui permet de piloter la carte principale via le port série. Ces 2 fichiers sont quasiment indépendants du reste. Il s'agit d'un exemple de gestion de fenêtre et de gestion du port série.
  • com_dsp.c, com_dsp.h, ces fichiers contiennent, à la fois une gestion de la boite dsp_util, et une 'pseudo' gestion des différents mode de communication. Il y'a aussi quelques fonctions (haut niveau) qui permettent le chargement du code sur la carte DSP.
  • com_i2c.c, com_i2c.h, sont les fichiers permettant de communiquer en I2C avec la carte d'asservissement via l'interface (à base de PIC) sur le port //
  • Les fichiers suivant, contiennent les routines (fournies par TI, et remodifiées), permettant de charger du code dans la carte Starter Kit
    • driver.c,dsk.h.routines bas niveau.
    • dsk_coff.c, dsk_coff.h, le chargement des fichiers hexa et/ou format starter kit
    • errormsg.c, messages d'erreur.
    • keydef.h, touches du clavier ???
    • object.c, gestion de qqchose
    • symbols.c, ???
    • target.c, commandes 'haut niveau'
    • typedefs.h, définition des correspondances de type 'TI'
  • flash.c, flash.h, contiennent toutes les routines permettant de flasher la carte DSP (via le PC), et gère la boite associée.
  • get_mem.c, get_mem.h, permettent d'aller lire le contenu de zones mémoire de la carte DSP (côté utilisateur). Appliqué à plusieurs cas (debug de ligne, trajectoire courbes, etc). Gestion de la fenêtre associée.
  • goto_home.c, goto_home.h, gestion d'une fenêtre minimale acceptant les touches du clavier pour faire déplacer le robot. Gestion de cette fenêtre, envoi des commandes directement via le debug à la carte DSP.
  • graphique.c, contient une très grande partie des routines graphiques utilisées pour dessiner le terrain. Quelques autres fonctions aussi ...
  • graphique.h, contient les prototypes de ces fonctions et quelques constantes graphiques.
  • handle.h, contient un certain nombre de variables globales (handle de fenêtres, timers, etc).
  • hard.c, fonctions de bases permettant de recréer un bus sur le port paralèlle.
  • hard.h, constantes associées.
  • lm629.h, constantes propres au LM629 (ordres,etc)
  • main.c, boite principale, timers d'update des différentes boites, en fonction des modes de fonctionnement.
  • res.h, constantes associées aux boites.
  • res.rc, contenu des boites (ressources)
  • sequenceur.c, sequenceur.h, code de la boite du séquenceur et séquenceur proprement (enfin propre, ça euh hum ... c'est vite) dit.
  • std.c, std.h, routines permettant d'aller lire dans le .map généré par le linker TI, l'adresse d'une variable globale ..
  • tmsfloat.c, tmsfloat.h, routines de conversion des formats de floats des DSP TMS320 vers le format IEEE (PC)
  • trajectoire.c, trajectoire.h, premier générateur minime de trajectoire, abandonné.
  • user.c, user.h, routines de haut niveau permettant de commander le LM.

Aucun commentaire n'est nécessaire quand au côté usine à gaz (presse-purée ... héhé), de la chose.

Les choses intéressantes en dehors de l'usine à gaz, là dedans :

  • bgenio qui peut être réutilisé n'importe où. Fonctionellement complètement identique à DLPortIo, ce truc avait été refait pour se passer d'une install. Il sert à effectuer des lecture/ecriture sur n'importe quel port du PC (in out).
  • tmsfloat.c qui effectue les conversions entre les formats de float PC<->TMS.
  • lm629.h, pour ne pas se retaper les constantes une fois de plus ...
  • std.c, std.h permettant de parser un fichier .map
  • graphique.c qui contient un exemple de fenêtre grpahique dessinée à la main.
  • routines TI permettant le chargement dans la carte.

Aperçu global

Quasiment impossible à réaliser.

Le fichier main.c contient le point d'entrée (WinMain). A partir de là sont créées les différentes autres fenêtres, initialisés les drivers permettant de causer ,etc.

Ce fichier contient le code de 2 timers :

  • Timer_para
  • Timer_i2c

qui vont permettre de venir périodiquement mettre les données à jour (pour la boite principale en particulier). En fonction du mode de fonctionnement (choisi dans la petite boite -- dont le code est dans com_dsp.c), soit l'un ou l'autre ou aucun des timers est activé.

Ensuite chaque boite réalise plus ou moins sa propre tambouille. Un certain nombre de variables globales permettent de gérer les différents accès (com avec le DSP par ex). Il y'a aussi un certain nombre d'intéractions (ex : get_mem mets ses données à disposition dans le cas du debug du recalage de ligne à graphique.c qui pourra les afficher)

Quelques fichiers sont inclus directement depuis le code source du DSP ("..\asser_dsp\robot.h" par ex). Cette métohde permet de s'assurer qu'il s'agit exactement du même header qui a été inclus, à la fois dans le code DSP et dans le code PC. L'opération est utile pour le debug.

dans hard.h, une constante WINNT permet d'utiliser les E/S pour NT ou 9X
//#define WINNT // INDIQUE si le prog est compilé pour NTx ou 9x

 

Points particuliers

BGenIO

Pour utiliser ces routines, il faut commencer par appeler BGenIO_init(), et en fin de session, BGenIO_exit(). L'initialisation va charger le driver BGenIO.sys qui devra se trouver dans le rep où se trouve le soft.

Par la suite les commandes style BGenIO_inportb, permettent de lire et écrire sur les ports.
Ces routines fonctionnent pour WinNT,2K,XP.

Pour 9x, il est utilisé un bout de code assembleur, compilé dans ProjetsAjout\Asservissement-balisees\asser_dsp_new\lm629_dsp\lcc\outportb.obj
Les prototypes correpondant sont définis dans hard.h

extern void _outportb(int add,int val);
extern int _inportb(int add);
extern void _outportw(int add,int val);

 

Carte_Chef

La boite associée est créée par void create_carte_chef(HWND hwnd);. La création de cette boite est déclenchée dans com_dsp.c (qui gère la petite barre en haut).

La boite créée, permet de gérer la carte principale via le port série. Le port série est initalisé par HANDLE init_rs232(HWND hwnd). Cette fonction crée un thread qui recevra les différents caractères venu du port série. La carte principale envoie en permanence ses infos de debug, elles seront affichées dès que le thread aura reçu quelquechose de cohérent.

L'envoi des commandes (clic sur des boutons) se résume à un envoi de caractères sur la liason série par void send_rs232(char *data, int n)

Com_DSP

Ce fichier contient le code de la petite boite permettant de switcher entre les différents modes. void create_dsp(HWND hwnd) permet de créer la boite. En fonction du debug (//, I2C, aucun), les timers sont crées, tués, etc. Ce fichier contient aussi les fonctions 'très haut niveau' gérant la communication avec le DSP :(La petite boite peut aussi les déclencher -- chargement du code, etc,etc)

  • int init_com_dsp(), initialise notamment les E/S sur le PC (BGenIO) (vérifie aussi qu'il s'agit bien ou non de NT)
  • void de_init_com_dsp(), ferme le driver
  • int init_DSK3(void), initialise la com avec le DSP, vérifie que la carte DSP est bien branchée, y charge le KERNEL dedans.
  • int chargement_programme(char DSK_APP[]), permet de charger le code (utilisateur) dans le DSP
  • void init_user_part(), permet d'initaliser, de charger le fichier dans le DSP et de lancer ce code (avec le *fameux* SINGLE_STEP indispensable avant l'execution, sinon le debug plante). Cette routine écrit ensuite dans une zone réservée dans le DSP et y relit pour voir si le code n'est pas *déjà* planté (en gros, que le KERNEL est toujours fonctionnel).
  • void proc_envoi_direct(int data[],int len), qui permet d'envoyer des ordres directement au DSP (via le debug //)
  • le nom du fichier envoyé dans le dsp (et executé) est défini dans flash.h
    #define PROG_NAME "..\\..\\asser_dsp\\lcc\\asser_dsp.out"

Com_I²C

Ce fichier contient le code permettant d'envoyer des trames I²C, via l'interface sur le port //

  • int get_busy(); permet de récupérer l'octet de status de la carte d'asservissement.
  • void proc_envoi(int add,int cmd,int data[]); envoie une certaine quantité de données
  • le reste sont des fonctions plus bas niveau spécifiques à cette com'.

Driver.c

    Routines bas niveau pour la communication avec le LM. Rebidouillées pour le port sous win. Les fonctions sont documentées pour certaines dans le guide du starter kit.

Dsk_coff.c

Routine pour la lecture et l'écriture des fichiers starter kit, raw, hex, etc

Flash

Contient la boite utilisée pour le flashage et le test de la RAM, et de la flash. Cette boite est créée par : void create_flash(HWND hwnd);

  • int check_bootload(HWND hwnd) permet de s'assurer que le programme utilisateur n'EST PAS en train de s'exécuter (et que les routines de com' : KERNEL) sont bien chargées dans le DSP. Utilisée lorsqu'il faut tester ram ou flash et /ou flasher. Sans cette précaution, le programme tournant dans le DSP viendrait effectuer n'importe quoi (lire et écrire dans la RAM ou la flash) et les actions ne seraient pas correctes.
  • void test_ram(HWND hwnd); effectue un test de la RAM.
    Cette routine commence par déterminer la quantité de RAM présente sur la carte.
    L'adresse de départ est fixée par : #define RAM_ADD 0x0900000
    Une info est écrite à chaque adresse puissance de 2, on écrit ensuite une autre info à l'adresse de base.
    Si on récupère la 1ère info, il y'a toujours de la mémoire à cette adresse. Sinon non. Il faut faire attention aux 'images' mémoire. Il n'y que les adresses nécessaires de décodées pour la zone mémoire. On a donc accès au même élément physique à l'@ de base et à l'@ de base + taille mémoire.
    Vient ensuite un test basique (écriture complète puis relecture)
  • static void sel_fic(HWND hwnd); permet d'afficher la boite d'ouverture de fichier.
  • void set_flash_read(); void set_flash_write(); réalise un accès à une @ précise(indiquée en dessous) permettant de passer la flash en LECTURE ou ECRITURE (cf description carte)

dans flash.h

#define ADD_BASE 0xC00000
#define EN_WRITE_FLASH ADD_BASE+0xA
#define EN_READ_FLASH ADD_BASE+0xC

  • void flash_soft(HWND hwnd);
    convertit le fichier format 'dsk', en fichier binaire, image à flasher directement dans la flash. (Pour pouvoir être bootloadé)
    écrit ce fichier en flash
  • void aff_dump(HWND hwnd,int pos); rafraichit la fenêtre de dump dans la boite (contenu de la flash), appelée à chaque fois que cette fenêtre nécessite d'être mise à jour (changement d'@, de contenu, etc)
  • void flash_reset(); void flash_sector_erase(int sec); void flash_test(HWND hwnd); void flash_getid(int *manufacturer,int *device_id,int *secteur_protection); void flash_erase(HWND hwnd); void wait_write_end(); etc ...
    commande spécifique à la flash (cf datasheet de la flash)
    La flash, une fois effacée peut être programmée (bits mis à 0). Il n'est pas possible de les remettre à 1 sans effacer la flash. On peut soit effacer entièrement la flash, soit effacer uniquement un bloc.
    • void flash_reset(); RAZ, permet d'être sûr de ne pas être dans un mode spécial de la flash
    • void flash_test(HWND hwnd); permet d'identifier la flash (product ID), en fait permet surtout de savoir si la flash répond bien
    • void flash_getid(int *manufacturer,int *device_id,int *secteur_protection); utilisé par flash test
    • void flash_sector_erase(int sec); efface un seul sector
    • void flash_erase(HWND hwnd); efface complètement la flash
    • void flash_byte(int add,int data); écrit un octet de flash
    • void wait_write_end(); attend la fin de l'écriture dans la flash
    • la lecture étant un accès banal à cette adresse (get_mem)
  • dump_flash(HWND hwnd); permet de dumper le contenu de la flash dans un fichier texte
  • void dump_flash_raw(HWND hwnd); permet de faire une image de la flash (fichier binaire)
  • void dump_ram(HWND hwnd); permet de faire un dump de la ram (fichier binaire)
  • void dump_ram_raw(HWND hwnd); permet de faire un dump texte de la ram
  • void flash_fic(HWND hwnd,char *fic,int offset); effectue le flashage complet d'un fichier binaire (effacement si nécessaire, flashage, vérification)

GetMem

Contient la boite utilisée pour récupérer des données dans le DSP. Cette boite a servi à de nombreux debug (ligne, LM, i2C, etc). Elle inclut quelques fichiers du code DSP (structure de debug)

La boite est crée par void create_getmem(HWND hwnd);

  • void recup_data_ligne(), récupère les infos du debug de ligne.
  • void recup_data_traj_courbe(), récupère les infos de trajectoire courbe
  • void recup_data_lm(), récupère les données propres au LM (et les envoie par liaison série à un autre soft sur un autre PC, pour les récupérer dans Matlab). Ce sont les routines de carte_chef qui sont utilisées pour la com' série.
  • la récupération se passe en plusieurs étapes :
    • réucupération de l'@ par : add=get_add_var("..\\..\\asser_dsp\\lcc\\asser.map","nb_dbg_l"); on récupère l'@ de la variable nb_dbg_l, on indique la localisation du fichier .map (get_var est dans std.c)
    • on récupère ensuite les données. (get mem)
    • on les affiche
  • void aff_dbg_ligne(); affiche les infos de debug de recalage de ligne dans les boites à droite.
  • void aff_dbg_traj_courbe(TRAJ_COURBE *tc); affiche les infos de debug d'une trajectoire courbe (dans la boite à gauche)
  • void set_dbg_ligne(int n); indique l'info à afficher pour le recalage de ligne (dans cette boite et sur le graphique du terrain)
  • void recup_mem(); récupère une certaine quantité de mémoire à une certaine adresse.

Goto_Home

Pur produit de faignantise.
void create_gh(HWND hwnd);
crée la boite. Cette boite lorsqu'elle est sélectionnée envoie un message WM_KEYDOWN pour chaque touche appuyée. En fonction des touches les ordres sont envoyés au robot.
void step(int s); envoie un ordre au LM (com' directe par debug //), utilise la routine dans com_dsp.c pour l'envoi.
void step(int s); envoie un ordre(en velocity mode) au LM (com directe par debug //), utilise la routine dans com_dsp.c pour l'envoi.

Graphique

Usine à gaz s'occupant des dessins du terrain et autres éléments du style (robot, balise,etc). A subit x modifications depuis le début.

Doc dans graphique.h

  • void create_terrain(HWND hwnd); crée la fenêtre. Il s'agit d'une fenêtre créée de toute pièce (c'est à dire non issue d'une ressource).
  • void process_fichier(HWND hwnd); affiche des données issues d'un fichier texte (position des boules sur le terrain, pour le debug de la caméra ... #define FIC_DATA "terrain.txt")
  • DWORD WINAPI make_ordre(void *a); envoie un ordre lorsque l'on clique quelque part sur le terrain (fait aux portes ouvertes, pour amuser le chef ... aïe pas sur la tête !)
  • void tracerAireDeJeu( HWND hwnd ); bah euh explicite non ? tout le terrain l'arrière plan, les lignes, etc,etc <Mode glandage ON>
  • void tracerTerrain(HWND graphe, HDC hdc, float reduCoef); // Trace le terrain vert ... hum oui ...
  • void tracerLignesBlanches(HWND graphe, HDC hdc, float reduCoef); // Trace les lignes blanches du terrain
  • void tracerPaniers(HWND graphe, HDC hdc, float reduCoef); // Trace les paniers en gris, les notres (où on met les boules rouges) étant entourés de bleu et ceux de l'adversaire de noir
  • void tracerBalises(HWND graphe, HDC hdc, float reduCoef){ // Trace les balises en gris, les notres (où on met les boules rouges) étant entourées de bleu et celles de l'adversaire de noir
  • void tracerContours(HWND graphe, HDC hdc, float reduCoef){ // Trace les contours du terrain vert en gris
  • void tracerRectangle(HWND graphe, HDC hdc, float reduCoef, int length, int highth, short x_center, short y_center, short borderWidth, int borderColor, int contentColor){ // Trace un rectangle (Valeurs en 10emes de mm)
  • void tracerLigne(HWND graphe, HDC hdc, float reduCoef, int x_start, int y_start, short x_end, int y_end, int width, int color){ // Trace une ligne blanche
  • void dessinerBoule(HWND hwnd_terrain,HDC hdc,float reduCoef,int x,int y,int c){ // Tracer une boule
  • void tracerCercle(HWND graphe, HDC hdc, float reduCoef, int x_center, int y_center, short radius, short width, int color){ // Trace un cercle
  • void tracerPartDeTarte(HWND graphe, HDC hdc, float reduCoef, short x_center, short y_center, short radius, short angle_1, short angle_2, short width, int borderColor, int contentColor) { // Trace un arc de cercle rempli (Valeurs en mm) <Mode glandage OFF> part de tarte ? oui, c'est celà ...
  • void dessinerZeus(HWND graphe, HDC hdc, float reduCoef, position newPosition) { // Dessine un robot circulaire à sa nouvelle position et trace les positions précédentes
    Le robot est 'xoré' sur le terrain ce qui permet de l'effacer beaucoup plus facilement si on connait son ancienne position à l'appel suivant
  • void dessinerSnooky(HWND graphe, HDC hdc, float reduCoef, position newPosition) { // Dessine Snooky
  • void dessinerAdv(HWND graphe, HDC hdc, float reduCoef, position newPosition) { // Dessine un robot circulaire
  • void afficherBoule(HWND hwnd, int x,int y,int c){ // Affiche une bouboule ...
  • void afficherPosition(HWND hwnd, position newPosition, codewheels lmValues, int clearScreen){ // Met à jour l'affichage de la position du robot
    C'est à dire efface l'ancienne position si nécessaire, affiche la nouvelle, etc
  • void afficherPositionAdv(HWND hwnd, position newPosition, int clearScreen){ // Met à jour l'affichage de la position du robot

    Idem pour l'adversaire (balise)
  • void marquerAnciennePosition(HWND graphe, HDC hdc, float reduCoef, position oldPosition){ // Marque d'un point rouge une ancienne position
  • void afficherRecalage(HWND hwnd_terrain); Affiche quelques gribouillis sur le terrain correspondant à une info de recalage de ligne
  • void TracerLigneTraj(float posx,float posy); trace une trajectoire du séquenceur

Hard

Recréation du bus de données sur le port // pour y connecter directement les LM.
Quelques constantes et commentaires dans hard.h

 

Sequenceur

Gestion du séquenceur.

  • void create_sequenceur(HWND hwnd); affiche la boite correspondante
  • Les 'pas' du séquenceur (une instruction) sont stockés directement dans la list box à gauche (sous forme de texte). Lorsqu'on en extrait (ou crée un), on le met dans une structure :
    typedef struct{
    int posx;
    int posy;
    int angle;
    int v;
    int a;
    }SEQ_PAS;
  • les fonctions sont prototypées au début du .c et très très sommairement commentées.
  • les séquences peuvent être chargées et enregistrées sur disque, en fichiers .SM6 (il en traine un grand nombre).
  • une séquence est exécutée par : void deroule_sequence(void)
  • cette fonction crée un thread qui se charge de tout le déroulement : DWORD WINAPI seq_exec(void *a)
  • BOOL ouvre_fichier(HWND hwnd,char *sortie,int taille_buffer), affiche la boite de choix d'ouverture de fichier


Std

Permet de parser le .map pour trouver l'adresse correspondant à une variable globale dans le DSP : long get_add_var(char *fic,char *var). Quelques routines de traitement de fichiers textes par ligne.

TmsFloat

Convertit un float du DSP en float du PC. et inversement. Conversion d'autres formats aussi.

Trajectoire

Première usine à gaz de gestion des trajectoires. Abandonnée, et non décrite ici.

User

Commande 'haut niveau' pour le LM (lorsque la commande est réalisée par le port // avec LM directement dessus ). (équivalent de LM_629.C sur le dsp). Contient quelques commentaires sur le positionnement (valeur, remarques,etc)

 





Rentrer plus dans les détails aboutirait à une doc inexploitable (déjà que ...). Ce code est un immonde empilement de fonctions, d'utilisation de morceaux dans d'autres fichiers, etc,etc. C'est un CODE DE DEBUG.