Task2.py error can't convert 'int' object to str implicitly

I test my task2.py and it shows as below:

File “task2.py”, line 30, in
robotcontrol.turn(90, -1, 1.8)
File “/home/user/catkin_ws/src/python_exam/robot_control_class.py”, line 185, in turn
s = “Turned robot " + clockwise + " for " + str(time) + " seconds”
TypeError: Can’t convert ‘int’ object to str implicitly

should I need to modify the robot_control_class.py?

Hi @katrinac ,

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.

Regards,
Girish

Hi @katrinac ,

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

Regards,
Girish

Hi Grirish,

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.

Hi @katrinac ,

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.

Regards,
Girish

Hello @katrinac,

thanks for reporting, do you remember the name of the course and the unit? That information would be of great help to quickly analyze this issue.

Cheers,

Roberto

Hi @rzegers ,

Just saw your post, so I am replying instead.

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.

Thanks,
– Girish

2 Likes

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.

Cheers,

Roberto

1 Like

Yes, I call it robotcontrol.turn(“clockwise”, 0.3, 5) and pass the gradebot.

1 Like