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

code structure with several callbacks

asked 2017-06-07 05:55:49 -0600

mattMGN gravatar image


I am working on a small 4WD rover. I use ultrasonic sensors, and a RPlidar for autonomous navigation and a joy for manual teleoperation. My aim is quite simple, but i am asking some questions about the right python script architecture.

The main idea is to have a loop which check joy inputs, and update both sonar and laser data Joy input decide the current mode ('AUTO' or 'MANUAL')

Thus I write this code :

#!/usr/bin/env python

import rospy
import time
from geometry_msgs.msg import Twist
from sensor_msgs.msg import Joy
from rospy_tutorials.msg import Floats
from sensor_msgs.msg import LaserScan 


def auto_mode():
    print( sonar_array[0] + sonar_array[1])
    print( laser_array[0] + laser_array[1])
    # detect obstacle
    # compute path


def callback_joy(data):

    if data.buttons[0]<0.5 :
        switchMode = 'AUTO'
        switchMode = 'MANUAL'
        twist.linear.x = 4*data.axes[1]
        twist.angular.z = 4*data.axes[0]

def callback_sonar(data):

    sonar_array =
    #some data filtering and processing

def callback_laser(scan):

    laser_array = scan.ranges
    #some data filtering and processing

if __name__ == '__main__':

    # initialisation
    print("initialization ")

    pub = rospy.Publisher('/cmd_vel',Twist,queue_size=5)
    twist = Twist() 
    rospy.init_node('viva_node', anonymous=True)
    rospy.Subscriber('joy', Joy, callback_joy)
    rospy.Subscriber('sonar', Floats, callback_sonar)
    rospy.Subscriber('/scan', LaserScan, callback_laser)

    # loop
    while True:
        print 'Current Mode is : ',  switch_mode

        if switch_mode == 'AUTO':

But, when i run, this script nothing append except :

pi@rasberrypi:~ $ rosrun perso_package




Then script get stuck and nothing append. I don't know why, any idea would are welcome.


edit retag flag offensive close merge delete


A suggestion: use the teleop_twist_joy package instead of converting raw Joy msgs to Twists yourself.

gvdhoorn gravatar image gvdhoorn  ( 2017-06-08 00:48:05 -0600 )edit

I need to switch between manual and auto mode from my joystick, so I am oblige to import raw Joy msgs. But maybe there is an other way

mattMGN gravatar image mattMGN  ( 2017-06-09 11:25:06 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2017-06-07 07:39:37 -0600

Airuno2L gravatar image

When you use rospy.spin(), you're telling the program to sit there and wait (i.e. don't exit) until ros is shutdown. It's mainly used when for when your program just launches some subscribers then there's nothing to do except let the callbacks run when new messages come in.

Since you have a while loop there, the program would not be exiting, so you do not need rospy.spin() in this case. I don't think there is ever a case where you would have an endless while loop and need to use a rospy.spin().

edit flag offensive delete link more


It can be a little confusing because in roscpp, I think you would have needed a spinOnce() there to allow the callbacks to be called, but rospy doesn't need that because each subscriber has it's own thread.

Airuno2L gravatar image Airuno2L  ( 2017-06-07 07:44:03 -0600 )edit

They should use rospy.sleep() instead of spin, or better yet switch to a timer callback

lucasw gravatar image lucasw  ( 2017-06-07 08:32:30 -0600 )edit

Your answer is helpfull, I have removed ropsy.spin() and it is now working. I though that rospy.spin() told callback to be executed. Sorry for this misunderstanding


mattMGN gravatar image mattMGN  ( 2017-06-09 02:06:49 -0600 )edit

No problem. If that answers the question please select the check mark to close it out.

Airuno2L gravatar image Airuno2L  ( 2017-06-13 08:24:26 -0600 )edit

Question Tools

1 follower


Asked: 2017-06-07 05:55:49 -0600

Seen: 507 times

Last updated: Jun 07 '17