Learn to program the Anki Cozmo robot with Python!
Note: It is highly recommended to have a printed or saved copy of this tutorial available before you start. Using the Cozmo requires you to connect to it over wifi, meaning your computer will no longer have access to the internet through your usual network connection.
Students of mine will be given this as a print out. You should check my website for any updates/changes @ https://pbaumgarten.com/myp-design/cozmo/
This unit assumes some existing knowledge of Python basics.
Last updated: 02/01/2020
|MYP item||This unit|
|Statement of inquiry||Robotic systems are a technical innovation where computers are capable of functioning in and adapting to a variety of physical environments.|
|Related concepts||Function, Adaptation|
|Global context||Scientific and technical innovation|
|Assessment objectives||A (inquiring & analysing), B (devising ideas), D (evaluating)|
12 lessons as follows:
The website for this unit is at https://pbaumgarten.com/myp-design/cozmo
This assumes you have a recent version of Python installed, typically at least version 3.6
If you don’t have it, go to https://wwww.python.org and download it.
When running the installer, make sure you turn on the option to “Add Python to PATH”
I have a video walk through of the process for installing Python and VS Code at
Once you have Python installed, open the command prompt and run the following
pip install pycozmo Pillow ImageToolsMadeEasy
If you get a permissions error with the above, try it again with the
--user switch as follows
pip install --user pycozmo Pillow ImageToolsMadeEasy
This guide assumes a basic familiarity with Python. I have written a quick recap designed for a one hour lesson should you need it. It is available at:
If you need a more detailed introduction to Python I have a set of detailed tutorials on my website. Each lesson contains detailed notes, videos and practice exercises. Each lesson is roughly an hour in length with 9 lessons in “the basics” (though only the first 5 are required for this tutorial).
A video walk through of the connection process is available on YouTube via the QR code or manually, at https://youtu.be/-k_oiQhBa5o. Alternatively, the steps are as follows…
VS Codeor your preferred Python editor. The following is a simple program to test your connection is working properly. It will cause the backlight on the cozmo to turn green for 1 second, then red for 1 second, then off.
# You will require these import statements for all Cozmo programs import time import math import pycozmo from PIL import Image import ImageTools # Connect to Cozmo cozmo = pycozmo.Client() cozmo.start() cozmo.connect() cozmo.wait_for_robot() # Do something simple cozmo.set_all_backpack_lights(pycozmo.lights.blue_light) time.sleep(1) cozmo.set_all_backpack_lights(pycozmo.lights.red_light) time.sleep(1) cozmo.set_all_backpack_lights(pycozmo.lights.off_light) # Disconnect from Cozmo cozmo.disconnect() cozmo.stop()
The following demonstrate some of the commands you can use to control different features of the Cozmo.
# The multicolor LED on the back of the Cozmo cozmo.set_all_backpack_lights(pycozmo.lights.red_light) cozmo.set_all_backpack_lights(pycozmo.lights.green_light) cozmo.set_all_backpack_lights(pycozmo.lights.blue_light) cozmo.set_all_backpack_lights(pycozmo.lights.white_light) cozmo.set_all_backpack_lights(pycozmo.lights.off_light) # Front facing head light cozmo.set_head_light(True) # Turn on cozmo.set_head_light(False) # Turn off
# Drive forward at speed 50 cozmo.drive_wheels(lwheel_speed=50.0, rwheel_speed=50.0) # Drive forward at speed 50 for 5 seconds then stop cozmo.drive_wheels(lwheel_speed=50.0, rwheel_speed=50.0, duration=5.0) # Drive the right wheel (making the robot veer left) # for 2.5 seconds cozmo.drive_wheels(rwheel_speed=50.0, duration=2.5) # Drive the left wheel forward, right wheel in reverse # (making the robot veer right) ... notice the minus sign! cozmo.drive_wheels(lwheel_forward=50.0, rwheel_speed=-50.0) # Drive in reverse at speed 50 (notice the minus signs!) cozmo.drive_wheels(lwheel_speed=-50.0, rwheel_speed=-50.0) # All stop cozmo.stop_all_motors()
Tilt head up/down
# === Move Cozmo's head === # Cozmo's head should move in a range from -25 degrees (facing down) to +44 degrees (up). # Python expects the angle to be in radians so it needs converting from degrees. # The angle can be provided as a variable or a number. angle = 0 cozmo.set_head_angle(math.radians(angle))
Raise/lower lifting arm
# === Move Cozmo's lifting arm === # Cozmo's lifting arm can move in a range from 32mm (fully lowered) to 92mm (fully raised) # Height can be provided as a variable or a number. height = 90 cozmo.set_lift_height(height)
Using a combination of the above commands, can you make your Cozmo…
Cozmo has sensors built in through which it can detect different situations and events. The following command
add_handler tells Cozmo that if a particular event occurs, there is a function we have written to handle it. In this case, the event is if a cliff edge is detected, and the handling function is specified in the 2nd parameter as being called
… which could look like this when added to a full program …
# ... remmeber to add your import statements first ... # Connect to Cozmo cozmo = pycozmo.Client() cozmo.start() cozmo.connect() cozmo.wait_for_robot() # Add cliff detection cozmo.add_handler(pycozmo.event.EvtCliffDetectedChange, on_cliff_detected) # Start moving cozmo.drive_wheels(lwheel_speed=50.0, rwheel_speed=50.0) # Run for 60 seconds for second in range(60): time.sleep(1) # Disconnect from Cozmo cozmo.disconnect() cozmo.stop()
So if our main section is going to tell Cozmo to run the
on_cliff_detected function, we need to ensure it actually exists. Here is an example of what it could look like. You can modify yours to do something different.
def on_cliff_detected(cozmo, state): if state: print("Cliff detected.") # Reverse straight back cozmo.drive_wheels(lwheel_speed=-50.0, rwheel_speed=-50.0, duration=1.0) # Reversing turn cozmo.drive_wheels(lwheel_speed=0.0, rwheel_speed=-50.0, duration=2.8) # Drive forward cozmo.drive_wheels(lwheel_speed=50.0, rwheel_speed=50.0)
There are other handlers you should know about. In addition to detecting a cliff edge, the Cozmo can also detect when the button on it’s top is pressed, or when you pick it up. Examples of how these work follow…
Detect pressing the button on top of Cozmo…
# This handler will trigger when the button on top of Cozmo is pressed cozmo.conn.add_handler(pycozmo.protocol_encoder.ButtonPressed, on_button_pressed) # Example handler function for button press def on_button_pressed(cozmo, state): if state.pressed: print("Button pressed.") cozmo.drive_wheels(lwheel_speed=50.0, rwheel_speed=50.0)
Detect when Cozmo is picked up…
# This handler will trigger when the robot is picked up cozmo.add_handler(pycozmo.event.EvtRobotPickedUpChange, on_robot_picked_up) # Example handler function for picked up def on_robot_picked_up(cozmo, state): if state: ## state is set to True if picked up print("Picked up.") cozmo.stop_all_motors()
Your Cozmo has a camera. Admittedly the resolution isn’t great, but at least getting it to work is easy enough. After we enable the camera, we then create another event handler to process the content of the image we receive.
# Setup the camera cozmo.conn.send(pycozmo.protocol_encoder.EnableCamera(enable=True)) cozmo.conn.send(pycozmo.protocol_encoder.EnableColorImages(enable=True)) # Instruct the camera to take a photo cozmo.add_handler(pycozmo.event.EvtNewRawCameraImage, process_photo, one_shot=True)
An example event handling function could look like…
def process_photo(cozmo, image): import uuid # additional import required filename = str(uuid.uuid1()) + ".jpg" # generate a unique filename image.save(filename, "JPG") # save the image as JPG to your project folder image.show() # open the image to view on screen
one_shot=Trueparameter. When set to
Trueit will trigger the camera to take just one photo. When set to
Falseit will take photos continually (about 15 per second)
cozmo.add_handler()command does not have to appear with the camera setup commands. It could be placed in the function that handles another event such as a cliff or the button.
While the view from the Cozmo camera might be nice, it also has a practical purpose. We can use vision recognition systems to recognise what the Cozmo can see and behave accordingly.
For this exercise we are going to keep it simple and use some ArUco Markers. Think of ArUco as mini-QR-codes. They are a 2D black and white block code that are very easy for the vision system to recognise and decode. There are a couple of different versions, but the one we are using will create 4x4 black and white grids that Python will recognise as being a number between 0 and 999. This ArUco represents the number 50.
You will need to print your own ArUco labels. You can generate them from this website http://chev.me/arucogen/ (keep the “dictionary” setting on 4x4). From my trials a marker of 50mm was detectable by the Cozmo at a distance of approximately 50cm. You will have to experiment with the sizes you need based on the range you want it to recognise the code.
def process_photo(cozmo, image): # Use the ImageTools.get_aruco() function to decode any arUco markers in the image markers = ImageTools.get_aruco(image) if 70 in markers: print("I saw ArUco marker 70") if 71 in markers: print("I saw ArUco marker 71") if 72 in markers: print("I saw ArUco marker 72") cozmo = pycozmo.Client() cozmo.start() cozmo.connect() cozmo.wait_for_robot() # Look straight ahead cozmo.set_head_angle(0.0) # Take photos continually. Run the process_photo() function on each image. cozmo.conn.send(pycozmo.protocol_encoder.EnableCamera(enable=True)) cozmo.conn.send(pycozmo.protocol_encoder.EnableColorImages(enable=True)) cozmo.add_handler(pycozmo.event.EvtNewRawCameraImage, process_photo, one_shot=False) # Loop for 60 seconds stop_at = time.time() + 60 while time.time() < stop_at: time.sleep(0.1) print("Time's up, quitting...") cozmo.disconnect() cozmo.stop()
Make a new copy of your table-top driving code. We’re going to experiment with using Cozmo to detect ArUco markers that change it’s behaviour.
By now you have experimented with quite a few features of the Cozmo. Design an obstacle course that you will build for the Cozmo to self navigate from point A to point B.
Create planning drawings for your obstacle course and include those in your portfolio for lesson 7. You want to strike the balance between making a complex yet achievable obstacle course. You should work on the basis of having 3 lessons for physically building the course and programming the Cozmo.
Show your obstacle course ideas to your teacher for approval before proceeding.
Create your obstacle course (~1 lesson) and program your Cozmo to complete it (~2 lessons).
How long does it take your cozmo to capture the flag?
Make a video recording demonstrating the success (complete or partial) of your Cozmo robot…
Upload your video to your portfolio.