Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

The cleanest way is to use: msg._type

Here I leave an example of two susbcribers in ros using the same callback. The callback called common_callback will process the messages differently depending on their type. In this case it processes type LaserScan or Odometry, but this can be used for anything really because the output of the msg._type is sensor_msgs/LaserScanor nav_msgs/Odometry. So its easy too work with that.

I'll leave a video with a full blown example of how to use this: Video Example

Here que have the python code:

#! /usr/bin/env python

import rospy
from std_msgs.msg import Int32
from sensor_msgs.msg import LaserScan
from nav_msgs.msg import Odometry
from geometry_msgs.msg import Point

"""
user:~$ rosmsg show sensor_msgs/LaserScan
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities
"""
"""
user:~$ rosmsg show nav_msgs/Odometry
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
string child_frame_id
geometry_msgs/PoseWithCovariance pose
  geometry_msgs/Pose pose
    geometry_msgs/Point position
      float64 x
      float64 y
      float64 z
    geometry_msgs/Quaternion orientation
      float64 x
      float64 y
      float64 z
      float64 w
  float64[36] covariance
geometry_msgs/TwistWithCovariance twist
  geometry_msgs/Twist twist
    geometry_msgs/Vector3 linear
      float64 x
      float64 y
      float64 z
    geometry_msgs/Vector3 angular
      float64 x
      float64 y
      float64 z
  float64[36] covariance
"""

class MultipleSubs(object):
    def __init__(self):

        self.laser_center_distance = 100.0
        self.kobuki_position = Point()

        sub_laserscan = rospy.Subscriber('/kobuki/laser/scan', LaserScan, self.common_callback)
        sub_odom = rospy.Subscriber('/odom', Odometry, self.common_callback)

    def common_callback(self,msg):

        input_message_type = str(msg._type)

        rospy.logdebug("msg._type ==>"+input_message_type)
        #rospy.loginfo("type(msg)"+str(type(msg)))

        if input_message_type == "sensor_msgs/LaserScan":
            rospy.loginfo("sub_laserscan called me, with type msg==>"+input_message_type)

            self.laser_center_distance = msg.ranges[len(msg.ranges)/2]

        if input_message_type == "nav_msgs/Odometry":
            rospy.loginfo("sub_odom called me, with type msg==>"+input_message_type)

            self.kobuki_position = msg.pose.pose.position

if __name__ == "__main__":
    #rospy.init_node('topic_publisher', log_level=rospy.DEBUG)
    #rospy.init_node('topic_publisher', log_level=rospy.INFO)
    rospy.init_node('topic_publisher', log_level=rospy.WARN)

    multiple_subs_object = MultipleSubs()
    rate = rospy.Rate(2)

    while not rospy.is_shutdown(): 
      rospy.logwarn("Kobuki Center Laser Distance Reading==>"+str(multiple_subs_object.laser_center_distance))
      rospy.logwarn("Kobuki Odometry Position Reading==>"+str(multiple_subs_object.kobuki_position))
      rate.sleep()

Hope this helps ;).

Here I want to add an example of use of this _typeaccess. For various reasons: 1) I'm giving here a complete example on how to use this _type access, not only an indication of how its done, which I find more enriching for anyone that want to use this. 2) Although this example is trivial, I've come across a lot of poeple trying to use a unique callback for multiple subscribers, and this _typevariable is perfect for this application. It opens the possiblity of using callback another way.

The cleanest way is to use: msg._type

Here I leave an example of two susbcribers in ros using the same callback. The callback called common_callback will process the messages differently depending on their type. In this case it processes type LaserScan or Odometry, but this can be used for anything really because the output of the msg._type is sensor_msgs/LaserScanor nav_msgs/Odometry. So its easy too work with that.

I'll leave a video with a full blown example of how to use this: Video Example

Here que have the python code:

#! /usr/bin/env python

import rospy
from std_msgs.msg import Int32
from sensor_msgs.msg import LaserScan
from nav_msgs.msg import Odometry
from geometry_msgs.msg import Point

"""
user:~$ rosmsg show sensor_msgs/LaserScan
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities
"""
"""
user:~$ rosmsg show nav_msgs/Odometry
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
string child_frame_id
geometry_msgs/PoseWithCovariance pose
  geometry_msgs/Pose pose
    geometry_msgs/Point position
      float64 x
      float64 y
      float64 z
    geometry_msgs/Quaternion orientation
      float64 x
      float64 y
      float64 z
      float64 w
  float64[36] covariance
geometry_msgs/TwistWithCovariance twist
  geometry_msgs/Twist twist
    geometry_msgs/Vector3 linear
      float64 x
      float64 y
      float64 z
    geometry_msgs/Vector3 angular
      float64 x
      float64 y
      float64 z
  float64[36] covariance
"""

class MultipleSubs(object):
    def __init__(self):

        self.laser_center_distance = 100.0
        self.kobuki_position = Point()

        sub_laserscan = rospy.Subscriber('/kobuki/laser/scan', LaserScan, self.common_callback)
        sub_odom = rospy.Subscriber('/odom', Odometry, self.common_callback)

    def common_callback(self,msg):

        input_message_type = str(msg._type)

        rospy.logdebug("msg._type ==>"+input_message_type)
        #rospy.loginfo("type(msg)"+str(type(msg)))

        if input_message_type == "sensor_msgs/LaserScan":
            rospy.loginfo("sub_laserscan called me, with type msg==>"+input_message_type)

            self.laser_center_distance = msg.ranges[len(msg.ranges)/2]

        if input_message_type == "nav_msgs/Odometry":
            rospy.loginfo("sub_odom called me, with type msg==>"+input_message_type)

            self.kobuki_position = msg.pose.pose.position

if __name__ == "__main__":
    #rospy.init_node('topic_publisher', log_level=rospy.DEBUG)
    #rospy.init_node('topic_publisher', log_level=rospy.INFO)
    rospy.init_node('topic_publisher', log_level=rospy.WARN)

    multiple_subs_object = MultipleSubs()
    rate = rospy.Rate(2)

    while not rospy.is_shutdown(): 
      rospy.logwarn("Kobuki Center Laser Distance Reading==>"+str(multiple_subs_object.laser_center_distance))
      rospy.logwarn("Kobuki Odometry Position Reading==>"+str(multiple_subs_object.kobuki_position))
      rate.sleep()

Hope this helps ;).

Here I want to add an example of use of this _typeaccess. For various reasons: reasons:

1) I'm giving here a complete example on how to use this _type access, not only an indication of how its done, which I find more enriching for anyone that want to use this. this.

2) Although this example is trivial, I've come across a lot of poeple trying to use a unique callback for multiple subscribers, and this _typevariable is perfect for this application. It opens the possiblity of using callback another way.

The cleanest way is to use: msg._type

Here I leave an example of two susbcribers in ros using the same callback. The callback called common_callback will process the messages differently depending on their type. In this case it processes type LaserScan or Odometry, but this can be used for anything really because the output of the msg._type is sensor_msgs/LaserScanor nav_msgs/Odometry. So its easy too work with that.

I'll leave a video with a full blown example of how to use this: Video Example

Here que have the python code:

#! /usr/bin/env python

import rospy
from std_msgs.msg import Int32
from sensor_msgs.msg import LaserScan
from nav_msgs.msg import Odometry
from geometry_msgs.msg import Point

"""
user:~$ rosmsg show sensor_msgs/LaserScan
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities
"""
"""
user:~$ rosmsg show nav_msgs/Odometry
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
string child_frame_id
geometry_msgs/PoseWithCovariance pose
  geometry_msgs/Pose pose
    geometry_msgs/Point position
      float64 x
      float64 y
      float64 z
    geometry_msgs/Quaternion orientation
      float64 x
      float64 y
      float64 z
      float64 w
  float64[36] covariance
geometry_msgs/TwistWithCovariance twist
  geometry_msgs/Twist twist
    geometry_msgs/Vector3 linear
      float64 x
      float64 y
      float64 z
    geometry_msgs/Vector3 angular
      float64 x
      float64 y
      float64 z
  float64[36] covariance
"""

class MultipleSubs(object):
    def __init__(self):

        self.laser_center_distance = 100.0
        self.kobuki_position = Point()

        sub_laserscan = rospy.Subscriber('/kobuki/laser/scan', LaserScan, self.common_callback)
        sub_odom = rospy.Subscriber('/odom', Odometry, self.common_callback)

    def common_callback(self,msg):

        input_message_type = str(msg._type)

        rospy.logdebug("msg._type ==>"+input_message_type)
        #rospy.loginfo("type(msg)"+str(type(msg)))

        if input_message_type == "sensor_msgs/LaserScan":
            rospy.loginfo("sub_laserscan called me, with type msg==>"+input_message_type)

            self.laser_center_distance = msg.ranges[len(msg.ranges)/2]

        if input_message_type == "nav_msgs/Odometry":
            rospy.loginfo("sub_odom called me, with type msg==>"+input_message_type)

            self.kobuki_position = msg.pose.pose.position

if __name__ == "__main__":
    #rospy.init_node('topic_publisher', log_level=rospy.DEBUG)
    #rospy.init_node('topic_publisher', log_level=rospy.INFO)
    rospy.init_node('topic_publisher', log_level=rospy.WARN)

    multiple_subs_object = MultipleSubs()
    rate = rospy.Rate(2)

    while not rospy.is_shutdown(): 
      rospy.logwarn("Kobuki Center Laser Distance Reading==>"+str(multiple_subs_object.laser_center_distance))
      rospy.logwarn("Kobuki Odometry Position Reading==>"+str(multiple_subs_object.kobuki_position))
      rate.sleep()

Hope this helps ;).