ROS Basics Project: Part 2 Services

How do I ensure that callback2 only gets called once? When I call the service, the callback2 keeps running over and over even after a response of True has been given.
Note: This project requires the use of services and I don’t have any python knowledge beyond what has been introduced in the course up to this point.

#! /usr/bin/env python

import rospy
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
from srv_message_pkg.srv import FindWall, FindWallResponse
import time

def callback2(msg):
    move = Twist()
    minimum = min(msg.ranges)
    index = msg.ranges.index(minimum)
    if index < 180:
        move.angular.z = -3.14/18.0
    else:
        move.angular.z = 3.14/18.0
    print("index: ", index)
    print("dist: ", minimum)
    pub.publish(move)
    time.sleep(abs(180-index)/10.0)
    move.angular.z = 0
    move.linear.x = 0.1
    pub.publish(move)
    time.sleep(minimum * 5)
    move.linear.x = 0
    pub.publish(move)

def callback(request):
    sub = rospy.Subscriber("/scan", LaserScan, callback2)
    response = FindWallResponse()
    response.wallfound = True
    time.sleep(20)
    return response
    
rospy.init_node("find_wall_server")
my_service = rospy.Service('/find_wall', FindWall, callback)
pub = rospy.Publisher("/cmd_vel", Twist, queue_size=1)
rospy.spin()

hi @1gonzalezparramanuelarturo, one advice, when you publishing code, look for this icons that help you to display better:
image

Thanks! Do you have any advice on the issue regarding the repeated calls to callback2?

bear in mind that callback2 is a callback of a your subscriber, so it gets called every time a msg is sent to /scan topic and you have no control of that so it may be calling like 10 times per second or even more. what you can do is get the rest of the code out of the callback2 function create a flag that starts in false and become true when your callback2 is called and then execute the rest of the code you like

1 Like

I will try that, thank you. Also, do you reckon that this is the intended way of using services and sensor data?

I’m having trouble mostly with how to access the scan data outside of the callback2 function, don’t I need to access it through the subscriber?

think in the subscriber as a watch dog, when something arrives to the topic you are subscribed to, the callback function you define is called. Create a global variable to hold the sensor data and just update it in the callback like so:

minimun = 0
def callback2(msg):
    global minimun
    minimum = min(msg.ranges)

try to embed everything in a class so you dont have problem with the scope of the variable (the global stuff).

3 Likes

I don’t know too much about classes, but thank you so much for your help. I think I’ll be able to manage from here.

If you want to get serious into ROS you will need to learn about classes. I recommend you to take the Python3 for Robotics course, the Unit that talks about Python Classes.