ROSDS - Part 1 Topics - Robot Hitting the walls

Hello dear community !

After completing the Subscribers and Messages lesson, I have been trying to complete the Part 1 of the Rosject given there (Wall following robot) (part 1 is related to Topics only). But even after many trials, my robot is still hitting the side walls. My python code goes like this –

#! /usr/bin/env python

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

def callback(laser):
    if (laser.ranges[0]>0.3):
        move.linear.x=0.04 # this much speed I found okay for the robot while running simulation
        move.angular.z=-0.09
    elif (laser.ranges[0]<0.2):
        move.linear.x=0.04
        move.angular.z=0.09
    elif (laser.ranges[360]<0.5):
        move.linear.x=0.04
        move.angular.z=0.1
    else:
        move.linear.x=0.04
        move.angular.z=0
    pub.publish(move)

rospy.init_node('topic_sub_node')
sub = rospy.Subscriber('/scan',LaserScan,callback)
pub = rospy.Publisher('/cmd_vel',Twist,queue_size=1)

move = Twist()
rospy.spin()

Also, after the robot hits the wall, I do Ctrl+C on the terminal (although it does not stop the robot in the simulation), and in another terminal run –

roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch

and move my robot to the normal position using keyboard to start again. But after sometime I find my robot is still rotating at its place.

May anyone please help me rectifying these issues.

Hi @arjun2312

I would recommend to check that laser.ranges[0] is the ray from the right side.
It think the laser.ranges starts from the back of the robot and goes counter-clockwise to cover the 360 degrees around the robot.

2 Likes

Hello @arjun2312 ,

Like @RPDC1 mentioned, you can use the laser to detect the walls. Having a range of points that identifies the wall is a good way of doing this, use the minimum value and calibrate that value.
There is an example here: [Exploring ROS using a 2 Wheeled Robot] #7: Wall Follower Algorithm - YouTube

But you need to calibrate and make necessary changes for the robot and environment you are working at.

1 Like

Thank you for your kind reply.

I tried to understand it but did not get it properly sir.

Maybe sir. I tried to change the values, but still robot hits the walls and goes here and there. My current code is –

#! /usr/bin/env python

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

def callback(laser): # assuming that laser at back is at zero degrees, laser at right is at 90 degrees, laser at front is at 180 degrees
    if (laser.ranges[90]>0.3 and laser.ranges[45]>0.3 and laser.ranges[135]>0.3): # all the lasers' readings are more than 0.3
        move.linear.x=0.1
        move.angular.z=-0.1
    elif (laser.ranges[90]<0.2 and laser.ranges[45]<0.2 and laser.ranges[135]<0.2): #all the laser readings are less than 0.2
        move.linear.x=0.1
        move.angular.z=0.1
    elif (laser.ranges[135]<0.2 and laser.ranges[45]>0.2): # robot is tilted towards right from front face
        move.linear.x=0.1
        move.angular.z=0.1
    elif (laser.ranges[135]>0.2 and laser.ranges[45]<0.2): #robot is tilted towards right from back face
        move.linear.x=0.1
        move.angular.z=-0.1
    elif (laser.ranges[180]<0.5): # laser at front
        move.linear.x=0.1
        move.angular.z=0.1
    else:
        move.linear.x=0.04
        move.angular.z=0
    pub.publish(move)

rospy.init_node('topic_sub_node')
sub = rospy.Subscriber('/scan',LaserScan,callback)
pub = rospy.Publisher('/cmd_vel',Twist,queue_size=1)

move = Twist()
rospy.spin()

Hi @arjun2312,

Is that the entire code? I think you should put your code after the callback in a main() function:

if __name__ == '__main__':

And you can add some prints to your if statements to see what laser.ranges[x] is looking at.

What do you mean by

I tried to change the values, but still robot hits the walls and goes here and there.

How did you change them? To make sure how long the ranges value is, try printing the length of ranges, and the middle of the array corresponds to the front of the robot.

1 Like

I found this in the Unit 4 (Subscribers and Messages)


I don’t understand your answer. This image is from Unit 4 in the course, not the rosject simulation that your post is about. Have you launched the simulation to look at the laser values?

I recommend doing so and opening rviz to add the robot model and laser topics so you can see what the robot in the rosject is seeing

1 Like

Okay sir. I thought the ranges array would be the same for both the Unit 4 of the course and the Rosject.

Yes i printed the laser values. I did not use Rviz as of now. Below is my code which prints the values and the link of the screen recording of what is happening –

Screen Recording Link

#! /usr/bin/env python

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

def callback(laser):
    if (laser.ranges[0]>0.3):
        move.linear.x=0.04 
        move.angular.z=-0.09
        print("If laser.ranges[0]>0.3, value for laser.ranges[0] is ", laser.ranges[0])
        print("Value for laser.ranges[360] is ", laser.ranges[360])
        print("Value for laser.ranges[90] is ", laser.ranges[90])
        print("Value for laser.ranges[180] is ", laser.ranges[180])
    elif (laser.ranges[0]<0.2): 
        move.linear.x=0.04
        move.angular.z=0.09
        print("If laser.ranges[0]<0.2, value is", laser.ranges[0]) # my program is stuck at first case only, so this print statement is irrelevant.

    elif (laser.ranges[360]<0.5):
        move.linear.x=0.04
        move.angular.z=0.1
        print("If laser.ranges[360]<0.5, value is", laser.ranges[360])
    else:
        move.linear.x=0.04
        move.angular.z=0
        print("Its a normal position")
    pub.publish(move)

rospy.init_node('topic_sub_node')
sub = rospy.Subscriber('/scan',LaserScan,callback)
pub = rospy.Publisher('/cmd_vel',Twist,queue_size=1)

move = Twist()
rospy.spin()

I m very sorry for taking so much of time on this. :sweat_smile:

You should put your main code in a main() function, as I explained earlier in the post.

You are also using the ranges[0] value, which corresponds to the back of the robot. Is that what you want to do?

1 Like

Okay. Actually i don’t know how to use -

if __name__ == '__main__':

Can u plz copy paste my code and send ?

May I please know ranges[90],ranges[180],ranges[360] correspond to which positions of the robot here?

The back of the robot corresponds to values [0] and [720], since the scan has 720 values starting at the back. Therefore, 360 corresponds to the front. I’ll leave it to you to figure out the rest. As I said, you can use rviz for this, try putting the robot with a wall on one side. The smaller values of the array will correspond to that side.

Check the code on the topics unit in the course. You will see an example with a main

1 Like

Okay.
Thank you so much for the help.
I will surely do as told.