Does rosserial (arduino) work with rosparam server ?
I wanted to replace some hard-coded values in a working Arduino program with parameters read from the ROS parameter server, but I can't get it to work and wondered if the ROS Melodic parameter server is supported in rosserial ?
In my Arduino code I have:
int max_clicks;
if (!nh.getParam("/encoders/max_clicks", &max_clicks)) {
strcpy(msgbuf, "Failed to read /encoders/max_clicks");
}
else
sprintf(msgbuf, "max_clicks: %d", max_clicks);
nh.loginfo(msgbuf);
/encoders/max_clicks is an integer, value 9999:
$ rosparam get /encoders/max_clicks
9999
$
When I compile the program I get an error in the ROS library:
/usr/share/arduino/hardware/tools/avr/bin/avr-g++ -x c++ -include Arduino.h -MMD -c -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=105 -D__PROG_TYPES_COMPAT__ -I/usr/share/arduino/hardware/arduino//cores/arduino -/usr/share/arduino/hardware/arduino//variants/standard -/home/dmb/catkin_ws/src/storm/sketchbook/libraries/LiquidCrystal/src -/home/dmb/catkin_ws/src/storm/sketchbook/libraries/ros_lib -Wall -ffunction-sections -fdata-sections -Os -fpermissive -fno-exceptions -std=gnu++11 -fno-threadsafe-statics -flto EncoderReader.ino -o build-uno/EncoderReader.ino.o
In file included from /home/dmb/catkin_ws/src/storm/sketchbook/libraries/ros_lib/ros.h:38:0,
from EncoderReader.ino:2:
/home/dmb/catkin_ws/src/storm/sketchbook/libraries/ros_lib/ros/node_handle.h: In instantiation of ‘bool ros::NodeHandle_<Hardware, MAX_SUBSCRIBERS, MAX_PUBLISHERS, INPUT_SIZE, OUTPUT_SIZE>::getParam(const char*, int*, int, int) [with Hardware = ArduinoHardware; int MAX_SUBSCRIBERS = 5; int MAX_PUBLISHERS = 5; int INPUT_SIZE = 256; int OUTPUT_SIZE = 256]’:
EncoderReader.ino:88:54: required from here
/home/dmb/catkin_ws/src/storm/sketchbook/libraries/ros_lib/ros/node_handle.h:614:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (length == req_param_resp.ints_length)
And when I run the program it fails to find the parameter:
[rosout][WARNING] 2020-06-20 20:11:03,249: Failed to get param: timeout expired
[rosout][INFO] 2020-06-20 20:11:03,264: Failed to read /encoders/max_clicks
Any ideas appreciated :)
David
Yes it does work in Melodic.
I get similar warnings to you when compiling for teensy 4 (added basic example code round the fragment of code that you provided).
When running in Melodic I get:
until I load the parameter onto the server, then I get
Without the rest of your code, difficult to say what it might be. Are you sure the parameter exists on the server ?
Hi,
That's interesting ... I definitely have the parameter loaded. I wonder if there's some race condition, even though I have the rosparam as the first entry in the launch file ? Maybe the parameter isn't available at the time when the arduino comes up ?
Tomorrow I'll try running the parameter server and other nodes from the launch file, and then starting up the rosserial to the arduino from the command line.
David
Partly solved but still problems. Waiting until connected made it work more often:
OK, I give up ...
The "wait until connected" does seem to have the effect that the parameter is loaded more often, but unfortunately nothing else happens after the final loginfo() call - it looks like the program never runs the arduino loop() code.
The only thing I can think of is some memory overwrite, but I can't see any reason. There's loads of memory compared to what's needed (it's an Arduino Mega 2560), and all the variables are big enough (e.g. msgbuf is 128 characters, so there's nothing obvious and I don't have time at the moment to dig around in the rosserial code. I've ditched the getParam() code and gone back to hard-coding.
Difficult to know - may be some issue with the code that you haven't included - I was just running
on a teensy4 connecting to a virtual machine. If you can post all the code somewhere there may be something that is interfering.
Yes it's possible. The main difference I can see is that I'm doing a one-time read on the parameter server in setup(), where your code hits it every time loop() is called, so this might be avoiding some kind of timing problem or race condition at startup. However a stripped-down version of the code with the parameter code in setup() has worked properly for me a few times in a row, so I'm pretty sure I have some other problem to track down.