Why is list index out of range?

Hi,

I’m continously having issues with LaserScan when trying to get range data from one of the sensors.
Please see code and error message below.
The error message I’m getting, is as follows:

ROS_MASTER_URI=http://4_simulation:11311

process[main_program-1]: started with pid [1219]
[main_program-1] process has finished cleanly
log file: /home/user/.ros/log/f0853ee6-5d3b-11ed-b3ef-0242c0a8d007/main_program-1*.log
all processes on machine have died, roslaunch will exit
shutting down processing monitor...
... shutting down processing monitor complete
done
user:~/catkin_ws/devel$ rosrun basics_exam exam_service_server.py
Traceback (most recent call last):
  File "/home/user/catkin_ws/src/basics_exam/scripts/exam_service_server.py", line 37, in <module>
    frontLaser = ls.ranges[360]
IndexError: list index out of range

My code:

#! /usr/bin/env python

# Specifications
# The service response must return one of the following words: front, left or right.
# This service itself should not move the robot. That should be done in Task 3.
# Hint: has laser scan

import rospy

from sensor_msgs.msg import LaserScan
from std_srvs.srv import Trigger, TriggerResponse
    
def laser_callback(msg):
    msg = ls
    rospy.loginfo('asdf') 


def trigger_response(request):
    service_msg = 'front'

    if frontLaser <= 10 and rightLaser <= 10:
        service_msg = 'left'
    elif frontLaser <= 10 and leftLaser <= 10:
        service_msg = "right"
    elif frontLaser > 10 and leftLaser > 10 and rightLaser > 10:
        service_msg = "front"
    else:
        service_msg = 'front'
    return TriggerResponse(success=True, message=service_msg)


rospy.init_node('server_node')
exam_service = rospy.Service('/crash_direction_service', Trigger, trigger_response)
laser_sub = rospy.Subscriber('/Kobuki/Laser/Scan', LaserScan, laser_callback)

ls = LaserScan()
frontLaser = ls.ranges[360]
leftLaser = ls.ranges[540]
rightLaser = ls.ranges[180]
rospy.spin()

If you try to print len(ls.ranges) it contains 0 elements.

Would appreciate help, as this is a major barrier for me.

Thanks!

Hi @Olavio ,

I think you are new to learning ROS, which is great, but I believe you are new to programming with Python also.
So, the free course Python 3 for Robotics would help you very much.

Here is your solution:
List Index Out of Range error occurs when the list is either completely empty or the index you are looking for does not exist (yet) in the list.

Looking at your code:

You have assigned LaserScan() message class to variable ls
with the line ls = LaserScan().

But in the laser callback:

You seem to be assigning ls to msg with the line msg = ls. Here the variable ls is out of scope and is not referenced by the word global.
Also you are assigning ls to msg instead of assigning msg to ls. This will always clear out the msg variable and that is why ls.ranges[...] lines are not working because they are always empty.

Finally, here is the solution to have it working:

def laser_callback(msg):
    # msg = ls  <<<----- This line is wrong! Delete this line.
    global ls  # <<<----- This line is required to access 'ls' variable
    ls = msg  # <<<----- with this line you are assigning 'msg' to 'ls'
    rospy.loginfo('asdf') 

I think you should take some time to familiarize yourself with Python programming. The errors you got are not ROS errors - they are very basic Python errors. Please learn Python with focus on Object Oriented Programming (OOP) - otherwise things will become difficult to understand without you knowing the basics.

Regards,
Girish

Hi,

Thank you for your response.

I am done with Python 3 for robotics and am working on ROS in 5 days basics exam.

Thank you for providing an alternative to my existing code in the callback, but laser_callback never gets called, so those lines you are referring to never gets run, so it’s just there for no reason atm.
It’s my understanding that “ranges” contains 720 elements, laser radius 0-180 degrees providing float values for range. When assigning one of those elements to a new variable

ls = LaserScan()
frontLaser = ls.ranges[360]

that element does not exist.
Am I completely misunderstanding something here maybe?

EDIT as I was writing:
I figured it out. I can’t use /kobuki/Laser/Scan to publish and subscribe, for some reason I don’t understand.
Setting up a publisher to publish on /revised_scan and subscribing to /scan and adjusting my code to that solved it for me.

Thanks for your time anyway! Appreciate it.

Hi @Olavio ,

The code lines actually would not work because ls = LaserScan() just initializes an empty class of LaserScan() with zeros for ints and floats and probably empty array for ranges. Since ls.ranges[360] gives you list index out of range, this signifies that the ls.ranges is an empty list/array after initialization.
Also the place where you have initialized ls variable is right after Subscriber initialization. So it did not work until the subscriber callback was called at least once.

You could have just subscribed to /scan topic directly instead of /kobuki/Laser/Scan. Creating a new node /revised_scan and publishing modified /scan messages would be something unnecessary.
The idea is to use what is available for use directly. I believe, you were not instructed to re-create a /scan node.

Regards,
Girish

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.