# Ros basics in 5 days project

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

def callback_msg(self,msg):
self.left = msg.ranges[715]
self.right = msg.ranges[5]
self.front = msg.ranges[360]

def callback(self,request):

r = rospy.Rate(4)

while ((self.left == 0) and (self.right == 0) and (self.front == 0)):
rospy.sleep(1)

if ((self.left < self.right) and (self.left < self.front)):

left_1 = round(self.left , 1)
front_1  = round(self.front , 1)
while front_1 != left_1:
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)
r.sleep()

while self.front >= 0.3:
self.move_2.linear.x = 0.1
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()

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)):

right_1 = round(self.right , 1)
front_1 = round(self.front , 1)

while front_1 != right_1:

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)
r.sleep()
while self.front >= 0.3:

self.move_2.linear.x = 0.08
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()
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:

while self.front >= 0.3:
self.move_2.linear.x = 0.1
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()

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)

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()

``````

Hi @80601 ,

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`.

Refer this post for more info: Incorrect Robot Scan Values in ROS Basics Course - Wall Follower Robot / TurtleBot3

Regards,
Girish

2 Likes

actually i do not know why but the front readings at 360 are totally wrong are you sure ?

Hi @80601 ,

I think I exactly know why you have this problem!

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:

``````angle_min: -3.141590118408203
angle_max: 3.141590118408203
angle_increment: 0.008738775737583637   # equals 0.5 degrees
``````

For a 360 degree laser with 1.0 degree angle increment you will have 360 values:

``````angle_min: -3.141590118408203
angle_max: 3.141590118408203
angle_increment: 0.017477551   # equals 1.0 degrees
``````

So now you have two options (choose one, not both):

1. 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.
2. 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 am certain this will solve your problem.

Regards,
Girish

i got this the readings seam to be 720 my service code act as expected but i think the problem starts with the wall following function

``````header:
seq: 15
stamp:
secs: 13
nsecs: 233000000
frame_id: "base_scan"
angle_min: -3.1415998935699463
angle_max: 3.1415998935699463
angle_increment: 0.008738803677260876
time_increment: 0.0
scan_time: 0.0
range_min: 0.11999999731779099
range_max: 3.5
``````

code for service

``````#! /usr/bin/env python

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

def callback_msg(self, msg):
self.left = msg.ranges[540]
self.right = msg.ranges[180]
self.front = msg.ranges[360]

def callback(self, request):

r = rospy.Rate(6)

while ((self.left == 0) and (self.right == 0) and (self.front == 0)):
rospy.sleep(1)

if ((self.left < self.right) and (self.left < self.front)):

left_1 = round(self.left, 1)
front_1 = round(self.front, 1)
while front_1 != left_1:
self.move_2.linear.x = 0
self.move_2.angular.z = 0.45  # rotate to the left
pub_s.publish(self.move_2)
front_1 = round(self.front, 1)
r.sleep()

while self.front >= 0.3:
self.move_2.linear.x = 0.1
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()

self.move_2.linear.x = 0
self.move_2.angular.z = 0.45  # rotate to the left
pub_s.publish(self.move_2)
r.sleep()

elif ((self.right < self.left) and (self.right < self.front)):

right_1 = round(self.right, 1)
front_1 = round(self.front, 1)

while front_1 != right_1:

self.move_2.linear.x = 0
self.move_2.angular.z = -0.45  # rotate to the  right
pub_s.publish(self.move_2)
front_1 = round(self.front, 1)
r.sleep()
while self.front >= 0.3:

self.move_2.linear.x = 0.08
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()
self.move_2.linear.x = 0
self.move_2.angular.z = 0.45  # rotate to the left
pub_s.publish(self.move_2)
r.sleep()

else:

while self.front >= 0.3:
self.move_2.linear.x = 0.1
self.move_2.angular.z = 0
pub_s.publish(self.move_2)
r.sleep()

self.move_2.linear.x = 0
self.move_2.angular.z = 0.45  # 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)

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()
self.server.set_succeeded(self._result)

if __name__ == '__main__':
rospy.init_node('action_node')
record_odomClass()
rospy.spin()

``````

main code

``````#! /usr/bin/env python

import time
import rospy
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
from project.srv import FindWall, FindWallRequest
import actionlib
from project.msg import OdomRecordAction, OdomRecordGoal
from std_msgs.msg import Empty

####service####
rospy.init_node("project_node")
rospy.wait_for_service('/find_wall')
FindWall_service = rospy.ServiceProxy('/find_wall', FindWall)
result = FindWall_service(FindWallRequest())
print(result)

####acttion####
PENDING = 0
ACTIVE = 1
DONE = 2
WARN = 3
ERROR = 4
nImage = 1

def feedback_callback(feedback):
print("feedback from action server totall distance moved so far\n"+str(feedback))

action_server_name = 'record_odom'
action_client = actionlib.SimpleActionClient(
action_server_name, OdomRecordAction)
action_client.wait_for_server()
action_client.send_goal(Empty(), feedback_cb=feedback_callback)
state_result = action_client.get_state()

rate = rospy.Rate(1)

####wall_following####

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

def callback(msg):
# perform wallfollower programm
if msg.ranges[180] > 0.3 :
# approach the wall slowly
move.linear.x = 0.06
move.angular.z = -0.09
pub.publish(move)

elif msg.ranges[180] < 0.2 :
# get away from the wall slowly
move.linear.x = 0.06
move.angular.z = 0.09
pub.publish(move)

elif (2 > msg.ranges[180] > 0.3) and msg.ranges[360] > 0.5  :
# keep moving forward
move.linear.x = 0.06
move.angular.z = 0
pub.publish(move)

elif msg.ranges[360] < 0.5:
# turn left while moving forward
move.linear.x = 0.06
move.angular.z = 0.6
pub.publish(move)

state_result = action_client.get_state()
if state_result == DONE:

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

rospy.spin()

``````

Hi @80601 ,

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.

Regards,
Girish

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.