Action Quiz Error

Hello All, I got an error message for the actions quiz as shown below. I can successfully launch the server.launch file and use rostopic pub to send goal by TAB+TAB. The error I got is right after hitting the TAB+TAB. And I attach my server code as shown below. Appreciate anyone who could help me.

#! /usr/bin/env python

import rospy

import time

import actionlib

from my_custom_action_msg_pkg.msg import CustomActionMsgAction, CustomActionMsgGoal, CustomActionMsgFeedback

from std_msgs.msg import Empty

class CommandDroneClass(object):

def __init__(self):

#create messages that are used to publish feedback/result

self._goal = CustomActionMsgGoal()

self._feedback = CustomActionMsgFeedback()

    # creates the action server

    self._as = actionlib.SimpleActionServer("action_custom_msg_as", CustomActionMsgAction, self.goal_callback, False)

    self._as.start()

    self.ctrl_c = False

    self.rate = rospy.Rate(10)

def publish_once_in_cmd_vel(self, cmd):

    """

    This is because publishing in topics sometimes fails teh first time you publish.

    In continuos publishing systems there is no big deal but in systems that publish only

    once it IS very important.

    """

    while not self.ctrl_c:

        connections = self._pub_cmd_vel.get_num_connections()

        if connections > 0:

            self._pub_cmd_vel.publish(cmd)

            rospy.loginfo("Publish in cmd_vel...")

            break

        else:

            self.rate.sleep()



def goal_callback(self,goal):

    # helper variables

    r = rospy.Rate(1)

    success = True

    # define the different publishers and messages that will be used

    self._pub_takeoff = rospy.Publisher('/drone/takeoff', Empty, queue_size=1)

    self._takeoff_msg = Empty()

    self._pub_land = rospy.Publisher('/drone/land', Empty, queue_size=1)

    self._land_msg = Empty()

    if self._goal.goal == 'TAKEOFF':

         # make the drone takeoff

        i=0

        while not i == 3:

            self._pub_takeoff.publish(self._takeoff_msg)

            self._feedback.feedback = 'taking off'

            self._as.publish_feedback(self._feedback)

            time.sleep(1)

            i += 1

    elif self._goal.goal == 'LAND':

        #make the drone land

        i=0

        while not i == 3:

            self._pub_land.publish(self._land_msg)

            self._feedback.feedback = 'landing'

            self._as.publish_feedback(self._feedback)

            time.sleep(1)

            i += 1

if name == ‘main’:

rospy.init_node('move_drone_by_command_server')

CommandDroneClass()

rospy.spin()

I think you missed this part of the actionlib_tutorial:

    if success:
        self._result.sequence = self._feedback.sequence
        rospy.loginfo('%s: Succeeded' % self._action_name)
        self._as.set_succeeded(self._result)

The last line is the critical part - you have to set the action as succeeded

Hi Simon, I put the ‘if success’ statement to my code but the drone still is not able to takeoff. But a success message is printed in the command prompt as shown below. Could you provide me any further tips on fixing this error? Appreciate for your time.

Here is my revised version of code

#! /usr/bin/env python

import rospy

import time

import actionlib

from my_custom_action_msg_pkg.msg import CustomActionMsgAction, CustomActionMsgGoal, CustomActionMsgFeedback, CustomActionMsgResult

from std_msgs.msg import Empty

class CommandDroneClass(object):

def __init__(self):

    #create messages that are used to publish feedback/result

    self._goal = CustomActionMsgGoal()

    self._feedback = CustomActionMsgFeedback()

    self._result = CustomActionMsgResult()

    # creates the action server

    self._as = actionlib.SimpleActionServer("action_custom_msg_as", CustomActionMsgAction, self.goal_callback, False)

    self._as.start()

    self.ctrl_c = False

    self.rate = rospy.Rate(10)

def publish_once_in_cmd_vel(self, cmd):

    while not self.ctrl_c:

        connections = self._pub_cmd_vel.get_num_connections()

        if connections > 0:

            self._pub_cmd_vel.publish(cmd)

            rospy.loginfo("Publish in cmd_vel...")

            break

        else:

            self.rate.sleep()

def goal_callback(self,goal):

    # helper variables

    r = rospy.Rate(1)

    success = True

    # define the different publishers and messages that will be used

    self._pub_takeoff = rospy.Publisher('/drone/takeoff', Empty, queue_size=1)

    self._takeoff_msg = Empty()

    self._pub_land = rospy.Publisher('/drone/land', Empty, queue_size=1)

    self._land_msg = Empty()

    if self._goal.goal == 'TAKEOFF':

        # make the drone takeoff

        i=0

        while not i == 3:

            self.publish_once_in_cmd_vel(self._takeoff_msg)

            self._feedback.feedback = 'taking off'

            self._as.publish_feedback(self._feedback)

            time.sleep(1)

            i += 1

    elif self._goal.goal == 'LAND':

        #make the drone land

        i=0

        while not i == 3:

            selfpublish_once_in_cmd_vel(self._land_msg)

            self._feedback.feedback = 'landing'

            self._as.publish_feedback(self._feedback)

            time.sleep(1)

            i += 1

    

    if success:

        self._result.result = 'success'

        rospy.loginfo('The command to move drone is sucessful')

        self._as.set_succeeded(self._result)

if name == ‘main’:

rospy.init_node('move_drone_by_command_server')

CommandDroneClass()

rospy.spin()

you are publishing in the cmd_vel topic, but your self._takeoff_msg is of the Type Empty(), not Twist(). And you never assign a value for it. If you wanna take off, you have to send the appropiate cmd_vel message

1 Like

Hi simon, Thanks for pointing it out, now I got 10 for the quiz. Appreciate so much!

1 Like