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

List index out of range

asked 2019-06-17 14:39:50 -0600

Jojo gravatar image

updated 2019-06-17 17:15:47 -0600

jayess gravatar image

Hi, I am new to python and ros and i am trying to get to different goals defined by me but I get the error: list imdex out of range and i dont know why because as far as i know, the list index is not out of range. my code is below and also the error:

#!/usr/bin/env python
import rospy
import math
from std_msgs.msg import String
from std_msgs.msg import Int32
from geometry_msgs.msg import Twist          # Import the Twist message from the geometry_msgs
from sensor_msgs.msg import LaserScan       # Import the LaserScan message from the sensor
from gazebo_msgs.msg import ModelStates  #import ModelState message from gazebo_msgs
from geometry_msgs.msg import Pose,Point         # Import the Pose message from the geometry_msgs
from tf.transformations import euler_from_quaternion
from goal_publisher.msg import PointArray
from math import pow, atan2, sqrt


PI= 3.1415926535897
repeat = 0
theta = 0.0
x = 0.0
y = 0.0
msg = 0.0
index_same=0.0
target = 90
kp=0.5

class MovetoGoals:
    def __init__(self):

        # Creates a node with name 'final_projekt_node' and make sure it is a
        # unique node (using anonymous=True).
        rospy.init_node('final_projekt_node', anonymous=True)

        # Publisher which will publish to the topic 'Twist'.
        self.pub = rospy.Publisher('cmd_vel',Twist, queue_size=10)

        # A subscriber to the topic 'Modelstate'. self.update_pose is called
        # when a message of type Pose is received.
        self.pose_sub = rospy.Subscriber('/gazebo/model_states',ModelStates, self.update_pose)
        self.goals_sub = rospy.Subscriber('/goals',PointArray,self.get_goals)
        self.dist_sub = rospy.Subscriber('/distance',Int32,self.distance_tracker)
        self.laser_sub = rospy.Subscriber('scan', LaserScan,self.detect_obstacle)# subscriber to subscribe to laser messages
        self.pose = ModelStates()
        self.current_distance = Int32()
        self.the_goals = PointArray()
        self.rate = rospy.Rate(10)

    def update_pose(self, data):
        """Callback function which is called when a new message of type Pose is
        received by the subscriber."""
        #print('in update_pose function')

        self.pose = data
        self.pose.pose[1].position.x = round(self.pose.pose[1].position.x, 4)
        self.pose.pose[1].position.y = round(self.pose.pose[1].position.y, 4)

        #print ('robots x position' self.pose.pose[1].position.x)

    def euclidean_distance(self,goal_pose):

        return sqrt(pow((goal_pose.x - self.pose.pose[1].position.x), 2) +
                    pow((goal_pose.y - self.pose.pose[1].position.y), 2))

    def linear_vel(self,goal_pose, constant=1):

        #return constant * (self.euclidean_distance(goal_pose))
        return abs(1.0)

    def steering_angle(self, goal_pose):

        return atan2(goal_pose.y - self.pose.pose[1].position.y,goal_pose.x - self.pose.pose[1].position.x)

    def angular_vel(self,goal_pose, constant=2):

        global theta
        self.pose.pose[1].orientation = self.pose.pose[1].orientation
        (roll, pitch, theta) = euler_from_quaternion([self.pose.pose[1].orientation.x, self.pose.pose[1].orientation.y, self.pose.pose[1].orientation.z, self.pose.pose[1].orientation.w])
        #print ('theta at update pose is', + theta)
        #print ('theta is', + theta)
        return constant * (self.steering_angle(goal_pose) - theta)
        #return 0.3

    def get_goals(self,the_goals):
        global x
        global y
        x = the_goals.goals[0].x
        y = the_goals.goals[0].y
        #print x
        #print y

    def distance_tracker(self,distance):
        self.current_distance ...
(more)
edit retag flag offensive close merge delete

Comments

Please make sure to use the preformatted text (101010) button when posting code or terminal output. It makes your question much easier to read when you use it

jayess gravatar image jayess  ( 2019-06-17 17:16:36 -0600 )edit

What topic are you showing exactly? Can you please update your question with the output of

rostopic echo /gazebo/model_states

with just one message of the topic printed? Something doesn't look right because when I do it, i get

name: [ground_plane]
pose: 
  - 
    position: 
      x: 0.0
      y: 0.0
      z: 0.0
    orientation: 
      x: 0.0
      y: 0.0
      z: 0.0
      w: 1.0
twist: 
  - 
    linear: 
      x: 0.0
      y: 0.0
      z: 0.0
    angular: 
      x: 0.0
      y: 0.0
      z: 0.0

notice the - in there which is YAML syntax for a list.

jayess gravatar image jayess  ( 2019-06-17 17:37:10 -0600 )edit

Thank you for edting my question and the tips on posting a code here. I have solved the problem with the answer given below.

Jojo gravatar image Jojo  ( 2019-06-20 09:03:28 -0600 )edit

If that answered your question, then please click the to the left of the answer to mark it as correct.

jayess gravatar image jayess  ( 2019-06-20 11:20:29 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted
2

answered 2019-06-17 19:46:20 -0600

Geoff gravatar image

You need to allow some time for poses to be received from Gazebo before you try to use them. Although you set up the subscriber for /gazebo/model_states in the MovetoGoals object's constructor, you do not give ROS any time to receive anything on the topic before you start calling move2goal which internally via the euclidean_distance function tries to use the value that will be set by update_pose. This means that update_pose has not yet been called when euclidean_distance is called so it tries to access a pose in the empty ModelStates object's array.

To solve this, you need to give some time to ROS to receive the data you want to use before you start trying to send movement commands based on received data. Add a function that allows ROS to receive a few methods (e.g. creating a rate object of 10 Hz and doing a rate.sleep() on it) until you see that the size of the ModelStates object has data.

Also make sure that the second pose in the list is the one you want. In Python, list indices are zero-based.

edit flag offensive delete link more

Comments

Solved it .Thanks

Jojo gravatar image Jojo  ( 2019-06-20 09:03:55 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2019-06-17 14:39:50 -0600

Seen: 2,014 times

Last updated: Jun 17 '19