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.
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.
#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
... un altra cosa di cui ti devi renere conto è che, se, ad esempio, definiamo una matrice:
float miaMatrice[3][3];
abbiamo una matrice di 3 x 3 elementi che sono numerati da 0 a 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).
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.
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);
}