Simulateur & conduite automatique d'1 voiture

Fermé
soniabenhamida Messages postés 3 Date d'inscription vendredi 1 mai 2009 Statut Membre Dernière intervention 2 mai 2009 - 1 mai 2009 à 12:00
 loupius - 8 mai 2009 à 15:50
Bonjour,
Bonjour,
voila, je suis en train de créer un petit simulateur de voiture avec conduite automatique :
j'ai un état 1 (position, cap, vitesse, accélération). La fonction commande permet de donner la direction et l'accélération à prendre en fonction de l'environnement (il s'agit d'un circuit avec des obstacles représentés par des 1 et des espaces libres par 0).

La fonction balayage consiste à balayer dans les directions teta appartenant à [cap-pi/2, cap+pi/2]
pour chercher l'obstacle le plus loin dans chacune de ces directions.
ensuite on sélectionne la valeur maximale de ces distances. Et cette valeur sera le nouveau cap à prendre.

voila le code :
le pb que je rencontre, c'est que j'obtient tjs 0 comme distance maximale
je crois que le pb se situe au niveau de la boucle while


typedef struct {float abscisse;float ordonnee;} points;

float balayage ( points position,float cap , int** circ, int n, int m) {

float teta ;int r=0; int k=1;
int a= (position.abscisse);
int b= (position.ordonnee);
points libre1 = position; points libre2;
int i2= (libre2.abscisse);
int j2= (libre2.ordonnee);
float * tab_teta = tab_radians (181);
for ( r=0; r<=180; r++) {
teta = (cap- PI/2. +r*0.01745 ); /*on balaye tous les 1° ( Pi/180~0.01745... */
while (i2<(n*COEF) && j2<(m*COEF) && i2>=0 && j2>=0 && circ[i2][j2]==0) {
libre1 =libre2;
i2= (a + floor (0.1*k));
j2= (b+ floor (tanf (teta) *0.1*k));
k++;
}
tab_teta [r]= distance (position, libre1);
}
return max_tab ( tab_teta, 181);
}





float * tab_radians ( int n) {
float * tab = (float*) malloc (n* sizeof(float ) );
int i;
for (i=0; i<n; i++) tab[i] = 0 ;
return tab;
}

/* fonction puissance pour flottants*/

float puissf (float x, int y) {
return (y > 0) ? (x*puissf(x, y-1)) : 1;
}

/* recherche du maximum dans un tab de flottants*/

float max_tab (float *tab,int taille){
int i;
float max=tab[0];
for(i=1;i<taille;++i){
if (tab[i]> max){
max=tab[i];
}
}
return max;
}


/* calcul de la distance entre deux points du circuit */

float distance (points p1, points p2) {
return sqrtf ( puissf(((p1.abscisse)-(p2.abscisse)),2)+ puissf(( (p1.ordonnee)- (p2.ordonnee)),2));
}
A voir également:

4 réponses

soniabenhamida Messages postés 3 Date d'inscription vendredi 1 mai 2009 Statut Membre Dernière intervention 2 mai 2009
1 mai 2009 à 17:52
est ce que quelqu'un peut m'aider? je sais que c estune question bete, mais je suis bloquée.
0
Je pense, sans prétention, pouvoir résoudre ce genre de situation. Seulement, j'ai 3 objections à formuler:
- 1) je n'ai pas du tout envie de lire ton code, il faut utiliser les balises 'codes', sinon je passe trop de temps à essayer de comprendre,
- 2) pour se lancer dans un tel projet il faut avoir des bases (c'est-à-dire une certaine connaissance) sinon on se contente de faire des 'copié-collé' de code et, en fait, on n'arrive jamais au résultat escompté,
- 3) avoir des bases signifie aussi savoir se débrouiller avec les erreurs. Pour cela 2 méthodes: le 'débugueur' et les 'printf'.
J'ai donc l'impression que le problème est facile à résoudre mais que tu ne te donnes pas (et que tu ne nous donnes pas) les moyens de la faire.
Sur ce, je veux bien t'aider (et je ne suis sans doute pas le seul), mais il faut au moins que le code soit lisible.
Bon courage.
0
soniabenhamida Messages postés 3 Date d'inscription vendredi 1 mai 2009 Statut Membre Dernière intervention 2 mai 2009 > loupius
2 mai 2009 à 11:13
j'avais pas vu que l'indentation a été modifiée dans le code.
j'ai pas de bug, le pb c est que je n ai pas le résultat escompté, je trouve toujours que pour la distance maximale à l'obstacle le plus proche de la voiture dans une direction donnée est égale à 0.

/* utilisation de la structures suivante */
typedef struct {float abscisse;float ordonnee;} points;  

/* fonction principale : balayage sur 180°*/

float balayage (points position,float cap , int** circ, int n, int m) {
  
  float teta ;int r=0; int k=1; 
  int a= (position.abscisse);
  int b= (position.ordonnee);
  points libre1 = position; points libre2;
  int i2= (libre2.abscisse);
  int j2= (libre2.ordonnee);
  float * tab_teta = tab_radians (181);
  for ( r=0; r<=180; r++) {                    /*calcul pour r directions */
    teta = (cap- PI/2. +r*0.01745 );       /*on balaye tous les 1° ( Pi/180~0.01745...*/
    while (i2<(n*COEF) && j2<(m*COEF) && i2>=0 && j2>=0 && circ[i2][j2]==0) {
      libre1 =libre2;                                                               /* le circuit est de taille (n*COEF,m*COEF)*/
      i2= (a + floor (0.1*k));                                     /* les coordonnées sont de type int*int */
      j2= (b+ floor (tanf (teta) *0.1*k));     /* éq polaire de la demi-droite  d'origine (a,b) : y=tan (teta) *x */
      k++;                                              /*ici x = k, je choisis d'incrémenter de 0.1 pour etre sure de tomber sur toutes les cases dans une meme direction */
    }
    tab_teta [r]= distance (position, libre1);       
  }
  return max_tab ( tab_teta, 181); 
}



int main () {
  points p1 = { 2 , 2 };
  
  printf ("%f\n", balayage ( p1, PI/2., circuit (2,2), 10, 10));
  return 0;
}

/* fonctions auxiliaires */

/* création d'un tableau qui contiendra la distance minimale à l'obstacle pour chaque direction */

float * tab_radians ( int n) {
  float * tab = (float*) malloc (n* sizeof(float ) );
  int i;
  for (i=0; i<n; i++) tab[i] = 0 ;                                                    
  return tab;                                                                              
}

/* fonction puissance pour flottants*/

float puissf (float x, int y) {
  return (y > 0) ? (x*puissf(x, y-1)) : 1;
}

/* recherche du maximum dans un tab de flottants*/

float max_tab (float *tab,int taille){
  int i;
  float max=tab[0];
  for(i=1;i<taille;++i){
     if (tab[i]> max){
        max=tab[i];
     }
  }
  return max;
}


/* calcul de la distance entre deux points du circuit */

float distance (points p1, points p2) {
  return sqrtf ( puissf(((p1.abscisse)-(p2.abscisse)),2)+ puissf(( (p1.ordonnee)- (p2.ordonnee)),2));
}<code>
</code>


0
pont > soniabenhamida Messages postés 3 Date d'inscription vendredi 1 mai 2009 Statut Membre Dernière intervention 2 mai 2009
2 mai 2009 à 11:43
Bonjour Sonia

Je crois comme Loupius que nous n'avons pas assez d'éléments pour résoudre.
C'est en faisant tourner le programme PAS A PAS que vous verrez apparaître le résultat
qui ne vous convient pas, où cela apparaît et pour quelle raison.
Personnellement,
je pense que ce problème s'apparente à un automatisme de machine, et donc que c'est l'assembleur
qui convient le mieux par sa finesse et sa simplicité, pour programmer cela, accompagné d'un bon émulateur du µC que vous avez choisi. Des instructions complexes du C font beaucoup de choses que l'on ignore, et il est donc quasi impossible de savoir si l'erreur vient de vous ou d'une interférence entre instructions. Un copain a écrit un simulateur de pilotage d'avion, en assembleur et pour lui ce ne serait pas possible autrement.
0
loupius > soniabenhamida Messages postés 3 Date d'inscription vendredi 1 mai 2009 Statut Membre Dernière intervention 2 mai 2009
2 mai 2009 à 12:30
Quelques erreurs dans la fonction balayage:
- COEF: qu'est-ce ?
- 'libre2' est déclaré mais non initialisé (et par défaut ce n'est pas 0, mais c'est indéfini comme pour toute variable locale); donc i2 et j2 prennent n'importe quelle valeur et par conséquent le test 'while...' peut donner n'importe quoi !
- 'int** circ', alors là c'est le cirque ! ;-) Imagine-toi un instant à la place du programme avec à résoudre: 'circ[1][2]==0', eh bien tu es dans l'incapacité de savoir où se trouve la case mémoire correspondant à 'circ[1][2]', pourquoi ? Il faut savoir que jusqu'ici la mémoire de l'ordinateur est à une dimension, donc un tableau à deux dimensions est, en mémoire, sur une seule dimension. Exemple: circ[2][3] -> e00 e01 e02 e10 e11 e12, pour aller chercher l'élément circ[1][2], je vais prendre l'élément n° (1*3+2) parce que je sais qu'il y a 3 éléments pour la 2ème dimension. Alors 2 solutions: soit tu passes, comme tu l'as fait, un pointeur à la fonction et tu calcules ensuite comme ci-dessus en supposant connu le nombre d'éléments, soit tu passes un tableau int tab[][3].
Bon courage.
0
sonia393 Messages postés 4 Date d'inscription samedi 2 mai 2009 Statut Membre Dernière intervention 4 mai 2009 > loupius
3 mai 2009 à 14:49
je comprends pas ce qu'il se passe
j'ai mis des printf un peu partout comme conseillé, et lorsque je demande d'afficher le contenu d'une case du circuit, j'obtiens un entier qui ressemble à une adresse

/* allocation de mémoire pour les tableaux à deux dimension */

int ** creer_mat ( int n, int  m ) {
  int ** mat = (int**) malloc (n* sizeof(int*));
  int i,j;
  for (i=0; i<n; i++) mat[i] = (int*) malloc (m* sizeof(int));
  for (i=0; i<n; i++) { 
    for (j=0; j<m; j++) mat[i][j]=1;}                          /*initialisation des éléments de la mat à 1*/
  return mat;
}


void affiche_circuit ( int ** circ, int n, int m) {
  int l, k;
  for (l=0; l<(n*COEF) ; l++) { 
    for (k=0; k<(m*COEF); k++) printf ("%d ", circ[l][k]);
    printf ("\n");}
}  

/* création de circuits */

int **circuit ( int n, int  m ) {
  int i,j; int k, l;
  int n_fois_coef= n*COEF;
  int m_fois_coef= m*COEF;
  int **mat = creer_mat (n, m);
  for (i=0; i<n; i++) {
    printf ("entrer la ligne %d du circuit qui contient au plus %d 0 ou 1\n", i, m );
    for (j=0; j<m; j++) scanf ( "%d", &mat[i][j]);}
  int **circ= creer_mat ( n_fois_coef,m_fois_coef);
   for (i=0; i<n; i++) { 
     for (j=0; j<m; j++) {                                                       /*on divise les cases pour avec un circuit de taille (n*COEF,m*COEF) */
       for (l=(COEF*i); l<(COEF*(i+1)); l++) {
	 for  (k=(COEF*j); k<(COEF*(j+1)); k++) circ[l][k]= mat[i][j];}
     }                                                                           /* obstacles : 0, libre : 1 */
   }
   for (j=0; j<(m_fois_coef); j++) {circ[0][j]=0; circ[n_fois_coef-1][j]=0;}                  /*bord du circuit cloturé */
     for (i=0; i<m_fois_coef; i++) { circ[i][0]=0; circ[i][n_fois_coef-1]=0;}
     affiche_circuit (circ, n, m);
   return circ;
}


/* allocation de mémoire pour tableau */

double * tab_radians ( int n) {
  double * tab = (double*) malloc (n* sizeof(double ) );
  int i;
  for (i=0; i<n; i++) tab[i] = 0 ;                                                    
  return tab;                                                                              
}


/* recherche du maximum dans un tab de flottants*/

double max_tab (double *tab,int taille){
  int i;
  double max= tab[0];
  for(i=1;i<taille;++i){
     if (tab[i]> max) max=tab[i] ; 
  }
  return max;
}


/* calcul de la distance entre deux points du circuit */

double distance (points p1, points p2) {
  return sqrtf ( pow(((p1.abscisse)-(p2.abscisse)),2)+ pow(( (p1.ordonnee)- (p2.ordonnee)),2));
}

  

double balayage (  points position,double cap , int circ[NC][MC]) {          
  double teta ;int r=0; int k=1; 
  int a= (position.abscisse);
  int b= (position.ordonnee);
  points libre2 = position; points libre1 = position;
  int i2= (libre2.abscisse);
  int j2= (libre2.ordonnee);
  int i1= (libre1.abscisse);
  int j1= (libre1.ordonnee);
  double * tab_teta = tab_radians (181);
  for ( r=0; r<=1; r++) {
    k=1;
    teta = (cap- PI/2. +r*DELTA_PHI );  
    printf ("r= %d, teta= %f \n", r, teta);
    while (i2<(NC) && j2<(MC) && i2>=0 && j2>=0 && circ[i2][j2] ) {  /* les 0 sont des obstacles*/
      printf ( "dans la boucle \n circ[i2][j2]= %d \n",circ[i2][j2]);
	  i1 =i2; j1=j2;                                                
         i2= (a + floor (k));
         j2= (b+ floor (tanf (teta) *k));
        printf ("k= %d ", k);
        printf ( "i2= %d, j2= %d \n", i2, j2); 
        k++;
    }
    printf( "en sortie de boucle \n i2= %d, j2= %d \n", i2, j2);printf( "i1= %d, j1= %d \n", i1, j1); 
    printf( "circ[i2][j2]= %d \n",circ[i2][j2] );
   printf( "circ[i1][j1]= %d \n",circ[i1][j1]);
    tab_teta [r]= distance (position, libre1);
  }   
  for ( r=0; r<=1; r++) printf ( " tab_teta (%d)= %f\n", r, tab_teta [r]);
  return max_tab ( tab_teta, 181);
}



int main () {
  points p1 = { 0 , 0 };// points p2 = { 2 , 4 };
  //printf ("dist_obst= %lf\n", distance ( p1, p2));
  printf ("résultat dist max =%lf\n", balayage ( p1, PI/2., circuit (N,M)));
  return 0;
}



j'obtiens
le circuit
0 0 0 0 0 0 0 0 0 0
0 1 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
r= 0, teta= 0.000000
dans la boucle
circ[i2][j2]= 138624
k= 1 i2= 1, j2= 0
dans la boucle
circ[i2][j2]= 41
k= 2 i2= 2, j2= 0
en sortie de boucle
i2= 2, j2= 0
i1= 1, j1= 0
circ[i2][j2]= 0
circ[i1][j1]= 41
r= 1, teta= 0.017450
en sortie de boucle
i2= 2, j2= 0
i1= 1, j1= 0
circ[i2][j2]= 0
circ[i1][j1]= 41
tab_teta (0)= 0.000000
tab_teta (1)= 0.000000
résultat dist max =0.000000
0
sonia393 Messages postés 4 Date d'inscription samedi 2 mai 2009 Statut Membre Dernière intervention 4 mai 2009
4 mai 2009 à 13:07
voici le code compilable
j'ai un pb au niveau des pointeurs, le programme ne renvoit pas le contenu de la case du cricuit mais son adresse.
J'ai essayé *(ptr + MC*i+j) mais j obtiens le m résultat, et je comprends pas prquoi puisque * indique le contenu du pointeur, non?
je suis dsl de ne pas etre assez claire, merci de votre aide.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
//#include "creercircuit.h"  
//#include "balayage.h"


/* constantes de la voiture */
#define MASSE 1200. /*masse en kg*/
#define VIT_MAX 47.22   /*vitesse max en m/s 170.0 / 3.6  */ 
#define FROT 0.45     /*coefficient de frottement*/
#define ACC_MAX 2.78  /*acceleration maximale en m/s²,hypothese : acceleration uniforme*/
#define PCE_MAX 29.15  /*Puissance maximale de la voiture (vitesse_max/3.6)/k*/
#define L 2.    /*longueur du vehicule*/




/* constantes pour créer le circuit */
#define N 3
#define M 2
#define COEF 4 /* on créé un tableau plus grand à partir d'un premier tableaud e dimension (n,m) en divisant chaque case par un coef */
#define NC ((N)*(COEF))
#define MC ((M)*(COEF))    /* le circuit est de taille (NC, MC) */

#define PI (4*atan(1.0))

typedef struct s_point {int abscisse;int ordonnee;} points;   

typedef struct { points s_position; double s_cap;double s_vitesse;} etat;



#define DELTA_T 0.01
#define DELTA_CAP 0.05
/*constante de balayage : on balaye tous les 1° sur 180°, les calculs se font en radians */
#define DELTA_PHI (PI/180.)



/*************************************************************/
/*                   CREATION DU CIRCUIT */
/* allocation de mémoire pour les tableaux à deux dimension */

int ** creer_mat ( int n, int  m ) {
  int ** mat = (int**) malloc (n* sizeof(int*));
  int i,j;
  for (i=0; i<n; i++) mat[i] = (int*) malloc (m* sizeof(int));
  for (i=0; i<n; i++) { 
    for (j=0; j<m; j++) mat[i][j]=1;}                          /*initialisation des éléments de la mat à 1*/
  return mat;
}


void affiche_circuit ( int ** circ ,int a, int b) {
  int l, k;
  for (l=0; l<a ; l++) { 
    for (k=0; k<b; k++) printf ("%d ", circ[l][k]);
    printf ("\n");}
}  

/* création de circuits */

int **circuit ( int n, int  m ) {
  int i,j; int k, l;
  int n_coef= n*COEF;
  int m_coef= m*COEF;
  int **mat = creer_mat (n, m);
  for (i=0; i<n; i++) {
    printf ("entrer la ligne %d du circuit qui contient au plus %d 0 ou 1\n", i, m );
    for (j=0; j<m; j++) scanf ( "%d", &mat[i][j]);}
  int **circ= creer_mat ( n_coef,m_coef);
   for (i=0; i<n; i++) { 
     for (j=0; j<m; j++) {                          /*on divise les cases pour avec un circuit de taille (n*COEF,m*COEF) */
       for (l=(COEF*i); l<(COEF*(i+1)); l++) {
	 for  (k=(COEF*j); k<(COEF*(j+1)); k++) circ[l][k]= mat[i][j];}
     }                                                                           /* obstacles : 0, libre : 1 */
   }
   for (j=0; j<(m_coef); j++) {circ[0][j]=0; circ[n_coef-1][j]=0;}                  /*bord du circuit cloturé */
     for (i=0; i<n_coef; i++) { circ[i][0]=0; circ[i][m_coef-1]=0;}
    // affiche_circuit (circ, n_coef, m_coef);
   return circ;
}


/*************************************************************************************************/
/*   fonctions utiles pour la fonction balayage */



/* allocation de mémoire pour tableau */

double * tab_radians ( int n) {
  double * tab = (double*) malloc (n* sizeof(double ) );
  int i;
  for (i=0; i<n; i++) tab[i] = 0 ;                                                    
  return tab;                                                                              
}


/* recherche du maximum dans un tab de flottants*/

double max_tab (double *tab,int taille){
  int i;
  double max= tab[0];
  for(i=1;i<taille;++i){
     if (tab[i]> max) max=tab[i] ; 
  }
  return max;
}


/* calcul de la distance entre deux points du circuit */

double distance (points p1, points p2) {
  return sqrtf ( pow(((p1.abscisse)-(p2.abscisse)),2)+ pow(( (p1.ordonnee)- (p2.ordonnee)),2));
}


/* fonction balayge */

double balayage (  points position,double cap , int (*ptr)[MC]) {  /* int (*ptr)[MC] : pointeur vers un tableau de 4 int ( différent de int * ptr [MC]: tab de MC pointeurs vers des variables de type int)*/
  int *p;
  p = (int *) ptr;          /*caster p pour qu'il soit égal à l'adresse contenue dans ptr*/    
  double teta ;int r=0; int k=1; 
  int a= (position.abscisse);
  int b= (position.ordonnee);
  points libre2 = position; points libre1 = position;
  int i2= (libre2.abscisse);
  int j2= (libre2.ordonnee);
  int i1= (libre1.abscisse);
  int j1= (libre1.ordonnee);
  double * tab_teta = tab_radians (181);
  for ( r=0; r<=2; r++) {
    k=1;
    teta = (cap- PI/2. +r*DELTA_PHI );  
    printf ("r= %d, teta= %f \n", r, teta);

    while (i2<(NC) && j2<(MC) && i2>=0 && j2>=0 && *(ptr[MC*i2+j2] )) {  /* les 0 sont des obstacles*/
      printf ( "dans la boucle \ncirc[i2][j2]= %d \n",*(ptr[MC*i2+j2]));/*  ptr[MC * i + j] <=> t[i][j] */
	  i1 =i2; j1=j2;                                                /*quand j'écris libre1= libre2; ca n'a pas d'effet*/
         i2= (a + floor (k));
         j2= (b+ floor (tanf (teta) *k));
        printf ("k= %d ", k);
        printf ( "i2= %d, j2= %d \n", i2, j2); 
        k++;
    }
    printf( "en sortie de boucle\ni2= %d, j2= %d \n", i2, j2);
    printf( "i1= %d, j1= %d \n", i1, j1); 
    printf( "circ[i2][j2]= %d \n",ptr[MC*i2+j2] );
    tab_teta [r]= distance (position, libre1);
  }   

  // for ( r=0; r<=1; r++) printf ( " tab_teta (%d)= %f\n", r, tab_teta [r]);
  return max_tab ( tab_teta, 181);
}



int main () {
  points p1 = { 0 , 0 };points p2 = { 2 , 4 };
  
  //printf ("dist_obst= %lf\n", distance ( p1, p2));
  printf (" dist max =%lf\n", balayage ( p1, PI/2., circuit (N,M)));
  return 0;
}
0
Bon j'ai mis ton programme en 'forme' correcte, mais il y a des choses que le ne comprends pas:
- qu'est ce que tu veux passer comme paramètres à balayage: à quoi sert: int (*ptr)[MC])
- /*quand j'écris libre1= libre2; ca n'a pas d'effet*/, c'est normal, tu ne passes pas dans la boucle.
- dans la fonction double* tab_radians (int n), tu alloues de mémoire qui n'est jamais libérée!
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
//#include "creercircuit.h"
//#include "balayage.h"

/* constantes de la voiture */
#define MASSE    1200.  /*masse en kg*/
#define VIT_MAX  47.22  /*vitesse max en m/s 170.0 / 3.6  */
#define FROT     0.45   /*coefficient de frottement*/
#define ACC_MAX  2.78   /*acceleration maximale en m/s²,hypothese : acceleration uniforme*/
#define PCE_MAX  29.15  /*Puissance maximale de la voiture (vitesse_max/3.6)/k*/
#define L        2.     /*longueur du vehicule*/

/* constantes pour créer le circuit */
#define N 3
#define M 2
#define COEF 4             /* on créé un tableau plus grand à partir d'un premier tableaud e dimension (n,m) en divisant chaque case par un coef */
#define NC   ((N)*(COEF))
#define MC   ((M)*(COEF))  /* le circuit est de taille (NC, MC) */

#define PI (4*atan(1.0))

typedef struct s_point
{
  int abscisse;
  int ordonnee;
} points;

typedef struct
{
  points s_position;
  double s_cap;
  double s_vitesse;
} etat;

#define DELTA_T    0.01
#define DELTA_CAP  0.05
/*constante de balayage : on balaye tous les 1° sur 180°, les calculs se font en radians */
#define DELTA_PHI (PI/180.)

/*************************************************************/
/*                   CREATION DU CIRCUIT */
/* allocation de mémoire pour les tableaux à deux dimension */

int** creer_mat (int n, int m)
{
  int** mat = (int**)malloc (n * sizeof(int*));
  int i,j;
  for (i=0; i<n; i++)
  {
    mat[i] = (int*) malloc (m * sizeof(int));
    for (j=0; j<m; j++)
      mat[i][j] = 1;     /*initialisation des éléments de la mat à 1*/
  }
  return mat;
}

void affiche_circuit (int** circ, int a, int b)
{
  int i, j;
  for (i=0; i<a; i++)
  {
    for (j=0; j<b; j++)
      printf ("%d ", circ[i][j]);
    printf ("\n");
  }
}

/* création de circuits */

int** circuit (int n, int  m)
{
  int i,j,k,l;
  int n_coef = n*COEF;
  int m_coef = m*COEF;
  int** mat = creer_mat (n, m);
mat[0][0] = 0;
mat[0][1] = 1;
mat[1][0] = 0;
mat[1][1] = 1;
mat[2][0] = 1;
mat[2][1] = 0;
//  for (i=0; i<n; i++)
//  {
//    printf ("entrer la ligne %d du circuit qui contient au plus %d 0 ou 1\n", i, m);
//    for (j=0; j<m; j++)
//      scanf ("%d", &mat[i][j]);
//  }
  int **circ= creer_mat (n_coef,m_coef);
  for (i=0; i<n; i++)
    for (j=0; j<m; j++)      /*on divise les cases pour avec un circuit de taille (n*COEF,m*COEF) */
      for (l=(COEF*i); l<(COEF*(i+1)); l++)
        for  (k=(COEF*j); k<(COEF*(j+1)); k++)
          circ[l][k] = mat[i][j];
  /* obstacles : 0, libre : 1 */
  for (j=0; j<(m_coef); j++)
  {
    circ[0][j] = 0;
    circ[n_coef-1][j] = 0;   /*bord du circuit cloturé */
  }
  for (i=0; i<n_coef; i++)
  {
    circ[i][0] = 0;
    circ[i][m_coef-1] = 0;
  }
  affiche_circuit (circ, n_coef, m_coef);

  return circ;
}

/*************************************************************************************************/
/*   fonctions utiles pour la fonction balayage */

/* allocation de mémoire pour tableau */

double* tab_radians (int n)
{
  double* tab = (double*)malloc (n* sizeof(double));
  int i;
  for (i=0; i<n; i++)
    tab[i] = 0;
  return tab;
}

/* recherche du maximum dans un tab de flottants*/

double max_tab (double *tab,int taille)
{
  int i;
  double max = tab[0];
  for(i=1;i<taille;++i)
    if (tab[i]> max)
      max = tab[i];
  return max;
}

/* calcul de la distance entre deux points du circuit */

double distance (points p1, points p2)
{
  return sqrt (pow(p1.abscisse - p2.abscisse, 2) + pow(p1.ordonnee - p2.ordonnee, 2));
}

/* fonction balayge */

double balayage (points position, double cap , int (*ptr)[MC])
{  /* int (*ptr)[MC] : pointeur vers un tableau de 4 int (différent de int * ptr [MC]: tab de MC pointeurs vers des variables de type int)*/
  int* p;
  p = (int*) ptr;          /*caster p pour qu'il soit égal à l'adresse contenue dans ptr*/
  double teta;
  int r = 0, k;
  int a = (position.abscisse);
  int b = (position.ordonnee);
  points libre1 = position, libre2 = position;
  int i1 = a;
  int j1 = b;
  int i2 = a;
  int j2 = b;
  double* tab_teta = tab_radians (181);
  for (r=0; r<=2; r++)
  {
    k = 1;
    teta = (cap - PI/2. + r*DELTA_PHI);
    printf ("r= %d, teta= %f \n", r, teta);

    while (i2<(NC) && j2<(MC) && i2>=0 && j2>=0 && *(ptr[MC*i2+j2]))  /* les 0 sont des obstacles*/
    {
      printf ("dans la boucle \ncirc[i2][j2]= %d \n",*(ptr[MC*i2+j2]));/*  ptr[MC * i + j] <=> t[i][j] */
	    i1 = i2;
      j1 = j2;                                 /*quand j'écris libre1= libre2; ca n'a pas d'effet*/
      i2= (a + floor (k));
      j2= (b+ floor (tan (teta) *k));
      printf ("k= %d ", k);
      printf ("i2= %d, j2= %d \n", i2, j2);
      k++;
    }
    printf("en sortie de boucle\ni2= %d, j2= %d \n", i2, j2);
    printf("i1= %d, j1= %d \n", i1, j1);
    printf("circ[i2][j2]= %d \n", ptr[MC*i2+j2]);
    tab_teta[r] = distance (position, libre1);
  }
  // for (r=0; r<=1; r++) printf (" tab_teta (%d)= %f\n", r, tab_teta [r]);
  return max_tab (tab_teta, 181);
}

int main()
{
  points p1 = { 0 , 0 };
  points p2 = { 2 , 4 };

  //printf ("dist_obst= %lf\n", distance (p1, p2));
  printf (" dist max =%lf\n", balayage (p2, PI/2., circuit (N,M)));
  return 0;
}
0
sonia393 Messages postés 4 Date d'inscription samedi 2 mai 2009 Statut Membre Dernière intervention 4 mai 2009
4 mai 2009 à 22:51
bonjour, je n'avais pas alloué correctement la mémoire pour les structures que je définissais.
j'obtiens maintenant un résultat, par contre je ne suis pas sûre qu'il soit juste
ah oui, j'ai un warning que je n'arrive pas à regler : dans la fonction main , dans la fonction balayage 3eme parametre, pb de pointeur il n 'aime pas circuit(N, M)
que dois-je faire pour arranger ca?
merci beaucoup

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
/* coef pour creer le circuit*/
#define N 2
#define M 2
#define NC ((N)*(COEF))
#define MC ((M)*(COEF))
#define COEF 4

/* constantes pour balayer */
#define PAS 90
#define DELTA_TETA (PI/PAS)
#define PI (4*atan(1.0))


/////////////////**************structures utilisées ******************//////////////////////////////////
struct s_point {int abscisse;int ordonnee;};   
typedef  struct s_point* points;

points creer_point ( int p_x, int p_y ){
  points p = (points)malloc(sizeof(struct s_point));
  p->abscisse = p_x; p->ordonnee = p_y;
  return p;
}


struct s_direction { double s_teta; double s_dist_obst;};
typedef struct s_direction * p_direction;

p_direction creer_direction (double teta, double dist_obst) {
  p_direction d = (p_direction)malloc(sizeof(struct s_direction));
  d->s_teta = teta; d->s_dist_obst = dist_obst;
  return d;
}


///////////////***********************CREATION DU CIRCUIT************//////////////////////////
 /* fonction puissance */

int puiss (int x, int y) {
  return (y > 0) ? (x*puiss(x, y-1)) : 1;
}


/* allocation de mémoire pour les tableaux à deux dimension */

int ** creer_mat ( int n, int  m ) {
  int ** mat = (int**) malloc (n* sizeof(int*));
  int i,j;
  for (i=0; i<n; i++) mat[i] = (int*) malloc (m* sizeof(int));
  for (i=0; i<n; i++) { 
    for (j=0; j<m; j++) mat[i][j]=1;}                          /*initialisation des éléments de la mat à 1*/
  return mat;
}


void affiche_circuit ( int ** circ, int n, int m) {
  int l, k;
  for (l=0; l<(n*COEF) ; l++) { 
    for (k=0; k<(m*COEF); k++) printf ("%d ", circ[l][k]);
    printf ("\n");}
}  

/* création de circuits */

int **circuit ( int n, int  m ) {
  int i,j; int k, l;
  int n_fois_coef= n*COEF;
  int m_fois_coef= m*COEF;
  int **mat = creer_mat (n, m);
  for (i=0; i<n; i++) {
    printf ("entrer la ligne %d du circuit qui contient au plus %d 0 ou 1\n", i, m );
    for (j=0; j<m; j++) scanf ( "%d", &mat[i][j]);}
  int **circ= creer_mat ( n_fois_coef,m_fois_coef);
   for (i=0; i<n; i++) { 
     for (j=0; j<m; j++) {                                                       /*on divise les cases pour avec un circuit de taille (n*COEF,m*COEF) */
       for (l=(COEF*i); l<(COEF*(i+1)); l++) {
	 for  (k=(COEF*j); k<(COEF*(j+1)); k++) circ[l][k]= mat[i][j];}
     }                                                                           /* obstacles : 0, libre : 1 */
   }
   for (j=0; j<(m_fois_coef); j++) {circ[0][j]=0; circ[n_fois_coef-1][j]=0;}                  /*bord du circuit cloturé */
     for (i=0; i<m_fois_coef; i++) { circ[i][0]=0; circ[i][n_fois_coef-1]=0;}
     affiche_circuit (circ, n, m);
   return circ;
}

/***********************************fonctions secondaires pour la fonciton balayage *////////////
/* allocation de memoire pour tableau */

double * tab_radians ( int n) {
  double * tab = (double*) malloc (n* sizeof(double ) );
  int i;
  for (i=0; i<n; i++) tab[i] = 0 ;                                                    
  return tab;                                                                              
}


/* recherche du maximum dans un tab de flottants*/

p_direction max_tab (double *tab,int taille, double cap){
  int i; 
  p_direction d= creer_direction ( tab[0], cap -PI/2.);
  double max_teta= d->s_teta;
  
  for(i=1;i<taille;++i){
    if (tab[i]> max_teta){ max_teta=tab[i]; d->s_dist_obst =(cap -PI/2. + i*DELTA_TETA);
    }
  } 
  return d;
}


/* calcul de la distance entre deux points du circuit */
/* ici je ne comprends pas pourquoi la fonction distance ne marche pas sous cette forme */
//double distance (points p1, points p2) {
//  return sqrtf ( pow((((*p1).abscisse)-((*p2).abscisse)),2)+ pow(( ((*p1).ordonnee)- ((*p2).ordonnee)),2));
//}

double distance (int ax, int ay, int bx, int by) {
  return sqrtf ( pow((ax-bx),2)+ pow((ay-by),2));
}


/*********************************LA FONCTION BALAYAGE *****************///////////////
p_direction balayage (  points position,double cap , int circ[NC][MC]) {          
  double teta ;int r=0; int k=1; 
  int a= ((*position).abscisse);
  int b= ((*position).ordonnee);
  points libre1= creer_point (a, b);
  points libre2 = creer_point(a,b);
  int i1= ((*libre1).abscisse);
  int j1= ((*libre1).ordonnee);
  int i2= ((*libre2).abscisse);
  int j2= ((*libre2).ordonnee);
  double * tab_teta = tab_radians (PAS);

  for ( r=0; r<=PAS; r++) {
    k=1;
    teta = (cap- PI/2. + r*DELTA_TETA );  
    //printf ("r= %d, teta= %f \n", r, teta);
    
    while (i2<(NC) && j2<(MC) && i2>=0 && j2>=0 && circ[i2][j2] !=0 ) {  /* les 0 sont des obstacles*/
      //printf ( "dans la boucle \n circ[i2][j2]= %d \n",circ[i2][j2]);
	  i1 =i2; j1=j2;                                                
         i2= (a + floor (k));
         j2= (b+ floor (tanf (teta) *k));
	 //printf ("k= %d ", k);
	 //printf ( "i2= %d, j2= %d \n", i2, j2); 
        k++;
    }
    i2=a; j2=b;
    
    // printf( "en sortie de boucle \n i2= %d, j2= %d \n", i2, j2);printf( "i1= %d, j1= %d \n", i1, j1); 
    // printf( "circ[i2][j2]= %d \n",circ[i2][j2] );
    // printf( "circ[i1][j1]= %d \n",circ[i1][j1]);
    //printf( " distance a l'obstacle= %lf \n",distance ( a, b, i1, j1));
    tab_teta [r]= distance ( a, b, i1, j1);
  }   
  
  //for ( r=0; r<=PAS; r++) printf ( " tab_teta (%d)= %f\n", r, tab_teta [r]);
  return max_tab ( tab_teta, PAS, cap);
}
 
 
 
int main () {
  points p1=creer_point (4,4);
  //printf ("dist_obst= %lf\n", distance ( p1, p2));
  p_direction d=  balayage ( p1, PI/2.,circuit (N,M));  
  printf (" direction max =%lf\n", (d->s_teta)*180./PI );       /* indication en degré */
  printf (" dist max =%lf\n", d->s_dist_obst);
  return 0;
}
0
Eh oui c'est normal qu'il n'aime pas.
Pour simplifier le problème, déclare un tableau global 'int circ[NC][MC]'.
Une fois que le programme tournera comme tu le désireras, il sera alors temps d'essayer de le déclarer en dynamique.
Les deux lignes suivantes doivent aussi poser un problème à la compilation (avant c'étati mieux):
int a = ((*position).abscisse);
int b = ((*position).ordonnee);

Encore un petit effort ;-)
0
godzilla393 Messages postés 16 Date d'inscription mardi 5 mai 2009 Statut Membre Dernière intervention 9 mai 2009 1 > loupius
8 mai 2009 à 13:25
boujour,
mon programme fonctionne, mais il y a certaines choses qui me laissent perplexe.
-dans le programme ci-dessous et plus précisément dans la fonction balayage, l'égalité de 2 structures n'a pas d'effet ( cf "position = libre1; )

-la fonction distance2 fonctionne correctement mais pas distance1 qui renvoie tjs 0

-la fonction max_tab ne fonctionne pas alors que max fonctionne

tous ces pbs me semblent venir d'une meme origine, à savoir un pb de définition de structure ou de leur utilisation, sinon d'un mauvais usage des pointeurs.

voici le programme qui marche :

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#define N 3
#define M 3
#define COEF 2           /* circuit de taille finale (MC, NC)*/
#define NC ((N)*(COEF))
#define MC ((M)*(COEF))
#define PAS 20        /*on choisit de regarder dans PAS directions*/ 
#define INC 0.001         /*on se balade sur la droite x=a+PAS*k  avec a : abscisse de la position où l'on fait le balayage, k un compteur*/
#define DELTA_TETA (PI/(PAS))
#define PI (4*atan(1.0))

struct s_point {int abscisse;int ordonnee;};   
typedef  struct s_point* p_point;

p_point creer_point ( int p_x, int p_y ){
  p_point p = (p_point)malloc(sizeof(struct s_point));
  p->abscisse = p_x; p->ordonnee = p_y;
  return p;
}



 /* fonction puissance */

int puiss (int x, int y) {
  return ((y > 0) ? (x*puiss(x, y-1)) : 1);
}


/* allocation de mémoire pour les tableaux à deux dimension */

int ** creer_mat ( int n, int  m ) {
  int ** mat = (int**) malloc (n* sizeof(int*));
  int i,j;
  for (i=0; i<n; i++) mat[i] = (int*) malloc (m* sizeof(int));
  for (i=0; i<n; i++) { 
    for (j=0; j<m; j++) mat[i][j]=1;}                          /*initialisation des éléments de la mat à 1 (case libre)*/
  return mat;
}


void affiche_circuit ( int ** circ, int n, int m) {
  int l, k;
  for (l=0; l<(n*COEF) ; l++) { 
    for (k=0; k<(m*COEF); k++) printf ("%d ", circ[l][k]);
    printf ("\n");}
}  

/* création de circuits */

int **circuit ( int n, int  m ) {
  int i,j; int k, l;
  int n_fois_coef= n*COEF;
  int m_fois_coef= m*COEF;
  int **mat = creer_mat (n, m);
  int **circ= creer_mat ( n_fois_coef,m_fois_coef);
   for (i=0; i<n; i++) { 
     for (j=0; j<m; j++) {                                                       /*on divise les cases pour avec un circuit de taille (n*COEF,m*COEF) */
       for (l=(COEF*i); l<(COEF*(i+1)); l++) {
	 for  (k=(COEF*j); k<(COEF*(j+1)); k++) circ[l][k]= mat[i][j];}
     }                                                                           /* obstacles : 0, libre : 1 */
   }
   for (j=0; j<(m_fois_coef); j++) {circ[0][j]=0; circ[n_fois_coef-1][j]=0;}                  /*bord du circuit cloturé */
     for (i=0; i<m_fois_coef; i++) { circ[i][0]=0; circ[i][n_fois_coef-1]=0;}
     affiche_circuit (circ, n, m);
   return circ;
}
/****************************************************************************/

/* allocation de memoire pour tableau */

double * tab_radians ( int n) {
  double * tab = (double*) malloc (n* sizeof(double ) );
  int i;
  for (i=0; i<n; i++) tab[i] = 0 ;                                                    
  return tab;                                                                              
}

double mod_2pi (double f) {                   
  while(f>2*PI) f-=2*PI;
  while(f<0) f+=2*PI;
  return f;
}



struct s_direction { double s_teta; double s_dist_obst;};
typedef struct s_direction* p_direction;

p_direction creer_direction (double teta, double dist_obst) {
  p_direction d = (p_direction)malloc(sizeof(struct s_direction));
  d->s_teta = teta; d->s_dist_obst = dist_obst;
  return d;
}

/* recherche du maximum dans un tab de flottants*/

p_direction max_tab (double *tab,int taille, double cap){
  int i; 
  p_direction d= creer_direction ( mod_2pi(cap-PI/2.), tab[0]);
  double max_teta= (*d).s_dist_obst;
  
  for(i=1;i<taille;++i){
    if (tab[i]> max_teta){ max_teta = tab[i]; d->s_teta = mod_2pi(cap -PI/2.+i*DELTA_TETA);
    }
  } 
  return d;
}


/* calcul de la distance entre deux points du circuit */

double distance1 (p_point p1, p_point p2) {
  double d= sqrtf (pow( p1->abscisse - p2->abscisse,2)+ pow(p1->ordonnee - p2->ordonnee,2));
  return d;}

double distance2 (int ax, int ay, int bx, int by) {
  return sqrtf ( pow((ax - bx),2) + pow((ay - by),2));
}

double max (double *tab, int taille ) {
  int i; double max = tab[0];
  for (i=1; i<taille; i++) {
    if (max < tab[i]) max = tab[i];
  }
  return max;
}
  

#define SIGNE(teta) ((( teta < PI/2.) && (teta  > -PI/2.)) ? 1 : (-1))

double balayage (  p_point position,double cap , int **circ) {          
  double teta ;int r=0; int k=1; 
  int a= (position->abscisse);
  int b= (position->ordonnee);
  p_point libre1= creer_point (a, b);
  p_point libre2 = creer_point(a,b);
  int i1= (libre1->abscisse);
  int j1= (libre1->ordonnee);
  int i2= (libre2->abscisse);
  int j2= (libre2->ordonnee);
  double * tab_teta = tab_radians (PAS);

  for ( r=0; r<=PAS; r++) {
    k=1;
    teta = mod_2pi (cap- PI/2. + r*DELTA_TETA );    /* 2 cas : soit teta appartient à [-PI/2,PI/2] alors on ajoute à a (l'abscisse de la position) le calcul, sinon on le retranche */

    while (i2<(NC) && j2<(MC) && i2>=0 && j2>=0 && circ[i2][j2] !=0 ) {  /* les 0 sont des obstacles*/
      i1 =i2; j1=j2;                                                
      i2= (a +SIGNE(teta)*floor (INC * k));
      j2= (b + floor (tanf (teta) * INC * k));
      k++;
    }

    i2=a; j2=b;      /* ici aussi c est bizarre, si j'écris libre2 = position; ca n'a pas d'effet!! */
    tab_teta [r]= distance2 (a, b, i1, j1);           /* problème ici avec distance1*/
    i1=a; j1=b;
  }   
  
  for ( r=0; r<=PAS; r++) printf ( " tab_teta (%d)= %f\n", r, tab_teta [r]);
  return max (tab_teta, PAS);
  //return max_tab ( tab_teta, PAS, cap); /* et pour finir la fonction max fonctionne mais pas max_tab:!!!!!!*/
}


int main()
{
    p_point p1=creer_point (1,1);
    p_point p2=creer_point (1,2);
    printf("Distance : %f\n", distance1(p1, p2));
    int **circ = circuit (N,M);
    double d=  balayage ( p1, PI/2., circ);
   return 0;
}


0
loupius > godzilla393 Messages postés 16 Date d'inscription mardi 5 mai 2009 Statut Membre Dernière intervention 9 mai 2009
8 mai 2009 à 15:04
la fonction max_tab ne fonctionne pas alors que max fonctionne
Si elles doivent toutes les deux fonctionner. Seulement, dans la fonction 'double balayage...', 'return max...' retourne un double (correct) et 'return max_tab...' retourne une structure (le compilateur doit râler!).
D'autre part la fonction 'max_tab' est quasiment incompréhensible (avec max_teta qui représente une distance!); je propose la suivante qui est beaucoup plus rapide (1 seul appel à 'creer_direction):
p_direction max_tab (double* tab, int taille, double cap)
{
  int i, maxIndex = 0;
  double maxTab = tab[0];

  for (i=1; i<taille; i++)
    if (tab[i]> maxTab)
      maxTab = tab[maxIndex=i];  /* memorise la valeur max et l'angle */
  return (creer_direction (mod_2pi(cap - PI/2.+ maxIndex*DELTA_TETA), maxTab));
}


l'égalité de 2 structures n'a pas d'effet
Si, il y a un effet mais pas celui escompté.
Dans le cas présent, 'libre1' et 'libres2' sont deux pointeurs sur des structures (qui ont été allouées et initialisées lors de leurs définitions).
En faisant libre1 = libre2, on dit que 'libre1' va pointer sur la structure pointée par 'libre2'. Donc ceci ne copie pas les valeurs de 'libre2' dans 'libre1', mais 'fusionne' les deux pointeurs. Première conséquence, l'ancienne structure 'libre2' est désormais pointée par deux pointeurs et toute modification faite via un des pointeurs se répercutera dans l'autre. Deuxième conséquence, l'adresse de la structure pointée précédemment par 'libre1' est perdue, elle ne pourra donc pas être libérée. Troisième conséquence, il ne faudra surtout pas libérer 'libre1' puis 'libre2' car ce serait libérer deux fois la même zone mémoire avec probablement un plantage à la clef.

NB: l'angle se note 'thêta' et non "teta' (cela aide à la lisibilité...).
0
godzilla393 Messages postés 16 Date d'inscription mardi 5 mai 2009 Statut Membre Dernière intervention 9 mai 2009 1 > loupius
8 mai 2009 à 15:19
oui bien sur, j'avais changé la structure de la fonction comme ceci

p_direction balayage ( ....
.....
return max_tab ( tab_teta, PAS, cap);
}


int main () {
p_point p1=creer_point (1,1);
int **circ = circuit (N,M);
p_direction d= balayage ( p1, PI/2., circ);
printf (" direction max =%lf\n", (d->s_teta)*180/PI );
printf (" dist a l'obstacle max =%lf\n", (*d).s_dist_obst);
return 0;
}

renvoie

0 0 0 0 0 0
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
0 0 0 0 0 0
tab_teta (0)= 3.000000
tab_teta (1)= 3.000000
tab_teta (2)= 3.162278
tab_teta (3)= 3.605551
tab_teta (4)= 3.605551
tab_teta (5)= 4.242640
tab_teta (6)= 3.605551
tab_teta (7)= 3.605551
tab_teta (8)= 3.162278
tab_teta (9)= 3.000000
tab_teta (10)= 0.000000
tab_teta (11)= 0.000000
tab_teta (12)= 0.000000
tab_teta (13)= 0.000000
tab_teta (14)= 0.000000
tab_teta (15)= 0.000000
tab_teta (16)= 0.000000
tab_teta (17)= 0.000000
tab_teta (18)= 0.000000
tab_teta (19)= 0.000000
tab_teta (20)= 0.000000
direction max =45.000000
dist a l'obstacle max =3.000000 !!!!!!
0
godzilla393 Messages postés 16 Date d'inscription mardi 5 mai 2009 Statut Membre Dernière intervention 9 mai 2009 1 > godzilla393 Messages postés 16 Date d'inscription mardi 5 mai 2009 Statut Membre Dernière intervention 9 mai 2009
8 mai 2009 à 15:35
merci pour ton explication sur libre1 = libre2;
c'est très claire
j'avais vu ca dans un livre mais ce n'etait pas des pointeurs.
que dois-je écrire si je veux égaliser le contenu des pointeurs? j'ai essayé *libre1 = *libre2;
mais ca ne marche pas. Pour moi cette affectation veut dire que le contenu de la structure vers laquelle pointe libre1 reçoit comme valeurs le contenu de la structure vers laquelle pointe libre2.
mais ca doit etre faux parce que ca ne marche pas.

peux tu m'éclairer davantage sur la question?
merci bcp
0