Python Basics for Robotics Laser Identification issue

Hello, I was trying to figure out which laser index corresponds to the front, back, left and right and I was doing it by orienting the robot so that the front of the robot was close to the wall and reading the minimum distance measured and which laser index it corresponded to. I repeated this for left, right and back by orienting the robot such that the left, right and back are closest to the wall and seeing the laser index with the minimum distance. This worked in simulation, however, in trying this with the FastBot, I got the same laser index with minimum distance regardless of the orientation of t he robot which I believe should not be possible if different directions of the robot (and therefore different laser indices) are closest to a wall. I have attached my code below if it helps. I would appreciate any help regarding this.

#!/usr/bin/python3

# python imports
import time
import threading
import traceback
from math import inf
import statistics as stat
# ros2 imports
import rclpy
from rclpy.executors import MultiThreadedExecutor
# module imports
from robot_interface import RobotInterface


#~#~#~#~#~# start your class after this line #~#~#~#~#~#

class RobotControl:

    def __init__(self, robot_interface):
        # class constructor
        # write your initialization codes here if any
        self.robot_interface = robot_interface
        self.initial_position = dict()
        self.initial_orientation = dict()
        self.current_position = dict()
        self.current_orientation = dict()
        self.total_distance = 0.0
        self.start_time = time.time()
        return None
    
    def __del__(self):
        # class destructor
        # write your termination codes here if any
        return None
    
    #~#~#~#~#~# add your functions after this line #~#~#~#~#~#
    def get_linear_and_angular_velocities(self):
        return self.robot_interface.linear_velocity, self.robot_interface.angular_velocity

    def stop_robot(self):
        self.robot_interface.linear_velocity = 0.0
        self.robot_interface.angular_velocity = 0.0

    def move_robot_front(self, linear_speed):
        self.robot_interface.angular_velocity = 0.0
        self.robot_interface.linear_velocity = linear_speed

    def move_robot_back(self, linear_speed):
        self.robot_interface.angular_velocity = 0.0
        self.robot_interface.linear_velocity = -1.0 * linear_speed

    def turn_robot_left(self, angular_speed):
        self.robot_interface.linear_velocity = 0.0
        self.robot_interface.angular_velocity = angular_speed

    def turn_robot_right(self, angular_speed):
        self.robot_interface.linear_velocity = 0.0
        self.robot_interface.angular_velocity = -1.0 * angular_speed

    def timed_move_front(self, linear_speed, time_to_move):
        self.move_robot_front(linear_speed)
        time.sleep(0.3)
        print("Moving forward at ", linear_speed, " m/s for ", time_to_move, " s")
        time.sleep(time_to_move)
        self.stop_robot()

    def timed_move_back(self, linear_speed, time_to_move):
        self.move_robot_back(linear_speed)
        time.sleep(0.3)
        print("Moving backward at ", linear_speed, " m/s for ", time_to_move, " s")
        time.sleep(time_to_move)
        self.stop_robot()

    def timed_turn_left(self, angular_speed, time_to_move):
        self.turn_robot_left(angular_speed)
        time.sleep(0.3)
        print("Turning left at ", angular_speed, " rad/s for ", time_to_move, " s")
        time.sleep(time_to_move)
        self.stop_robot()

    def timed_turn_right(self, angular_speed, time_to_move):
        self.turn_robot_right(angular_speed)
        time.sleep(0.3)
        print("Turning right at ", angular_speed, " rad/s for ", time_to_move, " s")
        time.sleep(time_to_move)
        self.stop_robot()

    def move_distance_front(self, linear_speed, distance_to_move_cm):
        distance_to_move_m = distance_to_move_cm / 100.0
        time_to_move = distance_to_move_m / linear_speed
        print("Moving forward by ", distance_to_move_cm, " cm at ", linear_speed, " m/s")
        self.timed_move_front(linear_speed, time_to_move)

    def move_distance_back(self, linear_speed, distance_to_move_cm):
        distance_to_move_m = distance_to_move_cm / 100.0
        time_to_move = distance_to_move_m / linear_speed
        print("Moving backward by ", distance_to_move_cm, " cm at ", linear_speed, " m/s")
        self.timed_move_back(linear_speed, time_to_move)

    def turn_angle_left(self, angular_speed, angle_to_move):
        time_to_move = angle_to_move / angular_speed
        print("Turning left by ", angle_to_move, " rads at ", angular_speed, " rad/s")
        self.timed_turn_left(angular_speed, time_to_move)

    def turn_angle_right(self, angular_speed, angle_to_move):
        time_to_move = angle_to_move / angular_speed
        print("Turning left by ", angle_to_move, " rads at ", angular_speed, " rad/s")
        self.timed_turn_right(angular_speed, time_to_move)

    def get_minimum_scan_angle(self):
        return self.robot_interface.scan_angle_min

    def get_maximum_scan_angle(self):
        return self.robot_interface.scan_angle_max

    def get_angle_increment(self):
        return self.robot_interface.scan_angle_increment

    def get_minimum_scan_range(self):
        return self.robot_interface.scan_range_min

    def get_maximum_scan_range(self):
        return self.robot_interface.scan_range_max

    def get_all_scan_ranges(self):
        return self.robot_interface.scan_ranges

    def get_scan_range_by_index(self, index):
        scan_ranges = self.get_all_scan_ranges()
        return scan_ranges[index]

    # TODO
    def get_front_scan_range(self):
        scan_ranges = self.get_all_scan_ranges()
        front_scan_ranges = scan_ranges[248:413]
        minimum_front_scan_range = inf
        for front_scan_range in front_scan_ranges:
            if front_scan_range == inf:
                continue
            if front_scan_range < minimum_front_scan_range:
                minimum_front_scan_range = front_scan_range
        return minimum_front_scan_range

    # TODO
    def get_back_scan_range(self):
        scan_ranges = self.get_all_scan_ranges()
        back_scan_ranges = scan_ranges[578:] + scan_ranges[0:83]
        minimum_back_scan_range = inf
        for back_scan_range in back_scan_ranges:
            if back_scan_range == inf:
                continue
            if back_scan_range < minimum_back_scan_range:
                minimum_back_scan_range = back_scan_range
        return minimum_back_scan_range

    # TODO
    def get_left_scan_range(self):
        scan_ranges = self.get_all_scan_ranges()
        left_scan_ranges = scan_ranges[413:578]
        minimum_left_scan_range = inf
        for left_scan_range in left_scan_ranges:
            if left_scan_range == inf:
                continue
            if left_scan_range < minimum_left_scan_range:
                minimum_left_scan_range = left_scan_range
        return minimum_left_scan_range
        

    # TODO
    def get_right_scan_range(self):
        scan_ranges = self.get_all_scan_ranges()
        right_scan_ranges = scan_ranges[83:248]
        minimum_right_scan_range = inf
        for right_scan_range in right_scan_ranges:
            if right_scan_range == inf:
                continue
            if right_scan_range < minimum_right_scan_range:
                minimum_right_scan_range = right_scan_range
        return minimum_right_scan_range

    def get_minimum_range_ne_infinity_with_index(self):
        scan_ranges = self.get_all_scan_ranges()
        index_of_minimum_range = -1
        minimum_range = inf
        for index, scan_range in enumerate(scan_ranges):
            if scan_range == inf:
                continue

            if scan_range < minimum_range:
                minimum_range = scan_range
                index_of_minimum_range = index

        return index_of_minimum_range, minimum_range

    def get_maximum_range_ne_infinity_with_index(self):
        scan_ranges = self.get_all_scan_ranges()
        index_of_maximum_range = -1
        maximum_range = -inf
        for index, scan_range in enumerate(scan_ranges):
            if scan_range == inf:
                continue
                
            if scan_range > maximum_range:
                maximum_range = scan_range
                index_of_maximum_range = index

        return index_of_maximum_range, maximum_range

    def get_current_position_x_y_z(self):
        return {"x": self.robot_interface.odom_position_x, "y": self.robot_interface.odom_position_y, "z": self.robot_interface.odom_position_z}

    def get_current_orientation_r_p_y(self):
        return {"r": self.robot_interface.odom_orientation_r, "p": self.robot_interface.odom_orientation_p, "y": self.robot_interface.odom_orientation_y}

    def get_distance_using_euclidean_formula(self, x1, y1, x2, y2):
        distance_squared = (x2 - x1)**2 + (y2 - y1)**2
        return distance_squared**0.5

    def display_statistics(self):
        lin_vel, ang_vel = self.get_linear_and_angular_velocities()
        print("Linear Velocity: ", lin_vel, " m/s  Angular Velocity: ", ang_vel, " rad/s")
        print("Number of scan samples: ", len(self.get_all_scan_ranges()))
        print("Minimum scan angle: ", self.get_minimum_scan_angle(), " rads")
        print("Maximum scan angle: ", self.get_maximum_scan_angle(), " rads")
        print("Scan angle increment: ", self.get_angle_increment(), " rads")
        print("Minumum scan range: ", self.get_minimum_scan_range(), " m")
        print("Maxumum scan range: ", self.get_maximum_scan_range(), " m")
        print("Front scan range: ", self.get_front_scan_range(), " m")
        print("Back scan range: ", self.get_back_scan_range(), " m")
        print("Left scan range: ", self.get_left_scan_range(), " m")
        print("Right scan range: ", self.get_right_scan_range(), " m")
        min_range_index, min_range = self.get_minimum_range_ne_infinity_with_index()
        print("Minimum range: ", min_range, " m  Index: ", min_range_index)
        max_range_index, max_range = self.get_maximum_range_ne_infinity_with_index()
        print("Maximum range: ", max_range, " m  Index: ", max_range_index)
        print("Position (m): ", self.get_current_position_x_y_z())
        print("Orientation (rads): ", self.get_current_orientation_r_p_y())

    def obstacle_prediction(self, scan_ranges):
        front_scan_ranges = scan_ranges[248:413]

        front_left_scan_ray_index = 412
        front_right_scan_ray_index = 248
        front_left_scan_ranges = scan_ranges[248:330]
        front_right_scan_ranges = scan_ranges[330:413]

        filtered_front_scan_ranges = []
        for front_scan_range in front_scan_ranges:
            if front_scan_range == inf:
                continue
            filtered_front_scan_ranges.append(front_scan_range)
        
        threshold = 0.300
        if min(filtered_front_scan_ranges) > threshold:
            print("None")
        else:
            if len(stat.multimode(filtered_front_scan_ranges)) > 1:
                print("Obstacle")
            else:
                print("Wall")

    def direction_tracking(self, current_orientation):
        yaw = current_orientation["y"]
        PI = 3.14159

        tolerance_rads = 0.1
        north_rads = 0.0
        north_west_rads = PI / 4
        north_east_rads = -1.0 * PI / 4
        west_rads = PI / 2
        south_west_rads = (PI / 2) + (PI / 4)
        south_plus_rads = PI
        south_minus_rads = -1.0 * PI
        east_rads = -1.0 * PI / 2
        south_east_rads = -1.0 * ((PI / 2) + (PI / 4))

        direction_string = ""
        if yaw <= (north_rads + tolerance_rads) and yaw >= (north_rads - tolerance_rads):
            direction_string = "-N-"
        elif yaw > (north_rads + tolerance_rads) and yaw < (north_west_rads - tolerance_rads):
            direction_string = "NNW"
        elif yaw <= (north_west_rads + tolerance_rads) and yaw >= (north_west_rads - tolerance_rads):
            direction_string = "N-W"
        elif yaw > (north_west_rads + tolerance_rads) and yaw < (west_rads - tolerance_rads):
            direction_string = "WNW"
        elif yaw <= (west_rads + tolerance_rads) and yaw >= (west_rads - tolerance_rads):
            direction_string = "-W-"
        elif yaw > (west_rads + tolerance_rads) and yaw < (south_west_rads - tolerance_rads):
            direction_string = "WSW"
        elif yaw <= (south_west_rads + tolerance_rads) and yaw >= (south_west_rads - tolerance_rads):
            direction_string = "S-W"
        elif yaw > (south_west_rads + tolerance_rads) and yaw < (south_plus_rads - tolerance_rads):
            direction_string = "SSW"
        elif yaw >= (south_plus_rads - tolerance_rads) or yaw <= (south_minus_rads + tolerance_rads):
            direction_string = "-S-"
        elif yaw <= (north_east_rads + tolerance_rads) and yaw >= (north_east_rads - tolerance_rads):
            direction_string = "N-E"
        elif yaw > (north_east_rads + tolerance_rads) and yaw < (north_rads - tolerance_rads):
            direction_string = "NNE"
        elif yaw > (east_rads + tolerance_rads) and yaw < (north_east_rads - tolerance_rads):
            direction_string = "ENE"
        elif yaw <= (east_rads + tolerance_rads) and yaw >= (east_rads - tolerance_rads):
            direction_string = "-E-"
        elif yaw > (south_east_rads + tolerance_rads) and yaw < (east_rads - tolerance_rads):
            direction_string = "ESE"
        elif yaw <= (south_east_rads + tolerance_rads) and yaw >= (south_east_rads - tolerance_rads):
            direction_string = "S-E"
        elif yaw > (south_minus_rads + tolerance_rads) and yaw < (south_east_rads - tolerance_rads):
            direction_string = "SSE"
        else:
            direction_string = "N/A"
        print("Current direction: ", direction_string)

    def initialise_position_and_orientation(self):
        self.initial_orientation = self.get_current_orientation_r_p_y()
        self.initial_position = self.get_current_position_x_y_z()

    def remove_inf_from_list(self, input_list):
        list_to_return = list()
        for var in input_list:
            if var == inf:
                continue    
            list_to_return.append(var)
        return list_to_return

    def execute(self):
        if len(self.initial_orientation) == 3 and len(self.initial_position) == 3:
            # TODO
            scan_ranges = self.get_all_scan_ranges()
            number_of_lasers = len(scan_ranges)
            front_centre = scan_ranges[289:371]
            back_centre = scan_ranges[:41] + scan_ranges[618:]
            right_centre = scan_ranges[124:206]
            left_centre = scan_ranges[454:536]
            front_right = scan_ranges[206:289]
            front_left = scan_ranges[371:454]
            back_left = scan_ranges[536:618]
            back_right = scan_ranges[41:124]
            
            threshold = 0.300
            front_centre_blocked = min(self.remove_inf_from_list(front_centre)) < threshold
            front_left_blocked = min(self.remove_inf_from_list(front_left)) < threshold
            front_right_blocked = min(self.remove_inf_from_list(front_right)) < threshold

            current_time = time.time()
            if current_time - self.start_time > 1:
                print("There are ", number_of_lasers, " lasers")
                self.current_position = self.get_current_position_x_y_z()
                print("Current Position: ", self.current_position)
                self.direction_tracking(self.get_current_orientation_r_p_y())
                self.obstacle_prediction(scan_ranges)
                self.start_time = current_time

            if not front_centre_blocked:
                if front_left_blocked:
                    print("Front left blocked. Turning right")
                    self.stop_robot()
                    self.turn_angle_right(0.1, 0.5)
                    print("Moving forward now")
                    self.move_robot_front(0.1)
                elif front_right_blocked:
                    print("Front right blocked. Turning left")
                    self.stop_robot()
                    self.turn_angle_left(0.1, 0.5)
                    print("Moving forward now")
                    self.move_robot_front(0.1)
                else:
                    self.move_robot_front(0.1)
            else:
                if min(self.remove_inf_from_list(left_centre)) > min(self.remove_inf_from_list(right_centre)):
                    print("Forward blocked. More space on the left. Turning left")
                    self.stop_robot()
                    self.turn_angle_left(0.1, 0.5)
                    print("Moving forward now")
                    self.move_robot_front(0.1)
                else:
                    print("Forward blocked. More space on the right. Turning right")
                    self.stop_robot()
                    self.turn_angle_right(0.1, 0.5)
                    print("Moving forward now")
                    self.move_robot_front(0.1)





#~#~#~#~#~# finish your class before this line #~#~#~#~#~#

def spin_node():
    """
    make the robot interface program to run in a separate thread
    NOTE: THE ROBOT WILL NOT WORK IF THIS FUNCTION IS REMOVED !!!
    """
    global executor
    executor.spin()
    return None


if __name__ == "__main__":

    # initialize ros2 with python
    rclpy.init(args=None)
    # instantiate robot interface program module
    robot_interface = RobotInterface()
    # start robot interface program execution
    executor = MultiThreadedExecutor(num_threads=6)
    executor.add_node(robot_interface)
    # run robot interface program in a separate thread
    threading.Thread(target=spin_node).start()
    # wait for a few seconds for program to initialize
    print("Getting Ready in 5 Seconds...")
    time.sleep(5.0)
    print("READY !!!")

    try:
        #~#~#~#~#~# start your program after this line #~#~#~#~#~#

        ########## |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ##########
        ########## | ! YOU ARE ON YOUR OWN FROM HERE ! | ##########
        ########## |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ##########

        #~#~#~#~#~# write code here to run only once #~#~#~#~#~#
        rc = RobotControl(robot_interface)
        rc.initialise_position_and_orientation()

        #~#~#~#~#~# write code here to run continuously #~#~#~#~#~#
        while True:
            # threshold = 0.5
            # front_range = rc.get_front_scan_range()
            # right_range = rc.get_right_scan_range()
            # left_range = rc.get_left_scan_range()
            # back_range = rc.get_back_scan_range()
            
            # if front_range > threshold:
            #     rc.move_robot_front(0.1)
            # else:
            #     rc.stop_robot()
            #     if right_range > left_range:
            #         rc.turn_angle_right(0.5, 0.4)
            #     else:
            #         rc.turn_angle_left(0.5, 0.4)

            # rc.display_statistics()
            # time.sleep(0.5)
            # rc.turn_angle_left(0.1, 0.1)
            # rc.direction_tracking()
            # rc.execute()
            # minimum_range_index, minimum_range = rc.get_minimum_range_ne_infinity_with_index()
            # print("Minimum range index: ", minimum_range_index, "   Minimum range: ", minimum_range, " m")
            # time.sleep(1)
            # rc.move_distance_front(0.1, 100)
            # rc.move_robot_front(0.1)
            print(rc.get_minimum_range_ne_infinity_with_index())
            # print(rc.get_all_scan_ranges()[10])
            time.sleep(1)
        
        #~#~#~#~#~# finish your program before this line #~#~#~#~#~#

    except Exception as error:
        # report exception
        print("~~~~~~~~~~~ ERROR: ~~~~~~~~~~~")
        print(traceback.print_exception(error))
        print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
        # clean up before shutdown
        executor.shutdown()
        robot_interface.destroy_node()

    finally:
        # shutdown ros2
        rclpy.shutdown()

# End of Code