boolean return values from base classes not returning up through child classes

In my wrapper class I have:

//  (ROSArdbase is an abstract class. The idea is to have separate children classes for each type of motor controller.)
class ROSArdRoboclaw: public ROSArdBase {
  public:
    int rcAddress;     // address of the controller.
    RoboClaw *RCmc;    // instance of the RoboClaw controller object.

  public:
    ROSArdRoboclaw(RoboClaw *mc, int address, long baud)  {
      this->RCmc = mc;              // instance of RoboClaw class
      this->rcAddress = address;    // address of RoboClaw (allow use of multiple controllers)
      this->cbBaud = baud;          // set controller board baud rate. (Between Arduino and RoboClaw)
    }
    bool getPIDfromRC(VPID *p, int motor);   // retrieve settings actually on RoboClaw

...snip...

In main sketch I first initialize an instance of the RoboClaw controller with:

#include "ROSArdRoboclaw.h"
#include "BMSerial.h"
#include "RoboClaw.h"

// set up roboclaw object on RX 10, TX 11 with 10ms of timeout (between Arduino and RC)
RoboClaw mc(10,11,10000); 

// and then pass this object to my wrapper class:
ROSArdRoboclaw bot(&mc,0x80,38400);

Everything 'works' Commands that I execute through the wrapper class are passed to the motor controller and executed as expected. For example the getPIDfromRC method correctly returns values into the VPID structure, as well as all other methods that I've wrapped.

What's not working is that boolean values from the various base RoboClaw methods are not 'rippling' up.

For example, one of my wrapper methods is:

bool ROSArdRoboclaw::getPIDfromRC(VPID *p, int motor) {
    bool valid;
    if (motor == LEFT) {
      // valid should be 1, but is always 0, even though I've confirmed that this 
      // command is executing and reading values correctly !!!
      valid = this->RCmc->ReadM1VelocityPID(this->rcAddress, p->P,p->I,p->D,p->qpps);
    } else if (motor == RIGHT) {
      valid = this->RCmc->ReadM2VelocityPID(this->rcAddress, p->P,p->I,p->D,p->qpps);
    } else {
      return false;
    }
    return valid;
}

but even though ReadM1VelocityPID is executed successfully on the motor controller, the boolean 'true' value it's returning is not making its way into 'valid'

In the RoboClaw.h we see that it should be returning a 'true' upon success:

.h
	bool ReadM1VelocityPID(uint8_t address,float &Kp_fp,float &Ki_fp,float &Kd_fp,uint32_t &qpps);
	bool ReadM2VelocityPID(uint8_t address,float &Kp_fp,float &Ki_fp,float &Kd_fp,uint32_t &qpps);

.cpp

bool RoboClaw::ReadM1VelocityPID(uint8_t address,float &Kp_fp,float &Ki_fp,float &Kd_fp,uint32_t &qpps){
	uint32_t Kp,Ki,Kd;
	bool valid = read_n(4,address,READM1PID,&Kp,&Ki,&Kd,&qpps);
	Kp_fp = ((float)Kp)/65536;
	Ki_fp = ((float)Ki)/65536;
	Kd_fp = ((float)Kd)/65536;
	return valid;
}

I've confirmed that if I just use the motor controller instance 'mc' established at the beginning of the sketch rather than through my wrapper class, it ~does~ return the correct BOOL value upon success.

For example:

valid = mc.ReadM1VelocityPID(0x80,test2.P,test2.I,test2.D,test2.qpps);

results in valid being set to '1' which is the expected result as well as returning the same values for the PID as my wrapper method does.

Question. Why is the boolean value from the RoboClaw method not making it's way up through my wrapper object???

I'd like to be able to test for valid execution of commands just as I can if accessing the motor controller object directly.

Why is the boolean value from the RoboClaw method not making it's way up through my wrapper object???

You'd have to ask about your snippets at http://snippets-r-us.com. Here, we need to see all of your code.

By the way, this-> is almost never used by real programmers.

Full code as it currently exists attached. My code is in 'code.zip'. BMSerial and RoboClaw libraries in RoboClaw.zip

code.zip (11.1 KB)

RoboClaw.zip (306 KB)

I can't open your RoboClaw zip file. WinZip claims it is damaged.

Ditto. Can't open it.

the boolean 'true' value it's returning is not making its way into 'valid'

How do you know this?

I agree with PaulS, ditch the this-> stuff, it just makes it hard to read.

Weird. I've attached BMSerial and RoboClaw libraries as their individual components.

Full packages with all examples from RoboClaw

RoboClaw.cpp (16.1 KB)

RoboClaw.h (7.97 KB)

BMSerial.h (4.26 KB)

BMSerial.cpp (21.1 KB)

Before I wade through all that, you'll need to explain why you have duplicated the SoftwareSerial class, instead of deriving from it, with whatever improvements you've added. What they are is not clear.

For example, one of my wrapper methods is:

bool ROSArdRoboclaw::getPIDfromRC(VPID *p, int motor) {

In your posted code (in code.zip), that function is never called, so I don't know how you know what value it is returning.

#include "../BMSerial/BMSerial.h"

This isn't really the way to do libraries. Either put those files in the same directory, or make a library of them and put that in the libraries folder.

OK, I got it to compile OK. Now can you point me to the line which you say is not returning the "valid" validly?

Hello guys.

Thanks for your help.

I didn't write BMSerial or Roboclaw, so I have no idea why they were done that way. It's what the manufacturer provided.

I think I found the problem. The RoboClaw class always returns 'false' on methods involving 'writes' to the controller but 'true/false' if 'reading' from the controller. (Unless 'ack' is set to true when initializing the RoboClaw class.) See bool RoboClaw::write_n(uint8_t cnt, ... ) in the RoboClaw.cpp file.

I've made the following change to the code:

// set ACK to true to get 'write' methods to return useful booleans.
RoboClaw mc(10,11,10000,true);

As to the usage of the '->' operator, I couldn't get it to compile if I didn't use it. I don't know C++ that well.

For example here's some of my original code:

      valid = this->RCmc->SetM2VelocityPID(
                this->rcAddress,
                this->rightMotor.D,
                this->rightMotor.P,
                this->rightMotor.I,
                this->rightMotor.qpps);

I can clean it up a bit to:

      valid = ROSArdRoboclaw::RCmc->SetM2VelocityPID(
                ROSArdRoboclaw::rcAddress,
                ROSArdRoboclaw::rightMotor.D,
                ROSArdRoboclaw::rightMotor.P,
                ROSArdRoboclaw::rightMotor.I,
                ROSArdRoboclaw::rightMotor.qpps);

and it still works correctly and compiles, but I don't know how to get rid of the one remaining "->" between "RCmc->SetM2VelocityPID"

The things I try fail to compile:

      valid = ROSArdRoboclaw::RCmc::SetM2VelocityPID(...);
//
ROSArdRoboclaw.cpp: In member function 'bool ROSArdRoboclaw::sendPIDtoRC(int)':
ROSArdRoboclaw.cpp:203: error: 'ROSArdRoboclaw::RCmc' is not a class or namespace

or

      valid = ROSArdRoboclaw::RCmc.SetM2VelocityPID(...);
// ROSArdRoboclaw.cpp: In member function 'bool ROSArdRoboclaw::sendPIDtoRC(int)':
ROSArdRoboclaw.cpp:203: error: request for member 'SetM2VelocityPID' in '((ROSArdRoboclaw*)this)->ROSArdRoboclaw::RCmc', which is of non-class type 'RoboClaw*'

I'm all for doing it the 'right' way. Please let me know how.

For example here's some of my original code: ... I can clean it up a bit to:

Completely and utterly (and incorrectly) changing the meaning of the code.

      valid = RCmc->SetM2VelocityPID(
                rcAddress,
                rightMotor.D,
                rightMotor.P,
                rightMotor.I,
                rightMotor.qpps);

As PaulS says, all you have to do is do a "change all" of "this->" to nothing (an empty string). Nothing more or less.

Don't replace "this->" with something else, and don't try to get rid of all of "->" in the code.

Thank you for your guidance. I've made the changes in the code and it seems to be working and cleaner.

and it still works correctly and compiles, but I don't know how to get rid of the one remaining "->" between "RCmc->SetM2VelocityPID"

If its a pointer, you have to use it ( or use * first ). There is also no reason whatsoever to remove the use if the 'this' pointer. You are better off getting into the habit of using it, as it takes a far more learning to know where its actually important, which is a problem a not so lazy programmer will never encounter.

PaulS:
By the way, this-> is almost never used by real programmers.

lol, real programmers would slap you.

Also, if the members are part of 'ROSArdRoboclaw' its fine to use 'ROSArdRoboclaw::' to keep the identifier fully qualified.

Personally I think it clutters up your code for no reason. Sure, it is needed sometime to clarify scope, but why use it when you don't have to?

You may as well be writing:

  ::Serial.begin (115200UL);
  ::Serial.println ();
  ::delay (1000UL);

"Just in case".

You are better off getting into the habit of using it, as it takes a far more learning to know where its actually important,

I'm calling bullshit on this. It IS important to know why you might need to use this->, and to know when you don't need to. Using it all the time is a sign of cluelessness.

I've been doing C++ programming for 15 years, and have never NEEDED to use this->. To avoid it, I've sometimes needed to resort to changing argument names so that they don't clash with member fields, or I've needed to artificially name member fields. But I don't just get in the habit is splattering unnecessary this->s all over the place.