This problem was already reported by someone else. I guess the problem still remains.
The quick fix would be to change the time in the string to something like t.
Also, change all variable names defined as time after the import time line to t.
Since the file has import time declared as one of the imports, time cannot be used as a variable.
This error needs to be fixed by TheConstruct team.
Here is a fixed version of that python script: robot_control_class.py
#!/usr/bin/env python
import rospy
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
import time
class RobotControl():
def __init__(self, robot_name="turtlebot"):
rospy.init_node('robot_control_node', anonymous=True)
if robot_name == "summit":
rospy.loginfo("Robot Summit...")
cmd_vel_topic = "/summit_xl_control/cmd_vel"
# We check sensors working
self._check_summit_laser_ready()
else:
rospy.loginfo("Robot Turtlebot...")
cmd_vel_topic='/cmd_vel'
self._check_laser_ready()
# We start the publisher
self.vel_publisher = rospy.Publisher(cmd_vel_topic, Twist, queue_size=1)
self.cmd = Twist()
self.laser_subscriber = rospy.Subscriber(
'/kobuki/laser/scan', LaserScan, self.laser_callback)
self.summit_laser_subscriber = rospy.Subscriber(
'/hokuyo_base/scan', LaserScan, self.summit_laser_callback)
self.ctrl_c = False
self.rate = rospy.Rate(1)
rospy.on_shutdown(self.shutdownhook)
def _check_summit_laser_ready(self):
self.summit_laser_msg = None
rospy.loginfo("Checking Summit Laser...")
while self.summit_laser_msg is None and not rospy.is_shutdown():
try:
self.summit_laser_msg = rospy.wait_for_message("/hokuyo_base/scan", LaserScan, timeout=1.0)
rospy.logdebug("Current /hokuyo_base/scan READY=>" + str(self.summit_laser_msg))
except:
rospy.logerr("Current /hokuyo_base/scan not ready yet, retrying for getting scan")
rospy.loginfo("Checking Summit Laser...DONE")
return self.summit_laser_msg
def _check_laser_ready(self):
self.laser_msg = None
rospy.loginfo("Checking Laser...")
while self.laser_msg is None and not rospy.is_shutdown():
try:
self.laser_msg = rospy.wait_for_message("/kobuki/laser/scan", LaserScan, timeout=1.0)
rospy.logdebug("Current /kobuki/laser/scan READY=>" + str(self.laser_msg))
except:
rospy.logerr("Current /kobuki/laser/scan not ready yet, retrying for getting scan")
rospy.loginfo("Checking Laser...DONE")
return self.laser_msg
def publish_once_in_cmd_vel(self):
"""
This is because publishing in topics sometimes fails the first time you publish.
In continuous publishing systems, this is no big deal, but in systems that publish only
once, it IS very important.
"""
while not self.ctrl_c:
connections = self.vel_publisher.get_num_connections()
if connections > 0:
self.vel_publisher.publish(self.cmd)
#rospy.loginfo("Cmd Published")
break
else:
self.rate.sleep()
def shutdownhook(self):
# works better than the rospy.is_shutdown()
self.ctrl_c = True
def laser_callback(self, msg):
self.laser_msg = msg
def summit_laser_callback(self, msg):
self.summit_laser_msg = msg
def get_laser(self, pos):
time.sleep(1)
return self.laser_msg.ranges[pos]
def get_laser_summit(self, pos):
time.sleep(1)
return self.summit_laser_msg.ranges[pos]
def get_front_laser(self):
time.sleep(1)
return self.laser_msg.ranges[360]
def get_laser_full(self):
time.sleep(1)
return self.laser_msg.ranges
def stop_robot(self):
#rospy.loginfo("shutdown time! Stop the robot")
self.cmd.linear.x = 0.0
self.cmd.angular.z = 0.0
self.publish_once_in_cmd_vel()
def move_straight(self):
# Initilize velocities
self.cmd.linear.x = 0.5
self.cmd.linear.y = 0
self.cmd.linear.z = 0
self.cmd.angular.x = 0
self.cmd.angular.y = 0
self.cmd.angular.z = 0
# Publish the velocity
self.publish_once_in_cmd_vel()
def move_straight_time(self, motion, speed, tsecs):
# Initilize velocities
self.cmd.linear.y = 0
self.cmd.linear.z = 0
self.cmd.angular.x = 0
self.cmd.angular.y = 0
self.cmd.angular.z = 0
if motion == "forward":
self.cmd.linear.x = speed
elif motion == "backward":
self.cmd.linear.x = - speed
i = 0
# loop to publish the velocity estimate, current_distance = velocity * (t1 - t0)
while (i <= tsecs):
# Publish the velocity
self.vel_publisher.publish(self.cmd)
i += 1
self.rate.sleep()
# set velocity to zero to stop the robot
self.stop_robot()
s = "Moved robot " + motion + " for " + str(tsecs) + " seconds"
return s
def turn(self, clockwise, speed, tsecs):
# Initilize velocities
self.cmd.linear.x = 0
self.cmd.linear.y = 0
self.cmd.linear.z = 0
self.cmd.angular.x = 0
self.cmd.angular.y = 0
if clockwise == "clockwise":
self.cmd.angular.z = -speed
else:
self.cmd.angular.z = speed
i = 0
# loop to publish the velocity estimate, current_distance = velocity * (t1 - t0)
while (i <= tsecs):
# Publish the velocity
self.vel_publisher.publish(self.cmd)
i += 1
self.rate.sleep()
# set velocity to zero to stop the robot
self.stop_robot()
s = "Turned robot " + clockwise + " for " + str(tsecs) + " seconds"
return s
if __name__ == '__main__':
robotcontrol_object = RobotControl()
try:
robotcontrol_object.move_straight()
except rospy.ROSInterruptException:
pass
TheConstruct team, please make this change in the python script.
The variable time conflicts with import time.
I have changed the time variable to tsecs in the functions move_straight_time(...) and turn(...).
I changed the all the conflict time you mentioned above.
However, there is another issue also need to fix.
s = “Turned robot " + clockwise + " for " + str(tsecs) + " seconds”
I have to change it to
s = “Turned robot " + str(clockwise) + " for " + str(tsecs) + " seconds”
Then I passed the task2.py, don’t know why I have to convert the clockwise as string type since it declared as string, but the error mention about that. So I changed.
Glad to know that you have fixed this issue yourself!
It is strange to note that a default string variable needed conversion to string.
I see that clockwise variable is printed only in the turn(...) function.
Are you sure that you called the function this way (string, float, float) ?
# to turn 90 degrees clockwise at 10 degrees per sec for 9 secs
# 10 degs / sec = 0.17 rads / sec
robot_control.turn("clockwise", 0.17, 9.0)
I am sure TheConstruct team would look into this issue and fix it for future students.
This script is a part of the “Prerequisites Exam”. It is not exactly a course.
I usually access this by going to “Learning Paths” and clicking on “Prerequisites Exam” under “Code Foundation for ROS”.
There is a script called robot_control_class.py. This needs to be fixed.
Hello @girishkumar.kannan Thank you very much for sharing the solution, which will enable other students to proceed without any problems.
Also thanks for pointing me to where I can find the files that need to be changed. I have created an issue so that we can fix this and have an updated version as soon as possible.