Ros in 5 days Rosject, part II. Problems with the while loop

Hello everyone. I’m trying to do the second part of the rosject for Ros in 5 days. My problem is in creating the FindWall server: the robot in the simulation is supposed to take the data from the /scan topic, find the minimum value of the ranges vector given by the topic and rotate up to the point where its frontal scan (ranges[180]) is the minimum value. Then it should approach it and use the same logic to put the wall to its right.
To follow this logic my idea was to use a while cycle to rotate the robot while the ranges[180] value is bigger than the minimum (plus a tolerance term, since it seems that the laser values tend to change over time even if the robot is not moving) and then stop:

#! /usr/bin/env python

import rospy
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist

def callback (msg):
print(msg.ranges[180])
a = min(msg.ranges)
print(a)
while msg.ranges[180]>a+0.05:
    tw_var.angular.z = 0.3
    pub.publish(tw_var)
tw_var.angular.z = 0.0
if msg.ranges[180]>0.3:
    tw_var.linear.x = 0.1
    pub.publish(tw_var)
else:
    b = msg.ranges[180]
    while msg.ranges[90]>b+0.05:
        tw_var.angular.z = 0.3
        pub.publish(tw_var)
    tw_var.angular.z = 0.0
 pub.publish(tw_var)

rospy.init_node("my_rosject1_node")

sub = rospy.Subscriber("/scan",LaserScan,callback)

pub = rospy.Publisher("/cmd_vel",Twist,queue_size=1)

tw_var = Twist()

rospy.spin()

Obviously I still haven’t written the part about the server, but I think that in order to do that I first have to solve this problem.
My problem is that the readings of the laser are not updated inside the while cycle, which means that the robot ends up in a loop and rotates for a virtually infinite time. This doesn’t happen when I use the if commands.
Did I miss something obvious? How can I solve this?
Thanks in advance for your help!

Hi @emmanuelef.aced.94 ,

Could you format your code shown above?

Because the way it looks like, I don’t think it makes sense. The callback function, for example, does not have indented lines inside

A common approach to use updated values is declaring a global variable outside the callback and using it inside the callback and the main loop. E.g:

laser_ranges = []

def callback (msg):
    global laser_ranges
    laser_ranges = msg.ranges

def loop():
    global laser_ranges
   ...

Thanks for your reply. I updated the code with the suggestion you provided me, but the situation does not change: the prints I have in the while loop (for the minimum laser value and the frontal laser value) keep giving as output the same two values even if the robot is rotating.
For example:

0.24863050878047943 (the min(laser_ranges) print)
1.5075628757476807 (the laser_ranges[180] print)
0.24863050878047943 (…)
1.5075628757476807
0.24863050878047943
1.5075628757476807
0.24863050878047943

This is the updated version of the code, this time with the correct indentation:

#! /usr/bin/env python
import rospy
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist
laser_ranges = []
def callback (msg):
    global laser_ranges
    laser_ranges = msg.ranges
    print(laser_ranges[180])
    a = min(laser_ranges)
    print(a)
        while laser_ranges[180]>a+0.05:
        tw_var.angular.z = 0.3
        print(a)
        print (laser_ranges[180])
        pub.publish(tw_var)
    tw_var.angular.z = 0.0
    if laser_ranges[180]>0.3:
        tw_var.linear.x = 0.1
        pub.publish(tw_var)
    else:
        tw_var.angular.z = 0.0
        b = laser_ranges[180]
        while laser_ranges[90]>b+0.05:
            tw_var.angular.z = 0.3
            pub.publish(tw_var)
        tw_var.angular.z = 0.0
    pub.publish(tw_var)