ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Does rosserial (arduino) work with rosparam server ?

asked 2020-06-20 14:24:18 -0500

dmb gravatar image

updated 2020-06-20 14:25:49 -0500

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

edit retag flag offensive close merge delete

Comments

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:

[WARN] [1592780031.921891]: Failed to get param: timeout expired
[INFO] [1592780031.925491]: Failed to read /encoders/max_clicks
[ERROR] [1592780031.930196]: Parameter /encoders/max_clicks does not exist

until I load the parameter onto the server, then I get

[INFO] [1592780043.372762]: max_clicks: 9999

Without the rest of your code, difficult to say what it might be. Are you sure the parameter exists on the server ?

nickw gravatar image nickw  ( 2020-06-21 18:06:30 -0500 )edit

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

dmb gravatar image dmb  ( 2020-06-21 19:20:28 -0500 )edit

Partly solved but still problems. Waiting until connected made it work more often:

int max_clicks;

void setup()
{
   ...
    nh.initNode();

    while (!nh.connected()) {nh.spinOnce();}                              // this is better, works sometimes

   ...

    if (!nh.getParam("/encoders/max_clicks", &max_clicks)){    // default value doesn't work - max_clicks gets set to 0 on failure
        max_clicks = 9999;
        strcpy(msgbuf, "Failed to read /encoders/max_clicks");
    }
    else
        sprintf(msgbuf, "max_clicks: %u", max_clicks);

    nh.loginfo(msgbuf);
}
dmb gravatar image dmb  ( 2020-06-25 09:36:33 -0500 )edit

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.

dmb gravatar image dmb  ( 2020-06-26 08:10:47 -0500 )edit

Difficult to know - may be some issue with the code that you haven't included - I was just running

#include "ros.h"

ros::NodeHandle nh;

//char buffer[250];
float pid_constants[3];
char msgbuf[100];

void setup(){
    while (!nh.connected()) {
        nh.spinOnce();
    }
}

void loop(){
    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);
    delay(1000);
    nh.spinOnce();
}

on a teensy4 connecting to a virtual machine. If you can post all the code somewhere there may be something that is interfering.

nickw gravatar image nickw  ( 2020-06-26 08:39:53 -0500 )edit

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.

dmb gravatar image dmb  ( 2020-06-26 09:36:56 -0500 )edit

1 Answer

Sort by » oldest newest most voted
0

answered 2020-06-25 09:29:29 -0500

dmb gravatar image

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

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2020-06-20 14:24:18 -0500

Seen: 697 times

Last updated: Jun 25 '20