Pages: [1]   Go Down
Author Topic: returning two values from a function  (Read 425 times)
0 Members and 1 Guest are viewing this topic.
NYC
Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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??????
}
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24317
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could pass by reference, and not return anything.
Or you could return a struct.
Watch out for the function prototypes.
« Last Edit: February 14, 2012, 04:49:32 pm by AWOL » Logged

"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.

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 508
Posts: 31374
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

NYC
Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24317
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just make sure you don't return a pointer to a local automatic variable.
Logged

"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.

0
Offline Offline
God Member
*****
Karma: 1
Posts: 596
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Something along these lines:

Code:
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:
// 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);
}
Logged

0
Offline Offline
God Member
*****
Karma: 1
Posts: 596
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

NYC
Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks! will work in implementing that now
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16499
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 58
Posts: 4002
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Examples can be found in your IDE.

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16499
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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'.  smiley-wink
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 508
Posts: 31374
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16499
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

GM, due to your seniority and revered stature on this forum, I would give you first pick on any color (not colour!) you wished to paint your beard. Here is something to help you decide:

http://www.google.com/imgres?q=names+of+colors&hl=en&sa=X&qscrl=1&nord=1&rlz=1T4GGLL_enUS373US373&biw=1117&bih=720&tbm=isch&prmd=imvns&tbnid=eKzS6wiEdkjViM:&imgrefurl=http://msdn.microsoft.com/en-us/library/system.windows.media.colors.aspx&docid=xy5BaP900O6o3M&imgurl=http://i.msdn.microsoft.com/dynimg/IC24340.png&w=871&h=679&ei=Xys7T-q3DIOw2QXKtu2oCg&zoom=1&iact=rc&dur=594&sig=108332181031703398911&page=1&tbnh=157&tbnw=202&start=0&ndsp=15&ved=1t:429,r:2,s:0&tx=97&ty=66
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

That is probably the simplest.

Code:
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.
Logged

Pages: [1]   Go Up
Jump to: