0

I'm taking a sample I found on the web about how to get ROS and arduino to communicated together over serial. I have the sample working and now I'm moving the idea of the sample into my OOP project and am running into some trouble.

My sketch works but when I move a certain global variable to a protected member it breaks my sketch.

How do I declare this global variable

ros::Publisher chatter("chatter", &str_msg);

as a protected variable

protected:
  ros::Publisher chatter("chatter", &str_msg);

without getting this error

expected identifier before string constant

sample .ino

/*
 * rosserial Publisher Example
 * Prints "hello world!"
 */

#include <ros.h>
#include <std_msgs/String.h>

ros::NodeHandle nh;

std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);

char hello[13] = "hello world!";

void setup()
{
  nh.initNode();
  nh.advertise(chatter);
}

void loop()
{
  str_msg.data = hello;
  chatter.publish( &str_msg );
  nh.spinOnce();
  delay(1000);
}

ROSController class

#include <ros.h>
#include <std_msgs/String.h>

class ROSController {
  protected:
    ros::NodeHandle _nh;
    std_msgs::String str_msg;
//    ros::Publisher chatter("chatter", &str_msg);
    int _throttle;
    bool _is_on = false;
  public:
    void loop();
    ROSController();
    double* getAttitude();
    bool isOn() {
      return this->_is_on;
    }
    int getThrottlePerc() {
      return this->_throttle / ROSController::THR_MAX;
    }

    static const int THR_MAX;
};

const int ROSController::THR_MAX = 100;

ROSController::ROSController() {
  this->_nh.initNode();
//  this->_nh.advertise(chatter);
}

double* ROSController::getAttitude() {
  return new double[3]{0, 0, 0};
}

void ROSController::loop() {
//  str_msg.data = new char[] {"hello"};
//  chatter.publish( str_msg );
  this->_nh.spinOnce();
  delay(1000);
}
5
  • I don't understand what you are trying to do there. Some context would be nice - ideally some actual code that demonstrates just what you are trying to do (before and after maybe?)
    – Majenko
    Sep 7, 2016 at 23:07
  • I added my sample .ino and a little more of the backstory. It's really such a small issue so I was hoping I could keep the question just as simple but I suppose to be thorough you'll have to see the bigger picture.
    – Jacksonkr
    Sep 7, 2016 at 23:12
  • And where are you trying to move that global variable to?
    – Majenko
    Sep 7, 2016 at 23:13
  • I've added my ROSController class to the bottom of the question
    – Jacksonkr
    Sep 7, 2016 at 23:16
  • 1
    There's no such thing as a "protected" global variable. Protected variables belong inside classes.
    – Nick Gammon
    Sep 7, 2016 at 23:16

2 Answers 2

2

The problem you are having is you are trying to both define and declare a class member variable at the same time. You can't. Instead you need to split it:

protected:
    ros::Publisher chatter;

ROSController::ROSController() : chatter("chatter", &str_msg)
{
    this->_nh.initNode();
//  this->_nh.advertise(chatter);
}

That is, set up the variable as a protected member, then have the constructor call the constructor for you with the right parameters.

(I think that is the right syntax off the top of my head).

3
  • Then your Publisher class has no default constructor. Add one.
    – Majenko
    Sep 16, 2016 at 10:27
  • Hey, that worked! I don't understand what you did on line 4. What is that called? I want to research it and find out more about it.
    – Jacksonkr
    Sep 16, 2016 at 10:30
  • 1
    It's called an initialization list - you can read a little more about it here: tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm
    – Majenko
    Sep 16, 2016 at 10:31
0

You can't call the constructor in the class definition. Example:

class foo
  {
  protected:
    String bar ("fubar");
  };

void setup ()
  {
  }  // end of setup

void loop ()
  {
  }  // end of loop

That gives this error:

sketch_sep08b:4: error: expected identifier before string constant
     String bar ("fubar");
                 ^
sketch_sep08b:4: error: expected ',' or '...' before string constant
exit status 1
expected identifier before string constant

Instead declare the class (without the constructor) and call the constructor in the constructor for the parent class, like this:

class foo
  {
  protected:
    String bar;
  public:

    foo () : bar ("fubar") {};  // constructor
  };

void setup ()
  {
  }  // end of setup

void loop ()
  {
  }  // end of loop

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.