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

AttributeError : 'int' object has no attribute 'action'

asked 2019-03-15 14:45:12 -0500

suho0515 gravatar image

updated 2019-03-16 22:27:26 -0500

jayess gravatar image

Hello, i'm trying to control mobile robot 'rb1 base', it has elevate function which can move its head up and down. You can see the Service caller in the down side of the picture, it has the service topic named '/rb1_base/robotnik_base_control/set_elevator', based on that information, i wrote the service call program, you can see this top of the picture. In the SetElevator.h there is only one variable named 'int32 action', if i make the action variable to 1 then the robot elevate up, if i make it to -1 then the robot elevate down. so i wrote the code 'srv(1)' to elevate up the robot. But it says 'AttributeError : 'int' object has no attribute 'action''. Is there special way to change the variable 'int32 action'? Is it not just int?

here is the code.

from random import sample
from math import pow, sqrt
from actionlib_msgs.msg import *
from geometry_msgs.msg import Pose, PoseWithCovarianceStamped, Point, Quaternion, Twist
from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal
from robotnik_msgs.srv import SetElevator, SetElevatorRequest, SetElevatorResponse
import rospy
import actionlib



class MultiPointNav():
    def __init__(self):
        rospy.init_node('multi_point_nav', anonymous=True)

        rospy.on_shutdown(self.shutdown)

        # How long in seconds should the robot pause at each location?
        self.rest_time = rospy.get_param("~rest_time", 3)

        # Are we running in the fake simulator?
        self.fake_test = rospy.get_param("~fake_test", False)

        # Goal state return values
        goal_states = ['PENDING', 'ACTIVE', 'PREEMPTED', 
                       'SUCCEEDED', 'ABORTED', 'REJECTED',
                       'PREEMPTING', 'RECALLING', 'RECALLED',
                       'LOST']


        locations = dict()

        locations['Point1'] = Pose(Point(-0.64500000000, 0.82600000000, 0.000), Quaternion(0.000, 0.000, 0.000, 1.000))
        locations['Point2'] = Pose(Point(-1.24000000000, -0.95300000000, 0.000), Quaternion(0.000, 0.000, 0.000, 1.000))
        #locations['Point3'] = Pose(Point(-2.50947999954, -5.9229183197, 0.000), Quaternion(0.000, 0.000, 0.000, 1.000))
        #locations['Point4'] = Pose(Point(-12.919, -23.867, 0.000), Quaternion(0.000, 0.000, 0.000, 1.000))
        #locations['Point5'] = Pose(Point(1.471, 1.007, 0.000), Quaternion(0.000, 0.000, 0.480, 0.877))
        #locations['Point6'] = Pose(Point(-0.861, -0.019, 0.000), Quaternion(0.000, 0.000, 0.892, -0.451))

        # Publisher to manually control the robot (e.g. to stop it, queue_size=5)
        self.cmd_vel_pub = rospy.Publisher('/rb1_base/cmd_vel', Twist, queue_size=5)

        # Subscribe to the move_base action server
        self.move_base = actionlib.SimpleActionClient("rb1_base/move_base", MoveBaseAction)

        rospy.loginfo("Waiting for move_base action server...")

        # Wait 60 seconds for the action server to become available
        self.move_base.wait_for_server(rospy.Duration(60))

        rospy.loginfo("Connected to move base server")

        # A variable to hold the initial pose of the robot to be set by 
        # the user in RViz
        initial_pose = PoseWithCovarianceStamped()

        # Variables to keep track of success rate, running time,
        # and distance traveled
        n_locations = len(locations)
        n_goals = 0
        n_successes = 0
        i = n_locations
        distance_traveled = 0
        start_time = rospy.Time.now()
        running_time = 0
        location = ""
        last_location = ""

        # Get the initial pose from the user
        rospy.loginfo("*** Click the 2D Pose Estimate button in RViz to set the robot's initial pose...")
        rospy.wait_for_message('/rb1_base/initialpose', PoseWithCovarianceStamped)
        self.last_location ...
(more)
edit retag flag offensive close merge delete

Comments

1

Is there any way that you can share a bit of code? You are likely incorrectly using the classes created from the service definition.

jarvisschultz gravatar image jarvisschultz  ( 2019-03-15 16:48:50 -0500 )edit

You probably need something like the following:

from robotnik_msgs.srv import SetElevatorRequest
req = SetElevatorRequest(1)
service_client(req)

Where service_client would be an instance of rospy.ServiceProxy

jarvisschultz gravatar image jarvisschultz  ( 2019-03-15 16:55:07 -0500 )edit

Thank you for your information, jarvisschultz! okay i would share a bit of code where related with service call, and i fixed the code based on what you said, like

try to call service

rospy.wait_for_service('/rb1_base/robotnik_base_control/set_elevator')
srv = rospy.ServiceProxy('/rb1_base/robotnik_base_control/set_elevator', SetElevator)
#self.srv = srv
#self.srv(1)
req = SetElevatorRequest(1)
srv(req)

but it came same error 'AttributeError : 'int' object has no attribute 'action'' i would post more information you told me!

suho0515 gravatar image suho0515  ( 2019-03-16 02:05:15 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2019-03-18 00:43:01 -0500

suho0515 gravatar image

updated 2019-03-18 02:18:33 -0500

gvdhoorn gravatar image

I solved this issue somehow! jarvisschultz told me it could be problem with service definition. so i try to make differnce about service definition,

I fixed it to

# fixed code
rospy.wait_for_service('/rb1_base/robotnik_base_control/set_elevator')
srv = rospy.ServiceProxy('/rb1_base/robotnik_base_control/set_elevator', SetElevator)
req = SetElevator()
req.action = 1 or -1
srv(req)

now i can handle it perfectly. thanks for advice, jarvisschultz!

edit flag offensive delete link more

Comments

You should be able to use keyword args. Something like this should also work:

req = SetElevator(action=1)
gvdhoorn gravatar image gvdhoorn  ( 2019-03-18 02:18:56 -0500 )edit

Are you using SetElevator() or SetElevatorRequest()? Shouldn't you need to instantiate a request to pass into the ServiceProxy? The keyword arguments @gvdhoorn mentioned certainly work, but the positional arguments first mentioned in my comment should work as well.

jarvisschultz gravatar image jarvisschultz  ( 2019-03-18 15:18:14 -0500 )edit

Hm... it doesn't works in those ways... If i put SetElevatorRequest argument in ServicePoxy then it says 'AttributeError: type object 'SetElevatorRequest' has no attribute '_request_class' And if i use 'req = SetElevator(action=1)' then it says 'TypeError: object() takes no parameters' And if i use 'req = SetElevatorRequest(1)' then it says 'AttributError: 'int' object has no attribute 'action''

suho0515 gravatar image suho0515  ( 2019-03-18 21:43:51 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2019-03-15 14:43:19 -0500

Seen: 1,877 times

Last updated: Mar 18 '19