# Compte Rendu Projet Cartographie Biométrique

Polytech Montpellier

Paul Chaillou

Juin - Août 2019
Table des matières

<table><tr><td>Introduction</td><td>3</td></tr><tr><td>Modèle Matlab</td><td>3</td></tr><tr><td>1 – Commande cinématique</td><td>3</td></tr><tr><td>2 – Cartographie</td><td>4</td></tr><tr><td>A – Balayage</td><td>4</td></tr><tr><td>B – Interpolation polynomiale</td><td>5</td></tr><tr><td>C – Cartes des variations angulaires</td><td>8</td></tr><tr><td>3 – Adaptation angulaire</td><td>8</td></tr><tr><td>4 – Prévention collision</td><td>8</td></tr><tr><td>Commande du bras robotique</td><td>9</td></tr><tr><td>1 – Le logiciel de commande</td><td>10</td></tr><tr><td>2 – Communication TCP/IP</td><td>11</td></tr><tr><td>Mesure de profondeur</td><td>12</td></tr><tr><td>1 – Premier prototype</td><td>12</td></tr><tr><td>2 – Laser</td><td>12</td></tr><tr><td>3 – Étalonnage de la mesure de profondeur</td><td>13</td></tr><tr><td>4 – Prise de mesure</td><td>14</td></tr><tr><td>Cartographie</td><td>14</td></tr><tr><td>1 – Rectification</td><td>14</td></tr><tr><td>2 – Tests de cartographie</td><td>15</td></tr><tr><td>3 – Enregistrement des cartes</td><td>16</td></tr><tr><td>Données Biométriques</td><td>16</td></tr><tr><td>1 – Déclenchement du laser Opotek</td><td>16</td></tr><tr><td>2 – Récupérations des informations du Spectre de masse</td><td>17</td></tr><tr><td>3 – Utilisation des données</td><td>18</td></tr><tr><td>Pour aller plus loin</td><td>20</td></tr><tr><td>Conclusion</td><td>20</td></tr></table>
## Introduction

J'ai réalisé mon stage de fin de quatrième année (équivalent MI) au sein du laboratoire Defrost, à l'Inria.

L'objectif du projet était de réaliser la commande d'un bras manipulateur robotique 6 axes pour réaliser la cartographie biométrique d'un organe ou d'une parcelle de peau.

Le projet était en collaboration avec le laboratoire INSERM qui a conçu un dispositif capable d'analyser rapidement la composition d'un tissu. A l'aide d'un laser réglable, le dispositif vaporise quelques cellules, qui sont ensuite aspiré à l'aide d'un tube jusqu'à un spectromètre de masse qui crée le spectre de masse de la cellule.

Ainsi, allié à un bras robotisé qui balaye la parcelle de peau, on peut ainsi recréer une carte en 3 dimensions contenant des informations sur les cellules qui la compose. On pourrait ainsi imaginer recréer une carte 3D de la peau affichant, par exemple, les zones cancéreuses dans une couleur différente. Ce dispositif pourrait servir d'outil au chirurgien pour lui permettre de savoir précisément ou se trouve le cancer et agir en conséquence. A termes, l'objectif de l'équipe, qui ne s'occupe habituellement que de robots déformables, serait d'utiliser ce dispositif avec un robot déformable pour scanner les organes atteints de tumeurs ou de métastases directement dans le corps du patient.

## Modèle Matlab

Durant le premier mois, j'ai réalisé une simulation du robot pour me familiariser avec la problématique et tester les différentes solutions.

### I - Commande cinématique

J'ai commencé par adapter la commande cinématique d'un bras réalisé lors du semestre 7, pour avoir un modèle de robot pour mes tests, et pour être capable de commander le robot en position cartésiennes (j'utiliserais au final la commande cinématique livrée avec le robot). Je ne vais pas détailler le fonctionnement de la commande cinématique, je mettrais le rapport du projet que j'ai réalisé en cours en annexe.

On peut tout de même noter que pour l'adapter, j'ai dû reprendre mes paramètres DH, auxquels j'ai ajouté deux articulations fixes : une pour un coude qui était présent sur le robot, et une pour le dispositif que je vais mettre au bout robot (cette dernière n'était pas indispensable pour le modèle Matlab, mais aurait pu être utile pour l'utilisation réelle du robot).
```
robot.joint(2).DH = [0              0              teta1 robot.l1];
robot.joint(3).DH = [-pi/2         0              -pi/6+teta2  0];
robot.joint(4).DH = [0              robot.l2         -2*pi/6+teta3 0];
robot.joint(5).DH = [pi/2          robot.l3_bis      0      0];
robot.joint(6).DH = [0              teta4 robot.l34 ];
robot.joint(7).DH = [-pi/2         0              teta5-2*pi/6   0];
robot.joint(8).DH = [pi/2          0              teta6          robot.l5 ];
robot.joint(9).DH = [0              0              robot.pointe]; %ajouter
```

## Paramètres DH sur Matlab

Il faut bien faire attention à bien adapter le reste des fonctions de la commande cinématique à ces nouvelles articulations.

Il faut aussi évidemment ajouter les autres caractéristiques du robot, comme la taille des différents segments, les vitesses maximales et butées articulaires, etc.

On peut voir dans l'illustration ci-contre le laser au bout du bras robot, dont je n'ai représenté que 4 cm, la distance d'utilisation du dispositif de mesure spectrométrique et l'articulation fixe perpendiculaire que j'ai ajouté.

<figure><img src="image_1.png" /></figure>

## 2 – Cartographie

Grâce à un dispositif de mesure de profondeur dont j'explique le fonctionnement plus loin dans le rapport, je recrée une carte en 3 dimensions de la surface de ce que nous voulons analyser. Je fais balayer le robot, qui enregistre dans une matrice les différentes hauteurs enregistrées.

### A – Balayage

Pour créer cette carte 3D, je dois balayer la surface de l'objet. Pour ce faire, je balaye la surface en effectuant un slalom pour minimiser la distance parcourue par le robot et gagner du temps. J'utilise la fonction modulo pour faire passer le robot successivement dans le sens des x croissant puis décroissant.

```
if ( mod(u,2) == 0 )
v = 0;
for j = objet.dec : scan.pas : objet.dim+objet.dec-1
```
Tous ces points enregistrés régulièrement sont ensuite stockés dans une matrice, qui servira de carte pour se repérer dans la surface scannée, dont les dimensions dépendent de la taille de la surface à scanner et du pas entre chaque prise de mesure.

<figure><img src="image_2.png" /><figcaption>Simulation du robot lors de la création d'une carte</figcaption></figure>

J'hésitais entre deux solutions pour les cartes : effectuer un premier balayage pour créer la carte puis un second pour y ajouter les informations biométriques, ou alors créer la carte et faire l'analyse biométrique en même temps. J'ai effectué différents tests comparatifs, et il s'est avéré que, même si cela peut paraître contre-intuitif, il est plus rapide d'effectuer d'abord la cartographie puis le scan biométrique. En effet l'effecteur final du robot est à des hauteurs différentes lors de la cartographie et lors du scan biométriques, alors le robot devait sans cesse réaliser de petits allers-retours entre ces hauteurs. De plus, la deuxième méthode ne permet ni l'adaptation angulaire par rapport à la surface, ni l'interpolation polynomiale qui devient inutile.

## B – Interpolation polynomiale

Pour que la carte de la surface soit proche de la réalité en ne prenant pas trop de points, je réalise une approximation polynomiale entre les points successifs. Cela permet d'avoir une surface lisse, c'est important pour avoir une carte fidèle et car on doit s'assurer que l'effecteur du robot est bien orienté de façon perpendiculaire à la surface pour réaliser des prises de mesure précises. J'ai réalisé deux interpolations polynomiales, une du second et une du troisième ordre.
Pour réaliser l'interpolation polynomiale du second ordre, j'utilise la fonction Matlab polyfit() qui trouve le polynôme de second degré passant par les trois points que je lui passe en argument.

x = [u-1, u, u + 1];
y = [carte.r(u-1,v), carte.r(u,v), carte.r(u+1,v)];
q(u, :) = polyfit(x,y,scan.n);

J'ai donc un polynôme pour chaque groupe de 3 points. Entre deux points successifs, sauf pour les bords, j'ai donc deux polynômes pour relier ces deux points entre eux. Pour ne pas perdre d'informations et ne pas éviter d'avoir des effets de crêtes, je fais la moyenne de ces deux polynômes entre ces deux points :

a = p(u-1,1)*k^2 + p(u-1,2)*k + p(u-1,3);
b = p(u,1)*k^2 + p(u,2)*k + p(u,3);
if a =~ 0
    o2(g,v) = (a + b) / 2;
else
    o2(g,v) = b;
end

J'utilise ensuite ces polynômes pour calculer un nombre de points voulus entre les mesures effectuées précédemment. Ce nombre de points dépend donc de la précision voulue du modèle.

Je réalise d'abord le calcul des polynômes puis des points en x. J'utilise ensuite ces points pour calculer les nouveaux polynômes en y puis pour ajouter les points. Pour améliorer la précision de l'approximation, je pourrais effectuer les interpolations en x et en y alternativement jusqu'à obtenir la précision désirée. Pour l'application présente, j'ai estimé que réaliser toutes les approximations en x puis toutes celles en y permettaient d'avoir une précision suffisante. D'autant que pour ne pas trop perdre d'information, je préfère augmenter la fréquence d'échantillonnage et ainsi n'utiliser l'interpolation polynomiale que comme un complément ( en général entre 4 et 8 nouveaux points entre chaque prise de mesure ).

Malheureusement, l'interpolation du seconde ordre n'était pas suffisante et ne permettait pas de lisser suffisamment la surface, j'ai dû donc passer à une interpolation du troisième ordre. En effet les polynômes me permettent de prendre en compte les dérivés des points, et donc d'assurer la continuité des points entre eux sans arrêtes.

Pour le troisième ordre, j'utilise la même méthode que pour le second ordre. J'utilise la fonction polyfit(), cette fois ci entre 4 points.

b̃ = p̃(v,1)*k^3 + p(v,2)*k^2 + p(v,3)*k + p(v,4);
if b~= 0
    carte.o(u,g) = b + b_offset;
Je n'utilise ce polynôme du 3ème ordre qu'entre les deux points centraux, pour justement pouvoir assurer la continuité entre les points. Je n'effectue donc plus de moyenne comme pour le second ordre. Cette méthode a une contrepartie : je n'ai pas d'interpolation entre les points aux extrémités de la surface à scanner. Je réalise la carte complète avec les interpolations du 3ème ordre et je comble les extrémités sans points par les points trouvés avec l'interpolation du second ordre.

On peut voir ici différentes cartes réalisées, à des précisions différentes : à gauche, la surface généré par Matlab ; au milieu la carte reconstituée à partir des prises de mesures et à droite la carte reconstituée grâce aux interpolations polynomiales entre les points mesurés.

<figure><img src="image_3.png" /></figure>
## C – Cartes des variations angulaires

Je dois adapter l'orientation de mon effecteur à la surface à scanner : Je dois donc savoir par rapport à quels angles le robot dois s'orienter.

Pour avoir ces angles, je calcule deux cartes de variations angulaires, une en x et une en y, utilisant la fonction tangente pour connaître l'inclinaison selon ces axes en fonction du point précédent et du point suivant :

```
x = [carte.y_o(u-1,v), carte.y_o(u+1,v)];
y = [carte.o(u-1,v), carte.o(u+1,v)]; %
dx = x(2) - x(1);
dy = y(2) - y(1);
% carte.a_ul(u,v) = atan(dy/dx);
carte.a_u(u,v) = atan2(dy,dx); %les deux méthodes sont identiques
```

J'enregistre ces angles dans deux carte, carte.a_u et carte.a_v, de la même dimension que la carte obtenue après l'interpolation polynomiale, pour savoir à quel point de la surface chaque angle correspond.

## 3 – Adaptation angulaire

Une fois que les angles représentant la variation d'une surface ont été enregistrés, il faut que la commande les utilise pour s'adapter automatiquement à la surface. J'utilise donc ces variations angulaires dans des matrices de rotations pour calculer l'angle désiré de l'effecteur du bras robot.

```
robot.alpha = -carte.a_u(u,v)/fact_angle + pi;
robot.sigma = carte.a_v(u,v)/fact_angle; %+ pi
gamma = 0;
A_x = RotX robot.sigma);
A_y = RotY (robot.alpha);
A_z = RotZ(gamma);
A_d = A_x(1:3,1:3)* A_y(1:3,1:3) * A_z(1:3,1:3);
```

## 4 – Prévention collision

En plus de commander le robot de manière précise, il faut s'assurer, pour la sécurité des patients, des médecins, et pour ne pas endommager le robot, que celui-ci n'entre pas en collision avec son environnement. J'ai ajouté une fonction collision() qui assure un minimum de sûreté de fonctionnement en bloquant le robot avant qu'il n'entre en collision avec le sol, lui-même ou la surface à scanner. S'il se rapproche dangereusement de l'un de ces obstacles,
la fonction renvoie d'abord quelques messages préventifs, avant de se bloquer si le rapprochement devient critique.

```matlab
if z < e_c
    stop = 1;
    disp(' Robot trop proche du sol => arret sécurité ')
elseif z < e_w
    disp('Attention robot proche du sol');
end
```

Pour la surface à scanner, j'ai opéré en deux étapes : si le robot n'a pas encore scanné l'objet, il doit se tenir à une distance supérieure à la hauteur maximale de l'objet estimé qui a été rentré par l'utilisateur. Cette hauteur est aussi utilisée pour fixer la hauteur à laquelle dois se fixer le bras robot pour effectuer le premier balayage.

Si jamais Matlab renvoie ces messages ou se bloque alors qu'il ne risque de causer aucun problème, il faut redéfinir les distances de sécurité e_c ( écart collision ) et e_w ( écart warning ) dans la fonction collision().

## Commande du bras robotique

<figure><img src="image_4.png" /><figcaption>MECA500 équipé du dispositif d'analyse biométrique</figcaption></figure>

Le bras robotique choisit par l'équipe est le MECA500 développé par Mecademic, une entreprise canadienne basée à Montréal, développé au Centech, une centre d'aide au développement crée par l'ETS, l'école de Technologie Supérieure de Montréal.

<figure><img src="image_5.png" /><figcaption>Boitier d'alimentation du MECA500</figcaption></figure>
Le robot est fourni avec un boitier d'alimentation, sur lequel est ajouté un bouton d'arrêt d'urgence, au cas où le robot mettrait en danger des biens ou des personnes.

Ce robot a été choisi car c'est le bras manipulateur le plus précis du marché. C'est aussi le plus petit, avec un espace de travail de 26 cm, ce qui est suffisant pour l'application présente.

# I – Le logiciel de commande

Le robot est fourni avec une interface de commande pré faite, qui permet de commander le robot avec plusieurs fonctions et d'écrire de petits scripts exécutables que l'on peut enregistrer.

Pour lancer cette interface web, il suffit de taper l'adresse IP du robot (192.168.0.100) dans un navigateur web, comme Chrome ou Firefox.

<figure><img src="image_6.png" /><figcaption>Capture d'écran de l'interface web du MECA500</figcaption></figure>

Cette interface est plutôt utile pour dédebugger et prendre en main le robot, mais je ne l'utiliserai pas, mis à part pour quelques tests. Matlab est plus complet et me permet d'interfacer directement le robot et la caméra pour la mesure de profondeur, et propose des fonctions pour afficher des surfaces en 3 dimensions. De plus, Matlab propose dans sa
Bioinformatics Toolbox des fonctions permettant l'analyse de fichier .mzXML qui contiennent les informations du spectre de masse, ce qui rend beaucoup plus facile la mise des données biométriques sur la carte.

## 2 – Communication TCP/IP

Le robot est connecté via Ethernet et utilise le protocole TCP/IP. Pour commander le robot, il faut lui envoyer des trames prédéfinies, qui se terminent par le caractère ASCII nul.

Pour initialiser le robot, il faut envoyer une trame pour l'activer et une trame pour l'étalonner. Le robot effectue un petit mouvement, puis le mouvement inverse pour revenir à la position initiale, cela lui permet de connaître précisément la position initiale de toutes les articulations, très utiles pour la commande cinématique.

Le robot peut être commandé en position angulaire comme en position cartésienne. Il existe plusieurs trames pré faites qui permettent de paramétrer et de commander le robot.

J'ai écrit des fonctions Matlab pour envoyer les bonnes trames en fonction des positions désirées :

```matlab
function set_pos(a,t)
    global robot
    data = "MovePose("+a(1)+","+a(2)+","+a(3)+","+a(4)+","+a(5)+","+a(6)+")"+char(0);
    data = char(data);
    robot.arret = collision_top(a(1),a(2),a(3));
    if robot.arret == 0
        fwrite(t,data);
        %pause(0.2);
        % h = 0;
        while tAvailable == 0 % && h < 100 % attend le message
            % h = h + 1;
        end
        data = fread(t, tCTRAvailable);
        m = char(data);
        m1 = convertCharsToStrings(m);
        m2 = convertContainedStringsToChars(m1);
        m3 = m2(2 : 5 );
        u = str2double(m3);
        if u ~= 3012 %& length(m) == 22
            robot.arret = 1;
        end
    else
        disp('robot arrêté par sécurité');
    end
```

Je teste si la position que j'essaie d'envoyer ne risque pas d'aboutir à un problème avec la fonction collision, auquel cas la trame n'est pas envoyée. J'attends ensuite la trame retour n°3012, qui atteste que le robot est arrivé à la position désirée, pour être sûr que le robot passe bien par toutes les positions voulues.
# Mesure de profondeur

## I - Premier prototype

J'ai réalisé un premier prototype de mesure de profondeur, qui mesure seulement si l'ensemble formé par la webcam et le pointeur laser se rapproche ou s'éloigne d'une surface.

Pour ce faire, j'ai utilisé une fonction Matlab trouvées sur leur site, qui renvoie la position d'un point laser sur une image.

Plus le dispositif et loin de la surface, plus le point laser est proche du centre de l'image, c'est du à l'angle de vue de la caméra. Je peux donc utiliser cet écart pour estimer si le dispositif se rapproche ou s'éloigne.

Ce premier prototype est concluant et j'estime que cette méthode est une solution viable pour créer un modèle 3D d'une surface, et je peux donc commander une caméra miniature de meilleure qualité pour avoir une précision acceptable pour la suite.

## 2 - Laser

Le pointeur laser utilisé est, à la base, un petit pointeur laser donné en tant que 'goodies' aux partenaires et lors des conférences de l'Inria. Il est alimenté par deux piles boutons 392/384 de 1,55 V. Le laser n'étant pas conçu pour une utilisation en continu (lorsque que je cartographie plusieurs objets à la suite, il peut rester allumés durant plusieurs heures de suite), il consommait les piles très rapidement. De plus, l'intensité du laser décroissait ce qui rendait la détection du laser problématique. Pour éviter des changements réguliers, qui auraient étés fastidieux et onéreux, j'ai choisi d'alimenter le laser directement en USB, ce qui permet de l'alimenter depuis un ordinateur ou directement depuis une prise secteur à l'aide d'un adaptateur.

Pour ce faire, j'ai dû adapter les 5 V en sortie de la prise USB aux 3,1 V nécessaire au bon fonctionnement du laser. J'ai donc utilisé un pont diviseur de tension et un montage suiveur pour l'adaptation d'impédances. J'ai utilisé deux résistances de 470 et 330 kΩ et un ampli OP LM324N. J'ai choisi cette solution et ces composants en fonction de ce qui était à ma disposition au workshop du laboratoire, pour avoir un dispositif fonctionnel le plus rapidement possible. J'ai aussi ajouté un commutateur pour pouvoir allumer et éteindre le laser sans avoir à le débrancher.

J'ai aussi imprimé un boîtier en 3D pour ne pas laisser traîner la petite carte électronique et pour fixer le bouton.
<figure><img src="image_7.png" /><figcaption>Vue de l'intérieur du boîtier du pointeur laser</figcaption></figure>

<figure><img src="image_8.png" /><figcaption>Boitier du pointeur laser</figcaption></figure>

## 3 – Étalonnage de la mesure de profondeur

Pour mesurer la profondeur avec précision et annuler l'effet de distorsion qu'ont les lentilles des caméras, j'effectue un étalonnage des positions des points laser en fonction de la hauteur de l'effecteur final du robot. J'effectue deux mesure, une ou je fais monter l'effecteur

final entre deux hauteurs choisies et une ou je le fais descendre entre ces mêmes hauteurs. Je compare ensuite ces deux tableaux, pour que le tableau final soit cohérent. En effet si deux mesures à la même hauteur ne renvoient pas la même position en pixel, la mesure n'est pas utilisée par la suite, car j'ai estimé qu'il était préférable de ne garder que les valeurs précises dans le tableau, quitte à ce qu'il y ait moins de points dans ma courbe représentant l'évolution de la hauteur en fonction du décalage en pixels.

<figure><img src="image_9.png" /></figure>
De plus, pour supprimer de potentielles autres valeurs fausses, j'utilise la fonction `tabcontinu()` qui vérifie que les différentes valeurs du tableau sont bien continus et qui supprime les valeurs fausses.

Lors de l'utilisation du tableau, je fais une interpolation du troisième ordre avec la méthode que pour la cartographie : je calcule le polynôme en fonction de 4 points grâce à la fonction `polyfit()` et je n'utilise ce polynôme qu'entre les deux points centraux.

Pour ne pas avoir à refaire la calibration de la mesure à chaque fois, j'ai créé deux fonctions `record_etal()` et `load_etal()` pour pouvoir enregistrer l'étalonnage.

## 4 – Prise de mesure

Pour récupérer la hauteur de la surface, je fais la différence entre la hauteur mesurée et la hauteur réelle de l'effecteur final du robot.

```c
for z = 1 : si(2)-3
    if abs(d_y) < abs(new_tab(2,z+1)) && abs(d_y) > abs(new_tab(2,z+2))
        hauteur_1 = ( new_tab(1,z) + new_tab(1,z+1) ) / 2;
    y = [ new_tab(1,z) new_tab(1,z+1) new_tab(1,z+2) new_tab(1,z+3) ];
    x = [ new_tab(2,z) new_tab(2,z+1) new_tab(2,z+2) new_tab(2,z+3) ];
    p = polyfit(x,y,3);
    hauteur_1 = p(1)*d_y^3 + p(2)*d_y^2 + p(3)*d_y + p(4);
    hauteur_2 = scan.h - hauteur_1
    mes_ok = 1;
end
end
```

Pour choisir la hauteur optimale à laquelle mettre l'effecteur final du robot, je choisis de le placer au vingtième point du tableau, plus la hauteur maximale de l'objet à analyser, pour être sûr que la mesure ne soit pas impossible (position du point rouge en pixel en dehors du tableau).

## Cartographie

### I – Rectification

Lors de la cartographie, pour éliminer les valeurs fausses, je supprime toutes les valeurs supérieures à la hauteur maximale de l'objet ( en effet il arrive parfois qu'il y ai quelques points incohérents ). Je supprime aussi toutes les valeurs négatives, car dans l'application présente, on mesure de la hauteur d'un objet sur un support, et les valeurs négatives sont donc impossibles.

Les valeurs ainsi supprimés sont remplacés par la moyenne des valeurs justes environnantes.
## 2 – Tests de cartographie

Pour tester la précision de ma cartographie et vérifier la pertinence de ma solution, j'ai réalisé quelques cartes de certaines surfaces :

- d'un morceau de placo, dans lequel j'ai fait différents trous :

<figure><img src="image_10.png" /></figure>

<figure><img src="image_11.png" /></figure>

- d'une clé USB avec un petit relief, pour tester la précision sur de petites surfaces avec de petits dénivelés :

<figure><img src="image_12.png" /></figure>
<figure><img src="image_13.png" /></figure>

<figure><img src="image_14.png" /></figure>

## 3 – Enregistrement des cartes

Pour pouvoir réutiliser les cartes et toutes leurs informations, il fallait trouver un moyen de stocker ces informations dans un fichier. J'ai donc créé un format .map qui contient tous les différents points de la carte. Pour pouvoir recréer la carte fidèlement, la première ligne de ce document contient les dimensions du tableau, les lignes suivantes contiennent les positions des différents points en x, y et z. J'ai créé deux fonctions, une pour stocker les informations dans le document et une pour lire les informations, ce qui permet ensuite de les afficher et de les traiter dans Matlab.

Cette fonction s'est avérée indispensable, car la cartographie et la mise des informations biométriques se font sur deux ordinateurs différents, et il fallait un moyen de passer les cartes d'un ordinateur à l'autre.

# Données Biométriques

## I – Déclenchement du laser Opotek

Le laser de la société californienne Opotek permet, de par sa grande précision, de vaporiser quelques cellules, qui après avoir été aspirées, sont analysées par le Spectromètre de masse. Pour pouvoir réaliser nos cartes biométriques, il faut donc pouvoir déclencher automatiquement ce laser pour déclencher une prise de mesure à chaque position.

Ce laser ne se situe pas dans les longueurs d'ondes visibles, et c'est pour ça que l'on doit utiliser deux lasers distincts, un pour la Spectrométrie de masse et un pour la cartographie. Leur dispositif utilise une diode qui a la même distance focale que le laser et qui permet d'ajuster à l'œil la distance entre la pointe du dispositif et la surface à analyser. Cette diode n'étant nette qu'à une distance précise, elle n'était pas utilisable pour réaliser la cartographie.

<figure><img src="image_15.png" /></figure>
Le laser est commandé par un logiciel Opotek complètement fermé, il fallait donc trouver une solution rapidement réalisable. Ainsi, j'ai démonté une souris d'ordinateur et j'ai remplacé le bouton du clic gauche par une des pins de l'Arduino, pour pouvoir commander cette souris directement par Matlab. En effet Matlab a développé des toolbox tout spécialement pour commander des cartes arduino en temps réel.

<figure><img src="image_16.png" /><figcaption>Intérieur du boitier du cliquez automatisé</figcaption></figure>

<figure><img src="image_17.png" /><figcaption>Cliqueur, avec l'ordinateur et le laser Opotek</figcaption></figure>

J'ai cherché des solutions moins contraignantes et plus élégantes, mais cette solution était pour moi la plus simple et la plus rapide. Je voulais être sûr d'avoir une solution fonctionnelle pour pouvoir continuer la suite du projet sans perdre de temps.

## 2 – Récupérations des informations du Spectre de masse

Les informations sont enregistrées par le logiciel du spectromètre de masse sous la forme d'un fichier brut `.raw`. Il faut alors les convertir pour les rendre utilisables dans Matlab. Nous utilisons le logiciel ProteoWizard qui permet de les convertir au format `.mzXML`.

Dans un premier temps, je récupère les informations du spectre de masse sous la forme d'une structure à partir du fichier `.mzXML`. Ensuite, je dois identifier quelles informations correspondent à de réelles prise de mesure. En effet, le spectromètre de masse analyse les informations en temps réel, et je dois identifier quelles mesures correspondent à de réelles prise d'informations. Pour ce faire, nous réalisons une prise de mesure toutes les 3 secondes, et lors du déclenchement du laser il y a une augmentation du courant d'ionisation due à l'augmentation de la quantité de matière qui passe dans le spectromètre de masse. Ainsi, je devais détecter une augmentation périodique du courant d'ionisation, et n'utiliser que le spectre de masse associé. Pour ce faire, je dois connaître le temps de début et de fin d'acquisition, et je prends des maximums espacés de trois secondes. J'ai commencé par prendre une mesure toutes les 3 secondes, mais à cause de certains délai que l'on ne peut pas anticiper ( temps d'aspiration des molécules dans le tube, temps de calcul, temps de

<figure><img src="image_18.png" /></figure>
déplacement du robot), seules les premières valeurs étaient juste. Ainsi, pour ne garder que les valeurs voulues, à chaque fois que je trouve un maximum (une valeur voulue) je prends le maximum suivant qui est approximativement 3 secondes plus tard.

Lors de certaines cartographies, une partie de la carte représente le support sur lequel est pose ce que nous voulons analyser. Il est totalement inutile et même problématique d'essayer d'analyser biométriquement le sol, car le tuyau qui aspire les molécules est très proche de la surface, et en essayant d'analyser le support ce tube pourrait toucher ce que nous essayons d'analyser. J'utilise donc un seuil d'analyse, et si sur la carte topographique, la hauteur mesurée est inférieure à ce seuil, le point n'est pas analysé biométriquement.

Pour savoir si ma reconstruction est juste, je compare le nombre de points devant contenir des informations biométriques et le nombre d'informations triées et jugées comme correspondant à ces points à partir de la spectrométrie de masse. Lors de mes reconstructions, ces valeurs étaient à chaque fois similaire, de l'ordre de 1 à 5 points d'écart en moyenne, ce qui est satisfaisant vis à vis du nombre de point dans une carte (au moins 400 pour une petite carte).

## 3 – Utilisation des données

Pour savoir quel point de la carte correspond quel spectre de masse, je parcours le tableau comme lors du scan.

Ainsi, pour chaque prise de mesure (point sur la carte), j'ai un spectre de masse associé. Ne pouvant pas afficher l'intégralité d'un spectre de masse sur une carte en 3 dimensions à l'aide d'un code couleur, il a été choisi d'afficher sur la carte l'intensité dans une gamme de charge.

Pour que la valeur soit utilisable, il faut normaliser en utilisant cette formule :

$$ \frac{(\text{intensité} \times \text{médiane\_des\_intensités})}{\text{intensité\_totale}} $$
Ainsi par exemple, nous pouvons afficher sur la carte en 3D l'intensité du signal pour plusieurs rapports masse/charge m/z différents :

<figure><img src="image_19.png" /></figure>

Extrait du rapport sur la première cartographie d'un morceau d'éponge avec informations biométriques

Nous pouvons voir que la reconstruction avec le seuil de détection fonctionne bien, car, en plus d'avoir le bon nombre d'informations biométriques, les informations se trouvent bien sur le morceau de poulet que nous voulons cartographier :

<figure><img src="image_20.png" /></figure>

Cartographie biométrique trois dimensions d'un échantillon de chair de poulet
A la demande de l'INSERM, j'ai ajouté une fonctionnalité permettant de réaliser rapidement des scans en deux dimensions :

<figure><img src="image_21.png" /><figcaption>Cartographie deux dimensions d'une tranche de cerveau de rat</figcaption></figure>

J'ai ensuite ajouté deux fonctions pour pouvoir enregistrer et lire ces nouvelles cartes avec les informations biométrique (format .biomap).

## Pour aller plus loin

- Par manque de temps, je n'ai pas développé d'interface permettant d'utiliser plus facilement les programmes. Matlab propose des outils pour la réaliser.

- On pourrait ajouter le seuil de détection pour le scan biométrique dans les informations contenues dans la carte .map, pour éviter d'avoir à la rentrer à la main.

## Conclusion

J'ai trouvé ce stage très intéressant et constructif, particulièrement le fait d'avoir à collaborer avec plusieurs personnes de milieux scientifiques différents, ce qui m'a permis de m'ouvrir et varier mes expériences. C'était une des premières fois ou je devais réaliser un dispositif qui devait être utilisé par d'autres personnes, par forcément habitué à l'utilisation de ce type de logiciel. Cela a bien mis en évidence l'importance de bien commenter le code et de prendre en compte les utilisateurs lors de la conception d'une solution.