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

Raising Exceptions in Subscriber Callbacks

asked 2023-02-07 12:15:38 -0500

Rhea gravatar image

ROS distribution: noetic, rospy

I want to raise specific exceptions depending on the data received from the rostopic. However, raising exceptions in the subscriber callback (user_callback) returns a bad callback error due to rospy callback exception handling: https://github.com/ros/ros_comm/blob/...

Is there a way to raise custom ROS exceptions in one node (user_command node) and handle it in another (control node)? Or is there another way to filter data from a subscribed topic and raise an exception accordingly?

For example: I am subscribed to /user_commands. If a "t" is published I want to immediately exit the "scan" state while loop and switch to another state (track)

class command_t(Exception):
    pass

class command_h(Exception):
    pass

class command_hv(Exception):
    pass

class actions:
    def __init__(self):
           #initialize all my variables

    #CALLBACKS
    def user_callback(self,msg):

       if (msg.data == 't'):
           rospy.loginfo(msg.data)
           raise command_t #BAD CALLBACK ERROR
       if (msg.data == 'h'):
           raise command_h


    #STATES
    def scan(self):
        try:
           rospy.loginfo("scan mode")
           local_delta = 0
           while (x0 + local_delta < x1):
               self.waypoint(x0 + local_delta, y0, z)
               self.waypoint(x0 + local_delta, y1, z)
               local_delta = local_delta + self.delta
               self.waypoint(x0 + local_delta, y1, z)
               self.waypoint(x0 + local_delta, y0 , z)
               local_delta = local_delta + self.delta
           local_delta = 0

       except command_t:
         self.track()
       except command_h:
          self.home()

if __name__ == '__main__':
    rospy.init_node("control")
    action = actions()
    user_sub = rospy.Subscriber("/user_commands", String, action.user_callback)

    rate = rospy.Rate(100)
    action.scan()
edit retag flag offensive close merge delete

Comments

Regardless of the technical implementation, and probably pedantic, but using exceptions for regular control flow seems like an abuse of the concept to me.

If you're happy, we're happy of course, but you might be trying to solve an xy-problem, or have other options which would follow best-practices more and don't rely on (potentially) incomplete implementations.

gvdhoorn gravatar image gvdhoorn  ( 2023-02-08 06:53:45 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2023-02-08 02:50:40 -0500

You'd have to handle your own exceptions that are thrown so that the ROS internal system isn't catching them for you (or not catching them). The exceptions you throw and don't catch in callbacks are being processed on the node executor thread.

Instead, you could have the callback simply buffer the data into an internal variable which you can call a function to interpret and process on a timer or in another thread which you can throw and catch your own exceptions while processing them in a context which you can do something contextually about.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2023-02-07 12:15:38 -0500

Seen: 140 times

Last updated: Feb 08 '23