Errore funzione carica matrice: Risolto

Buongiorno ho un errore in fase di compilazione in c++ della seguente funzione:

float  caricaMatrice(float mat[R][C])
{
   int C=0; int R=0;
   
  switch (R) {
        case 0:
             mat[R][C]=cos(theta); C = C + 1;
             mat[R][C]=0; C = C + 1;
             mat[R][C]=sin(theta);
             break;

        case 1:
             mat[R][C]=0; C = C + 1;
             mat[R][C]=1; C = C + 1;
             mat[R][C]=0;
             break;

        case 2:
             mat[R][C]=-sin(theta); C = C + 1;
             mat[R][C]=0; C = C + 1;
             mat[R][C]=cos(theta);
             break;  
       R = R + 1;
        } 
     return mat;   
} 
```src\main.cpp: In function 'float caricaMatrice(float (*)[0])':
src\main.cpp:77:13: error: cannot convert 'float (*)[0]' to 'float' in return
      return mat;
Questa funzione mi deve ritornare un amatrice . Come correggere?...Grazie

Una matrice di float, ma in generale qualsiasi array, NON si può passare direttamente ... il C, in realtà, passa un puntatore all'inizio dell'array ...

Il compilatore ti sta dicendo che stai sbagliando il return (e, ti dico io, il tipo impostato come tipo di ritorno) ... se tu ritorni una matrice (un array) in realtà ritorni un puntatore al primo elemento e ... un puntatore è cosa ben diversa da un float. :wink:

Guglielmo

Buongiorno , la ringrazio per la sua disponibilita' ma
e' da poco che sto iniziando ad approfondire sia il c++ sia il python
e quindi sono in difficolta' per l'obiettivo che voglio raggiungere.
Avrei bisogno di un suggerimento di come poter risolvere l'errore,
e fare in modo che la funzione successiva che dovra' ricevere
la matrice caricata , dovra' eseguire dei calcoli . Grazie

Una cosa brutta della tua funzione: stai passando una matrice come parametro ma non theta. Quindi la tua funzione lavora usando una variabile presumo globale.
O alla funzione passi tutte le var globali che ti servono come parametro oppure non passi parametri e lavori su var globali. Fare un mix è brutta cosa.

Metti tutto il codice e spiega ... che con solo un pezzo NON si capisce cosa vuoi fare, cosa vuoi passare e cosa ti serve di ritorno!

Guglielmo

#include <Arduino.h>
#include <Wire.h>
#include <Octopus.h>
#include <stdlib.h>
#include <math.h>

using namespace std;

//octopus output: Definisco servo base porta 0 , shoulder porta 1, ecc..

#define basePin 0
#define shoulderPin 1
#define elbowPin 2
#define wristPin 3
#define rotationPin 4
#define gripperPin 5

//Fine octopus output
int attesa = 20;
int R=0; int C=0; // Indici Matrice di Rotazione 
float mat[R][C];

int theta = M_PI/4;
int thetag=0;
int k=0;

int ang = 0;


void posizioneIniziale() {
  // Fase di posizionamento dei servo
  Octopus.analogWrite(basePin, 180);
  delay(500);
  Octopus.analogWrite(shoulderPin, 150);
  delay(500);
  Octopus.analogWrite(elbowPin, 85);
  delay(500);
  Octopus.analogWrite(wristPin, 130);
  delay(500);
  Octopus.analogWrite(gripperPin, 150);
  delay(500);
  Octopus.analogWrite(rotationPin, 360);
  delay(500);
  // Fine fase di posizionamento dei servo
}

void  caricaMatrice()
{
   int C=0; int R=0;
   
  switch (R) {
        case 0:
             mat[R][C]=cos(theta); C = C + 1;
             mat[R][C]=0; C = C + 1;
             mat[R][C]=sin(theta);
             break;

        case 1:
             mat[R][C]=0; C = C + 1;
             mat[R][C]=1; C = C + 1;
             mat[R][C]=0;
             break;

        case 2:
             mat[R][C]=-sin(theta); C = C + 1;
             mat[R][C]=0; C = C + 1;
             mat[R][C]=cos(theta);
             break;  
       R = R + 1;
        } 
     
} 
//---------------------------------------------------------------//

float calcolaAngRot(float mat[R][C])
{
    
  float el02=mat[0][2]; 
  float el12=mat[1][2];
  float el22=mat[2][2];

  float sqr=sqrt(el02*el02 + el12*el12);
  float angr=atan2(sqr, el22);
  int thetag=int(degrees(angr));
  
  return(thetag);

}
//--------------------------------------------------------------//

void muoviServo(){

      
      int k = (180 + thetag);

    for (ang = 180; ang  <  k;  ang++) 
    {
         Octopus.analogWrite(basePin, ang);
         delay(attesa);
    }
   
}
//--------------------------------------------------------------//
void setup(void)
{
  Wire.begin();
  Wire.setClock(100000); 
  Octopus.setPWMFreq(frequenza);
  posizioneIniziale();
  caricaMatrice();
  calcolaAngRot(mat);
  
  //delay(attesa);
}

void loop(void)

{
  
  muoviServo();
  
  delay(50);
 
  posizioneIniziale();
  delay(attesa);
}



L'obiettivo , apparentemente banale, è quello che dato un angolo , theta , viene caricata una matrice , che rappresenta una rotazione intorno all'asse y , e deve restituire thetag che è il risultato espresso in gradi della rotazione. E' evidente che al termine theta e thetag siano uguali ovvero pari a 45 gradi ma, questo esercizio mi serve poichè , sto imparando ad utilizzare le matrici di rotazioni e quindi è la base per un proggetto piu' complesso. In python , utilizzando un servomotore di un kit arduino per principianti , funziona correttamente . Il servo si muove di 45 gradi . Questo codice lo sto applicando ad un braccio sulla cui scheda arduino uno , è montata una shielld Octopus su cui sono agganciati i servomotori del braccio a 6 gradi di liberta'. Attualmente dopo il suggerimento precedente , il programma viene compilato ma esegue solo il posizionamento iniziale. Non esegue la funzione mouvSservo . Se potete darmi un suggerimento. Grazie

Mah ... il primo suggerimento sarebbe ... prima di iniziare ad usare un linguaggio bisognerebbe studiarselo abbastanza bene ... comincia con QUESTO :roll_eyes:

Spiegami secondo te cosa fanno queste due righe:

int R=0; int C=0; // Indici Matrice di Rotazione 
float mat[R][C];

... perché sono proprio le basi eh (Vd. il mauale sopra indicato, cap. 4)!

Guglielmo

1 Like

pensavamo nemmeno compilasse

E comunque se compila alloca 0 byte
Lavoro inutile fatica sprecata

Si mi sono reso conto dell'errore. Grazie

Molto interessante comunque l'argomento

Seguo connpiacere

... un altra cosa di cui ti devi renere conto è che, se, ad esempio, definiamo una matrice:

float miaMatrice[3][3];

  1. abbiamo una matrice di 3 x 3 elementi che sono numerati da 0 a 2

  2. se ad una funzione passi uno specifico elemento, il passaggio avviene "by value" ovvero, alla funzione, viene passato il valore contenuto nell'elemento ( es. miaFunzione (miaMatrice[1][1]);). Quello che tu fai nella funzione NON altera l'elemento che hai passato (hai passato solo il suo valore).

  3. se ad una funzione passi la matrice, ma NON uno specifico elemento, in realtà viene passato il puntatore di memoria al primo elemento della matrice (es. miaFunzione(miaMatrice);). In tal caso, dato che all'interno della funzione tu operi proprio sull'area di memoria della matrice, area puntata dal suo puntatore, quello che fai nella funzione va ad alterare il contenuto della matrice!

Cerca di approfondire bene queste cose ... variabili locali, variabili globali, passaggio per valore, passaggio di puntatore, ecc. ecc. altrimenti avrai sempre problemi nei tuoi programmi. :wink:

Guglielmo

Io comunque farei così:

mat[R][C]=...
mat[R][C+1]=...
mat[R][C+2]=...

No?

Grazie mille . Lo faro'

È proprio il caso che condivida quanto hai detto, anche perché:

void  caricaMatrice()
{
   int C=0; int R=0;  // variabili locali R = C = 0
   
  switch (R) {

Cioè la funzione non eseguirà mai altri case all'infuori del case 0 (zero).

Ciao.

Buonasera non è solo quella la parte da correggere . Anche l'incremento di R non va bene . Dovro' rivedere la procedura di caricamento . La dovro' fare in modo diverso. In ogni caso grazie mille per il vostro supporto . Siete preziosi . Mi permettero' di aggiornarvi. Saluti

Buongiorno ho risolto. Anche in C++è il programma funziona correttamente . Il servo Base del braccio si muove esattamente di 45 gradi cosi come calcolato dalla matrice di rotazione , il codice è:

#include <Arduino.h>
#include <Wire.h>
#include <Octopus.h>
#include <HCSR04.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>

#include <stdlib.h>
#include <math.h>
using namespace std;

float theta = M_PI/4;
float sinang=0;
float cosang=0;
float el02; float el12; float el22; float angr;

float mat[3][3];


int thetag=0; int i=0; int j=0;
int R=0; int C=0; int ang=0;

//---------------------------------------------------//

//octopus output
#define basePin 0
#define shoulderPin 1
#define elbowPin 2
#define wristPin 3
#define rotationPin 4
#define gripperPin 5

int gradi_servo = 180;
int attesa = 20;
int frequenza = 40;

void caricaMatrice()
{
  

  switch (R)
   {
        case 0:
             mat[R][C]=cos(theta);  C = C + 1;
             mat[R][C]=0; C = C + 1;
             mat[R][C]=sin(theta); //sinang;

             C=0;
             R = R + 1;
             
             
        case 1:
             mat[R][C]=0; C = C + 1;
             mat[R][C]=1; C = C + 1;
             mat[R][C]=0;

             C=0;
             R = R + 1;
             
        case 2:
             mat[R][C]=(-1)*sin(theta); C = C + 1;
             mat[R][C]=0; C = C + 1;
             mat[R][C]=cos(theta);

             C=0;
             R = R + 1;
              
   }
}

float calcolaAngRot(float mat[3][3])
{
    
   el02=mat[0][2]; 
   el12=mat[1][2];
   el22=mat[2][2];

  float sqr=sqrt(el02*el02 + el12*el12);
  angr=atan2(sqr, el22);
  int thetag=int((angr / M_PI) * 180.0);
  
  return(thetag);

}
//--------------------------------------------------------------//

void posizioneIniziale() {
  // Fase di posizionamento dei servo
  Octopus.analogWrite(basePin, 180);
  delay(500);
  Octopus.analogWrite(shoulderPin, 150);
  delay(500);
  Octopus.analogWrite(elbowPin, 85);
  delay(500);
  Octopus.analogWrite(wristPin, 130);
  delay(500);
  Octopus.analogWrite(gripperPin, 150);
  delay(500);
  Octopus.analogWrite(rotationPin, 360);
  delay(500);
  // Fine fase di posizionamento dei servo
}


//--------------------------------------------------------------//

void setup(void)
{
    Serial.begin(9600);
    Wire.begin();
    Wire.setClock(100000); 
    Octopus.setPWMFreq(frequenza);

    posizioneIniziale();
       
    caricaMatrice();

}  

void loop (void)
{

      int angrot=calcolaAngRot(mat);

      int k = (180 + angrot);

       

      for (ang = 180; ang  <  k;  ang++) 
       {
        
         Octopus.analogWrite(basePin, ang);
         delay(attesa);

       }
       
   
   delay(500);
   posizioneIniziale();
   delay(500);
   
 }   

 uint16_t to(int gradi)
{
  float ms_min;
  float ms_max;
  float ms_gradi;
  float valore_PWM;

  ms_min = 120; //Rappresenta il valore PWM pari a 1 ms (posizione 0°)
  ms_max = 470; //Rappresenta il valore PWM pari a 1 ms (posizione 180°)
  ms_gradi = (ms_max - ms_min) / gradi_servo;
  valore_PWM = ms_min + (ms_gradi * gradi);
  return (valore_PWM);
}

Grazie mille per i consigli e il supporto. Saluti

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.