Exercici de navegació

Un robot mòbil com el Roomba de la imatge ha d'evitar xocar amb els obstacles del seu entorn, i si arriba a col·lisionar, ha de reaccionar per a no fer, ni fer-se mal.

Amb el sensor de tacte no podem evitar el xoc, però si detectar-lo un cop es produeix, i reaccionar.

L'objectiu d'aquest exercici és programar el següent comportament en el robot:

  • mentre no detecte res, el robot va cap avant
  • si el sensor detecta un xoc, el robot anirà cap enrere i girarà

Connecteu el robot:


In [ ]:
from functions import connect, touch, forward, backward, left, right, stop, disconnect
from time import sleep
connect()

Versió 1.0

Utilitzeu el codi de l'exemple anterior del bucle while: només heu d'afegir que, quan xoque, el robot vaja cap enrere, gire una mica (cap al vostre costat preferit), i pare.


In [ ]:
while not touch():
    forward()
backward()
sleep(1)
left()
sleep(1)
stop()

Versió 2.0

Se suposa que la maniobra del robot li permet evitar l'obstacle, i per tant tornar a anar cap avant. Com ho podem programar?

Cal repetir tot el bloc d'instruccions del comportament, incloent el bucle. Cap problema, els llenguatges de programació permeten posar un bucle dins d'un altre, el que s'anomena bucles anidats.

Utilitzeu un bucle for per a repetir 5 vegades el codi anterior.


In [ ]:
for ...:
    while ...:
        ...
    ...

In [ ]:
for i in range(5):
    while not touch():
        forward()
    backward()
    sleep(1)
    left()
    sleep(1)
    stop()

Versió 3.0

I si en lloc de repetir 10 o 20 vegades, volem que el robot continue fins que el parem nosaltres? Ho podem fer amb un bucle infinit, i indicarem al programa que pare amb el botó interrupt kernel.

En Python, un bucle infinit s'escriu així:

while True:
    statement

Quan s'interromp el programa, s'abandona la instrucció que s'estava executant en eixe moment, i cal parar el robot. En Python, aquest procés s'anomena excepció i es gestiona d'aquesta manera:

try:
    while True:
        statement    # ací anirà el comportament
except KeyboardInterrupt:
    statement        # ací pararem el robot

Utilitzeu un bucle infinit per a repetir el comportament del robot fins que el pareu.


In [ ]:
try:
    while True:
        while not touch():
            forward()
        backward()
        sleep(1)
        left()
        sleep(1)
except KeyboardInterrupt:
    stop()

Versió 4.0

El comportament del robot, girant sempre cap al mateix costat, és una mica previsible, no vos sembla?

Anem a introduir un component d'atzar: en els llenguatges de programació, existeixen els generadors de números aleatoris, que són com els daus dels ordinadors.

Executeu el següent codi vàries vegades amb Ctrl+Enter i comproveu els resultats.


In [ ]:
from random import random
random()

La funció random és com llançar un dau, però en compte de donar una valor d'1 a 6, dóna un número real entre 0 i 1.

Aleshores, el robot pot utilitzar eixe valor per a decidir si gira a esquerra o dreta. Com? Doncs si el valor és major que 0.5, gira a un costat, i si no, cap a l'altre. Aleshores, girarà a l'atzar, amb una probabilitat del 50% per a cada costat.

Incorporeu la decisió a l'atzar per a girar al codi de la versió anterior:


In [ ]:
try:
    while True:
        while not touch():
            forward()
        backward()
        sleep(1)
        if random() > 0.5:
            left()
        else:
            right()
        sleep(1)
except KeyboardInterrupt:
    stop()

Recapitulem

Abans de continuar, desconnecteu el robot:


In [ ]:
disconnect()

Tot el que hem vist en aquest exercici:

  • bucles anidats
  • excepcions
  • números aleatoris

No està malament, quasi hem vist el temari d'un primer curs de programació, i això només amb un sensor!

Passem a vore doncs el següent sensor.

>>> Sensor de so