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);
}
2 Answers 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).
-
Then your Publisher class has no default constructor. Add one.Majenko– Majenko2016年09月16日 10:27:29 +00:00Commented 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– Jacksonkr2016年09月16日 10:30:50 +00:00Commented Sep 16, 2016 at 10:30
-
1It's called an initialization list - you can read a little more about it here: tutorialspoint.com/cplusplus/cpp_constructor_destructor.htmMajenko– Majenko2016年09月16日 10:31:52 +00:00Commented Sep 16, 2016 at 10:31
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
ROSController
class to the bottom of the question