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 –
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.
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()
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.
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
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 –
#! /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.
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