Changing a variable declared in a class

Hello, I am fairly new to Arduino, and I’m having some trouble with variables within a class…

Anyway, here is my code:

class MyServo 
{
  int driverNum;
  int servoNum;
  int mult = 1;
  float servoMin = 20.0;
  float servoMax = 160.0;
  float alpha = 90.0;
  
public:
MyServo(int n, int d, float minimum, float maximum){
  servoNum = n;
  driverNum = d;
  servoMin = minimum;
  servoMax = maximum;
}
MyServo(const MyServo& s){
  servoNum = s.servoNum;
  driverNum = s.driverNum;
  servoMin = s.servoMin;
  servoMax = s.servoMax;
}
void setAlpha(float a){
  alpha = a;
}
void setMult(int m){
  mult = m;
}
void setMin(float minim){
  servoMin = minim;
}
void setMax(float maxim){
  servoMax = maxim;
}
void setAngle(float angle){
  float newAng = alpha + mult*angle;//servoMax - (alpha + (mult * angle));
  //Serial.println(newAng);
  if (newAng < servoMin){
    newAng = servoMin;
  }else if (newAng > servoMax){
    newAng = servoMax;
  }
  writeToServo(driverNum, servoNum, newAng);
}
};

I know it’s messy and I bet it’s pretty obvious that I don’t know a whole lot about C++ classes, but later in the code I use the following:

servoObject.setAlpha(80.5);
servoObject.setAngle(0.0);

but the value in the class doesn’t change.
Edit: What I mean is that if I uncomment Serial.println(newAng); it prints 90.0 instead of 80.5.
I’m assuming this is because it’s not actually changing the variable’s value, but simply changing some local version of it, but that’s a complete guess :slight_smile:
What I want to know is how to change the value of the variable in the object permanently.
Thanks for the help!

Hexapod.ino (25.1 KB)

fourth-decent:

servoObject.setAlpha(80.5);

but the value in the class doesn't change.

It does.

class MyServo {
    float alpha;
  public:
    MyServo() {
      alpha = alpha = 90.0;
    }
    void setAlpha(float a) {
      alpha = a;
    }
    void print() {
      Serial.print(F("alpha = "));
      Serial.println(alpha);
    }
} test;

void setup() {
  Serial.begin(250000);
  test.print();
  test.setAlpha(69.96);
  test.print();
}
void loop() {}
alpha = 90.00
alpha = 69.96

Okay so then it must be an issue with the Leggy class…
I changed the coxas setup function to not use the array of alphas, mins, and maxes, so I don’t think the problem is there.

class Leggy
{
 //* 
  int leggyNum;
  float zOffset = 34.5;
  float coxaLength = 46.0;
  float femurLength = 65.0;
  float tibiaLength = 69.0;
  MyServo coxaServo;
  MyServo femurServo;
  MyServo tibiaServo;
  //((78.03509)^2 + (26.57038)^2)^0.5
  
  
  float coxAlpha;// = 90.0;
  float coxMin;// = 20.0;
  float coxMax;// = 160.0;

  float femAlpha;// = 90.0;
  float femMin;// = 20.0;
  float femMax;// = 160.0;
  
  float tibAlpha;// = 90.0;
  float tibMin;// = 20.0;
  float tibMax;// = 160.0;

  MyServo SERVOS[3] = {coxaServo, femurServo, tibiaServo};

  float alphas[3] = {coxAlpha, femAlpha, tibAlpha};
  float mins[3] = {coxMin, femMin, tibMin};
  float maxes[3] = {coxMax, femMax, tibMax};

  int alphaMult = -1;
  int gamaMult = 1;
  int betaMult = 1;

  int mults[3] = {gamaMult, alphaMult, betaMult};
  
  //double gama;
  //double alpha;
  //double beta;
  float legLength;
  //double L_1;
  double len;
  String legNames[3] = {"coxa", "femur", "tibia"};
  
  
public://*/
//takes pre-initialized MyServo objects. 
MyServo ServoBois[3] = {SERVOS[0], SERVOS[1], SERVOS[2]};
Leggy(MyServo& coxa, MyServo& femur, MyServo& tibia, 
  int legNum) :
  coxaServo(coxa),
  femurServo(femur),
  tibiaServo(tibia)
  {
  legLength = coxaLength + femurLength + tibiaLength;
  leggyNum = legNum;
}
float getLegLength(){
  return legLength;
}
/*
 * mult is either a 1 or -1 to set the direction of the servo.
 * angles are later multiplied by this value.
 */
void setMults(int gamaM, int alphaM, int betaM){
  gamaMult = gamaM;
  alphaMult = alphaM;
  betaMult = betaM;
  mults[0] = gamaMult;
  mults[1] = alphaMult;
  mults[2] = betaMult;

  SERVOS[0].setMult(mults[0]);
  SERVOS[1].setMult(mults[1]);
  SERVOS[2].setMult(mults[2]);
  
}

/*
 * sets up the angles to make the Coxa behave like the math wants it to.
 */
void setupCoxa(float cAlpha, float cMin, float cMax){
  alphas[0] = cAlpha;
  mins[0] = cMin;
  maxes[0] = cMax;
  Serial.println("COXA");
  Serial.println("alpha:\tmin:\tmax:");
  Serial.print(cAlpha);
  Serial.print("\t");
  Serial.print(cMin);
  Serial.print("\t");
  Serial.println(cMax);

  SERVOS[0].setAlpha(cAlpha);//alphas[0]);
  SERVOS[0].setMinMax(cMin, cMax);//mins[0], maxes[0]);
}
/*
 * see above
 */
void setupFemur(float fAlpha, float fMin, float fMax){
  femAlpha = fAlpha;
  femMin = fMin;
  femMax = fMax;
  alphas[1] = femAlpha;
  mins[1] = femMin;
  maxes[1] = femMax;
  Serial.println("FEMUR:");
  Serial.println("alpha:\tmin:\tmax:");
  Serial.print(femAlpha);
  Serial.print("\t");
  Serial.print(femMin);
  Serial.print("\t");
  Serial.println(femMax);

  SERVOS[1].setAlpha(alphas[1]);
  SERVOS[1].setMinMax(mins[1], maxes[1]);
}
/*
 * see above
 */
void setupTibia(float tAlpha, float tMin, float tMax){
  tibAlpha = tAlpha;
  tibMin = tMin;
  tibMax = tMax;
  alphas[2] = tibAlpha;
  mins[2] = tibMin;
  maxes[2] = tibMax;
  Serial.println("TIBIA:");
  Serial.println("alpha:\tmin:\tmax:");
  Serial.print(tibAlpha);
  Serial.print("\t");
  Serial.print(tibMin);
  Serial.print("\t");
  Serial.println(tibMax);

  SERVOS[2].setAlpha(alphas[2]);
  SERVOS[2].setMinMax(mins[2], maxes[2]);
}

/*
 * sets leg to point relative to the leg itself, not the robot. 
 * that should come from another class
 * y is a magnitude, the distance from the bot, not a location. so 
 * the left and right of the bot have +y coordinates.
*/
float mapAngleToServo(float desAngle, int servoIndex){
  float servoAngle = desAngle;//;// = 90.0;
  //desAngle *= mults[servoIndex]; //multiplies by 1 or -1
  /*
  Serial.println("desAngle:\talpha:");
  Serial.print(desAngle);
  Serial.print("\t");
  Serial.println(alphas[servoIndex]);
  //Serial.println(desAngle + alphas[servoIndex]);
  //*/
  /*
  if (desAngle + alphas[servoIndex] <= mins[servoIndex]){
    Serial.println(legNames[servoIndex]);
    Serial.println("MINIMUM REACHED");
    servoAngle = mins[servoIndex];
  }else if ((desAngle + alphas[servoIndex]) >= maxes[servoIndex]){
    Serial.println(legNames[servoIndex]);
    Serial.println("MAXIMUM REACHED");
    servoAngle = maxes[servoIndex];
  }else{
    //Serial.println("IN RANGE");
    servoAngle = maxes[servoIndex] - (desAngle + alphas[servoIndex]);
  }
  //Serial.println("mapped angle:");
  //Serial.println(servoAngle);
  //*/
  return servoAngle;
}
/*
 * sets the servos in the leg to actual angles. these are the angles passed to the driver.
 */
void setServoAngles(float gama, float alpha, float beta){
  coxaServo.setActAng(gama);
  femurServo.setActAng(alpha);
  tibiaServo.setActAng(beta);
}
/*
 * sets individual servos to this angle. the angle is passed to the driver.
 */
void setIndServoAngle(int index, float ang){
  SERVOS[index].setAngle(ang);
}
/*
 * sets individual servos to proper angles, so 0 is the geometrical start point.
 */

//the above and below now both do the same thing because the code I had origannly was dumb

void setIndAngle(int index, float ang){
  SERVOS[index].setAngle(mapAngleToServo(ang, index));
}

void setAngles(float gama, float alpha, float beta){
  coxaServo.setAngle(gama);//mapAngleToServo(gama, 0));//map(gama,0,180,0,180));
  femurServo.setAngle(alpha);//mapAngleToServo(alpha, 1));//map(alpha, 0,180, 0,180));
  tibiaServo.setAngle(beta);//mapAngleToServo(beta,2));//map(beta,0,180,40,180));
}
/*
 * sets leg to a point by calculating the angles needed. 
 * coordinates are relative to the leg (z represents the height of the base of the femur from the 0 height, more simply the height of the coxa joint)
 */
void setLegToPoint(float x, float y, float z){
  //math to set gama alpha and beta here
  float gama = atan(x/y);
  len = sqrt(sq(zOffset) + sq(y - coxaLength));
  double alpha_1 = acos(zOffset/len);
  double alpha_2 = acos((sq(tibiaLength) - sq(femurLength) - sq(len))/(-2*femurLength*len));
  float alpha = alpha_1 + alpha_2;
  float beta = acos((sq(len) - sq(tibiaLength) - sq(femurLength))/(-2*tibiaLength*femurLength));
  setAngles((gama*180)/PI, 180 - (alpha*180)/PI, (beta*180)/PI);
}
};
[\code]

later I use legs[0].setupCoxa(80.0, 5.0, 125.0);
legs is an array of Leggy objects.
when I use servoObject.setAngle(0.0); it just prints 90.0 instead of 80.0…

You should learn to walk before you try to run.

  float gama = atan(x/y);
  double alpha_1 = acos(zOffset/len);
  double alpha_2 = acos((sq(tibiaLength) - sq(femurLength) - sq(len))/(-2*femurLength*len));
  float alpha = alpha_1 + alpha_2;
  float beta = acos((sq(len) - sq(tibiaLength) - sq(femurLength))/(-2*tibiaLength*femurLength));

All the above statements have no effect.
Probably you don't understand the difference between iniitialized definition and assignment.

Race through a basic tutorial / language description.

That's okay I'll just try stack exchange XD
Thanks for the help, you fixed it!

fourth-decent:
That’s okay I’ll just try stack exchange XD

Oh, one of the lazy “I build my own robot” inventors that need to have their code spoonfed/written.

Have fun with your project. :wink:

I told you one of the basic misunderstandings of the C++ language you suffer from.
And I told you a way how you could (probably quite fast) learn what you are missing.

Are there any adults on here that can tell me where I need to look? I need some help with classes obviously. Also Whandall, you actually cannot act like you've been helpful at all here. All you've done is told me to go look at a "basic tutorial / language description," and then literally told me that I am some lazy kid who doesn't want to write his own code. This is a place for people to get help, not be condescended to.

Whandall:
All the above statements have no effect.

Your definition of "effect" is significantly different from the one offered by all modern dictionaries.

The value stored in gama is manipulated then passed as the first parameter to setAngles...

  setAngles((gama*180)/PI, 180 - (alpha*180)/PI, (beta*180)/PI);

...which then adjust the target angle of a servo...

  coxaServo.setAngle(gama);//mapAngleToServo(gama, 0));//map(gama,0,180,0,180));

Ditto for the other two.

Whandall:
Oh, one of the lazy "I build my own robot" inventors that need to have their code spoonfed/written.

fourth-decent:
Are there any adults on here that can tell me where I need to look?

Next personal insult results in some time away from the forum.

In any case, this code has worked before. I don't remember what's changed since then as I took a break on the project, but I think there's just a problem that I don't have the experience to notice. Sorry for acting childish. My bad behavior isn't excused by anyone else's.

The problem is definitely in the setupCoxa/Femur/Tibia functions in the leggy class. I fixed the problem by just not using those and directly setting the values in setup. I still want to know what's wrong with the stuff in the Leggy class, though.

Given the fact your code does not fit in a single post (>9K) and many people read this forum using a mobile device (cannot reasonably download attached code) I suggest, when possible, you reduce the code to the smallest compilable sketch that demonstrates each problem.

Yes, a MCVE would go a long way towards motivating other people to helping you. I'm not wading through 25KB of someone else's code.

Alright, I will do that when I have some free time. Thanks, I didn't realize that