0
$\begingroup$

Rosanswers logo

Suppose I have defined two custom dynamic parameters, gain1 and gain2, in a cfg file. I would like to use these in a node that subscribes and publishes to two topics. Here's what i tried:

import rospy
from std_msgs.msg import Float64
from dynamic_reconfigure.server import Server
from myPack.cfg import paramConfig

def param_callback(config, level):
      gain1 = config.gain1
      gain2 = config.gain2
      return config

def callback1(msg):
      in1 = msg.data

def callback2(msg):
      in2 = msg.data

rospy.init_node('mixer')
srv = Server(paramConfig, param_callback)

sub1 = rospy.Subscriber('in1', Float64, callback1)
sub2 = rospy.Subscriber('in2', Float64, callback2)

pub1 = rospy.Publisher('out1', Float64)
pub2 = rospy.Publisher('out2', Float64)

out1 = Float64()
out2 = Float64()

while not rospy.is_shutdown():
      out1.data = in1*gain1
      out2.data = in2*gain2
     
      pub1.publish(out1)
      pub2.publish(out2)
  

But it seems the subscribers callbacks don't work. This error is given for the first line of the while loop.

 NameError: name 'in1' is not defined

Note that the subscription and parameter server code work fine individually.

Am I using the right method?

Update: As suggested by gvdhoorn, I had to define gain1 and gain2 as global variables and initialize in1 and in2 before the while loop. The latter because the program could reach the while loop before a callback. In this case, in1 is still undefined and I would receive the same error .

I feel this method is a bit inelegant and as gvdhoorn pointed out, using a class instead of global variables is better programming.


Originally posted by mohsen on ROS Answers with karma: 249 on 2017-12-30

Post score: 0


Original comments

Comment by marcoarruda on 2018-01-08:
Another problem you should change: your publishers are being declared as Subscribers. pub1 = rospy.Subscriber('out1', Float64) Change to : pub1 = rospy.Publisher('out1', Float64, queue_size=1)

Comment by mohsen on 2018-01-08:
Whoops. Just saw that. The node is a simplified version of what I use and written specifically for this question so I never actually ran it.

Comment by marcoarruda on 2018-01-08:
Ah ok then! It's just that I reproduced your problem, fixed the variable scope and got into another problem related to that (A Subscriber object doesn't have the .publish method). =]

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

But it seems the subscribers callbacks don't work.

The callbacks are probably fine, and this is not a ROS problem (so there's nothing wrong with the publishers, subscribers or dyn re_cfg here), but most likely a Python scoping problem: you're trying to use variables (in1, in2, gain1 and gain2) in the body of your while-loop that are out of scope at that point (ie: they do not 'exist' there). See random tutorial about Python variable scopes for some explanation.

A quick work-around could be to put in1, in2, gain1 and gain2 in the global scope. Using a class and making those variables members would probably be nicer.


Edit: note that besides the scoping issue your current implementation also has some other issues:

  1. no rate limiting of your main while-loop (see wiki/rospy/Overview/Time - Sleeping and Rates)
  2. mixing an event system with a periodic, synchronous sampling one (and assuming that the event callbacks will be serviced at suitable intervals so the pub1 and pub2 publishers don't republish old data)

The first can lead to starvation of other tasks/nodes, while the second can lead to missed updates and publishing stale data (among other things).


Originally posted by gvdhoorn with karma: 86574 on 2017-12-30

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by mohsen on 2017-12-30:
Thank you. Is there a way to fix the second issue? I haven't found a different way to implement a publisher /subscriber that uses dynamic parameters.

Comment by gvdhoorn on 2017-12-30:
I'm not sure I understand how the dynamic reconfigure complicates things. Can you elaborate?

Comment by mohsen on 2017-12-30:
I think it is a misunderstanding on my part. By "an event system", I thought you meant the parameter server.

Comment by gvdhoorn on 2017-12-30:
No. ROS pub-sub is event-based, not just dynamic reconfigure.

Your while-loop implements a sync, periodic sampling on top of that. I just wanted to point that out.

$\endgroup$

Your Answer

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