a1tD0000003mESpIAM

Course: Graphical and Python programming using NAO
6: Do the Robot

  • 9-12 grade
  • Intermediate

Lesson Description:

In this lesson, students will learn how a computer/robot operates multi-tasking and create complex combinations of actions using behavior layers in Choregraphe.

Objective:
Make the robot walk and move with multitasking approach using:
Graphical programming (beginners) and Python (advanced).
 


 

Standards Covered

CCSS.ELA-LITERACY.RST.11-12.10

By the end of grade 12, read and comprehend science/technical texts in the grades 11-CCR text complexity band independently and proficiently.

CCSS.ELA-LITERACY.RST.11-12.3

Follow precisely a complex multistep procedure when carrying out experiments, taking measurements, or performing technical tasks; analyze the specific results based on explanations in the text.

CCSS.ELA-LITERACY.RST.11-12.8

Evaluate the hypotheses, data, analysis, and conclusions in a science or technical text, verifying the data when possible and corroborating or challenging conclusions with other sources of information.

CCSS.ELA-LITERACY.RST.11-12.9

Synthesize information from a range of sources (e.g., texts, experiments, simulations) into a coherent understanding of a process, phenomenon, or concept, resolving conflicting information when possible.

image description

Lesson Modules


Teaching Tips:

This module is an introduction to the concept of multi-tasking. Students can read for themselves. 

Multi-Tasking
 
We do many things simultaneously in our day-to-day life.  Chatting while walking, and eating while watching television are common examples. In computer science, this process is known as multi-tasking. A task is something that can be performed independently; multi-tasking is the process of performing many tasks in parallel.
 
Within each computer (and robot), there is a CPU that handles the processing of tasks. CPU stands for Central Processing Unit, and is where all the computational operations are processed in the computer.
 
How is multi-tasking done on a CPU? A CPU core can only execute one sequence of instructions at a time. One way to do multi-tasking is to use a multi-core CPU, so that multiple sequences of instructions can be executed concurrently.
 
But the NAO’s CPU has only a single core. Although only one sequence of program instructions can be executed at a time, the operating system is able to maintain an illusion of true concurrency. The different programs are split into threads. Threads are sequences of code to be executed. The operating system switches which thread is currently executing on the CPU thousands of times per second. This switching is faster than a human’s perception, and provides the illusion that all of the threads are executing simultaneously.
 
In the figure below, the operating system rapidly switches between three threads. As such, it appears as if all three threads are running in parallel. Notice that the amount of time each thread runs is not constant, and threads do not always run in the same order. The operating system decides when and how to switch between threads.
 



 
But we don’t need to worry about the underlying behavior of threads or the operating system on the NAO, since Choregraphe takes cares of this for us.
 
 
 


Teaching Tips:

You can download the code for this module here.

The code is a timeline box with the 4 layers of behavior as shown in the image. You can download the file, open it with Choregraphe and double click on t to show the layers.


Behavior Layers in Choregraphe
 
Behavior Layers are a feature in Choregraphe similar to threads. Each layer (or behavior) defines a separate thread that will run on the NAO. Some behaviors could be moving an arm, turning the head, saying something, or turning the LEDs on and off.

How would you create multiple layers in a timeline box in Choregraphe?

 
In the following exercises, we will show how to create behavior layers in Choregraphe to have the NAO do the robot dance.
 
 
 
 
 


Teaching Tips:

You can find the code for this module here .

A detailed step by step guide to the module is under CLASS VIEW.

In this lesson, we’ll learn how to use behavior layers on the NAO. Behavior layers allow the NAO to perform multiple tasks on the NAO at the same time. This is known as multi-tasking.

Basic Task: Arms and Head
 
In this lesson, we’ll learn how to use behavior layers on the NAO. Behavior layers allow the NAO to perform multiple tasks on the NAO at the same time. This is known as multi-tasking. Let’s implement the robot dance, and make the NAO move its arms up and down and shake its head at the same time.
 

1. In a new Choregraphe project, create a new “Timeline” box. 


2. Connect a Motor on box, Stand Up box, an Init Pose box, your new timline box, and a second Init Pose box, as shown below. The robot will stand up, go to its initial position, dance, and return to the initial position. Recall that you can open the Pose Library by clicking View -> Pose library in the top menu bar. 




 
3. Double click on your new timline box to edit it. Beneath the timeline and the word “Motion”, you will see the words “Behavior layers” with a plus sign next to it. Click the plus sign to add a new behavior layer. We will make this layer move the arms up and down.

4. Select the new layer, and add a custom timeline box. Connect it to the initial play arrow, and also connect it to itself. This causes the box to repeat forever. 

5. double click on the box and create using the simulated robot arm movements. At this point you need to store the position and make sure the movement stops at 115 frames.

6. Do the same procedure in another behavior layer for the head, creating "yes" and " no" head movements.

7. Play the behavior. The NAO should move its arms and shake its head, doing the robot dance. If the motions appear unstable, try reducing the frame rate. 

8. (Optional) Try experimenting with the frequencies of the different layers to find a combination that is visually pleasing. 
 
 


Teaching Tips:

You can download the code for this module here

The step by step guide for this code is under CLASS VIEW

Intermediate Task: Completing the Robot Dance
 
In the previous exercise, we finished the basic robot dance. Now we will add in leg motions, flashing lights, and speech.
 

1. First, add leg motions. As in the previous exercise, add a new behavior layer, Legs, with two keyframes. In one of the keyframes, make the robot squat, and in the second, make it stand up straighter. Be sure to only store angles for the legs in these keyframes 

2. Play the entire dance to make sure that the robot doesn’t fall over. If the robot does fall, try slowing down the rate of the squat motion, or make the robot stand up less tall. Changing the frequency of motion of the arm and head may also help. Make a dance that is stable and visually appealing. 

3. The beauty of using behavior layers is that you can change the speed of one aspect of the dance, while keeping the rest constant. Try changing the frequency of motion of the arm so that it matches the squats, and make the head bob at a different frequency.

4. We have finished with the dance motions. Add another layer for the NAO to speak. Place an infinitely repeating Say box in the layer, and have the robot say something of your choosing, such as “Nao.” You may also choose to add a Wait box to this layer, if you wish. Click the wrench on the Wait box to set how long the delay should be (in seconds) between saying words. The Wait box in NAO v6 is in programming tab, time folder

5. Now add the final behavior layer, which will control the LEDs. Place a bunch of loops with pairs of LED boxes, one to turn the LEDs on and one to turn them off. 

6. Click on the wrenches to set each box’s parameters. Choose an appropriate duration (in seconds), and make the intensity 100% in the first box and 0% in the second box. This will make the lights blink continuously. For the eye LEDs, you can double click on the boxes to select colors.




7. (Optional) Add another layer to play music of your choosing.

8. Now play the entire dance. It should include arm, head and leg motions, along with speech and flashing lights.


Teaching Tips:

You can find the code for this module here.

The step by step guide to programming for this module is under CLASS VIEW

The goal of the module is using Python to do something fancier, and have the NAO do part of the robot dance while walking in a circle. To do this, we will have the NAO use the omni-directional walk. We will record the odometry information as it walks to determine when we are finished.
 

Advanced Task: Walking in Circles
 
We have finished the robot dance. Now, let’s try doing something fancier, and have the NAO do part of the robot dance while walking in a circle. To do this, we will have the NAO use the omni-directional walk. We will record the odometry information as it walks to determine when we are finished.
 
1. First, remove the behavior layers for controlling the arms and the legs. The NAO cannot do these motions while walking stably. 





2. Next, add a new behavior layer for the walk. Create a new box in this layer, connected to both the start and end arrows. Double click on the box to edit the python code. We will be adding functions into the code, bit by bit. 





3. Before we begin editing and adding functions to the code, we need to import the relevant libraries. Add the following lines before the class MyClass line. 


 

4. The first function we will edit is__init__. 

 
 
__init__ is called only once (init stands for initialization), before the behavior starts executing. You have created a proxy to ALMotion in the past within the onInput_onStart function. The main difference here is that the variable name is self.motionProxy instead of just motionProxy. The addition of self. means that motionProxy is now a member variable of the class - it can be accessed in other functions.
 

5. Next, we will create a new function,simplifyAngle. 


 
The while structure is a loop, similar to a for loop. However, instead of iterating over some value, it repeats until the condition in the loop evaluates to false. So the first loop will continue subtracting 2pi  from theta until it is less than pi . Similarly, the second loop will continue adding  2pi  until  theta  is more than -pi . Thus, simplifyAngle normalizes  theta  (in radians) to between -pi  and pi .


6. We will now create another function, updateTheta. 


 
The updateTheta function computes how much we have rotated so far (also known as odometry). ALMotion’s function, getRobotPosition, returns the pose of the robot
(x, y, theta) in global coordinates based on where the NAO first started. Since we are only interested in the amount of rotation, we access the third element in the array (array indices start from 0, so we retrieve element [2]).
 
Also, we only want the change in position since the Circle box started, not since the robot started, and the second line maintains this information.
 
Finally, we return the amount of rotation since the Circle box started (theta), and the current global angle of the robot (nextTheta) - that is used for future calculations of updateTheta.
 
 
7. Lastly, we will edit the onInput_onStart function - this function is called when the box executes, which we have done in previous exercises. We will use this function to have the NAO walk in a complete circle and then stop walking. 
 


The first line calls setMoveArmsEnabled on ALMotion, which enables the swinging of the arms as the NAO walks. The swinging of the arms helps to keep the NAO balanced.
 
The next three lines initialize variables. globalTheta stores the global angle of the robot when the box starts executing; theta stores the rotation so far (0 since the robot hasn’t started walking yet); rotationSpeed is a value from -1 to 1 that controls how quickly the robot will rotate.

The
while loop continues executing until the odometry for theta exceeds  2pi , meaning that the circle is complete. Inside the loop, setWalkTargetVelocity is called to set the velocity of the NAO’s walk. The first 3 parameters are velocity in the x (forward), y (sideways, to the left), and theta  (rotation, counter-clockwise) directions. Since we want the robot to walk in an arc, the walk velocity is set to 0.5 in the forward direction and 0.25 in the rotational direction. This makes the robot walk in an arc, where it walks forward and rotates at the same time.
 
The time.sleep function puts the thread to sleep, so the CPU can focus on other tasks. Without this line, the robot would execute this loop as fast as possible, but this is unnecessary and a waste of processing time.

Finally, we set the walk velocity back to zero. This stops the robot’s walk once the circle is complete. Otherwise, the function would end but the robot would continue walking.



8. The behavior will currently stop when it reaches the red flag you placed on the timeline previously. Right click on the red flag, and select “Reset end frame.” Now the behavior will end when the robot finishes walking in a circle. 




9. Run the behavior. The robot should walk in a circle and stop.
WARNING: do not hit the red X button to stop the behavior. Otherwise, the robot may continue walking endlessly. If the NAO does walk endlessly, create a new project with a single Walk Toward box, and set the walk velocity in all directions (x, y and theta
 ) to 0.

10. Measure the odometry error at the end of the behavior. That is, how far does the robot’s final position differ from its initial position? 

11. Does the robot walk in a clockwise or counter-clockwise circle? Change the code so that the robot walks in the opposite direction.

12. Measure the radius of the circle the robot walked in. How can you change the radius of the circle that the NAO walks? Make the NAO walk in circles of radii 0.25 m and 1 m.

13. Look again at the simplifyAngle method. This algorithm works, but it is terribly inefficient. What will happen if a very large number is passed to the function? How many times will the loop repeat? In computer science, this algorithm is called  O(Ɵ)  (“big-O of theta”), meaning that the runtime increases linearly with  Ɵ. The simplifyAngle function can be written to be  O(1) , meaning the runtime does not depend on  Ɵ  and the algorithm always runs in constant time. Rewrite the simplifyAngle algorithm to be  O(1) . Your new function should not include any loops.

Hint: Use
int(number) to truncate (cut off the parts after the decimal) the number to an integer. So, int(1.2) = 1, int(2.0) = 2, and int(1.9999) = 1. 
 
 


Teaching Tips:

Additional Exercises
 
  1. Modify the robot dance so that the NAO only bobs its head up and down each time you touch the head sensors.
    Hint: add a Tactile Head box that links to the Head keyframe in the behavior layer.
  2. Make the NAO walk in a square (building off the earlier exercise) and perform a different combination of speech and/or motion as it traverses each edge of the square.
  3. Make the NAO walk in a figure eight while doing the robot dance (minus the arms).
Hint: Modify the advanced exercise to walk in a semicircle for the two ends of the figure eight. For the central crossovers, linearly interpolate the  Ɵ  in the walk velocity from the turning radial velocity to zero as the angle changes from 0 to 45 degrees. Once 45 degrees is reached, interpolate the radial velocity in the opposite direction until 0 degrees is reached again.
 
 

Teaching Tips:

Solutions
 
Basic:

  1. What does CPU stand for?
    Central Processing Unit.

     
  2. Explain, at a high level, how a single processor performs multi-tasking.
    The operating system executes one thread for a tiny slice of time, and then quickly switches to the next one to provide the illusion of true concurrency.

 
Intermediate:

  1. Explain the use for behavior layers.
    Behavior layers allow multiple behaviors using different body parts to be executed simultaneously in Choregraphe.

     
  2. Why does standing up straighter make the robot more susceptible to falling?
    Because the robot’s center of gravity is higher, a smaller tilt will make it leave the stable base region of the feet.

 
Advanced:

  1. Why did we need to use the simplifyAngle method when computing the odometry?
    To prevent wraparound issues. Let’s say that in one frame, the angle returned for the robot’s position is
      (pi) - 0.1 , and the next frame the robot rotates 0.2 radians. Then the new angle is -(pi) + 0.1 . Without the simplifyAngle method, we would calculate that in this frame, the robot turned nearly 2(pi) radians as opposed to the actual rotation of 0.2 radians. This makes quite a difference!
     
  2. Explain the use of the setWalkTargetVelcoity function.
    This sets a velocity - a direction and speed - for the robot to walk in. The velocity has x, y and rotational components. The robot continues to walk at this velocity until a new command is given.

     
  3. Why did we need to call time.sleep in the main loop?
    Otherwise the main loop will needlessly consume all the computation available, which is wasteful and prevents other important tasks from executing (such as the software making the robot walk).

     
  4. Why do we have to set the walk velocity to zero at the end of the loop?
    Otherwise the robot won’t stop walking.

     
  5. Using only division, multiplication, addition, subtraction, and integer truncation, compute the remainder of x / y in python. (This function, called modulus, is already implemented in python as the % operator. But do not use the % operator.)

    x - int(x / y) * y

     
  6. Find the big-O runtime cost of the following functions:
a. Searching for a name in a telephone book of n pages by:
i. Opening a page you bookmarked previously.
O(1)
 
ii. Beginning at the first page, and checking each page in order for the name.
O(n)
 
iii. Open the middle page, see if the name is to the left or the right, then open the middle of the remaining half of the book, and repeat until the name is found.
O(log n) . This algorithm is called binary search.
 
b. Enumerating every 5-card hand in a deck of n cards.
O(n5)

c. Finding the correct n-bit key to open a lock by trying every possible key (this is called a brute force attack in computer security).
O(2n)

d. Sorting a list of numbers by finding the lowest number of the entire list, placing it first, finding the next lowest number, placing it second, and so on. This is called selection sort.
O(2n) . There are faster sorting algorithms which are  O(n long n).

 

 

Questions
 
Basic:

What does CPU stand for?

Explain, at a high level, how a single processor performs multi-tasking.

 
Intermediate:

Explain the use for behavior layers.

Why does standing up straighter make the robot more susceptible to falling?

 
Advanced:

Why did we need to use the simplifyAngle method when computing the odometry?

Explain the use of the setWalkTargetVelocity function.

Why did we need to call time.sleep in the main loop?

Why do we have to set the walk velocity to zero at the end of the loop?

Using only division, multiplication, addition, subtraction, and integer truncation, write a function that finds the remainder of x / y. Note: this function, called modulus, is already implemented in python as %. But do not use %.

Find the big-O runtime cost of the following function: Searching for a name in a telephone book of n pages by: Opening a page you bookmarked previously.

Find the big-O runtime cost of the following function: Searching for a name in a telephone book of n pages by: Beginning at the first page, and checking each page in order for the name.

Find the big-O runtime cost of the following function: Searching for a name in a telephone book of n pages by:Open the middle page, see if the name is to the left or the right, then open the middle of the remaining half of the book, and repeat until the

Find the big-O runtime cost of the following function: Enumerating every 5-card hand in a deck of n cards.

Find the big-O runtime cost of the following function: Finding the correct n-bit key to open a lock by trying every possible key (this is called a brute force attack in computer security).

Find the big-O runtime cost of the following function: Sorting a list of numbers by finding the lowest number of the entire list, placing it first, finding the next lowest number, placing it second, and so on. This is called selection sort.