From 09579d31bda6d384e8e547e936c61b71414188dc Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 13 Apr 2025 15:49:05 +0200 Subject: [PATCH] =?UTF-8?q?D=C3=A9but=20de=20l'approche=20des=20gradins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cerveau/Cerveau.ino | 115 +++++++++++++++++- ...{Communication_chassis.h => Com_chassis.h} | 0 ...munication_chassis.ino => Com_chassis.ino} | 0 ...dversaire.h => Com_detection_adversaire.h} | 0 ...saire.ino => Com_detection_adversaire.ino} | 0 Cerveau/Com_gradins.h | 12 ++ Cerveau/Com_gradins.ino | 28 +++++ Doc/Communication I2C.odt | Bin 26720 -> 27208 bytes 8 files changed, 150 insertions(+), 5 deletions(-) rename Cerveau/{Communication_chassis.h => Com_chassis.h} (100%) rename Cerveau/{Communication_chassis.ino => Com_chassis.ino} (100%) rename Cerveau/{Communication_detection_adversaire.h => Com_detection_adversaire.h} (100%) rename Cerveau/{Communication_detection_adversaire.ino => Com_detection_adversaire.ino} (100%) create mode 100644 Cerveau/Com_gradins.h create mode 100644 Cerveau/Com_gradins.ino diff --git a/Cerveau/Cerveau.ino b/Cerveau/Cerveau.ino index 9caa08f..3714860 100644 --- a/Cerveau/Cerveau.ino +++ b/Cerveau/Cerveau.ino @@ -3,8 +3,9 @@ #include #include -#include "Communication_chassis.h" -#include "Communication_detection_adversaire.h" +#include "Com_chassis.h" +#include "Com_detection_adversaire.h" +#include "Com_gradins.h" #include "ServerWeb.h" @@ -99,7 +100,7 @@ int tolerance_position =100; float tolerance_orientation =0.03; // 2° -char* tableau[] = {"Lecture serveur", "Prise position", "Verif mvmt end ou cmd", "Compar position", "Deplacement absolu"}; +char* tableau[] = {"Lecture serveur", "Prise position", "Verif mvmt end ou cmd", "Compar position", "Deplacement absolu", "Approche gradin"}; char* statu[] = {"/..","./.","../"}; int index_statu=0; @@ -267,6 +268,8 @@ void gestion_match(){ struct chassis_reception_t chassis_reception; struct chassis_emission_t chassis_emission; struct triangulation_reception_t triangulation_reception; + struct detect_gradin_t detect_gradin; + enum etat_action_t etat_action; static int translation_x_mm, translation_y_mm; static float rotation_rad; static int couleur; @@ -277,6 +280,7 @@ void gestion_match(){ DEPLACEMENT_RELATIF=2, MATCH_EN_COURS=3, TEST_DEPLACEMENT_ABSOLU=4, + TEST_APPROCHE_GRADIN=5 }; switch(index_Maitre){ @@ -307,8 +311,7 @@ void gestion_match(){ translation_y_mm = 0; rotation_rad = 0; - index_Maitre = DEPLACEMENT_RELATIF; - Scan_Triangulation(&triangulation_reception); + index_Maitre = TEST_APPROCHE_GRADIN; } if(M5.BtnB.read() == 1){ Serial.println("BtnB"); @@ -365,6 +368,28 @@ void gestion_match(){ index_Maitre = ATTENTE_ORDRE; } break; + + case TEST_APPROCHE_GRADIN: + if(gradin_approche() != ACTION_EN_COURS){ + index_Maitre = ATTENTE_ORDRE; + affichage_standard_init(); + } + + /* + do{ + char chaine[200]; + Detect_gradin(&detect_gradin); + sprintf(chaine, "I2C OK\nStatus:%d\nCentre X:%4d\nCentre Y:%4d\nAngle:%2.2f\n", detect_gradin.status, + detect_gradin.centre_x_mm, detect_gradin.centre_y_mm, detect_gradin.angle_rad / M_PI * 180); + affiche_msg("Detect gradin", chaine); + // if(detect_gradin.status == 2){ + // while(deplacement_relatif(0, 0, - detect_gradin.angle_rad, 0) != ACTION_TERMINEE); + // } + }while(fabs(detect_gradin.angle_rad / M_PI * 180) > 0.5); + //index_Maitre = ATTENTE_ORDRE; + //affichage_standard_init(); + break; + */ } } @@ -466,6 +491,83 @@ enum etat_action_t Strategie(int couleur){ } +enum etat_action_t gradin_approche(void){ + static enum{ + GA_INIT, + GA_CHERCHE_GAUCHE, + GA_CHERCHE_DROIT, + GA_GOTO_LARGE, + GA_GOTO_PROCHE, + GA_GOTO_PREND + } statu_approche_gradin = GA_INIT; + static float angle_parcouru; + static int nb_erreur; + int translation_x, translation_y; + struct detect_gradin_t detect_gradin; + + Detect_gradin(&detect_gradin); + char chaine[200]; + sprintf(chaine, "I2C OK\nStatus:%d\nCentre X:%4d\nCentre Y:%4d\nAngle:%2.2f\n", detect_gradin.status, + detect_gradin.centre_x_mm, detect_gradin.centre_y_mm, detect_gradin.angle_rad / M_PI * 180); + affiche_msg("Detect gradin", chaine); + + switch(statu_approche_gradin){ + case GA_INIT: + angle_parcouru = 0; + statu_approche_gradin = GA_CHERCHE_GAUCHE; + break; + + case GA_CHERCHE_GAUCHE: + if(detect_gradin.status == 2){ + // On a trouvé ! + statu_approche_gradin = GA_GOTO_LARGE; + nb_erreur = 0; + }else if(detect_gradin.status == 0){ + // On a perdu la détection + statu_approche_gradin = GA_CHERCHE_DROIT; + }else{ + // On tourne à gauche de quelques degrés + while(deplacement_relatif(0, 0, 3. * M_PI / 180., 0) == ACTION_EN_COURS); + } + break; + + case GA_CHERCHE_DROIT: + if(detect_gradin.status == 2){ + // On a trouvé ! + statu_approche_gradin = GA_GOTO_LARGE; + nb_erreur = 0; + }else if(detect_gradin.status == 0){ + // On a perdu la détection + statu_approche_gradin = GA_INIT; + return ACTION_ECHEC; + }else{ + // On tourne à gauche de quelques degrés + while(deplacement_relatif(0, 0, -3. * M_PI / 180., 0) == ACTION_EN_COURS); + } + break; + + case GA_GOTO_LARGE: + Detect_gradin(&detect_gradin); + if(detect_gradin.status != 2){ + nb_erreur++; + if(nb_erreur > 100){ + affiche_erreur("Gradin Approche", "GA_GOTO_LARGE\n Status != 2"); + while(1); + } + } + translation_x = detect_gradin.centre_y_mm - 400 * cos(detect_gradin.angle_rad); + translation_y = -400 * sin(detect_gradin.angle_rad); + if(deplacement_relatif(translation_x, translation_y, 0, 0) == ACTION_TERMINEE){ + statu_approche_gradin = GA_INIT; + return ACTION_TERMINEE; + } + break; + + } + return ACTION_EN_COURS; + +} + /// @brief : compare la position actuelle et la position lue par la balise /// Note : Pour l'instant, on ne déclenche un mouvment qu'en cas d'ecart sur la distance, pas sur l'orientation. @@ -578,6 +680,7 @@ enum etat_action_t deplacement_absolu(int consigne_x_mm, int consigne_y_mm, floa /// @param angle_deplacement direction dans laquelle avance le robot, dans le référentiel du robot int detection_adversaire(float angle_deplacement){ int capteur_central, capteur_precedant, capteur_suivant; + struct detect_adv_reception_t detect_adv_reception; // On ramène l'angle entre 0 et 2 PI. while(angle_deplacement < 0){ angle_deplacement += 2 * M_PI; @@ -595,6 +698,8 @@ int detection_adversaire(float angle_deplacement){ if(capteur_suivant > 11){ capteur_suivant = 0; } + Detect_adv_lire(&detect_adv_reception); + if(detect_adv_reception.distance_cm[capteur_central] < 50 || detect_adv_reception.distance_cm[capteur_precedant] < 50 || detect_adv_reception.distance_cm[capteur_suivant] < 50 ){ diff --git a/Cerveau/Communication_chassis.h b/Cerveau/Com_chassis.h similarity index 100% rename from Cerveau/Communication_chassis.h rename to Cerveau/Com_chassis.h diff --git a/Cerveau/Communication_chassis.ino b/Cerveau/Com_chassis.ino similarity index 100% rename from Cerveau/Communication_chassis.ino rename to Cerveau/Com_chassis.ino diff --git a/Cerveau/Communication_detection_adversaire.h b/Cerveau/Com_detection_adversaire.h similarity index 100% rename from Cerveau/Communication_detection_adversaire.h rename to Cerveau/Com_detection_adversaire.h diff --git a/Cerveau/Communication_detection_adversaire.ino b/Cerveau/Com_detection_adversaire.ino similarity index 100% rename from Cerveau/Communication_detection_adversaire.ino rename to Cerveau/Com_detection_adversaire.ino diff --git a/Cerveau/Com_gradins.h b/Cerveau/Com_gradins.h new file mode 100644 index 0000000..8325890 --- /dev/null +++ b/Cerveau/Com_gradins.h @@ -0,0 +1,12 @@ +#ifndef COM_GRADINS_H +#define COM_GRADINS_H + +#define I2C_SLAVE_detect_gradin 0x19 + +struct detect_gradin_t{ + char status; + int centre_x_mm, centre_y_mm; + float angle_rad; +}; + +#endif \ No newline at end of file diff --git a/Cerveau/Com_gradins.ino b/Cerveau/Com_gradins.ino new file mode 100644 index 0000000..fc2dbe4 --- /dev/null +++ b/Cerveau/Com_gradins.ino @@ -0,0 +1,28 @@ +//#include "Chassis.h" +#include +#include +#include "Com_gradins.h" + + +/// @brief Lit les capteurs VL53L1X +void Detect_gradin(struct detect_gradin_t * detect_gradin){ + unsigned char tampon[14]; + char chaine[200]; + int angle_mrad; + //(Adresse I2c, Adresse dans le registre, tampon, longueur de donnée) + error = I2C_lire_registre(I2C_SLAVE_detect_gradin, 0, tampon, 13); + if (error !=0){ + affiche_erreur("Detect_gradin", "Erreur I2C"); + while(1); + }else{ + + detect_gradin->status = tampon[0]; + detect_gradin->centre_x_mm = tampon[1] << 24 | tampon[2] << 16 | tampon[3] << 8 | tampon[4]; + detect_gradin->centre_y_mm = tampon[5] << 24 | tampon[6] << 16 | tampon[7] << 8 | tampon[8]; + angle_mrad = tampon[9] << 24 | tampon[10] << 16 | tampon[11] << 8 | tampon[12]; + detect_gradin->angle_rad = angle_mrad / 1000.; + + + + } +} diff --git a/Doc/Communication I2C.odt b/Doc/Communication I2C.odt index 539e883641c1e02e8f06a80c1e6c7db0a4eb73d4..b78cc56de6b71cd6aaa4c72b8e453aa8b660b63a 100644 GIT binary patch delta 8840 zcmaJ{Ra9KdwrwD|yEN_&!QBbL3GVI^+@*2XZUVvGg9Ud89^BpCfEJI!QsQ5Lq(q7&Uo?0G1cW~h>NKE*p#B0T z!_a|h6h)Z7$!Tb49BUfbsFgJh)pqo;EDn9PxZl7Z9i+8E>$n`?blex-Ielqh48gYn zTHK&fe?WmQYr&Mm7rbzNrCAMp`XyKQ@bN*o@Iw zTb>3YqFFG&e}I9|2XWpvs6S3rnh$%lg}t~H6Pe*{Cz@t@l7@8G8ZLG|ZeSL#Jx~;% z*M*rSPOOkvj&X|CPJd_63}2Poj~&a=p8L-6b6}mr3&Q^0Z;lu3sc3|_pB~kWn6e$D ztSYC;wI*d3t5xyFal34yh!Q(9TUPdSuD=BR08So)?Bg^1Yu2> zeyx)==)xeqXV-Gkz)N?7FUhe;6hV73@itXM(;nvN0I~A;>sjZo_AM(bbq+ndTwi#0>@7F9-GsNR4bSP8$UTZZg z8KOAm<>;=c*hmk@KC#)~h2Yrn^ovbJ9v*?j8^C@A1psir0RaBBG|5_4|R#-C7 ziVG1xhW|#j)8!9izcrOwwLnP;=x}J_g?+_QuH1%q!ZbF)4^LcXR}l%yQ38*M19GzqMc>;X)0l?{W@U5>MNcNzKhLKJGrB}Jy_l&=2M8<>tv&5~ z_OJ{AuUI-1)Zcbj8D9q6pJrl0ls8(voz`G`muB`KDu|>pE+_nh--$L4E|Jyed?r zjB_k|wBPRH?tGWm&T8p7?MOrp}=;%1U8E*jK?AQ6(uKW_J{2jB22r zYvRMXN_WP?M_R{zCi#Z(_dGnH!Rw=!s#PN2Pxo5*2TvnwDXjSTpJqC!CcY;H_gcl^ z1F5?@c3!X&uar}@Zq2SW^TWfrFY204hO3_iC$qz}^aw^UQ zoZb&8VNvV}6zYC*s=Qq!4=jF3Zx^%Kw=XE%nOF{7J%#pH5A!~qdRlfyY)q2_`6Vyb z)m_{A>eFADVq>Ox8u&xhrRuYKk}1!pc#3M{$;j5h4O|+o9@BlGNVny@8tZ)7P~f&f zN^Ez#>CE$|fbmQiHP@5VM+_cfRkBvGFPUodM?Gd^j~w5-;G&)|`$AfZ&?RvBtMh|o z%QtN>2-8}%xX;c>s!J`4Cb#D5%Zy*qZCiE6&ZEe}uEt=}n_0-Vg20hiC6+)n6X;I} zv_Ms>&r8Yzv_mVPaocD(J$gItWCgWIUk;Zv#IL`KCANqq`$({66?b)wyb)OLefswL zDs=EhFnl@#$-mVGh6*^5(R@J;`NA!|ExbX|xPc)6?e0aB9BqK>%VI3B85=9H7{@2d zn@vInh}eLQYVuc6?+N&Zp*L%LjDc$S@eA)%b6|K1EfXdSh^s4~8AtX!3P)kam;;a+ z26%nq!b8*U#Xw*@y6+Y2Od^!*?8H?!38euiQA-R0-#83`D&^wO| z`7_eZm<4l!@-tUsadLN(FT;5;OK}~eOWJOow|{u(yybi)Hnz-%#)`t&&5U|vwnf1+ zm=DR*N_+P}jueE!@`M_Dr{9!nlTQ^8fRP`C6N;%;zNI_F9{Ak>NI>!h@M zV96yTWZRFb@aB4>-2ru~aNx3p4hfb;J)>DAG286}2*;nr59ZCi7Kf87>>Zk;2{Q+7 zFpCowzlT~pNst`EWvJp$#ktL^cGd>=YlG>4kYT%zo7ON9MjjjAHK;ER{XBe}z1?+k zWuqw!HNQz{%q5IU2vlY8i-2&X^oU0 z)a%BN1VRyGO*!nNA_(^G^l-VDnUr?HMWPN*pFon4SYxf4VE=@|;{lJIJ;OG2)^E=B zrg?AgFbrHX`_o%*ZK?~SrAE#EykbIV$G>QS)ybE3i@!bSEe3C_qi-dQhXl-ahTlcQ zE>DP5DS)^%PDiqqtpu*{e21D+>u0+j&4%(}hD5?G2J!Il7ja`S8+ z9)ui_qUSoUEvFI>)wSUx1KV!>%bE{PeH& z{Rr7d)}Lj&f*JQP8&NkTrpwB718Jld1{1m$60 zTQC|m!Y7|Ce^_g6M{!}V#Ib=&NL%F$OS@uQBr~FWcHPoD4@y~haW8B?%d!3V0z>jA zMfcWZF{VQzOo!NM9! z-2+ubZ5~=l@<=Sjox}YKbqolSVbTUvwt{@#06k+P_wu*N@QNTDJi{J~me+>2TzECD z(ncV5w&bMxL*Z;p=K4~CDh!t5-H&e}!~Oa8ewMJclN+9Rrqo{p??uV3Qyg&mJ=bn4 z1{->&TJM{ACP|L29mGVRg+9XMscA_>D`NBSKo|h5#>DyUr5^{>4CD~{l&s^HO+J*PQ+f`LX?_+9Fsxa%w*?^@8d}8^6iIuD+A`p1DsD9y*3yj66d66 zgcC}+vQ80erU=OMf~V9|R2&B9`dQMUro5xKcQ&XJ;>N>$feqNfnZZ>YC!`~M+x8nE zGc>9WtZUdE4lMhaex)DD=AZZm7cEM$&#-s>!o7IzGzEZ)n=}^%qxU>d2?tM@1*2tx z>qo}9{F<@h(hTM{&X^*--HtQEj&>;|;e7&H5ZAsu+TdZirNhyZ@+q6a1qB4}bOd1) z4u=sVBtnF`g~&U-*a5_HNk;XE&_hxxl5*GEDYc_n&0)M&QBcWjb=h@e)oL9x(K_6H zUIx7U`HBRDOqmwcD<6%f)ETRPVfOX1Cu(2u>w|_hxa@~T#IOfEVG4B&@0R8xz+g;r zR`i2iX(k7GmmnrTYV;5t%6nf`9LwVS_YST(>?+-?#A|ib8LdyB!C&H=ZnyH5@iYx0 zqp5ux`7Tp!l$**1sbTB4YwBpry5Mews~jwIVfrSpF-;s$im04mcq!o{W|eDrA(P4! z7((az*(d(YGZ5-687dc$Z60;jr5BUl;YXufFQ+yss?;SU_&h+YjLHFk>@tAk{`OVeR`r@5%;ScT*9FW>_n-zJ4&mh8ndI*kYdCPmbx8(#h zONVVykGvi=qx>5-g?E#V0Jfj8TSGWA7-|YRV>lpiN*xA^6`R3`cVx=7)eQJVvcB3p zRyy)69^2YpDuu3LryEPPM18x@k*;BcwfFOMgMPSmi{Fv%cQk?A{?C3?{d|Zg&7E;6 zOd!PL7Vv>xE40~8#WHhgh`ga6a_XB~r{SjQJ{oZY{VP9*Rjsk0TuZhG(AnM1GiXd_ zlNbkMu^op!cW^O~Csa#fZ8x=gvnY1nn_`1#jg0EhH5v-%_G@1h1JTb*6wTA{7>W-9 z(jqctoZ#_U3iFv1g}RyG(8O^c;$DUW7En?97>>kOd)eI*i9#O@gth!4GaWnyk0rAb zcVxpf69$T@j9Xor$7|szM%hz zBNVz-UAsJyA=!66KZBI2k%HPd6$yit#U&f<#22Cd?!s9^T@)y;_QE;nPz$BDV^AX-`MBNE zJGYOM`KUYA;>eoD=O}gxdvw90h>vf<93J;1ium@eu%f}!177|vZ$WKDc=e2lex6mY ztfc`;n0tp+6=h1AJ0%V*Ms#zDck;;L_1}uzvp<=D^_wIXo9uhgFszV_wy7cJ0CDIL~KdS}5&Pv|Li zzLD*YdZ5nq#2?X^&y=r&$ zk>?@!CcrN{38~~-nE<^<217)R0*aL2jj~^lk=wP&k+YW;k@OEiZ|A;|?z}Q)t`u0| z6~XxmX}{giiF(k5={+U@OwfbGYvc*Mu9318?c(D;8Q<*S0V9oy(3g#F$_(a(> z{sh<6mA`(;o(IVnTQ&L)r82G)bor~HA(&MqNrv!(xq0hrObgaFEG_GrWOahMr-Hqi z=lM{kM3|O-93poE2;r)Q7G^ukL=02-IuQAYux`8ty+ixi%I3Ik()z2kf84_cC~&ApM9u^qS*bo39i3A+emzba+aW6Argm= z4x35hnZ>%t@>^Y_bWgI_u16;JT5W1Bka-MQ5TSnW21REsxI#ox$@~3d=5!-k)Xb_q zl`;kA$Y?D79>u`Jjk!{{B8b4O?!)`!M&qTHH!SE$HsTJZi+f9`f@AW29%AFekz!=n zDR);V*5#pmpowCF7>tlJSadJqxy6m0#~WLn$@ay(+* zt=tZh`K~(!j71u(L;6Aww-EDJHQUgeM8nN-3I;)vm?Kg(MGfD>274hTnnMp8*HQ&QNs%L zJ3NIe5XsF84&WTV@E5Mn_XUhIjUF@$LYPm`6V^HRQfK7G`l%>7wtPz4np+!s6)iZD z!D8~3v6|!%y;1xCRsSF7iR^D|q}ty#(m!#Td2zgDX1#^JmP=$#DiLt%aTg#xt~>I8 z?-g;}_?TffAXNtB8PP^2uHWsEM8S^P4+gp`fyliI#wqk956j+Edozr^2beYT)ACT4 z$2bhx1t1HeT`){EqKv_xsZv>>LIh!68i%!U)i`l+S}c_DFzZ2aFX0;cd35Rg4ObbD*jEttgM_s)94jix6OaOMwMY@Q03!NhEZ6 z!Z_>0JMZqjto6JrrE?YU63^2189~GKBY*FOG2?|)PYvApv)>~lZB>9Gw)0kN`~tRf z4x}R$Z!5Rbc1{8HbwU!h^VrVz6U&;Dk+yQA6Ay2zn>_=q!0A*^gZh}I-=GN4vO?GO zReV(-%f~_4j(|Y$#Hq@#l}G6==Xvh#OmoPwyRAsw4tLJdg5O$fp#PYbhRIsh!)WLJ z36jcVdbOH|cMJAmb7MCc0K)Zre>+^^U%u-z7H9=y>WBhYt+T8?jC;f>kut-3w{~moKtDdqyqB<>VopD(!O6fJK* zL?UO3=P$HZlbgVMet0io(nuW_q1VfoGIFUp9krw(hIwI1IGsfSoxe_O$^Qc?*vaiu zC={mpK0fE>JjVn*s(wpjefk=K(rrk7YWo$p-SPlvd(MqMW+x}LwO&{5J71_NfeRZs zRB9wiUS1)1S@YqXvtt6}Hf^Q!Xg}+#8RCfCF`;qaGP8c*le2QkzcV{s0xN<)bt9s+ zbWrT>SM|d(#?q!lH;92o@d0-9n3=rXrk|)Dy+f}s?%Wl2-?Us0mMM`7S97xLY~cI! z!m{J(%(!!LR!875ME-U+|5k9T!;X7cykln0sZ|$v^z5-QxUU52n5jSFy1g5k*$AQJ zfS+>6KOlPnzN;J?Z4>%XtzBUB!*F%mMIFEVS7_V44x^HFx@&JK`__*gEe*O+Et{V_ zy{NQJw5Ulf6i%DCZj=b4FoQt~Nm=<>ZTDgU3TC@D?`c&iH=?C?n$KXXh|n0pczqs`u^(Cjd8y8U!F%fpHe8%VANrGD zAJ1j%2=NkJPqnwd;brTf2Fzh5$X*nFZvyQ^=U^#RIgIERGD$|^zGfVO1-20No zV1*8%ZqG)Ei%yB<`)z0&&^9&R{qwgXWXoQ6DFs|q_Ev3eYGBg(+^(|#t@b?C598Fu z87hpiAGtUhK5e&P>2hZg(~|y|FQ8-Wsm~L*_ns%e6XxS~mLGSpS}bi;fg>?puENJI zWEL(WW}#hck?6%VJAon2hbNM_!3QK37!c*gL8sBfOBKkFl9u$ftGf#5H3S|6ZXDtx zp+;_tg>CX%PJMoPF)>tvKbQzIJwq{rcR`4^p1`UkRi}6JVk29n8>&m3(1Uh^72+9H zpmu5%)Us^DdV5HUp^$+x4mvO}DO^->UhjHFuR$!t2`6jm3uG_-^)8L7xShzq3502! zEGSt=*uuIAP7up=d4g<{zp$YtuXy5Zy*k((A55Bx+wNXS+8*a!VW~y$4~d`N8PJ~@-mlHjLsf2Eh`E~ z^TB+V_S(y6s#t-uCOlU@`gl$s7D!%d0;ZgN?Quid>ibV04q0(lzbL7no;MOvrxQd& z^DOtnH0TvZ${e)Pi}Nd-yj_?5D_7C2;H{Gi#@*okfZ z9)|I}U;HGbdFWN<$>MS}hld(@1q*8Z@@7sVoummXl5#NOh7AaDaHj2+fw0n%#x_!Y zHiI$W+ma^BXt(!yx9`*6W8_O0;^D(%Ce3l9#WyAI|9WLT-vcVscJpFN@ z&7aKOTQH9(P!0;T^X!_!F&Cc7l zsSM$TQ&Hl!u8fW?d7_unU;fh>{%W_TvI*u1o(fPs!bSdsn<1PMl6Z_M^_k*N(**Ek_s-G+K3*UjLWt)fvNP(HJ zn4CW&C#c7RzhN^IWgGA(G6vD1^_5Dzb*xcC4Rk_86nitB2j1kscT znPH-8=*^lITR-{~uz4fb^;^*Kc=XBe`9`kV%cn>S1=Ht@Gd~s5I8l*4JiU(i$?z#u zZfL5Olc8ffE!j|1Jp)vkEz6C)tKq9{O)i}wqq<$4pSPWX>AFcy`k|pRDWMtT-}WtPdDOBHmjO-JO_eyw)0r8_P6eQvY_QENA=L z>~(uj`Ae1#8ZLF)!Yxeo;U$UhoyQs$0?N{MtEv;CpwRN;J1kHG>3YNKXD7|juTjkb zjX*8V1%8>ZVSxtjX-RiIpOd{@e6AFo{0Ohc*Gt~n%HE1f^n+~d#lnAx63;)Ojn359c66w#r18=R|P+UvS z90<9)SIhWVvB*J^RWS!cK{NmlBHXA#xE-%v`ftuICY6^WY7MBlR!!#w^@SPzslCF|W+atsR{?ydg(FRp*zllcw)@==y(-W9np%+Ra zg%I~S+1ZANWvuvhzB25>Z#XzH-w~v<;!EtOGEe2r?FlMv9aWL}fpSOja?fjRl6S=?yeyBJ#CeR;USBLB3|;LS z%N@3<(%SPA+nw+YRUh9y|MiH6Sn1Bl}wjNsLt%V&9lFWuYL+&V?IN08()MO7p& zk&iin${V4)Bonpg2q`g)>3E>t_)G%&T8kT5QCuD-Jn$;~D*ES)9j1Wofr1VIoP7JQ zGj?6DspG#Y1#Zm#RcY{I4unXX68ZlhK_L`m#+?2i_t2|QNjb#-W$$-b&{)t(Hvh=~<{cmnmb|EcjQ{U#I^@BU z;jan*J9&@t9}}*Ih+6^w@@8ZOgwlujTG9Qb@$c*g(tl`ZLwc+Tb^iGI_rLRp=lH)y ypz$B9hl>2azTZCtNwRzdGRyDlewyFc{kZ?9_4~=d9Fk;;50SIRfE%;;Gx9$SPhoHX delta 8267 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