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