why the reading from left and right laser are always very close in value and does not represent the true distance that i see in the gazebo simulation as iam sure they should be very different
import rospy
import time
from project.srv import FindWall , FindWallResponse
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
class my_node(object):
def __init__(self):
self.move_2 = Twist()
self.left = 0
self.right = 0
self.front = 0
self.ready_point = 0
def callback_msg(self,msg):
self.left = msg.ranges[715]
self.right = msg.ranges[5]
self.front = msg.ranges[360]
self.ready_point = msg.ranges[270]
def callback(self,request):
r = rospy.Rate(4)
rospy.loginfo("left distance"+str(self.left))
rospy.loginfo("right distance"+str(self.right))
rospy.loginfo("front distnace"+str(self.front))
while ((self.left == 0) and (self.right == 0) and (self.front == 0)):
rospy.sleep(1)
rospy.loginfo('findwall service started...')
if ((self.left < self.right) and (self.left < self.front)):
rospy.loginfo("first case")
left_1 = round(self.left , 1)
front_1 = round(self.front , 1)
while front_1 != left_1:
rospy.loginfo('rotating left..')
self.move_2.linear.x = 0
self.move_2.angular.z = 0.5 #rotate to the left
pub_s.publish(self.move_2)
front_1 = round(self.front , 1)
rospy.loginfo("current left distance"+str(left_1))
rospy.loginfo("current front distance"+str(front_1))
r.sleep()
while self.front >= 0.3:
rospy.loginfo("moving forward")
self.move_2.linear.x = 0.1
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()
while self.ready_point > 0.3:
rospy.loginfo("trying to reach the start state (ready_point)")
self.move_2.linear.x = 0
self.move_2.angular.z = 0.5 #rotate to the left
pub_s.publish(self.move_2)
r.sleep()
elif ((self.right < self.left) and (self.right < self.front)):
rospy.loginfo("second case")
right_1 = round(self.right , 1)
front_1 = round(self.front , 1)
while front_1 != right_1:
rospy.loginfo("rotating right ..")
self.move_2.linear.x = 0
self.move_2.angular.z = -0.5 #rotate to the right
pub_s.publish(self.move_2)
front_1 = round(self.front , 1)
rospy.loginfo("current right distance"+str(right_1))
rospy.loginfo("current front distance"+str(front_1))
r.sleep()
while self.front >= 0.3:
rospy.loginfo("moving forward")
self.move_2.linear.x = 0.08
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()
while self.ready_point > 0.3:
rospy.loginfo("trying to reach the start state (ready_point)")
self.move_2.linear.x = 0
self.move_2.angular.z = 0.5 #rotate to the left
pub_s.publish(self.move_2)
r.sleep()
else:
rospy.loginfo("third case")
while self.front >= 0.3:
rospy.loginfo("moving forward")
self.move_2.linear.x = 0.1
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()
while self.ready_point > 0.3:
rospy.loginfo("trying to reach the start state (ready_point)")
self.move_2.linear.x = 0
self.move_2.angular.z = 0.5 #rotate to the left
pub_s.publish(self.move_2)
r.sleep()
self.move_2.linear.x = 0
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
rospy.loginfo('findwall service finished..')
message = FindWallResponse()
message.wallfound = True
return message
if __name__ == '__main__':
rospy.init_node('service_node')
my_object = my_node()
sub_s = rospy.Subscriber("/scan" , LaserScan ,my_object.callback_msg)
rospy.wait_for_message("/scan" , LaserScan)
pub_s = rospy.Publisher('/cmd_vel' ,Twist , queue_size= 1 )
FindWall_service = rospy.Service('/find_wall' , FindWall , my_object.callback)
rospy.spin()
That is because, unlike in the robot that you used in the course that used 180 degree laser scanner with 0 - right, 360 - front and 719 - left, the turtlebot in rosject uses a 360 degree laser scanner that gives 0/719 - back, 180 - right, 360 - front and 540 - left.
When I worked on this rosject, I found out that the 360 degree laser has 360 readings instead of 720, whereas the real robot TurtleBot has 720 readings for the laser.
You can verify this by doing ros2 topic echo /scan and cancel after you get at least one reading.
You will need to see three fields:
For a 360 degree laser with 0.5 degree angle increment you will have 720 values:
So now you have two options (choose one, not both):
Use a parameter setting in your program (launch file) to use laser scan ranges as 720 values for real robot and 360 values for simulation.
Change the value of samples to 720 and resolution to 1 in the turtlebot3_burger.gazebo.xacro file that is located in the turtlebot3_description package. This will permanently change simulation robot’s laser scan values from 360 to 720.
I just went through your “Service” code. Long story short, your code will not work. You have some issues in your program, especially in the OOPS concept.
You must define Subscriber, Publisher and Service inside your my_node() object.
You have two if __name__ == "__main__": lines in your program.
The first one should be just def main(...). The second main function is correct.
Your “ServiceClient” code is fine, but it needs mode “beautification”, that is, rearranging of codes. It would be better if you can implement this as another class.