Gazebo unresponsive to service call

Hello,

I’m having an issue with task 2. I’ve got the drone moving, landing and taking off, and launch file works fine too. However, when calling the service /my_service through the command line, the method take_off() is called, but gazebo does not react. Is this an error in gazebo, or my coding?

Thank you.

forward_motion.py

#! /usr/bin/env python

import rospy

import time

from geometry_msgs.msg import Twist

from std_msgs.msg import Empty

class RobotControl(object):

    def __init__(self):

        # creates publishers

        self.pub_cmd_vel = rospy.Publisher("/cmd_vel", Twist, queue_size=10)

        self.pub_take_off = rospy.Publisher("/drone/takeoff", Empty, queue_size=10)

        self.pub_land = rospy.Publisher("/drone/land", Empty, queue_size=10)

        # creates messages to publish

        self.move = Twist()

        self.takeoff = Empty()

        self.land = Empty()

        self.rate = rospy.Rate(10)

    def take_off(self):

        rospy.loginfo('Taking off...')

        self.pub_take_off.publish(self.takeoff)

        time.sleep(5)

        rospy.loginfo("The quadcopter finished taking off")

    def move_forward(self):

        rospy.loginfo("Moving forward...")

        self.move.linear.x = 1

        self.move.angular.z = 0

        self.pub_cmd_vel.publish(self.move)

        time.sleep(5)

        rospy.loginfo("The quadcopter finished moving forward")

    def stopping(self):

        rospy.loginfo('Stopping...')

        self.move.linear.x = 0

        self.move.angular.z = 0

        self.pub_cmd_vel.publish(self.move)

        time.sleep(5)

        rospy.loginfo("The quadcopter finished stopping")

    def landing(self):

        rospy.loginfo('Landing...')

        self.pub_land.publish(self.land)

        time.sleep(5)

        rospy.loginfo("The quadcopter finished landing")

if __name__ == '__main__':

    name_of_node = "forward_motion"

    rospy.init_node(name_of_node)

    rospy.loginfo("Node initiated: %s", name_of_node)

    rc = RobotControl()

    time.sleep(2)

    rate = rospy.Rate(0.5)

    

    ctrl_c = False

    def shutdownhook():

        global ctrl_c

        rospy.loginfo("Shutdown time!")

        ctrl_c = True

    rospy.on_shutdown(shutdownhook)

    

    while not ctrl_c:   # while not true

        rospy.loginfo("Main loop...")

        rc.take_off()

        rc.move_forward()

        rc.stopping()

        rc.landing()

        ctrl_c = True

motion_service.py

#! /usr/bin/env python

import rospy

from std_srvs.srv import EmptyResponse, Empty as EmptyServiceMsg

from std_msgs.msg import Empty

from forward_motion import RobotControl

def my_callback(request):

    rospy.loginfo("The Service to start the drone has been called")

    rc = RobotControl()

    rc.take_off()

    rospy.loginfo("Finished service")

    response = EmptyResponse()

    return response

rospy.init_node('service_move_drone') 

my_service = rospy.Service('/my_service', EmptyServiceMsg , my_callback)

rospy.loginfo("Service /my_service Ready")

rospy.spin() # mantain the service open.

Try looping the command:

for i in range(10):
self.pub_take_off.publish(self.takeoff)

publishing in topics sometimes fails the first time you publish.

1 Like

Great. Thanks! It worked.

Say you have several topics in a program, how would one go about writing a function/method to publish once into all topics, without actually causing the robot to act on it? Would it make sense to put such a function as the first call in the program once everything is set up, or should it be called EVERY time a publish is wanted?

A post was split to a new topic: How to get all topics ready for publishing

@torpanvil.
Bravo!!!
This is a great way to do it, and I’m going to make this a wiki for everyone!

2 Likes

Oh great! I must be getting better at this! :sweat_smile: