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

Conditional statement for publisher and subscriber

asked 2021-03-03 02:25:38 -0500

Jefferson gravatar image

updated 2021-04-22 11:16:31 -0500

miura gravatar image

Hi,

I would like to enquire there are any examples for conditional statement for publisher and subscriber. For instance, if the battery level falls below the specified battery level, there would be a warning message. Else, the machine does not publish anything.

Thanks!

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2021-03-03 03:09:04 -0500

gvdhoorn gravatar image

updated 2021-03-03 03:17:12 -0500

Is this related / a follow-up / a repost of your #q372471?

As to your question: I don't believe there is anything special to publishers or subscribers here.

Publishers broadcast messages, subscribers receive them.

Publishers and subscribers do not contain messages, nor do they contain values (or at least: not the kind of values I believe you are interested in).

Messages are kept in a queue by subscribers, and they get passed to your callback function when it gets invoked (people typically give the name msg to that argument of the callback function/method).

In that callback function you then access the information you are interested in inside the message object. You can only do that inside the callback: the message object is "thrown away" after the callback completes and is not retained by the subscriber (by default). Nor does the data inside the message get stored in the subscriber directly.

To make it extra clear: publishers are not comparable to simple variables which contain data, nor are subscribers. They are active objects which you can use to transmit and receive data (called messages in ROS).

I would like to enquire there are any examples for conditional statement for publisher and subscriber.

I hope it's somewhat clearer now that this particular question isn't really something you can ask.

The direct answer would be: no, there are no comparison operators defined for ros::Publisher and ros::Subscriber. No direct (specialised) comparisons between publishers and subscribers are available.

I also don't believe it would make sense either: what would be compared (remember: there is no data directly stored in either of these which relates to message content)?

For instance, if the battery level falls below the specified battery level, there would be a warning message. Else, the machine does not publish anything.

This is certainly possible, but would be essentially the same as comparing any two number-like values in any programming language. Only in this case, you'd make that comparison in the callback.

To give an example (in C++, roscpp, pseudo-code):

void callback(const sensor_msgs::BatteryState::ConstPtr& msg)
{
  // minimum acceptable battery level
  const float MIN_PERCENTAGE = 0.1;

  // compare with level reported in the message
  if (msg->percentage < MIN_PERCENTAGE)
  {
    // do something when battery level drops below the minimum
    ..
  }
  else
  {
    // still sufficient battery charge available, do something else
    ..
  }
}

note how this code uses the percentage field which is part of the sensor_msgs/BatteryState message which was received.

It does not check anything in a subscriber or a publisher (and how could it: those objects do not contain any of this data).

note also this is exactly how you'd do something without ROS: comparing number-like variables is done using the regular < operator.

edit flag offensive delete link more

Comments

Hi, this is not a follow up of #q372471, as I managed to resolve my previous error. I am asking a new question, thanks for the clarification :)

Jefferson gravatar image Jefferson  ( 2021-03-03 19:07:51 -0500 )edit

So is your question now answered?

gvdhoorn gravatar image gvdhoorn  ( 2021-03-04 03:06:23 -0500 )edit
0

answered 2021-03-17 05:35:51 -0500

rodrigo55 gravatar image

updated 2021-03-17 05:39:18 -0500

Hi,

I believe that what you want to do is listen to a topic (battery level) in another node and if a condition is met, then publish one message from the second node. This can be done by nesting the published message in an if statement. To test this, you can first create a simple publisher and subscriber by downloading the example nodes from the official ROS2 documentation:

https://docs.ros.org/en/foxy/Tutorial...

Once you have those two nodes, make the following changes:

  • In publisher_member_function.py:

    def __init__(self):
        super().__init__('minimal_publisher')
        self.publisher_ = self.create_publisher(String, 'topic', 10)
        timer_period = 0.5  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 100
    
    def timer_callback(self):
        msg = String()
        msg.data = 'Battery Level: %d' % self.i
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.i -= 1
    

    This simulates a depleting battery by publishing a string. You can then modify this to be in whatever topic you have your battery level in.

  • Insubscriber_member_function.py:

    def __init__(self):
        super().__init__('minimal_subscriber')
        self.subscription = self.create_subscription(String, 'topic', self.listener_callback, 10)
        self.subscription  # prevent unused variable warning
        self.publisher_ = self.create_publisher(String, 'battery', 10)
    

    The last line creates an extra publisher with topic /battery that will publish a warning message once a condition is met, expressed in the following function:

    def listener_callback(self, msg):
        if msg.data == 'Battery Level: 70':
            self.get_logger().info('WARNING!: "%s"' % msg.data)
            self.publisher_.publish(msg)
    

Now, when the battery level falls below 70%, you will have a string being published once on /battery.

I hope this helps. I've also made this video that guides you how to do what I described above:

https://www.youtube.com/watch?v=zkK8r...

edit flag offensive delete link more

Comments

1

Isn't this already the same example given in the other answer?

This can be done by nesting the published message in an if statement.

The message isn't guarded by the conditional, the publication of the message is.

Now, when the battery level falls below 70%, you will have a string being published once on /battery.

what if the Battery Level skips the 70%?

gvdhoorn gravatar image gvdhoorn  ( 2021-03-17 05:53:58 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2021-03-03 02:25:38 -0500

Seen: 1,381 times

Last updated: Mar 17 '21