Evolution of a Crawling Behavior for a Humanoid Robot Using Genetic Algorithms

Controlling a biped robot with several degrees of freedom is a challenging task. For a humanoid robot to perform in complex environments, fast, stable and adaptive behaviors are required. In this session you will work on a solution for automatic generation of a crawling gait using genetic algorithms (GA).

Aim of this notebook

You will use Pyevolve for tuning the parameters of a crawling controller of a simulated NAO robot. You will perform experiments to validate the performance of the evolution strategy.

The Crawling Gait

Some human-like movements are inherently periodic and repeat the same set of steps several times (e.g. walk, crawl, etc). Such a periodic function can be decomposed into a sum of simple oscillators as represented by the following expression:

where $N$ is the number of frequencies, $C$ is the offset, $A_{n=1..N}$ are amplitudes, $T$ is the period and $Φ_{n=1..N}$ are phases. Applying these oscillators to each joint, a crawling gait can be developed and tested with the simulated humanoid NAO.

The figure shows the humanoid structure and the referential axis considered (more details about NAO joints can be found here). The main idea behind the definition of this gait is to place an oscillator on each joint we pretend to move in order to define its trajectory. The oscillators are placed on the following joints of the left (L) and right (R) sides: ShoulderPitch, ShoulderRoll, ElbowRoll HipPitch, HipRoll, and KneePitch (note: the "hip" is referred to as "thigh" in the figure).

Therefore, 12 single-frequency oscillators are used. Since each single-frequency oscillator will have 4 parameters to define, 48 parameters are needed to completely define the gait. It is common to assume a sagittal symmetry, which determines the same movements for corresponding left and right sided joints with a half-period phase shift. Hence, it is possible to reduce the number of parameters by half of the original size, resulting on 24 parameters. Additionally, the period of all oscillators should be the same to keep all the joints synchronized by a single frequency clock. This consideration reduces the number of parameters to 19. If the parameters are defined on the left-sided joints, the right-sided joints can be readily obtained: for roll joints the left and the right side perform the same trajectories over the time; only the sign of the offset needs to be changed. For pitch joints, the right side can be obtained by adding a phase, π, to the corresponding oscillator. The unknown parameters together form the genome that will be used by the genetic algorithm to generate the gait.

Simulation setup

Running the simulator: execute the script launch_map.bat. The UDK engine will start and a 3D environment will appear in a new window. You can navigate through it with the mouse and the WASD keys.

Spawning the Nao robot: a robot is created in the simulator by executing the script spawn_robot.bat. The robot is spawned at a pre-defined position, but it falls to the floor.

VERY IMPORTANT: if the Windows Firewall asks for permission when running the application, you must select BOTH types of network, private and public.

Connecting to the Nao robot

Once the simulator is running and the robot has been spawned, you can proceed with the following statements:


In [ ]:
import sys
sys.path.append('c:\\udk\\naoqi-sdk-1.12.5-win32-vs2010\\lib')
from Nao import Nao

Creating a nao object from class Nao:


In [ ]:
nao = Nao()

Standing up (if any error appears, please ask the teacher in order to use Choregraphe for putting the robot in a standing position):


In [ ]:
nao.stand_up()

Getting the actual posture:


In [ ]:
nao.getActualPose()

Setting the crawling posture:


In [ ]:
nao.initCrawling()

Run a crawling cycle:


In [ ]:
import math
params = [1.28,0.1,0.21,0.,0.035,0.039,-2.,0.12,-0.86,math.pi,\
          0.06,0.33,math.pi/2,0.005,-0.11,-2.,0.008,1.8,0.]
nao.crawl(params, seconds=5)

The result is the distance travelled by the robot during the specified time in seconds.

The argument params is a list with the period, and the amplitude (A), offset (K) and phase (Phi) of each joint oscillator:

  • period
  • shoulderPitchA
  • shoulderPitchK
  • shoulderPitchPhi
  • shoulderRollA
  • shoulderRollK
  • shoulderRollPhi
  • hipPitchA
  • hipPitchK
  • hipPitchPhi
  • hipRollA
  • hipRollK
  • hipRollPhi
  • elbowRollA
  • elbowRollK
  • elbowRollPhi
  • kneePitchA
  • kneePitchK
  • kneePitchPhi

This video shows the resulting behavior in the simulated Nao: https://www.youtube.com/watch?v=hlWUQAEbpX0

Task 1: GA Configuration

You should develop a Pyevolve application for the crawling problem, with the following restrictions:

  • Use a 1D list chromosome (see http://pyevolve.sourceforge.net/0_6rc1/module_g1dlist.html)
  • An initial population of 10 chromosomes initialized randomly
  • Roulette method for selection (use ga.selector.set)
  • Real range method for mutation (use genome.mutator.set), with a probability defined by pm=0.5 (use function setMutationRate)
  • Uniform method for crossover (use genome.crossover.set
  • Fraction of the population created by crossover defined by pc=0.8 (use function setCrossoverRate)

The fitness function has to be chosen carefully in order to achieve good results. A simple but effective fitness function to maximize can be the travelled distance during a fixed time.

The 1D list chromosome accepts the rangemin and rangemax parameters, but they are shared by all the elements of the genome. You should define a standard range (e.g. [0,1]) and then scale each element to any other pre-defined range, prior to sending the crawl motion to the robot. Scaling is easily calculated by the expression:

robot_parameter = genome_value * (max - min) + min

The suggested ranges for each joint parameter are shown in the following table:

  min max
period 0,8 1,8
shoulderPitchA 0 0,5
shoulderPitchK -0,5 0,5
shoulderPitchPhi -3,14 3,14
shoulderRollA 0,2 0,4
shoulderRollK -0,1 0,1
shoulderRollPhi -3,14 3,14
hipPitchA 0 0,4
hipPitchK -1,2 0
hipPitchPhi -3,14 3,14
hipRollA 0 0,2
hipRollK 0 0,5
hipRollPhi -3,14 3,14
elbowRollA 0 0,1
elbowRollK -0,5 -0,2
elbowRollPhi -3,14 3,14
kneePitchA 0 0,2
kneePitchK 1,6 1,9
kneePitchPhi -3,14 3,14

You are encouraged to experiment with your own ranges, but you should take into account the physical limits of the robot joints (see the Nao documentation).

Task 2: Experimental Results

Execute your GA and analyze the results:

  1. Include the necessary statements for storing the results in a database named 'crawling.db' with identifier 'ex1' (50 points).
  2. For 15 extra points, the evolution process should reach 20 generations, with a population of at least 10 individuals
  3. For other 15 extra points (maximum grade), the evolution process should reach 50 generations, with a population of at least 10 individuals

You can check now the results by plotting some graphs of the evolution process in this notebook.