2023-03-18 16:59:15 +00:00
|
|
|
#include "pico/multicore.h"
|
|
|
|
#include "stdio.h"
|
|
|
|
#include "hardware/i2c.h"
|
2023-03-26 19:28:13 +00:00
|
|
|
#include "math.h"
|
2023-03-18 16:59:15 +00:00
|
|
|
|
|
|
|
#include "Asser_Moteurs.h"
|
2023-04-01 08:40:30 +00:00
|
|
|
#include "Balise_VL53L1X.h"
|
2023-03-18 16:59:15 +00:00
|
|
|
#include "i2c_annexe.h"
|
|
|
|
#include "i2c_maitre.h"
|
|
|
|
#include "gyro.h"
|
|
|
|
#include "Localisation.h"
|
|
|
|
#include "QEI.h"
|
|
|
|
#include "Robot_config.h"
|
|
|
|
#include "Strategie.h"
|
|
|
|
#include "Temps.h"
|
|
|
|
#include "Trajet.h"
|
|
|
|
#include "Trajectoire.h"
|
|
|
|
#include "Test.h"
|
|
|
|
|
2023-03-26 14:56:34 +00:00
|
|
|
int test_accostage(void);
|
|
|
|
int test_longe(void);
|
2023-04-13 17:43:35 +00:00
|
|
|
int test_panier(void);
|
2023-03-26 14:56:34 +00:00
|
|
|
int test_homologation(void);
|
2023-04-01 08:40:30 +00:00
|
|
|
int test_evitement(void);
|
2023-03-28 21:03:35 +00:00
|
|
|
int test_tirette_et_couleur();
|
2023-04-01 13:29:54 +00:00
|
|
|
void affichage_test_evitement();
|
2023-03-26 14:34:06 +00:00
|
|
|
|
|
|
|
void affichage_test_strategie(){
|
|
|
|
uint32_t temps;
|
2023-03-26 19:28:13 +00:00
|
|
|
|
|
|
|
while(true){
|
|
|
|
temps = time_us_32()/1000;
|
|
|
|
printf(">contacteur_butee_A:%ld:%d\n", temps, i2c_annexe_get_contacteur_butee_A());
|
|
|
|
printf(">contacteur_butee_C:%ld:%d\n", temps, i2c_annexe_get_contacteur_butee_C());
|
|
|
|
printf(">contacteur_longer_A:%ld:%d\n", temps, i2c_annexe_get_contacteur_longer_A());
|
|
|
|
printf(">contacteur_longer_C:%ld:%d\n", temps, i2c_annexe_get_contacteur_longer_C());
|
|
|
|
printf(">V_consigne_A:%ld:%f\n>V_consigne_B:%ld:%f\n>V_consigne_C:%ld:%f\n", temps, AsserMoteur_getConsigne_mm_s(MOTEUR_A), temps, AsserMoteur_getConsigne_mm_s(MOTEUR_B), temps, AsserMoteur_getConsigne_mm_s(MOTEUR_C));
|
|
|
|
printf(">pos_x:%ld:%f\n", temps, Localisation_get().x_mm);
|
|
|
|
printf(">pos_y:%ld:%f\n", temps, Localisation_get().y_mm);
|
|
|
|
printf(">pos_angle:%ld:%f\n", temps, Localisation_get().angle_radian/M_PI*180.);
|
|
|
|
|
|
|
|
printf(">c_pos_x:%ld:%f\n", temps, Trajet_get_consigne().x_mm);
|
|
|
|
printf(">c_pos_y:%ld:%f\n", temps, Trajet_get_consigne().y_mm);
|
|
|
|
printf(">c_pos_angle:%ld:%f\n", temps, Trajet_get_consigne().angle_radian);
|
|
|
|
|
2023-04-01 13:29:54 +00:00
|
|
|
printf(">tirette:%ld:%d\n", temps, attente_tirette());
|
|
|
|
|
2023-03-28 21:03:35 +00:00
|
|
|
printf(">etat_strat:%d\n",etat_strategie);
|
|
|
|
|
|
|
|
/*switch(etat_strategie){
|
|
|
|
case STRATEGIE_INIT: printf(">etat_strat:STRATEGIE_INIT|t\n"); break;
|
|
|
|
case APPROCHE_CERISE_1_A: printf(">etat_strat:APPROCHE_CERISE_1_A|t\n");break;
|
|
|
|
case APPROCHE_CERISE_1_B: printf(">etat_strat:APPROCHE_CERISE_1_B|t\n");break;
|
|
|
|
case ATTRAPE_CERISE_1: printf(">etat_strat:ATTRAPE_CERISE_1|t\n");break;
|
|
|
|
case APPROCHE_PANIER_1: printf(">etat_strat:APPROCHE_PANIER_1|t\n");break;
|
|
|
|
case CALAGE_PANIER_1: printf(">etat_strat:CALAGE_PANIER_1|t\n");break;
|
|
|
|
case RECULE_PANIER: printf(">etat_strat:RECULE_PANIER|t\n");break;
|
|
|
|
case LANCE_DANS_PANIER: printf(">etat_strat:LANCE_DANS_PANIER|t\n");break;
|
|
|
|
case STRATEGIE_FIN: printf(">etat_strat:STRATEGIE_FIN|t\n");break;
|
|
|
|
}*/
|
|
|
|
|
2023-03-26 19:28:13 +00:00
|
|
|
sleep_ms(100);
|
|
|
|
}
|
2023-03-26 14:34:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int test_strategie(){
|
|
|
|
printf("A - Accoster.\n");
|
2023-03-28 21:03:35 +00:00
|
|
|
printf("C - Couleur et tirette.\n");
|
2023-04-13 17:43:35 +00:00
|
|
|
printf("H - Homologation.\n");
|
|
|
|
printf("L - Longer.\n");
|
|
|
|
printf("P - Panier.\n");
|
|
|
|
|
2023-03-26 14:34:06 +00:00
|
|
|
int lettre;
|
|
|
|
do{
|
|
|
|
lettre = getchar_timeout_us(0);
|
|
|
|
}while(lettre == PICO_ERROR_TIMEOUT || lettre == 0);
|
|
|
|
switch(lettre){
|
2023-03-26 14:56:34 +00:00
|
|
|
case 'a':
|
|
|
|
case 'A':
|
|
|
|
while(test_accostage());
|
|
|
|
break;
|
|
|
|
|
2023-03-28 21:03:35 +00:00
|
|
|
case 'c':
|
|
|
|
case 'C':
|
|
|
|
while(test_tirette_et_couleur());
|
|
|
|
break;
|
|
|
|
|
2023-04-01 08:40:30 +00:00
|
|
|
case 'e':
|
|
|
|
case 'E':
|
|
|
|
while(test_evitement());
|
|
|
|
break;
|
|
|
|
|
2023-03-26 14:56:34 +00:00
|
|
|
case 'h':
|
|
|
|
case 'H':
|
|
|
|
while(test_homologation());
|
|
|
|
break;
|
|
|
|
|
2023-03-26 14:34:06 +00:00
|
|
|
case 'l':
|
|
|
|
case 'L':
|
|
|
|
while(test_longe());
|
|
|
|
break;
|
|
|
|
|
2023-04-13 17:43:35 +00:00
|
|
|
case 'p':
|
|
|
|
case 'P':
|
|
|
|
while(test_panier());
|
|
|
|
break;
|
|
|
|
|
2023-03-26 14:34:06 +00:00
|
|
|
case 'q':
|
|
|
|
case 'Q':
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-01 14:44:08 +00:00
|
|
|
|
2023-03-26 14:56:34 +00:00
|
|
|
int test_homologation(){
|
|
|
|
int lettre, _step_ms = 1, temps_ms=0, _step_ms_gyro=2,temps_ms_init;
|
2023-03-26 19:28:13 +00:00
|
|
|
printf("Homologation\n");
|
2023-03-26 14:56:34 +00:00
|
|
|
|
|
|
|
i2c_maitre_init();
|
|
|
|
Trajet_init();
|
|
|
|
//printf("Init gyroscope\n");
|
2023-03-29 21:12:16 +00:00
|
|
|
set_position_avec_gyroscope(1);
|
|
|
|
if(get_position_avec_gyroscope()){
|
|
|
|
Gyro_Init();
|
|
|
|
}
|
2023-03-26 14:56:34 +00:00
|
|
|
|
|
|
|
stdio_flush();
|
|
|
|
|
2023-03-26 19:28:13 +00:00
|
|
|
multicore_launch_core1(affichage_test_strategie);
|
2023-03-26 14:56:34 +00:00
|
|
|
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
temps_ms_init = temps_ms;
|
|
|
|
do{
|
|
|
|
i2c_gestion(i2c0);
|
|
|
|
i2c_annexe_gestion();
|
2023-04-01 13:29:54 +00:00
|
|
|
Balise_VL53L1X_gestion();
|
2023-03-26 14:56:34 +00:00
|
|
|
// Routines à 1 ms
|
|
|
|
if(temps_ms != Temps_get_temps_ms()){
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
QEI_update();
|
|
|
|
Localisation_gestion();
|
|
|
|
AsserMoteur_Gestion(_step_ms);
|
|
|
|
|
|
|
|
// Routine à 2 ms
|
|
|
|
if(temps_ms % _step_ms_gyro == 0){
|
2023-03-26 19:28:13 +00:00
|
|
|
if(get_position_avec_gyroscope()){
|
|
|
|
Gyro_Read(_step_ms_gyro);
|
2023-03-26 14:56:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-26 19:28:13 +00:00
|
|
|
Homologation(_step_ms);
|
|
|
|
|
2023-03-26 14:56:34 +00:00
|
|
|
}
|
|
|
|
lettre = getchar_timeout_us(0);
|
2023-03-26 19:28:13 +00:00
|
|
|
//}while((lettre == PICO_ERROR_TIMEOUT) || (lettre == 0));
|
2023-04-01 08:40:30 +00:00
|
|
|
}while(1);
|
|
|
|
printf("STRATEGIE_LOOP_2\n");
|
|
|
|
printf("Lettre : %d; %c\n", lettre, lettre);
|
|
|
|
|
|
|
|
if(lettre == 'q' && lettre == 'Q'){
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void affichage_test_evitement(){
|
|
|
|
while(1){
|
|
|
|
printf(">min_dist:%d\n",Balise_VL53L1X_get_min_distance());
|
|
|
|
for(uint8_t capteur=0; capteur<12; capteur++){
|
|
|
|
printf(">c%d:%d\n",capteur, Balise_VL53L1X_get_capteur_cm(capteur));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int test_evitement(){
|
|
|
|
int lettre, _step_ms = 1, temps_ms=0, _step_ms_gyro=2,temps_ms_init;
|
|
|
|
struct trajectoire_t trajectoire;
|
|
|
|
printf("Evitement\n");
|
|
|
|
|
|
|
|
i2c_maitre_init();
|
|
|
|
Trajet_init();
|
|
|
|
Balise_VL53L1X_init();
|
|
|
|
Localisation_set(200,200,0);
|
|
|
|
//printf("Init gyroscope\n");
|
|
|
|
set_position_avec_gyroscope(0);
|
|
|
|
if(get_position_avec_gyroscope()){
|
|
|
|
Gyro_Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
stdio_flush();
|
|
|
|
Trajet_config(100, 500);
|
|
|
|
|
|
|
|
multicore_launch_core1(affichage_test_evitement);
|
|
|
|
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
temps_ms_init = temps_ms;
|
|
|
|
do{
|
|
|
|
i2c_gestion(i2c0);
|
|
|
|
i2c_annexe_gestion();
|
|
|
|
Balise_VL53L1X_gestion();
|
|
|
|
|
|
|
|
// Routines à 1 ms
|
|
|
|
if(temps_ms != Temps_get_temps_ms()){
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
QEI_update();
|
|
|
|
Localisation_gestion();
|
|
|
|
AsserMoteur_Gestion(_step_ms);
|
|
|
|
|
|
|
|
// Routine à 2 ms
|
|
|
|
if(temps_ms % _step_ms_gyro == 0){
|
|
|
|
if(get_position_avec_gyroscope()){
|
|
|
|
Gyro_Read(_step_ms_gyro);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Trajectoire_droite(&trajectoire,Localisation_get().x_mm, Localisation_get().y_mm,
|
|
|
|
1000,0,
|
|
|
|
0, 0); // Angles
|
|
|
|
|
|
|
|
if(parcourt_trajet_simple(trajectoire, _step_ms) == ACTION_TERMINEE){
|
|
|
|
etat_strategie = CALAGE_PANIER_1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
lettre = getchar_timeout_us(0);
|
|
|
|
//}while((lettre == PICO_ERROR_TIMEOUT) || (lettre == 0));
|
2023-04-13 17:43:35 +00:00
|
|
|
}while(1);
|
|
|
|
printf("STRATEGIE_LOOP_2\n");
|
|
|
|
printf("Lettre : %d; %c\n", lettre, lettre);
|
|
|
|
|
|
|
|
if(lettre == 'q' && lettre == 'Q'){
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int test_panier(){
|
|
|
|
int lettre, _step_ms = 1, temps_ms=0, _step_ms_gyro=2,temps_ms_init;
|
|
|
|
printf("Test panier\n");
|
|
|
|
|
|
|
|
static enum{
|
|
|
|
TEST_PANIER_INIT,
|
|
|
|
TEST_PANIER_ASPIRE,
|
|
|
|
TEST_PANIER_TEMPO,
|
|
|
|
TEST_PANIER_LANCE_BALLES,
|
|
|
|
TEST_PANIER_PORTE_OUVERTE,
|
|
|
|
} etat_test_panier=TEST_PANIER_INIT;
|
|
|
|
static uint32_t tempo_ms;
|
|
|
|
|
|
|
|
i2c_maitre_init();
|
|
|
|
Trajet_init();
|
|
|
|
//printf("Init gyroscope\n");
|
|
|
|
set_position_avec_gyroscope(0);
|
|
|
|
if(get_position_avec_gyroscope()){
|
|
|
|
Gyro_Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
stdio_flush();
|
|
|
|
|
|
|
|
multicore_launch_core1(affichage_test_strategie);
|
|
|
|
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
temps_ms_init = temps_ms;
|
|
|
|
do{
|
|
|
|
i2c_gestion(i2c0);
|
|
|
|
i2c_annexe_gestion();
|
|
|
|
Balise_VL53L1X_gestion();
|
|
|
|
// Routines à 1 ms
|
|
|
|
if(temps_ms != Temps_get_temps_ms()){
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
QEI_update();
|
|
|
|
Localisation_gestion();
|
|
|
|
AsserMoteur_Gestion(_step_ms);
|
|
|
|
|
|
|
|
// Routine à 2 ms
|
|
|
|
if(temps_ms % _step_ms_gyro == 0){
|
|
|
|
if(get_position_avec_gyroscope()){
|
|
|
|
Gyro_Read(_step_ms_gyro);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(etat_test_panier){
|
|
|
|
case TEST_PANIER_INIT:
|
|
|
|
if(lire_couleur()== COULEUR_VERT){
|
|
|
|
i2c_annexe_ferme_porte();
|
|
|
|
i2c_annexe_active_turbine();
|
|
|
|
etat_test_panier=TEST_PANIER_ASPIRE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TEST_PANIER_ASPIRE:
|
|
|
|
if(lire_couleur()== COULEUR_BLEU){
|
|
|
|
i2c_annexe_desactive_turbine();
|
|
|
|
tempo_ms = 3000;
|
|
|
|
etat_test_panier=TEST_PANIER_TEMPO;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TEST_PANIER_TEMPO:
|
|
|
|
if(temporisation_terminee(&tempo_ms, _step_ms)){
|
|
|
|
etat_test_panier=TEST_PANIER_LANCE_BALLES;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TEST_PANIER_LANCE_BALLES:
|
|
|
|
if(lance_balles(_step_ms) == ACTION_TERMINEE){
|
|
|
|
etat_test_panier=TEST_PANIER_PORTE_OUVERTE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case TEST_PANIER_PORTE_OUVERTE:
|
|
|
|
if(temporisation_terminee(&tempo_ms, _step_ms)){
|
|
|
|
i2c_annexe_ouvre_porte();
|
|
|
|
}
|
|
|
|
if(lire_couleur()== COULEUR_BLEU){
|
|
|
|
etat_test_panier=TEST_PANIER_INIT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
lettre = getchar_timeout_us(0);
|
|
|
|
//}while((lettre == PICO_ERROR_TIMEOUT) || (lettre == 0));
|
2023-03-26 19:28:13 +00:00
|
|
|
}while(1);
|
|
|
|
printf("STRATEGIE_LOOP_2\n");
|
2023-03-26 14:56:34 +00:00
|
|
|
printf("Lettre : %d; %c\n", lettre, lettre);
|
|
|
|
|
|
|
|
if(lettre == 'q' && lettre == 'Q'){
|
|
|
|
return 0;
|
|
|
|
}
|
2023-03-26 19:28:13 +00:00
|
|
|
return 0;
|
2023-03-26 14:56:34 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-03-26 14:34:06 +00:00
|
|
|
|
|
|
|
int test_longe(){
|
2023-03-18 16:59:15 +00:00
|
|
|
int lettre, _step_ms = 1, temps_ms=0, _step_ms_gyro=2,temps_ms_init;
|
|
|
|
|
|
|
|
i2c_maitre_init();
|
|
|
|
Trajet_init();
|
|
|
|
//printf("Init gyroscope\n");
|
|
|
|
//Gyro_Init();
|
|
|
|
|
|
|
|
stdio_flush();
|
|
|
|
|
|
|
|
//set_position_avec_gyroscope(1);
|
|
|
|
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
temps_ms_init = temps_ms;
|
|
|
|
do{
|
|
|
|
i2c_gestion(i2c0);
|
|
|
|
i2c_annexe_gestion();
|
|
|
|
// Routines à 1 ms
|
|
|
|
if(temps_ms != Temps_get_temps_ms()){
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
QEI_update();
|
|
|
|
Localisation_gestion();
|
|
|
|
AsserMoteur_Gestion(_step_ms);
|
|
|
|
|
|
|
|
// Routine à 2 ms
|
|
|
|
if(temps_ms % _step_ms_gyro == 0){
|
|
|
|
// Gyro_Read(_step_ms_gyro);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(temps_ms > temps_ms_init + 200){
|
2023-03-28 21:03:35 +00:00
|
|
|
if(avance_puis_longe_bordure(LONGER_VERS_A) == ACTION_TERMINEE){
|
2023-03-18 16:59:15 +00:00
|
|
|
printf("Accostage_terminee\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-26 14:34:06 +00:00
|
|
|
}
|
|
|
|
lettre = getchar_timeout_us(0);
|
|
|
|
}while((lettre == PICO_ERROR_TIMEOUT) || (lettre == 0));
|
|
|
|
printf("Lettre : %d; %c\n", lettre, lettre);
|
|
|
|
|
|
|
|
if(lettre == 'q' && lettre == 'Q'){
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int test_accostage(){
|
|
|
|
int lettre, _step_ms = 1, temps_ms=0, _step_ms_gyro=2,temps_ms_init;
|
|
|
|
|
|
|
|
i2c_maitre_init();
|
|
|
|
Trajet_init();
|
|
|
|
//printf("Init gyroscope\n");
|
|
|
|
//Gyro_Init();
|
|
|
|
|
|
|
|
stdio_flush();
|
|
|
|
|
|
|
|
//set_position_avec_gyroscope(1);
|
|
|
|
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
temps_ms_init = temps_ms;
|
|
|
|
do{
|
|
|
|
i2c_gestion(i2c0);
|
|
|
|
i2c_annexe_gestion();
|
|
|
|
// Routines à 1 ms
|
|
|
|
if(temps_ms != Temps_get_temps_ms()){
|
|
|
|
temps_ms = Temps_get_temps_ms();
|
|
|
|
QEI_update();
|
|
|
|
Localisation_gestion();
|
|
|
|
AsserMoteur_Gestion(_step_ms);
|
|
|
|
|
|
|
|
// Routine à 2 ms
|
|
|
|
if(temps_ms % _step_ms_gyro == 0){
|
|
|
|
// Gyro_Read(_step_ms_gyro);
|
|
|
|
}
|
2023-03-18 16:59:15 +00:00
|
|
|
|
2023-03-26 14:34:06 +00:00
|
|
|
if(temps_ms > temps_ms_init + 200){
|
|
|
|
if(cerise_accostage() == ACTION_TERMINEE){
|
|
|
|
printf("Accostage_terminee\n");
|
|
|
|
}
|
|
|
|
}
|
2023-03-18 16:59:15 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
lettre = getchar_timeout_us(0);
|
|
|
|
}while((lettre == PICO_ERROR_TIMEOUT) || (lettre == 0));
|
|
|
|
printf("Lettre : %d; %c\n", lettre, lettre);
|
|
|
|
|
2023-03-26 14:34:06 +00:00
|
|
|
if(lettre == 'q' && lettre == 'Q'){
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2023-03-28 21:03:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int test_tirette_et_couleur(){
|
|
|
|
int lettre;
|
|
|
|
uint couleur, tirette;
|
|
|
|
printf("Tirette et couleur\n");
|
|
|
|
|
|
|
|
stdio_flush();
|
|
|
|
|
|
|
|
do{
|
|
|
|
printf(">tirette:%d\n", attente_tirette());
|
|
|
|
if(lire_couleur() == COULEUR_VERT){
|
|
|
|
printf(">couleur:Vert|t\n");
|
|
|
|
}else{
|
|
|
|
printf(">couleur:Bleu|t\n");
|
|
|
|
}
|
|
|
|
sleep_ms(10);
|
|
|
|
|
|
|
|
lettre = getchar_timeout_us(0);
|
|
|
|
}while((lettre == PICO_ERROR_TIMEOUT) || (lettre == 0));
|
|
|
|
|
|
|
|
|
2023-03-18 16:59:15 +00:00
|
|
|
}
|