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

Waiting for callback before control loop

asked 2021-11-19 06:50:37 -0500

Roshan gravatar image

Hello, I have a node where I'm using lidar data to control a turtlebot. I'm subscribed to the /scan topic, and storing the distance and angle from the lidar callback inside class variables, and these are updated with every callback. These class variables are initialized to 0. Sometimes the first callback happens before the control loop, and then everything runs fine. But sometimes the callback does not happen before the control loop and this causes the values to keep their initial value on the first control loop iteration, which can cause issues.

Here is a simplified version of the code:

    class move:
        def __init__(self):
            self.pub = rospy.Publisher("tb3_1/cmd_vel",Twist,queue_size=100)
            self.sub2 = rospy.Subscriber("tb3_1/scan",LaserScan,self.lidar_callback)

            self.lidar_dist = 0
            self.lidar_angle = 0

      def control(self):
            move = Twist()
            --- Computation of control equations---

      def lidar_callback(self,msg):
           ---calculate distance and angle---
            self.lidar_dist = distance
            self.lidar_angle = angle

if __name__ == '__main__':
    rospy.init_node("lidar_follower",disable_signals=True)
    rate = rospy.Rate(100) 
    obj = move()

    while not rospy.is_shutdown():
            obj.control()
            rate.sleep()

Thanks in advance

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2021-11-19 08:04:23 -0500

Airuno2L gravatar image

updated 2021-11-19 08:04:49 -0500

I think you can wait for the first LaserScan message before setting up your publisher in the class constructor...something like this:

    def __init__(self):
        self.sub2 = rospy.Subscriber("tb3_1/scan",LaserScan,self.lidar_callback)
        rospy.wait_for_message("tb3_1/scan",LaserScan)
        self.pub = rospy.Publisher("tb3_1/cmd_vel",Twist,queue_size=100)

That returns the first message but you can just ignore it if you want.

edit flag offensive delete link more

Comments

Thank you for your answer, tried that but it just makes the class variables 0 on the first iteration all the time instead of just sometimes.

Roshan gravatar image Roshan  ( 2021-11-19 08:09:35 -0500 )edit

umm, I'm not sure why it would do that. Maybe do the wait_for_message before you even create the class object like this

if __name__ == '__main__':
    rospy.init_node("lidar_follower",disable_signals=True)
    rospy.wait_for_message("tb3_1/scan",LaserScan)
    rate = rospy.Rate(100) 
    obj = move()
Airuno2L gravatar image Airuno2L  ( 2021-11-19 09:10:15 -0500 )edit

Also, are you sure you want disable_signals=True in your init_node?

Airuno2L gravatar image Airuno2L  ( 2021-11-19 09:14:33 -0500 )edit

The disable_signals were just there for testing, I don't think they're doing anything at the moment. But doing

if __name__ == '__main__':
    rospy.init_node("lidar_follower",disable_signals=True)
    rospy.wait_for_message("tb3_1/scan",LaserScan)
    rate = rospy.Rate(100) 
    obj = move()

Seems to be doing the same as when it was in the class

Roshan gravatar image Roshan  ( 2021-11-19 09:17:31 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2021-11-19 06:50:37 -0500

Seen: 52 times

Last updated: Nov 19 '21