Learn 3: Create Your First Class

Site: GoLabs
Course: Robotic Challenges with Python and GoPiGo
Book: Learn 3: Create Your First Class
Printed by: Guest user
Date: Thursday, 21 November 2024, 6:37 PM

Description

This is the fifth challenge within the Robotics with GoPiGo and Python Curriculum.

Your task is to design a robot program to deliver a selection of mail to the residents of GoPiGo Drive, a small cul-de-sac containing 3 houses.

Learn how to how to use and calibrate the color sensor.

1. Variables: Global vs Local Scope

You may have noticed that we declared the relevant sensor instance variables as global within our test functions before using them. e.g.

def test_line_follower( ):
global line_follower

This allows the code within the function to interact safely with the globally scoped sensor instances that we created in the Sensor Setup Code cell. 

Any variable that is defined outside of a function definition is said to be  globally scoped. Variables that are defined within a function definition are said to be locally scoped (visible to that function only) unless we declare them as global by using the global keyword.

The interaction between local and global variables can become complicated so we're going to take an approach called defensive programming.

Defensive Programming: when you write code that is not really necessary but makes things more obvious to you as the programmer and to the computer too, in order to avoid bugs in the future. It's similar to looking both ways before crossing the street, even if you do not hear any car coming.

As for global and local scope, you can read this external in-depth tutorial if you want to know more about the interaction between the two scopes.


2. Creating a Variable Container Class

In previous missions we wrote code that was not contained within a function definition in the Main Code cell. This can see and use all globally scoped variables in the program.

In this mission we will be wrapping this code inside a main() function that we will trigger from a button click. This means that all globally scoped variables will have to be declared as global at the beginning of the function definition to be usable by our code. As we like to use a lot of variables this could get messy!

Objects can come to our rescue here. To make things simpler we can do the following:

      1. package all our variables up into a single globally scoped container class
      2. instantiate this class in the same way as the robot and sensors
      3. declare the container class instance as a single global variable in all our functions

 All our variables will then be accessible as class attributes from within the functions.


3. Variable Container Init()

Let’s show you how to do this with the simple test functions that you have written.

In the Variable Container Class cell we have created a basic class definition for you and called this our GlobalVariables class. It already contains some attribute definitions. These are attributes that will be set by the notebook’s template functions and buttons.

There is also an empty  __init__(self ) function definition. __init__(  ) is a special function, known as the constructor method. The code it contains is automatically run whenever an object of the class is instantiated. We do not need it but it's handy to see the print statement when we instantiate it.



4. Reset Method

To allow us to reset the courier’s state on demand, let’s also create a reset() function that performs the following functions

          • close its eyes
          • set the motor speed
          • clear the emergency stop flag
          • take an initial position reading from the line follower
def reset(self):
    courier.close_eyes()
    courier.set_speed(courier.DEFAULT_SPEED)
    self.emergency_stop_flag = 0
    self.position = line_follower.position_val()

Be certain that the indentation matches that of the init() method!!!

5. Init All the Things!

Let’s now create a basic class instance within our global init(  ) function (not the __init__() that is part of the GlobalVariables class)  a 

We do this by instantiating the container class

          • Find the Variable Initialization Cell
          • Add the following code.
          • Pay attention to indentation! (check against the image to be sure)

global var    
var = GlobalVariables()

You may have noticed that we haven’t passed the self argument to the GlobalVariables( ) class constructor function. self is a special class attribute. It references the current class instance. All class functions (or methods) use this as an implicit first argument. This means that you don’t need to state it when you call the function, it’s automatically added for you by the class definition. This makes the instance’s attributes and other methods accessible within the function definition.



6. Using your Container Class

To create a new container class and initialize all our variables all we need to do is call the init() function, exactly as we have done in previous missions.

As we will be controlling everything from a button panel in this mission, let’s call this init() function at the beginning of the Interactive Control Code cell.

That way we can be sure that the object (and the variables that it contains) will always be initialized immediately before the button panel appears.

We’ve already done this for you. Can you find the line in question? Turn Line Numbers on to be able to refer to it.


7. Next Step

You can move on to Courier Learn 4: Experiment With Color Sensing to learn more about the Color sensor,

Or you may go back to the main lesson : Autonomous Mail Courier.