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 :
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
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.
|