Go Down

Topic: returning two values from a function (Read 587 times) previous topic - next topic

dustynrobots

I'm breaking up some messy code into separate functions, and can't seem to figure out how to pass two parameters into a function, and get two back. The passing part is easy - I can just call get_angles(somenumber, somenumber), but how do I make theta1 and theta2 available within the loop() or wherever I call the function?  If anyone has insight or a good link to a reference that would be great! Thanks

Oh, and in case you're interested, this function is supposed to pass an x,y position and return two joint angles, so I can control this:
http://youtu.be/IHGXqud2m9Q

double get_angles(double Px, double Py)
{
  // first find theta2 where c2 = cos(theta2) and s2 = sin(theta2)
double c2 = (pow(Px,2) + pow(Py,2) - pow(a1,2) - pow(a2,2))/(2*a1*a2); // is btwn -1 and 1
double s2 = sqrt(1 - pow(c2,2));
double theta2 = degrees(atan2(s2,c2));  // solves for the angle in degrees and places in correct quadrant

  // now find theta1 where c1 = cos(theta1) and s1 = sin(theta1)
double theta1 = degrees(atan2(-a2*s2*Px + (a1 + a2*c2)*Py, (a1 + a2*c2)*Px + a2*s2*Py));

//return??????
}

AWOL

#1
Feb 14, 2012, 10:44 pm Last Edit: Feb 14, 2012, 10:49 pm by AWOL Reason: 1
You could pass by reference, and not return anything.
Or you could return a struct.
Watch out for the function prototypes.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Grumpy_Mike

Quote
and get two back.

You can't get two values back from a function, that is not the way C is built.

The closest you can get is to return a pointer to an array, or let it operate on global variables.

Alternatively you can pass an array pointer in and get the function to modify what it points to.

dustynrobots

return a pointer to an array - how?
You could pass by reference, and not return anything - how?
Or you could return a struct - how?
Watch out for the function prototypes - what do you mean?

or let it operate on global variables - okay so if I declare theta1 and theta2 as global, and the get_angles function does something to them, the new values of theta1 and theta2 will be available anywhere, correct?

thanks!

AWOL

Just make sure you don't return a pointer to a local automatic variable.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

mromani

Something along these lines:

Code: [Select]

struct angles {
   double a;
   double b;
};

struct angles f(double x, double y) {
   struct angles ang;

   ang.a = ....
   ang.b = ....

   return ang;
}

void loop() {
   struct angles theAngles;

   x = ...
   y = ...

   theAngles = f(x, y);
}



Code: [Select]

// inputs: x, y
// outputs: a, b
void f(double x, double y, double* a, double* b) {
   *a = ....
   *b = ....

   return;  // no return value
}

void loop() {
   double theta1;
   double theta2;

   x = ...
   y = ...

   f(x, y, &theta1, &theta2);
}


mromani

Quote
return a pointer to an array - how?
You could pass by reference, and not return anything - how?
Or you could return a struct - how?
Watch out for the function prototypes - what do you mean?


Ok, not the simplest you can find around, but at least they should get you started:

http://en.wikipedia.org/wiki/Function_prototype

http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_reference

http://en.wikipedia.org/wiki/Struct_%28C_programming_language%29

dustynrobots

thanks! will work in implementing that now

retrolefty

While frowned upon by the grey beards, I would just tend to use global variables is such situations. As my sketches tend to be on the small size, and I'm the only one writing and using the code, I don't have too much difficulty tracking of what functions will have access to changing such variables and have not had a bug yet where the reason was the use of global variables Vs if I had used local scope variables and passed the return values.

Lefty

GoForSmoke

Well my beard is white and I use globals. For one thing, they stay allocated.
I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

retrolefty


Well my beard is white and I use globals. For one thing, they stay allocated.



Well then both you and Santa Claus have white beards and therefore friendly by definition. While grey beards are always rather stern and abrupt with us less experienced 'Arduino programmers'.  ;)

Grumpy_Mike

Well I am with you on the use of global variables, so what colour does it make my beard?


Nick Gammon


You could pass by reference, and not return anything - how?


That is probably the simplest.

Code: [Select]
double a1 = 1, a2 = 2;

void get_angles(const double Px, const double Py, double & theta1, double & theta2)
{
 // first find theta2 where c2 = cos(theta2) and s2 = sin(theta2)
double c2 = (pow(Px,2) + pow(Py,2) - pow(a1,2) - pow(a2,2))/(2*a1*a2); // is btwn -1 and 1
double s2 = sqrt(1 - pow(c2,2));
theta2 = degrees(atan2(s2,c2));  // solves for the angle in degrees and places in correct quadrant

 // now find theta1 where c1 = cos(theta1) and s1 = sin(theta1)
theta1 = degrees(atan2(-a2*s2*Px + (a1 + a2*c2)*Py, (a1 + a2*c2)*Px + a2*s2*Py));
} // end of get_angles

void setup ()
{
 double t1, t2;
 get_angles (20, 30, t1, t2);
}

void loop () {}


I noticed when I was doing this that you have a1 and a2 as variables which presumably are global. So you need to make up your mind if the function is going to be a "black box" (and thus pass everything to it). If not, passing some stuff and not others seems to be hedging your bets a bit.

In my example get_angles returns its results by reference (the last two arguments) so it needs "return" nothing.

Go Up