Need help in reading LaserScan

Hi,
I am trying to complete part1 of ROS basics in 5 days. In the simulation, I am considering laser range[0] for reading right of the robot and range[359] for reading front of the robot. If this assumption is correct then I think the readings coming from the simulation are not correct as when robot gets closer to the wall the right distance reading is increasing.

Thanks.

Hi there, you need to watch this video [ROS Q&A] 031 - How to read LaserScan data - YouTube. This video completely explains how to find range and laserscan data. After watching this video, you will be able to better understand the concept. Also, if you consider four quadrant system, then you will be able to better understand the logic, there is 90 degrees difference for each quadrant. Please check this link Unit Circle - JavaTpoint to further understand this. Hope this helps.

Thanks for sharing the video. It certainly helped. So based on the video I figured out that as per the min and max angle, this laser scanner is making a 360 degree scan and total measurements in range list is 360. So as per information given by you we can divided the scanner range in each quadrant. Now based on that I am considering that heading axis of turtlebot is 90 deg and therefore taking value from range[89] and to the right will be 0 deg of the turtlebot which is range[0]. Based on that still the reading coming out are not making any sense. For example, if I am keeping the robot heading axis perpendicular to wall it is giving front reading less comapered to the right reading which does not make any sense.

Hi this clearly means that the values you are considering are incorrect. Ok, understand it like this, the total range is 360, you already know that. Now, if you divide the total range into four quadrants, then it means that 1st quad is 0 to 90 degrees, second quadrant is 90 to 180, third one is 180 to 270 and the fourth one is 270 to 360 again. I am sharing some pictures, as I was stuck on same problem. image. Now, to find out the front side, you need to keep the robot in front of wall and check which is the shortest value, is it 0, 90, 180, 270 or what, once you find the front side, then you can find corresponding right and left by checking the beam which makes 90 degree angle with the front one. One more thing, If the total range is 360 then it goes from 0 to 359. I am also working on the same project. Hope it helps.

Cheers

Thanks! that was helpful. I wish, if the orientation and heading angle was mentioned in the instruction as these informations are provided by the manufacturer and besided it takes more effort to find out these things rather than focus on the logic part and getting robot move. Coming to that I was able to find that 90 deg is to the right and 180 to the left. But another issue is with the obstacles in the path. It is really difficult to figure out how to move the robot across them. On one side, I have to move clockwise and on the other side counter clockwise…It’s really a tough one to get…Are you able to solve it? I am still figuring out the fix by reading scanner at different angles but no luck…Again these things are a lot of hit and trial and lot of recompiling :slight_smile:

Hi yes bro, I am working on it since last 2 weeks, It is certainly difficult. For me 90 degree is the right but as i told you that if 90 is the right, then 180 can’t be the left. Remember that there is 180 degrees difference between left and right. Even in the diagram above, if you check, 90 degrees is the right and if we add 90 degrees to it, then it will be 90+90 = 180 degrees, so 180 degrees is the front for me. try to do it and let me know, it should work for you as well. I had to do a lot of hit and trial to find it out. For Movement, you need to avoid wall by using while loops, check the example in python course where turtlebot stops when distance to the wall is less than a certain distance, in that case it moves forward but in our case we need to turn it left or right. Yes I know it takes a lot of time but this is how we learn. :smiley:

Hey sorry it was a typo i meant front instead of left there so yes at 180 it will be at the front.
For the logic, I am using code template from the Topics chapter by using publishers and subscribers. Here is my code.

import rclpy
# import the ROS2 python libraries
from rclpy.node import Node
# import the Twist module from geometry_msgs interface
from geometry_msgs.msg import Twist
# import the LaserScan module from sensor_msgs interface
from sensor_msgs.msg import LaserScan
from rclpy.qos import ReliabilityPolicy, QoSProfile

class WallFollowing(Node):
    def __init__(self):
        # Here we have the class constructor
        # call the class constructor
        super().__init__('WallFollowing')
        # create the publisher object
        self.publisher = self.create_publisher(Twist,'cmd_vel',10)
        # create the subscriber object
        self.subscriber = self.create_subscription(LaserScan,'/scan',self.move_turtlebot,QoSProfile(depth=10,reliability=ReliabilityPolicy.BEST_EFFORT))
        # prevent unused variable warning
        self.subscriber
        # define the timer period of 0.5 seconds
        self.timer_period = 0.2
        # define the variable to save the received info
        self.Laser_forward_left = 0
        self.Laser_forward_right = 0
        self.Laser_right = 0
        # create a Twist message
        self.cmd = Twist()
        self.timer = self.create_timer(self.timer_period,self.motion)

    def move_turtlebot(self,msg):
        self.Laser_forward_right = (msg.ranges[179])
        self.obsAtRight = min(msg.ranges[130:165])
        self.obsAtLeft = min(msg.ranges[190:250])
        self.Laser_right = msg.ranges[89]
        #print('length of ranges = ', len(msg.ranges))

    def motion(self):
        # print the data
        self.get_logger().info("I receive in front %s" % str(self.Laser_forward_right))
        self.get_logger().info("I receive in right wall %s" % str(self.Laser_right))

        # Logic to move
        if self.Laser_forward_right < 0.5 or (self.obsAtRight < 0.2 and self.obsAtLeft > 0.3):
            self.cmd.linear.x = 0.02
            self.cmd.angular.z = 0.2
            self.get_logger().info("obstacle detected or front near")
        else:
            if self.Laser_right > 0.3 or self.obsAtLeft < 0.3:
                self.cmd.linear.x = 0.02
                self.cmd.angular.z = -0.1
            elif self.Laser_right < 0.2 :
                self.cmd.linear.x = 0.02
                self.cmd.angular.z = 0.1
            else:
                self.cmd.linear.x = 0.02
                self.cmd.angular.z = 0.0
        # publishing the cmd_val to the topics
        self.publisher.publish(self.cmd)

def main(args=None):
    # initialie the ROS communication
    rclpy.init(args=args)
    # declaare the node constructor
    wall_following = WallFollowing()
    # pause the program execution, waits for a request to kill the node (ctrl+c)
    try:
        rclpy.spin(wall_following)
    except KeyboardInterrupt:
        pass
    # explicity destroy the node
    wall_following.destroy_node()
    # shutdown the ROS communication
    rclpy.shutdown()

if __name__ == '__main__':
    main()
    

Hi, actually I am not doing it using ROS2, I am doing it using ROS because I haven’t learnt ROS2 until now, apologies for that. Still, I can see one issue with your code, and that is you are not using loops here, instead you are using if else statements only, you need to use the loops because once you use loops, then only the robot will check the condition again and again. If there is no loop, then the robot will check the condition only once. Ok let me attach the code,

. Check it, it is the code in the loops section of python course, you can see here that we are using while loops so that the robot keeps on checking the distance again and again, if you don’t use loops, the robot will collide with the wall. as the condition is checked only once, this might be causing the issue. Just do it using the loop and let me know. Cheers.

Somehow I managed to run in the simulation :slightly_smiling_face:. Yes you are right that while loop is required but if you see, I have a created a timer function which will call the function self.motion repeatedly. So that way while loop is implemented here.

Actually I am already done with both the parts topics and services, My robot is wroking fine but I am stuck on the values, I am attaching a sample code for you to analyze as I am not familiar with ROS2. If you want to do it using ROS, then we can do it together. image. Look this is how I have made the loop work. I am using multiple loops one after the another. I have made one function and then used multiple loops inside it. Once, the condition inside one loop becomes false, the program will jump into another loop and so on. This is how I acheived it. I am only left with the actions part now. Well, what I think is you are calling function again and again but according to me you need to put multiple loops inside one function and execute it only once, Once you execute the function one time, while loops will handle everything, you don’t need to call the function multiple times. Cheers

1 Like