# Main not defined package python issue

My apologies but I've run out of ideas. I'm very new to python and stuck trying to execute the following code from this tutorial:

#!/usr/bin/env python

import rospy
from geometry_msgs.msg import Twist

import RPi.GPIO as GPIO

# Set the GPIO modes
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

_FREQUENCY = 20

def _clip(value, minimum, maximum):
# """Ensure value is between minimum and maximum."""

if value < minimum:
return minimum
elif value > maximum:
return maximum
return value

class Motor:
def __init__(self, forward_pin, backward_pin):
self._forward_pin = forward_pin
self._backward_pin = backward_pin

GPIO.setup(forward_pin, GPIO.OUT)
GPIO.setup(backward_pin, GPIO.OUT)

self._forward_pwm = GPIO.PWM(forward_pin, _FREQUENCY)
self._backward_pwm = GPIO.PWM(backward_pin, _FREQUENCY)

def move(self, speed_percent):
speed = _clip(abs(speed_percent), 0, 100)

# Positive speeds move wheels forward, negative speeds
# move wheels backward
if speed_percent < 0:
self._backward_pwm.start(speed)
self._forward_pwm.start(0)
else:
self._forward_pwm.start(speed)
self._backward_pwm.start(0)

class Driver:
def __init__(self):
rospy.init_node('driver')

self._timeout = rospy.get_param('~timeout', 2)
self._rate = rospy.get_param('~rate', 10)
self._max_speed = rospy.get_param('~max_speed', 0.5)
self._wheel_base = rospy.get_param('~wheel_base', 0.091)

# Assign pins to motors. These may be distributed
# differently depending on how you've built your robot
self._left_motor = Motor(13, 15)
self._right_motor = Motor(36, 32)
self._left_speed_percent = 0
self._right_speed_percent = 0

# Setup subscriber for velocity twist message
rospy.Subscriber(

# """Handle new velocity command message."""

# Extract linear and angular velocities from the message
linear = message.linear.x
angular = message.angular.z

# Calculate wheel speeds in m/s
left_speed = linear - angular*self._wheel_base/2
right_speed = linear + angular*self._wheel_base/2

# Ideally we'd now use the desired wheel speeds along
# with data from wheel speed sensors to come up with the
# power we need to apply to the wheels, but we don't have
# wheel speed sensors. Instead, we'll simply convert m/s
# into percent of maximum wheel speed, which gives us a
# duty cycle that we can apply to each motor.
self._left_speed_percent = (100 * left_speed/self._max_speed)
self._right_speed_percent = (100 * right_speed/self._max_speed)

def run(self):
# """The control loop of the driver."""

rate = rospy.Rate(self._rate)

while not rospy.is_shutdown():
# If we haven't received new commands for a while, we
# may have lost contact with the commander-- stop
# moving
if delay < self._timeout:
self._left_motor.move(self._left_speed_percent)
self._right_motor.move(self._right_speed_percent)
else:
self._left_motor.move(0)
self._right_motor.move(0)

rate.sleep()

def main():
driver = Driver()

# Run driver. This will block
driver.run()

if __name__ == '__main__':
main()


I get get the following error:

(classic)adeoduye@localhost:~/catkin_ws\$ rosrun simple_robot_navigation driver_node_controller
Traceback (most recent call last):
main()
NameError: name 'main' is not defined


BTW, it's ROS code which I have implemented in my custom catkin_ws/src/simple_robot_navigation package. I suspect it's a python issue but I very new at python and not sure how to fix it.

I would appreciate any help.

In the example code, the function main is defined as a function of the class Driver. However, as the actual code of main goes, it creates an instance of the class Driver and run it. So I think the function definition should be at the same indentation level as the class definition. What you need to do is to remove the indentation of the function definition of main. That is, remove four white spaces such that the function definition would be
def main():