ROS in 5 days (Python) Quiz 4.3 Task

Hello,

I have finished my task for 4.3 Quiz and I don’t get any error but I don’t know why my robot is not moving in Gazebo simulation. After doing catkin_make and sourcing the setup.bash I did roslaunch realrobotlab main.launch and then Launched my topics_quiz.launch. Below is my scripts and launch file for reference. Can anyone please help me out.

script

#!/usr/bin/env python

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


def callback(laser):

    if laser.ranges[360] < 1:
        print("Detected Obstacle in Front")
        print("Turning Left")
        move.linear.z = 0.3
        move.linear.x = 0.5
    elif laser.ranges[0] < 1:
        print("Detected Obstacle on Right")
        print("Turning Left again")
        move.linear.z = - 0.3
        move.linear.x = 0.5
    elif laser.ranges[719] < 1:
        print("Detected Obstacle on Left")
        print("Turning Right")
        move.linear.z = - 0.3
        move.linear.x = 0.5
    else:
        move.linear.x = 0.5
        print("Forward")


rospy.init_node("topics_quiz_node")
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
rate = rospy.Rate(2)
move = Twist()


while not rospy.is_shutdown():
    rospy.Subscriber("/kobuki/laser/scan", LaserScan, callback)
    pub.publish(move)
    rospy.spin()

Launch file

<launch>
  <node name="topics_quiz_node" pkg="topics_quiz" type="topics_quiz_scripts.py" output="screen">
  </node>
</launch>

Hi,
I think The problem in your code is move.linear.z = - 0.3, it should be angular.z.
try it,

1 Like

You are missing “/” at the end of the second line in the launch file

<node name="topics_quiz_node" pkg="topics_quiz" type="topics_quiz_scripts.py" output="screen"/>

Hi,

probably you need move.angular.z to make a turn. Also did you start your ros1 bridge again ?

Regards,
V

1 Like

Hi @balajigunasekeran22 ,

Welcome to this Community!

After going through what you have posted I can tell you the following:

  1. Your launch file is correct just the way you have posted. Do not do any changes to that!
  2. You must initialize Subscriber (as sub = ...) in the initialization part itself (and not inside a loop) - along with pub and rate.
  3. To rotate you must use move.angular.z and not move.linear.z
    move.linear.z would basically translate your robot up or down in the Z axis (your robot cannot fly or sink into ground!)

Do these changes and you should be fine!

Regards,
Girish

1 Like

Thank you for the comment Amna.

Thank you for the comment @girishkumar.kannan @AmnaMazen @vkuehn and @misbahsuhail123

Hi @girishkumar.kannan ,

I tried as you as by changing the point 2 & 3 from your above comments. But still the robot is not moving. I don’t know where I am missing. Could you help me pls

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


def callback(laser):

    if laser.ranges[360] < 1:
        print("Detected Obstacle in Front")
        print("Turning Left")
        move.angular.z = 0.3
        move.linear.x = 0.5
    elif laser.ranges[0] < 1:
        print("Detected Obstacle on Right")
        print("Turning Left again")
        move.angular.z = - 0.3
        move.linear.x = 0.5
    elif laser.ranges[719] < 1:
        print("Detected Obstacle on Left")
        print("Turning Right")
        move.angular.z = - 0.3
        move.linear.x = 0.5
    else:
        move.linear.x = 0.5
        print("Forward")


rospy.init_node("topics_quiz_node")
rospy.Subscriber("/kobuki/laser/scan", LaserScan, callback)
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
rate = rospy.Rate(2)
move = Twist()

pub.publish(move)
rospy.spin()

Hi @balajigunasekeran22 ,

Did you actually follow the Subscribers unit when you took the course?
I believe that you have not. You seem to be ignorant and not referring to the course material.

You DO NOT define a subscriber like this:
rospy.Subscriber("/kobuki/laser/scan", LaserScan, callback)

You SHOULD define a subscriber like this:
sub = rospy.Subscriber("/kobuki/laser/scan", LaserScan, callback)

Please go back to the course and learn again in case you have forgotton.
These are very simple problems that comes because of lack of attention while studying!

Cheers,
Girish

Hi @girishkumar.kannan

I tired subscriber step too. The robot in the simulation is not moving. So i even tried testing simulation when I do rosrun teleop_twist_keyboard the robot is not moving. Could you help me with that please.

Hi @balajigunasekeran22 ,

You seem to be struggling quite a bit. So, I am giving you a properly structured and modified version of your own code.

NOTE: I wrote this code directly in the post. I have not tested this code !

#! /usr/bin/env python
# the above line is called a "shebang"
# if you forget to include that line, your code will not run!

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

def scan_callback(msg):
    global range_left, range_front, range_right
    range_left = msg.ranges[719]
    range_front = msg.ranges[360]
    range_right = msg.ranges[0]
    return None

rospy.init_node("topics_quiz_node")
rate = rospy.Rate(2)
pub = rospy.Publisher("/cmd_vel", Twist, queue_size=1)
sub = rospy.Subscriber("/kobuki/laser/scan", LaserScan, scan_callback)

linear_speed = 0.15
angular_speed = 0.30
range_left = 0.0
range_front = 0.0
range_right = 0.0

while not rospy.is_shutdown():
    try:
        twist_cmd = Twist()
        if (range_front < 1.0):
            twist_cmd.linear.x = linear_speed
            twist_cmd.angular.z = angular_speed
            print("Obstacle in Front : Turning Left")
            pub.publish(twist_cmd)
        elif (range_right < 1.0):
            twist_cmd.linear.x = linear_speed
            twist_cmd.angular.z = angular_speed
            print("Obstacle on Right : Turning Left")
            pub.publish(twist_cmd)
        elif (range_left < 1.0):
            twist_cmd.linear.x = linear_speed
            twist_cmd.angular.z = -angular_speed
            print("Obstacle on Left : Turning Right")
            pub.publish(twist_cmd)
        else:
            twist_cmd.linear.x = linear_speed
            twist_cmd.angular.z = 0.0
            print("No Obstacle : Moving Straight")
            pub.publish(twist_cmd)
        rate.sleep()
    except:
        pass

# End of Code

Let me know if you get this working!

Cheers,
Girish

Hello Girish Thank you for your answer. It worked but still the robot was hitting against the wall. And it only evaluated the 1st if condition because at the end of the 1st loop it was already hitting wall. So, I tried defining function for foward, left_turn(CW) and right_turn but I don’t know it give me an error. There’s no indentation error as I checked it clearly. Can you please have a look at it and give your feedback on the code below.

#!/usr/bin/env python

import rospy
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
PI = 3.141592653589


def movingForward(move, pub, t0, current_distance, distance, speed, forwardSpeed, front):
    rospy.init_node('topics_quiz_node')
    pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
    move = Twist()
    t0 = rospy.Time.now().to_sec()
    t1 = rospy.Time.now().to_sec()

    move.linear.x = forwardSpeed
    move.angular.z = 0  # initialize angular z to zero
    print('Is moving')
    while(current_distance < distance):
        pub.publish(move)
    # Take actual time to velocity calculation
        t1 = rospy.Time.now().to_sec()
        current_distance = speed*(t1-t0)  # calculates distance
    # Stop the robot when the front distance from obstacle is smaller than 0.5
    if (front < 0.5):
        move.linear.x = 0
        move.angular.x = 0
        rospy.sleep(1)  # stop for 1 second


def turnCW(move, pub, t0, current_angle, turningSpeed, angle):
    angular_speed = round(turningSpeed*2*PI/360, 1)
    relative_angle = round(angle*2*PI/360, 1)
    move.linear.x = 0  # initialize linear x to zero
    move.angular.z = -abs(angular_speed)
    print('Turning')
    while(current_angle < relative_angle):
        pub.publish(move)  # Publish the velocity
        t1 = rospy.Time.now().to_sec()
        current_angle = angular_speed*(t1-t0)  # calculates distance
    rospy.sleep(1)  # stop the robot for 1 second


def turnCCW(move, pub, t0, current_angle, turningSpeed, angle):

    angular_speed = round(turningSpeed*2*PI/360, 1)
    relative_angle = round(angle*2*PI/360, 1)
    move.linear.x = 0  # initialize linear x to zero
    move.angular.z = abs(angular_speed)
    print('Turning')
    while(current_angle < relative_angle):
        pub.publish(move)  # Publish the velocity
        t1 = rospy.Time.now().to_sec()
        current_angle = angular_speed*(t1-t0)  # calculates distance
    rospy.sleep(1)  # stop the robot for 1 second


def callback(msg):
    global left
    global front
    global right

    left = msg.ranges[719]
    front = msg.ranges[360]
    right = msg.ranges[0]
    return None


while not rospy.is_shutdown():
    pub.publish(move)
    if (front < 0.5) or (left < 1.0):
        print("Detected Obstacle in Front Turning Left 1")
        turnCCW(move, pub, t0, current_angle, 0.25, 90)
    elif (right < 1.0)
        print("Detected Obstacle on Left Turning Right")
        turnCW(move, pub, t0, current_angle, 0.25, 90)
    else:
        movingForward(move, pub, t0, current_distance,
                      1.0, speed, forwardSpeed, front)
        print("Forward")

    sub = rospy.Subscriber('/kobuki/laser/scan', LaserScan, callback)
    rate = rospy.Rate(10)

Hi @balajigunasekeran22 ,

This is a fairly easy exercise and you seem to be struggling quite a lot. The task is also very simple.

Why have you complicated your program further? You just need to avoid hitting the wall when the robot moves. Why are you bringing in PI and turning calculations? You just need to turn and move - you are not instructed to make precision turns.

Also, from where did you learn to put the subscriber and rate declaration inside a while loop?
Why would you do that? I specifically told you (in my previous replies) to declare subscriber along with rate and publisher at the program initialization part.

What did you understand from learning the course? Seriously?
Are you copy-pasting your code from somewhere?

Here is an advice for you: PLEASE SCRAP YOUR RECENT CODE. Honestly, it is useless.
It seems that you have just jumbled a bunch of code lines without understanding which line goes where.
(Why would you put publisher declaration inside movingForward function?)

Just re-work on the previous logic (the one that I modified and restructured).
Use if..if..if.. block instead if if...elif...else. Understand scan priority.

Here is an outline of the logic:

  • if front is more than 1.0 then move straight else turn left (for a few seconds just to make a 60 or 90 degree turn)
  • if left is less than 1.0 then turn right (60-90 degrees) else do nothing
  • if right is less than 1.0 then turn left (60-90 degrees) else do nothing

Once the robot goes past the wall without hitting it, you will pass the exercise!

Please put some effort into understanding what you learn. Do not expect people to spoon-feed you the answers (like I did in my previous post).

Regards,
Girish