TDDD63 Project: Humanoids Version 2.0 Jon Dybeck (jondy276) Carl Ehrenstråhle (careh585) Erik Hansson (eriha172) Fredrik Heintz (fredrik.heintz@liu.se) September 19, 2014 Contents Project overview 1. Introduction . . . . . . . . . 2. Background . . . . . . . . . 3. The Nao robot . . . . . . . 4. Overview of RosBots . . . . 5. Handling Nao and guidelines . . . . . . . . for . . . . . . . . the . . . . . . . . . . . . lab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 6 7 7 Configuration and installation 10 1. Configuring the tools . . . . . . . . . . . . . . . . . . . . . . . . 10 2. Installing RosBots . . . . . . . . . . . . . . . . . . . . . . . . . 10 3. Updating RosBots . . . . . . . . . . . . . . . . . . . . . . . . . 11 Assignments Introduction . . . . . . . . . . . . . . . . . . . . . . . 1. Intro Phase: Assignment One – Hello world! . . . . . Purpose . . . . . . . . . . . . . . . . . . . . . Tasks . . . . . . . . . . . . . . . . . . . . . . . Examination . . . . . . . . . . . . . . . . . . . 1.1. Milestone One – Stand and sit in simulation . 1.2. Milestone Two – "Hello world!", says Nao . . . 1.3. Milestone Three – Wait for touch . . . . . . . 2. Intro Phase: Assignment Two – Basic skills . . . . . . Purpose . . . . . . . . . . . . . . . . . . . . . Task . . . . . . . . . . . . . . . . . . . . . . . Examination . . . . . . . . . . . . . . . . . . . 2.1. Milestone One – Walking . . . . . . . . . . . . 2.2. Milestone Two – Turning the head . . . . . . . 2.3. Milestone Three – Using the camera . . . . . . 2.4. Milestone Four – Finding and tracking the ball 2.5. Milestone Five – Following the ball . . . . . . 3. Main Phase: Assignment Three – Playing soccer . . . Purpose . . . . . . . . . . . . . . . . . . . . . 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 12 13 13 14 14 14 17 20 22 22 22 22 23 23 23 24 24 25 25 Task . . . . . . . . . . . . . . . . . . . Examination . . . . . . . . . . . . . . . 3.1. Milestone One – Kicking the ball . . . 3.2. Milestone Two – Finding the goal . . . 3.3. Milestone Three – Aligning the robot . 3.4. Milestone Four – Scoring a goal . . . . 4. Main Phase: Assignment Four – Co-operation Purpose . . . . . . . . . . . . . . . . . Task . . . . . . . . . . . . . . . . . . . Examination . . . . . . . . . . . . . . . 4.1. Milestone One – Send messages . . . . 4.2. Milestone Two – Wait for clearance . . 4.3. Milestone Three – Pass the ball . . . . 4.4. Milestone Four (optional) – Cross pass 5. Main Phase: Assignment Five – Elective task Purpose . . . . . . . . . . . . . . . . . Task . . . . . . . . . . . . . . . . . . . Examination . . . . . . . . . . . . . . . 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 25 25 26 26 26 26 26 26 27 27 27 28 28 28 28 28 29 Project overview 1. Introduction The goal of this project is to get hands on experience with programming humanoid robots. Your particular task is to program the Nao humanoid robot to play soccer. To achieve this you have to implement both relatively simple behaviors, such as finding and kicking the ball, and more complex behaviors, such as scoring a goal. However, programming a humanoid robot to play soccer from scratch is a huge task. Therefore, you will work with a system called RosBots, which provides a high level Python interface for programming Nao. Moreover, you will get detailed instructions on how to get started with RosBots and the assignments will lead you trough the basic behaviors for playing football. However, you still have to put in a lot of time and effort into the project for it to be successful. The examination of the project is to complete all the assignments described in this project description on time. This includes writing a short report describing your final assignment, where you decide what you want to do. 3 2. Background Figure .1: The goalkeeper of team Bembelbots (top left), picture from RoboCup official webpage (top right) and screenshot from the simulation league of RoboCup (bottom). The history of robots playing soccer dates back to 1992. At that time it was mainly a subject of some papers, workshops on challenges in artificial intelligence and discussions. However, this led to the start of RoboCup, which is an international robot soccer competition held every year starting in 1997 in Japan. Sony CSL has more information about the history of RoboCup and some of the original papers on their website if you are interested in reading more (http://www.sonycsl.co.jp/person/kitano/ RoboCup/RoboCup-old.html). RoboCup has many different leagues, such as the simulation league, the 4 small size league, the standard platform league and the kid size humanoid league. In the simulation league teams of 11 simulated robots and 1 simulated coach compete against each other, while the other leagues consists of teams of real robots. The Nao humanoid robot, that we use in this course, is currently the robot used in the standard platform league (SPL). A standard platform ensures that all teams compete in the league on the same terms when it comes to hardware. Hence, it is the software developed by the different teams that decides the winner. A game in the standard platform league takes 20 minutes, 2 × 10 minutes. The game is played on a soccer field that is 10.4m × 7.4m, with two goals of the same colour and an orange street hockey ball. For more information see the SPL home page (http://www.tzi.de/spl) and the SPL rules (http: //www.tzi.de/spl/pub/Website/Downloads/Rules2014.pdf). As the interest for RoboCup and robots in general has increased, more and more types of competitions have been introduced. For example, there is now competitions in rescue and dance. The main goal of RoboCup is to beat the FIFA (human) world champions in soccer by 2050. Of course, this has to be done on human terms, which means that the robots are limited to humanoids that may not harm people and with human-like sensors. To achieve this, many breakthroughs are required. For example, the robots need significantly better hardware that makes them faster and more robust while still being safe to play against. They also need better software to control the actuators and sensors on the robots, implement behaviors such as dribbling like Maradonna or Messi and making the right decisions at the right time. More information about RoboCup can be found at their website: http: //www.robocup.org/. 5 3. The Nao robot Figure .2: The Nao humanoid robot with its sensors and actuators. In this project you work with a robot called Nao, developed by the French company Aldebaran Robotics (http://www.aldebaran-robotics. com/en/). It is a humanoid robot with 25 degrees of freedom (DOF). DOF is a measurement of independent motions, for example a robot with one joint that can turn in one direction has one DOF. For the Nao, the 25 DOF are in the form of 25 motors and actuators. In addition, it has several sensors: Two cameras, four microphones, a sonar range finder, two infrared (IR) emitters and receivers, one inertial measurement unit (IMU) and nine tactile sensors. Furthermore, it is fitted with eight high-fidelity speakers and several LEDs. The Nao is equipped with an Intel ATOM 1.6 GHz CPU that runs a 6 Linux kernel and controls the mechanical hardware. It also has a middleware called NAOqi developed by Aldebaran Robotics. it provides a lot of predefined functionality and the possibility for users to add their own modules to NAOqi. However, one drawback is that the predefined functions are not always optimized. Therefore, the teams which competes with Nao have implemented their own versions of, for example, walk engines, predefined motions and image processing. However, this functionality still uses the NAOqi to control each joint and to fetch data from the sensors. The technical documentation for Nao can be downloaded from Aldebarans website (http://www.aldebaran-robotics.com/Downloads/Download-document/ 192-Datasheet-NAO-Humanoid.html). 4. Overview of RosBots RosBots is a software system developed at Linköpings University. It consists of a finite state machine (hereafter referred to as FSM) module, a functional wrapper around NAOqi, and a ROS layer which provides communication between different parts of the system, called nodes in ROS. Some parts of the ROS layer is open source code provided by the University of Freiburg. Furthermore, RosBots also has a communication layer between the FSM module and the ROS layer. In this project you only have to work with the FSM module. However, You are allowed to work with the other layers later in the project as well, but you must consult an assistant or supervisor before testing the code on the robts. Furthermore, we encourage you to share good modifications that you write by sending a pull request to the RosBots bitbucket repository (https://bitbucket.org/jondy276/rosbots). See http://githup-scm. com for more information about how to send one. You can read more about RosBots in the documentation (RosBots documentation). You are also welcome to ask an assistant if you have any questions regarding the project. 5. Handling Nao and guidelines for the lab There are, to avoid any unnecessary damages to the robot, rules for how to handle the Nao humanoid robot in the lab. • You should under no circumstances run any code on the robot unless someone is on the field and is prepared to catch the robot in case something happens. 7 • When you are lifting the robot you should have a firm grip around its waist with both your hands (see the picture below). • Always test your code in the simulator before you try it on the real robot. Note that all the functionality of the robot doesn’t work in the simulator. However, this doesn’t mean that you shouldn’t try it on the simulator first since the other parts will be tested. • Never run experimental code that is not using the RosBots system without consulting an assistant or supervisor in advance. • Use a new robot if the one you are using runs out of battery. If there is no other robot you will have to change battery by following the instructions at the table. • Do not leave the robots on the floor unsupervised. • Contact an assistant or supervisor immediately and mark the robot if something has broken on the robot. Figure .3: How to hold the Nao robot (left), Nao in sitting position (right) In addition to the rules for how to handle the Nao humanoid robot there are a few guidelines for the lab: • You should never wear shoes in the lab. We want to keep it as clean 8 as possible! • The computers in the lab is under the same rules as the rest of the computers at the university. This means that you are, for example, not allowed to play games on them. • Share the robots between each other in a fair way since there is a limited number of robots available. 9 Configuration and installation 1. Configuring the tools Before you can start on the first assignment you have to configure your account on the workstation in the lab. It does not matter which computer you use the first time since they are more or less the same. However, the accounts are individual on all the computers and therefore, you will be forced to install RosBots again and remake your configurations to the new workstation if you switch later on. After you have logged in to one of the workstations we strongly recommend that you configure the tools you will use. You are free to use all the programs that are installed and we will not require that you use a certain configuration. However, we strongly recommend that you use a configuration that will help you to keep tab on the length of your lines in your code since you should follow the standard for Python, pep 8. This includes a maximum of 80 characters per line, see below for instructions on how to show to long lines in Emacs. Furthermore, we recommend that you configure the indentation, according to pep 8, to four spaces. This saves you the trouble of having different indentation when writing code with others and on different computers. Moreover, it will make sure that you will not get any problems in the case that one of the assistants decides to test your code on their own accounts. The following three lines can be written to the the .emacs file in your home folder to graphically display the lines that are longer than 80 character as well as show unnecessary white spaces and tab characters. ( require ’ whitespace ) ( setq w h i t e s p a c e - s t y l e ’( face empty tabs lines-tail trailing )) ( global-whitespace-mode t) Lastly, in the project you are required to use SVN to store your code. Instructions for how to use SVN can be found at the course website. 2. Installing RosBots RosBots, unlike the rest of the programs that you will use, is not installed on the workstations. Therefore, you have to install it manually. This is done in two steps: First, download the source code. Second, run the RosBots 10 installation script. The script sets up all the required system variables for the programs that RosBots use (e.g. Python and ROS) and compiles the RosBots code. To download the RosBots source code you have to use git since it is stored in a git repository. The following two steps describes how you download the code. First, open a terminal and change directories to the folder where you want to store RosBots (it will be stored in a newly created folder called ’rosbots’ in your current directory). Second, run the command: git clone https://bitbucket.org/jondy276/rosbots. You should now have the source code stored in the folder of your choice. The next step after downloading the source code is to install RosBots. This is done by moving to the folder rosbots/scripts and executing the script rosbots_installation. Finally, you have to source your .bashrc file, alternatively restart the shell, to initialize the variables in the shell before RosBots is ready for use. 3. Updating RosBots It is higly likely that RosBots will be updated during the course. However, do not worry about having to check for updates. If an update is released you will be notified trough one of the assistants. However, you will have to install the update on your own. This is done by opening a terminal and move to the rosbots folder or any of its sub folders. Thereafter, run the command git pull, which will fetch all the updates to the source code. To compile the new source code run the command rosbots_update. Note that this command only works if you have installed RosBots before. When the command is finished, RosBots will be updated. Note that if you have modified the RosBots source code by your own you will have to run the update command as well. Furthermore, there is a small risk that you can encounter so called merge errors (see http://git-scm.com for more information) when you fetch the latest update if you have modified the files that have been updated. 11 Assignments Introduction The project consist of two phases, the introductory phase and the main phase. The introductory phase consists of two assignments and should be finished by the end of the first period. The main phase consists of three assignments and should be finished by the end of the course. You should separate your code for each assignment in different folders in your SVN repository. This should be done so that the assistants and the supervisor easily can see which files that is used for each assignment. However, this does not mean that you should rewrite the code but that you should copy your old code that you will use again. We recommended that you do the assignments in the order they are presented since they build upon previous assignments in most cases. This allows you to reuse the code that you developed in previous assignments. Furthermore, we strongly suggest that you follow the time schedule below so that you will be finished on time. Assignment Intro phase: Assignment 1 Intro phase: Assignment 2 Main phase: Assignment 3 Main phase: Assignment 4 Main phase: Assignment 5 Main phase: Technical report Expected week for completion week 42 week 44 week 46 week 48 week 50 week 51 Table .1: Project time schedule The instructions to all the assignments are presented in the same way as this introduction, i.e. an introduction and then the following subsections. Purpose A short description of what you are supposed to learn from the assignment and a very brief description on how it will be learned. Task A description on what you are supposed to do in the assignment. 12 Examination A detailed description on what you have to do to pass the assignment. Milestone(s) A detailed description for every milestone of an assignment. 1. Intro Phase: Assignment One – Hello world! In this assignment you will learn how you use the RosBots system to program Nao. Since this is the first assignment, you get highly detailed descriptions on how to complete each milestone. However, keep in mind that you will not get equally detailed descriptions in the other assignments. Before we explain the assignment we start with a short description of what a simulator is and which one we use in this project. A simulator, which you can derive from its name, simulates something. In our case, it simulates the Nao humanoid robot in an environment that is similar to the lab. The simulator used in the lab is called Webots and uses a physics engine called ODE to simulate Nao in its environment. The physics engine simulates the laws of physics and the effect of those on the simulated objects. Furthermore, Webots launches a version of NAOqi that runs locally on the workstation as part of the simulation. It works in the same way as the one which runs on the real robots which allows us to run the same code in the simulator as on the robot. However, instead of sending commands to the servos and fetching data from the sensors this version communicates with the physics engine to send commands and fetch sensor values. When using a simulator you should always be aware of the fact that it is a simulation. That means that the simulator will not behave exactly as in the real world. For example, the physics engine in Webots do not behave exactly as the physical laws of the real world. Hence, you will not get exactly the same sensor data in the simulation as in the real world. Furthermore, the robot might behave slightly different due to the fact that some part of the robot might be slightly worn while the simulated robot stays in perfect condition. Therefore, the simulation can be used for coarse adjustments and to make sure that the code will not hurt the robot while fine tuning is done on the real robot. Purpose The purpose of this assignment is that you should learn the basics of programming the Nao humanoid robot. Through the assignment you will be guided on how to use the Nao, RosBots and other related software. 13 Tasks Your task is to complete the three milestones of the assignment. This includes simulating simple motions in the simulator, Webots, and using the same code to run your first program on the robot. Finally, you have to read data from the sensors and access it through the world model module which contains all the robot’s information about the world. Examination To pass this assignment you have to: 1. Complete all the milestones. 2. Demonstrate your programs for each of the milestones of the assignment to an assistant. 3. Demonstrate an understanding of the code and the system by individually answering questions regarding your code. 1.1. Milestone One – Stand and sit in simulation The first milestone of the assignment is to run an FSM in the simulator. This involves three steps: 1. Create a state diagram. 2. Write the code for the FSM. 3. Run the code on the simulated robot. It is important to create a state diagram before implementing the FSM in code because it allows you to find errors in the FSM, before you have written large amounts of code. Furthermore, it also helps you to spawn ideas on how the robot should behave to complete it’s task. In this case you will not have to draw one since it is already drawn, see figure .1. However, do not forget to draw one for each future FSM that does not have a pre-drawn diagram. Your task in this milestone, is to create a FSM that makes the robot stand, then sit and lastly relax its actuators before it shutdown. You need four states to create an FSM that does this: One for standing up, one for sitting down, one for relaxing, and one for terminating the FSM. It is worth mentioning that the robot will start in a standing position in the simulator. However, the real robot starts in a sitting position. Since the purpose of simulating a robot is to test it before trying it in the real world, you should make the robot stand. 14 Figure .1: State diagram describing the stand and sit program. 1.1.1. Writing the program The FSM module (fsm.functions) contains all the functions you need to create an FSM using RosBots. Descriptions of the functions in the module can be found in the RosBots documentation. However, these doesn’t include the primitives that you will use in the states. The primitives can be found in the public API provided by RosBots (api.pubapi). For the FSM that makes the robot first stand and then sit before it relaxes and shutdowns we need the following imports: # Import the FSM functions from fsm . functions import ( createState , createFSM , addTransition , addStates , setInitialState , setMainFSM ) # Import primitive robot behaviors from api . pubapi import sit , stand , rest , shutdown As you can see we chose to only import the functions that we need for our FSM. This is something that always should be done when programming due to two major reasons. Firstly, it protects us from importing anything that we do not need at the time of writing. Secondly, it protects us from future changes in the module. These changes could include something that has the same name as one of our variables in our program and therefore, cause problem if we used a wild import (from someModule import * - wild import in Python). The next part of writing an FSM with RosBots is to create the states. This is done by calling the function createState with a name as the first argument and a function as the second argument. There is one limitation to the function that is given as an argument, it can only have the world model or nothing as a parameter. The reason is that RosBots will call the function during run-time with either the world model or nothing as arguments. Since we need to have a function as the second argument we can not directly use primitives that require an argument except the world model. For example, in the state shutdownState below we want to use the primitive shutdown. However, shutdown takes an argument, the reason for the system to shutdown, and therefore, we can not use the primitive as the function in shutdownState. To solve this we use an anonymous function (the key15 word lambda in python) that wraps the shutdown function with the wanted arguments. Hence, when the anonymous function is called, it will call the shutdown function with our wanted argument. We do not have to use an anonymous function to wrap our wanted primitive. Instead, we could declare a function outside the state that we give as the second argument to createState. This will become needed in future assignments but now it is only unnecessary. As you might have noticed, defining your own function allows you to define a function that returns different primitives depending on some conditions, sensor data for example. However, this should not be done even if it is possible. There are two main reasons for this. Firstly, the code becomes harder to understand and the diagram will not be able to describe the FSM. Secondly, in a FSM a state should only be able to execute a single primitive, the arguments to the primitive might vary depending on the world model but never the primitive itself. An allowed exception in this course is that a state is allowed to either execute a primitive or do nothing. # Create states sitState = createState ( " sitState " , sit ) standState = createState ( " standState " , stand ) restState = createState ( " restState " , rest ) shutdownState = createState ( " shutdownState " , lambda : shutdown ( " Final ␣ state ␣ reached " )) After we have created the states that we have in our FSM we need to add the transitions that connects the states. A transition has an originating state, a destination state and a condition to when the transition should happen. Transitions is added between the states in RosBots by using the function addTransition. The function has the following arguments: The origination state, a function which evaluates to a True or False value and the destination state. In the FSM that we are writing we will need the following transitions. # Add transitions between states addTransition ( standState , lambda wm : True , sitState ) addTransition ( sitState , lambda wm : True , restState ) addTransition ( restState , lambda wm : True , shutdownState ) The only thing that is left when we have created the states and the transitions is to create the FSM. This is done by calling createFSM with the name of the FSM as an argument. When we have created the FSM we need to add the states to the FSM which we do with the function addStates. The function takes an unlimited amount of arguments. However, the first argument must be the FSM that we want to add the states to and the rest of the arguments are the states that we want to add to the FSM. Lastly, we have to tell the 16 FSM which state is its initial state which we do with setInitialState where the first argument is the FSM and the second argument is the initial state. # Create the FSM and add the states created above myFSM = createFSM ( " myFSM " ) addStates ( myFSM , standState , sitState , restState , shutdownState ) # Set the initial state to standState s et In i ti al S ta t e ( myFSM , standState ) 1.1.2. Running the program Before we launch the FSM that we just have written in the simulator we can call a program which tests our code so that it creates a correctly written FSM. This is something that is strongly recommended to do since debugging from running the code on the simulator or on the robot results in a less tidy debugging information. To test the code, use the program fsm_syntax_check with the path to you program as command line arguments. For example: $ f s m _ s y n t a x _ c h e c k helloWorld . py When you receive a message that your code does not contain any errors you are ready to run the code in the simulator. To do this you execute the script run_simulation. The script takes up to four arguments with the following syntax: $ run_si mulati on <{ first , second , third , fourth } >= < path to the program > Note: The script will launch different worlds depending on how many robots you wish to simulate. However, it does not allow simulation of more than four robots. As an example, to run a program called helloworld.py located in your home directory on the first simulated robot assuming your user name is "user" would be (on a Linux system): $ run_si mulati on first =/ home / user / helloworld . py To run two different programs, called helloworld.py respectively standandsit.py in the home directory of the same account, on two robots while standing in that directory would be done with the following command: $ run_si mulati on first = helloworld . py second = standandsit . py 1.2. Milestone Two – "Hello world!", says Nao In this milestone you will extend your program from milestone one to make the robot say "Hello world" after it has stood up. To do this you need to add one more state to the FSM. Thereafter, you should run your code in the 17 simulator before you run it on the robot. However, do not worry about the lack of sound, Webots does not support sound. Figure .2: State diagram describing the hello world program. 1.2.1. Writing the program To write this code we follw the same principle as for the previous milestone. Firstly, you need to import the FSM functions and the robot primitives. These are the same as in the previous milestone, with the addition of the new primitive say. This primitive is a text-to-speech function that is included in the NAOqi. The say can either be used as a blocking primitive or a non-blocking primitive. A blocking primitive means that the FSM will wait until the primitive is executed on the robot and a non-blocking that it will continue. Normally, the blocking primitives are those that needs to be fully executed before something else can be done, for example sit and stand. However, the say is sometimes wanted to be executed while doing something else and sometimes you will want to wait. By default it will be a blocking primitive and you have to set the parameter isPost to True if you want it to be a non-blocking primitive. # Import the FSM functions from fsm . functions import ( createState , createFSM , addTransition , addStates , setInitialState , setMainFSM ) # Import primitive robot behaviors from api . pubapi import sit , stand , rest , say , shutdown As in the previous milestone we need to create the states for standing, sitting, relaxing and shutting down. # Create states for standing , sitting and resting sitState = createState ( " sitState " , sit ) standState = createState ( " standState " , stand ) restState = createState ( " restState " , rest ) 18 # Create a state which shuts down the FSM shutdownState = createState ( " shutdownState " , lambda : shutdown ( " Final ␣ state ␣ reached " )) The say primitive is like the shutdown primitive in the sense that it has a parameter which is not the world model. To solve this we use the same method as we used for the shutdown. # Create a state which commands the robot to say " Hello World !" sayState = createState ( " sayState " , lambda : say ( " Hello ␣ World " )) With all the states created we add the transitions just like in the previous milestone but do not forget to adapt so that the say primitive is added. # Add transitions according to the state diagram . # Each transition takes place as soon as possible . addTransition ( standState , lambda wm : True , sayState ) addTransition ( sayState , lambda wm : True , sitState ) addTransition ( sitState , lambda wm : True , restState ) addTransition ( restState , lambda wm : True , shutdownState ) The creation of the FSM is done in the same way as well, with the addition of the say primitive. # Create the FSM and add the states created above myFSM = createFSM ( " fsm " ) addStates ( myFSM , standState , sayState , sitState , restState , shutdownState ) # Set the initial state to standState s et In i ti al S ta t e ( myFSM , standState ) 1.2.2. Running the program As in the previous assignment we can check the FSM by using the fsm_syntax_check program before we test it in the simulator with the run_simulation script. When we have tried it in the simulation we can run the FSM on a robot. Firstly, find an unused robot, move it to the soccer field and place it in a sitting position. Thereafter, the FSM can be run with the run_robot script by typing the following in a shell. $ run_robot < robotname >= < path_to_FSM > You can find the name of the robot printed on the back of it. The names of all our robots are: • goliath • piff • puff 19 • david For example, running a program called helloworld.py located in your home directory on piff would look like this for user "user" (on a Linux based system): \ indent run_robot piff =/ home / user / helloworld . py 1.3. Milestone Three – Wait for touch In this milestone you will extend your program to make the robot wait until its middle tactile sensor is touched before it stands. Furthermore, the robot should wait with sitting down until its middle tactile sensor has been touched again. Moreover, it should say "goodbye" before it sits down. This requires that you add some more states to your FSM, see the diagram below. Figure .3: State diagram describing the touch program. The text on the arrows describes the condition for the transition. As you might have noticed, none of the previous figures have had any text on the arrows. That is because the lack of text indicates the condition is always True. 1.3.1. Writing the code To implement these extensions you need to add a few states and change some of the transitions used in the previous milestone. However, the major new 20 thing is that the program requires information from the robot. All information that the robot has about itself and its surrounding is located in the world model. To access this information you need the function readWM located in the fsm.functions module. Therefore, you have to update the imports to the following: # Import the FSM functions from fsm . functions import ( addStates , addTransition , setInitialState , setMainFSM , createState , createFSM , readWM ) # Import primitive robot behaviors from api . pubapi import sit , stand , rest , say , shutdown Now that you can access the world model, you need to create a function which detects touch so that it can be used in the transitions: # Define the event function which detects touch def detectTouch ( wm ): return readWM ( wm , " tactile " , " middle " ) The function readWM takes as arguments world model (wm) and any number of keys. These keys identify what data to fetch from the world model. Use the key "tactile" and "middle" to access the middle tactile sensor. This key has two possible return values, True and False, where True indicates that the middle tactile sensor is touched and False that it is not. A description of all the data in the world model and their keys can be found in the documentation for the world model (see the RosBots documentation). Note: It is easy to modify the code to accept a touch of any of the tactile sensors on the head or the front for standing and the rear for sitting. # Create states which command the robot to say hello and goodbye sayHelloState = createState ( " sayHelloState " , lambda : say ( " Hello ␣ World ! " )) s ay Go o db ye S ta t e = createState ( " s ay Go o db ye S ta te " , lambda : say ( " Goodbye ␣ World ! " )) As can be seen in the code snippet above, we have changed the name of the sayState to sayHelloState and added a new state goodbyeState since we want two different states where something is said. We also need to add two new states for waiting until the tactile sensor has been touched. These are needed since we do not want to do any primitive while waiting. Furthermore, we need two of them even though the essentially do the same thing since they have different transitions. # Create states for waiting for touch w a i t S i t t i n g S t a t e = createState ( " w a i t S i t t i n g S t a t e " , lambda : None ) w a i t S t a n d i n g S t a t e = createState ( " w a i t S t a n d i n g S t a t e " , lambda : None ) 21 The next step is to update the transitions and add new ones: # Add transitions according to the state diagram addTransition ( waitSittingState , detectTouch , standState ) addTransition ( standState , lambda wm : True , sayHelloState ) addTransition ( sayHelloState , lambda wm : True , w a i t S t a n d i n g S t a t e ) addTransition ( waitStandingState , detectTouch , sa yG o od b ye St a te ) addTransition ( sayGoodbyeState , lambda wm : True , sitState ) addTransition ( sitState , lambda wm : True , restState ) addTransition ( restState , lambda wm : True , shutdownState ) Do not forget to set the transition function to detectTouch for two of the transitions, see code snippet above. Lastly, all the states has to be added to the FSM and the initial state has to be set. # Set the initial state to standState s et In i ti al S ta t e ( myFSM , w a i t S i t t i n g S t a t e ) 1.3.2. Running the code Follow the instructions for the previous milestone to run the FSM on the robot. 2. Intro Phase: Assignment Two – Basic skills Purpose The purpose of this assignment is for you to get a deeper understanding of how a FSM works and how to program more a more advanced FSM. This is achieved through developing the basic skills that a robot needs for playing football. Task The task of this assignment is to make the robot find the ball, even if it is not in its line of sight, and then follow it. Examination To pass Assignment Two you have to: • Complete all the milestones. • Present a diagram over the FSM (hand drawn or computer made). • Divide the code in a logical manner between different files. • Demonstrate a working ball tracker. • Individually explain how the code works. 22 2.1. Milestone One – Walking The first milestone of the assignment is to write a FSM that makes the robot walk. First, it should walk forward for a while; then it should turn roughly ninety degrees on the spot; finally, it should walk in an arc so that it is close to face the same direction as it started in (basically doing a u-turn). As mentioned before you should start by drawing a diagram for the behavior. Remember that FSMs in RosBots are Moore machines. Therefore, the action associated with the current state is executed each tick and no actions are associated with the transitions. For more information see the RosBots documentation. When you have an initial state diagram, the next step is to implement it in Python. Thereafter, you should test the program in the simulator. Finally, when the FSM is running without crashing or doing hurtful motions for the robot in simulation, you may execute it on a robot. Note: You can find all the primitives that are available in the RosBots documentation. Tip: Remember to not fine tune parameters by running your program in simulation. After all, it is a simulation which can not simulate the real world perfectly. 2.2. Milestone Two – Turning the head In the second milestone you will write a new FSM that turns the head of the robot. Try to come up with a motion with the head that you can later on use while searching for a ball. To finish this assignment it is recommended that you follow the same procedure as described in the previous milestone. 2.3. Milestone Three – Using the camera The focus in the third milestone is to make use of the robot’s camera. This should be done by detecting the ball as well as reacting to finding the ball and loosing it. However, you must be aware that there is a risk that the robot will not recognize the ball in front of it every frame of the camera. Furthermore, you must take this into account since it is not acceptable if the robot believes it has lost the ball only because it has not been recognized in a couple of camera frames. The relevant data for balls and goals can be found in the world model and can be accessed in the same way you got information regarding the tactile sensors. Note: The say and setLED primitives is really good for troubleshooting 23 while running an FSM on the robot. However, remember to set the isPost argument for the say primitive to True so that it does not block your program from running properly. Note: Nao has two cameras, one facing forwards and the other facing downwards. Both of them can not be active at the same time, instead you have to swap between them. Furthermore, the top camera can not see the feet of the robot. Therefore, you have to use both cameras to keep the ball in sight. Switching camera can be done with the setCamera primitive. However, this switch do not happen instantaneously. Therefore, you will have to look at the data in the world model to see which camera that was used for the frame. Example: using the data in the world model as arguments for the primitive. def lookAtBall ( wm ): c a m e r a _ d a t a _ b a l l s = readWM ( wm , " balls " ) if not c a m e r a _ d a t a _ b a l l s : return None else : # Get the latest observation cur_frame = c a m e r a _ d a t a _ b a l l s [0] # The object with the largest area is most likely the true ball largest_ball = None for b in cur_frame : if ( not largest_ball ) or ( largest_ball [ ’ pa ’] < b [ ’ pa ’ ]): largest_ball = b # Turn the head to look straight at the ball return turnHead ( largest_ball [ ’ yaw ’] , largest_ball [ ’ pitch ’ ]) 2.4. Milestone Four – Finding and tracking the ball To achieve this milestone, the robot should be able to find the ball when it is within a two meter radius of the robot (it does not have to find the ball if it is located in an impossible spot, such as between its feet). This milestone combines the two previous milestones. For completing this milestone we recommend that you make use of the fact that a state in a FSM can be another FSM. This makes you able to make different abstraction layers so that your FSM is easier to understand, easier to debug and easier to maintain. 2.5. Milestone Five – Following the ball In the final milestone of this assignment you should make the robot find the ball and then follow it as it is pushed around the field (within reasonable 24 limits). As in milestone four it can be very useful to create an FSM with other FSMs as states to complete this milestone. 3. Main Phase: Assignment Three – Playing soccer Purpose The purpose of this assignment is to expand your code so that the robot is able to play football and not just mastering basic skills. To achieve this, you need to use more complex FSMs than in the previous assignments. You will most likely also have to improve the basic skills that you have started to develop in the previous assignment. Task The task is divided into four milestones that incrementally creates an FSM that can find the ball and kick it into the goal. As usual, we strongly recommend you to re-use the code you have written in previous assignments. Examination To pass Assignment Three you have to: • Complete all the milestones. • Present a diagram over the FSM. • Demonstrate how the robot can find the ball, position itself and then score a goal. • Be prepared to indivdually explain how the code works. 3.1. Milestone One – Kicking the ball First out is one more basic skill, which is to kick the ball. By now you should be familiar with how FSMs and the system works and you should be able to implement this behavior without much problem. Note that you are supposed to make the robot position itself in front of the ball as well as kick it. Tip: You will soon notice that you need different parameters for the simulation and for the real robot. In this case you should simply ignore that the parameters does not go well with the simulation and tune them after the robot. 25 3.2. Milestone Two – Finding the goal Finding and kicking the ball is quite useless unless you can find the opponent’s goal or your own position on the field. Therefore, the next milestone of this assignment is to locate the goal. Note: There are two goals with the same colour on the field and we will count both of the as the opponents in this case. 3.3. Milestone Three – Aligning the robot We are now ready to start with slightly more complex tasks related to making a robot play football. First, aligning it in relation to the goal and the ball in order to kick the ball in the right direction. Tip: Can your code keep control of the ball while aligning the robot? Tip: Can the robot realize that it has lost the ball? 3.4. Milestone Four – Scoring a goal As the final step in this assignment your robot should actually be able to score a goal. There are many ways to achieve this task and you are free to explore whichever of these that you want. However, your program should be able to score a goal from different positions around the field. This will most likely require that the robot kicks the ball more than one time. Hence, your code should be able to handle that in an acceptable manner. 4. Main Phase: Assignment Four – Co-operation Purpose In a soccer game with multiple players communication and co-operation is essential to winning. Until now your robot has been incapable of communicating with other robots. The purpose of this assignment is to teach you the basics of co-operation. Task In this assignment you will be introduced to the communication part of RosBots. Furthermore, you will create an FSM that allows two or more robots to co-operate in order to solve a couple of task. The first task consists of making one robot react to sensor inputs to another. Following this is a task to make one of the robot direct the other robot through giving permission for shooting. The final task is to make one robot pass the ball to the other. 26 Examination To pass Assignment Three you have to: • Complete at least the three first milestones. • Present a diagram of the state machines. • Demonstrate two robots passing the ball between themselves. • Be prepared to individually explain how the code works. 4.1. Milestone One – Send messages It is now time to introduce communication between agents. The basic primitive for communication is communicate which sends a string to a named robot. The string sent can then be extracted using the function readWM. See below for an example. s en dR e ad yS t at u s = createState ( " s endRea dyStat e " , lambda : communicate ( " goliath " , " Ready " )) An example state that will send the string “Ready” to Goliath. messages = readWM ( wm , " comms " ) An example of how to extract the available messages. However, note that the code above only extracts the dictionary of the messages that are available. These are labeled with an index (after the order they were received). Do not forget that if a dictionary is not always sorted so if you want to loop trough all the messages remember to sort the dictionary. Your task is now to modify the code from the last milestone of the first assignment so that touching the tactile sensor of one robot makes another robot react. 4.2. Milestone Two – Wait for clearance One of the fundamentals of passing is that the receiving robot should be prepared. Therefore, it is necessary for the robots to communicate to make a successful pass. Your task in this milestone is to make one of the robots find the ball, wait until it gets clearance from the other robot and then kick the ball. In addition, the robot should mark that it waits for clearance by saying something relevant. Furthermore, the robot giving clearance should also be saying something when it gives the kicking robot clearance to kick the ball. 27 4.3. Milestone Three – Pass the ball In the previous milestone the robot kicked as soon as it got clearance. However, kicking a ball in a random direction does not count as a pass. A pass has to be directed towards one of the robot’s teammates. To make a perfect pass is a complex task and therefore your task is to make one robot pass the ball in the general direction of the other robot (given that they are looking at each other before). The second robot should take control of the ball when it has been passed. 4.4. Milestone Four (optional) – Cross pass This milestone is an extension of the previous, with some more conditions: • The first robot should be located on your side of the field. • The second robot should be located on the opponent’s side of the field. • The robots may not cross the middle line (look at the line detection functions). • The second robot should score a goal after it has gotten control of the ball. 5. Main Phase: Assignment Five – Elective task Purpose Robots are used for a huge variety of tasks, not just playing football. There are always new ways of completing a task and new ideas on what could be solved by robots. This assignment gives you the opportunity to try your own ideas for what a robot can be used for. Task You are relatively free to define the task for this assignment. However, it has to be approved by one of the assistants or the supervisor. These are some examples of what you can do: • Program two robots to co-operate and play against two other robots. If there is another group that does the same, why not challenge them to a match? • Program a goalkeeper. • Make a throw-in.* • Make two robots hand the ball to each other.* • Make the robot go trough an obstacle course. * These tasks require functionality that is not part of the API. However, they 28 can be implemented by only using Python and you are very welcome to ask an assistant on how to do so. Examination The examination of this assignment is to define a task, make a serious effort to complete the task and write a short report. You are allowed to write the report based on assignment 1-4 if you do not think that you do not have enough data for writing a report on assignment 5. However, you should still make an effort to finish assignment 5. The report that you should write is a technical documentation and is therefore, classified as a formal text. Hence, you are should use a formal language and a good structure. Furthermore, you will need to include state diagrams over the FSMs that are used in the assignment(s) your report is covering. The following is an example of an outline that you can use: • Front page: The front page should include the name of the projects, the name of all the group members, the name of the institution that you have written it for (Linköpings University) and the date of the last change. • Table of content. • Introduction: A short description of the task and what you have done. • Implementation: This section includes a description of how your program works. Furthermore, this is the best place for you to present your state diagrams by referring to them in your description. However, do note that you are not supposed to describe your code line by line, not even function by function. Your code already does that. It should describe the general behavior the code generates. Furthermore, you should also include a short argumentation for why you implemented the way you did. • Results: In the result section you should include how well your implementation solved the problem. Any pictures that you might have taken could be really useful to explain what you are trying to say. • Discussion: Here you should discuss why you got the result you did and discuss the different conclusions you can draw from the result. • Conclusion: Under the conclusion section you should present your conclusions. In this project most of your conclusions will be concerning what could have been better (be it in your own implementation, the hardware of the robot or the system that you are using). However, these conclusions should be valid based on your discussion. Furthermore, you should also include some ideas of which improvements that could be made to your program, the RosBots system and the robot in 29 the future. • References: Include any references following a well know standard, such as the Harvard or Oxford reference system. • Appendix: Do not forget to write a table of content if you have a long appendix. 30