Pointer to PID object not working?

Hello, I have a header and cpp file where I declare three PID objects and then use an initializer list with my constructor in the robot class. Before I had to situate the PID object outside of the class just in the main script file, but I didn’t like that. I had it working there and am unsure why it is not working in this case. No errors during compile, I run a GUI and send a command over serial that starts the PID loop referenced below, even though I set the values through the → dereferencing command it doesn’t seem to do anything, because in the output the p i and d values are zero. I know they are zero in the constructor, just to save space, but I set it later in the script in robot::setup()

robot.h I removed some of the methods from robot.cpp just to make it easier to read since they aren’t important to this, but in the header they are still there

#ifndef robot_h
#define robot_h

#include "Arduino.h"
#include "Servo.h"
#include <PID_v1.h>


class robot {
  public:
    robot();
    Servo servo[3];
    void setup();
    int pin[3];
    void servSpeed(float _speed[3]);
	void servSpeed();
    char l[3];
	void processEncoders();
	void updateEncoders(int en1, int en2, int en3);
	double enc[3];
	PID lPID;
	PID mPID;
	PID rPID;
	PID* control[3];
	void stepServos(int step);
    void stepServo(int servo, int step);
	double kp[3];
	double kd[3];
	double ki[3];
	void processPID();
	double speed[3];
	double rotationWanted[3];
	double* rot;
	double* sp;
	double servoSpeed[3];
	int t;
	double smoothed[3];
};
#endif

robot.cpp

#include "robot.h"
#include "Arduino.h"
#include "Servo.h"
#include <PID_v1.h>

  robot::robot(): 
  lPID(&enc[0], sp, rot, 0,0,0, DIRECT),
  mPID(&enc[1], sp+1, rot+1, 0,0,0, DIRECT),
  rPID(&enc[2], sp+2, rot+2, 0,0,0, DIRECT) 
  {
  	Servo servo[3];
  	char l[] = "lmr";
	double enc[3] = {0, 0, 0};
	double servoSpeed[3] = {0,0,0};
	double rotationWanted[3] = {10, 10, 10};
	double* rot = rotationWanted;
	double* sp = servoSpeed;
	int t = 0;
	double smoothed[3] = {0,0,0};
	double kp[3] = {63.35, 0.11616, 0.278};
	double kd[3] = {1.11,0,0.883};
	double ki[3] = {2.16E-2,0.2323,5.22};
  }

  void robot::setup() {
  
	PID* control[3] = {&lPID,&mPID,&rPID};
  	for(int i=0;i<3;i++) {
      servo[i].write(90);
	  control[i]->SetMode(AUTOMATIC);
	  control[i]->SetOutputLimits(-2,2);
	  control[i]->SetSampleTime(10);
	  control[i]->SetTunings(kp[i], ki[i], kd[i]);
    }
  }
  double smooth(double data, float filterVal, float smoothedVal){
	  if (filterVal > 1){      // check to make sure param's are within range
		filterVal = .99;
	  }
	  else if (filterVal <= 0){
		filterVal = 0;
	  }

	  smoothedVal = (data * (1 - filterVal)) + (smoothedVal  *  filterVal);

	  return smoothedVal;
}
  void robot::servSpeed() {
	for(int i=0;i<3;i++) {
		if(servoSpeed[i] != speed[i]) {
			smoothed[i] = smooth(servoSpeed[i], 0.65, smoothed[i]);
			servo[i].write(servoSpeed[i]+90);
			speed[i] = servoSpeed[i];
		}
	}
  }
void robot::processPID() {
  for(int i=0;i<3;i++) {
		Serial.print(control[i]->GetKp());
		control[i]->Compute();
		Serial.print(",");
	}
	servSpeed();
	Serial.print(enc[0]);
	Serial.print(",");
	Serial.print(enc[1]);
	Serial.print(",");
	Serial.print(enc[2]);
	Serial.print(",");
	Serial.print(rotationWanted[0]);
	Serial.print(",");
	
	Serial.println(t);
	if(t==100) { 
		stepServos(10);
	}
	t++;
  }
  void robot::stepServos(int step) {
	for(int a=0;a++;a<3) {
		rotationWanted[a] += step;
	}
	
  }

every loop it is printing the encoder values and a zero speed and p i d value. It seems like there is an issue with pointing to the PID object and calling its methods?

  	Servo servo[3];
  	char l[] = "lmr";
	double enc[3] = {0, 0, 0};
	double servoSpeed[3] = {0,0,0};
	double rotationWanted[3] = {10, 10, 10};
	double* rot = rotationWanted;
	double* sp = servoSpeed;
	int t = 0;
	double smoothed[3] = {0,0,0};
	double kp[3] = {63.35, 0.11616, 0.278};
	double kd[3] = {1.11,0,0.883};
	double ki[3] = {2.16E-2,0.2323,5.22};

Why are you declaring local variables in the constructor that have the same name as class members? These arrays all go out of scope when the constructor ends.

	PID* control[3] = {&lPID,&mPID,&rPID};

Another local variable, in setup(), that masks a member array.

It seems like there is an issue with pointing to the PID object and calling its methods?

No. It's that you aren't valuing the member pointers in the PID array.

The Servo array in the class is never valued, so calling methods on Servo instances is plain stupid.

So is the issue that I shouldn’t be declaring them in the constructor? I.e. I should just assign values because they were already declared within the header? I’m really not used to header files and didn’t realize that’s how it worked.

So I’m assuming I should change double* rot = rotationWanted; to rot=&rotationWanted and then that will assign the location of rotationWanted to the public variable rot, rather than the private one?

I’m sorry for the silly mistakes, but in the past I had declared that Servo servo[3] variable this way and it actually always worked fine. I realize now that it is because I referred to the public variable of servo in my main sketch as shown:

for(int i=0;i<3;i++) {
      robot.servo[i].attach(pin[i]);
  }

(It’s not actually called robot though, it has a different name). Thanks for helping me realize this fundamental mistake I’ve made…

So is the issue that I shouldn’t be declaring them in the constructor?

Yes.

I.e. I should just assign values because they were already declared within the header?

Exactly.

So I’m assuming I should change double* rot = rotationWanted; to rot=&rotationWanted and then that will assign the location of rotationWanted to the public variable rot, rather than the private one?

You probably should copy the values from one array to another, rather than trying to point to an array whose contents might change or that might go out of scope.

I’m sorry for the silly mistakes, but in the past I had declared that Servo servo[3] variable this way and it actually always worked fine…I realize now that it is because I referred to the public variable of servo in my main sketch as shown:

Ah, but you didn’t post the sketch. And, you really shouldn’t be exposing all those fields as public. Make the variables private and the methods public. Add getters and setters as need to get and set the values in the private fields.