\chapter{Software e Firmware}

\epigraph{\emph{``É fazendo que se aprende a fazer aquilo que se deve aprender a fazer.''}}%
         {Aristóteles}

Neste capítulo é descrito o software de aprendizagem desenvolvido no SALbot, assim como o firmware dos dispositivos e os protocolos de comunicação utilizados. Primeiro, é descrita a arquitectura do sistema dos robôs, isto é, de que forma os dispositivos estão interligados e como são feitas as comunicações. Seguidamente, é abordado o firmware e o funcionamento dos diversos dispositivos, ou seja, a forma como os dispositivos estão programados para interagir com outros dispositivos e de que forma é realizada essa interacção. Depois, são descritos os protocolos de comunicação utilizados, nomeadamente o protocolo de comunicação desenvolvido para o envio e recepção de dados entre o SALbot e o computador, o I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}, utilizado entre o microcontrolador e uma unidade EEPROM externa, e o sinal PW, utilizado para controlar os servos. Por fim, é descrito o software implementado no microcontrolador, para a aprendizagem dos robôs.

\section{Arquitectura do SALbot}

Em primeiro lugar, é importante explicar o funcionamento da arquitectura do sistema do SALbot (figura \ref{fig:Arquitectura}). Como já foi referido no capítulo anterior, o SALbot possui duas placas de circuito impresso: a placa de circuito principal e a auxiliar, que é uma expansão da principal. Na placa de circuito principal está implementado um microcontrolador programado com um algoritmo de aprendizagem. Além dos cálculos específicos do algoritmo de aprendizagem, o microcontrolador é responsável por comandar os servos que fazem mover o robô, ler os valores das distâncias dos sensores de distância e o estado dos sensores de contacto (que estão ligados à placa de circuito auxiliar) necessários para o algoritmo de aprendizagem, escrever dados relativos à aprendizagem na memória EEPROM externa e enviar, e receber, dados pela porta série, nomeadamente enviar dados, relativos à aprendizagem ou ao estado do robô, e receber ordens. Os dados são enviados e recebidos pela porta série do microcontrolador pelos pinos TX e RX. Quando os dados são enviados, o microcontrolador envia-os para o módulo XBee que se encontra na placa de circuito auxiliar. Depois, o módulo XBee envia os dados, em ondas rádio moduladas usando o protocolo IEEE 804.15.4, para outro módulo XBee que se encontra na placa de interface de comunicação, a partir do qual, os mesmos dados são enviados para um computador pela porta série usando o protocolo de comunicação RS-232. Relativamente ao envio de dados do computador para o SALbot, é invertido o processo descrito anteriormente. Isto é, os dados são enviados pelo computador para o XBee na placa de interface de comunicação, que são enviados para o XBee na placa de circuito auxiliar e, por fim, chegam ao microcontrolador.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.8\textwidth]{Arquitectura_new}\\
  \caption{Arquitectura do sistema do SALbot.}\label{fig:Arquitectura}
\end{figure}

\section{Firmware e funcionamento dos dispositivos}

%Para detectar distância foram implementados dois tipos de sensores distintos, o de infra-vermelhos e o de ultra-sons. Porém o de ultra-sons apenas foi implementado na parte frontal dos robôs, uma vez que só mede distâncias efectivas a partir dos 150 mm, aproximadamente.

\subsection{Sensores de contacto}

Os sensores de contacto implementados no sistema de para-choques foram os DB3C-B1RC da Cherry. Estes sensores de contacto não são mais do que detectores de fim de curso, accionados por uma haste com uma roda na extremidade. Tais dispositivos funcionam como um interruptor normalmente aberto, entre os 5V de alimentação e o pino do microcontrolador do respectivo sensor, que é fechado quando o sensor é activado. Assim, os 5V são enviados para o pino do microcontrolador, indicando a existência de um contacto. Para evitar o flutuamento da tensão nos pinos do microcontrolador, o que induziria o microcontrolador em erro, foram implementados ``\textit{pull-downs}'' nos pinos do microcontrolador relativos aos sensores de contacto. Isto é, cada pino tem uma resistência de 1$k\Omega$ ligada à massa.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.2\textwidth]{DB3C}\\
  \caption{Fim de curso DB3C-B1RC.}\label{fig:DB3C_switch}
\end{figure}

\subsection{Sensores de distância infra-vermelhos}

Os sensores de infra-vermelhos utilizados foram os GP2D120 da Sharp, que permitem medir distâncias entre 30 mm e 400 mm. Cada um destes sensores possui três tipos de ligações: uma de alimentação a 5V, a ligação à massa e o sinal, que é enviado para o microcontrolador. Esse sinal é analógico, variando entre 0V e 5V, e representa a distância medida pelo sensor.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.3\textwidth]{GP2D120}\\
  \caption{Sensor de distância infra-vermelhos Sharp GP2D120.}\label{fig:GP2D120}
\end{figure}

\pagebreak

Basicamente, este tipo de sensores determina a distância a um objecto utilizando triangulação. Um emissor envia um feixe de luz infra-vermelha, que, caso encontre um objecto, é reflectido de volta, e é captado por um pequeno \textit{array} linear CCD (\textit{charge-coupled device}), formando um triângulo. O feixe infra-vermelhos, antes de chegar ao CCD, passa por uma lente que distribui o feixe infra-vermelho por diversos pontos do CCD, dependendo do ângulo da base do triângulo. Sabendo o ângulo da base do triângulo, dado pelo CCD, é então possível calcular a distância do sensor ao objecto.\cite{Autonomous_Robotics_Systems}\cite{IntAutoMobrobots}\cite{Mobile_Robots_inspiration_to_implementation}

\begin{figure}[!h]
  \centering
  \includegraphics[width=1\textwidth]{GP2D120_graph}\\
  \caption{Gráfico dos valores do sinal analógico em função da distância do sensor GP2D120.}\label{fig:GP2D120_graph}
\end{figure}

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.45\textwidth]{GP2D120_datasheet_graph}\\
  \caption{Gráfico do fabricante da voltagem em função da distância do GP2D120.}\label{fig:GP2D120_graph_datasheet}
\end{figure}

Apesar deste tipo de sensores ser quase imune à interferência da luz ambiente e não depender da cor do objecto detectado, é extremamente difícil detectar objectos transparentes. O sinal analógico enviado pelo sensor não é linearmente proporcional à distância (figura \ref{fig:GP2D120_graph_datasheet}) e o valor do ângulo medido pelo CCD varia com a temperatura ambiente e com o nível de reflectividade do objecto detectado. Assim, para uma melhor precisão das distâncias obtidas por estes sensores, retiraram-se vários valores do sinal enviado pelo sensor para diversas distâncias medidas, a partir dos quais, se construiu um gráfico do valor do sinal analógico em função da distância medida, que é possível ver na figura \ref{fig:GP2D120_graph}. Com esses valores, e usando uma regressão exponencial, que é a que mais se adequa aos valores obtidos, obteve-se uma função aproximada da distância medida, em função do sinal analógico enviado pelo sensor.

Embora a distância precisa, em milímetros, da distância entre o robô e um objecto não seja fundamental para o algoritmo de aprendizagem, sentiu-se a necessidade de fazer corresponder os valores analógicos, lidos pelo microcontrolador, a medidas de distância, para serem visualizadas na interface gráfica. Dando, assim, uma noção ao utilizador das distâncias detectadas pelos sensores.

\subsection{Sensores de distância ultra-sons}

Os sensores de ultra-sons instalados nos robôs foram os LV-MaxSonar\textsuperscript{\scriptsize{\textregistered}}-EZ0\textsuperscript{\scriptsize{\texttrademark}}, que  permitem a medição de distâncias entre 150 mm e 6450 mm. Cada sensor têm vários tipos de interface para a leitura da distância medida, nomeadamente porta série, PWM e sinal analógico. Por ser de mais fácil implementação e de serem necessários menos ligações ao sensor, utilizou-se o sinal analógico para a leitura da distância medida pelo sensor. Este tipo de interface de medição é semelhante ao do GP2D120; o sensor tem apenas três terminais: um de alimentação a 5V, a ligação à massa e o sinal analógico. Porém, ao contrário do GP2D120, o sinal analógico vai dos 0V até à tensão de alimentação $V_{CC}$, neste caso 5V, proporcionalmente à distância medida. Assim, o sinal analógico apresenta uma resolução de $3.845\times10^{-4}\ V\cdot mm^{-1}$.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.3\textwidth]{LV-EZ0}\\
  \caption{Sensor de distância ultra-sons LV-MaxSonar\textsuperscript{\scriptsize{\textregistered}}-EZ0\textsuperscript{\scriptsize{\texttrademark}}.}\label{fig:LV_EZ0}
\end{figure}

Nos sensores de distância por ultra-sons, a distância a que este se encontra de um objecto é calculada através da medição do tempo de voo de um feixe de sons ultra-sónicos. No sensor, existe um emissor que emite um feixe direccional de ultra-sons, que não são mais do que treze ondas mecânicas com uma frequência elevada de 42kHz, que não são detectadas pelos ouvidos humanos. Essas ondas mecânicas viajam pelo ar à velocidade do som (cerca de 343 $m\cdot s^{-1}$ em ar seco a 20$^{\circ}$) e, quando encontram um obstáculo no seu caminho, são reflectidas de volta para o sensor onde são captadas pelo receptor; as ondas reflectidas designam-se por eco. Assim, o sensor emite um feixe de ultra-sons e fica à espera do seu eco. Quando recebe o eco, o sensor determina o tempo que passou desde o envio do feixe até à recepção do eco e, sabendo a velocidade do som, a distância, do sensor ao objecto que reflectiu o som, é também facilmente determinada. O sensor envia, a cada 49 ms, um feixe de ultra-sons e coloca o PWM no nível lógico 1, que se mantém durante 37.5 ms se não for recebido um eco, caso seja recebido um eco o PWM é colocado no nível lógico 0. Do restante tempo, menos de 4.7 ms são usados para corrigir o nível do sinal analógico e os últimos 4.7 ms são para enviar dados pela porta série.\cite{IntAutoMobrobots}

Este sensor pode ser auto-calibrado, para tal, apenas é necessário que passados 250 ms, após a inicialização do sensor, o pino RX esteja aberto ou seja colocado no nível lógico 1. Se isso acontecer o sensor irá correr um ciclo de calibração de 49 ms e, seguidamente, uma leitura da distância, demorando assim aproximadamente 100 ms.

Para objectos entre os 0 mm e 150 mm, o sensor envia sempre o valor correspondente a 150 mm. Outra desvantagem é o facto do sensor não realizar uma reajustamento da velocidade do som em cada medição, relativamente à temperatura e humidade, que a influenciam. Em vez disso, a calibração do sensor consiste na compensação em relação ao padrão de \textit{ringdown} do sensor, para limitar a distância mínima de medição. Se a temperatura e/ou humidade se alterarem durante a operação do sensor, este pode apresentar medidas erróneas, pelo que será necessário recalibrar-lo para este se ajustar ao novo padrão de \textit{ringdown}. Este padrão de \textit{ringdown} tem a ver com o padrão de recepção do eco. Como o dispositivo, do sensor, que envia as ondas de ultra-sons é o mesmo que detecta a sua recepção, enquanto o sensor envia o feixe de ultra-sons, está, ao mesmo tempo, a receber, daí o termo \textit{ringdown}. Assim, o sensor mede o tempo que demora a enviar o feixe de ultra-sons, e com esse tempo é definido a distância mínima de medição.

\subsection{Servomotores}

Para a movimentação do SALbot, instalaram-se dois servos com a configuração diferencial de duas rodas. Isto é, os servos estão fixados no centro do robô, o que permite que este se mova num sentido movendo as rodas no mesmo sentido, ou que gire em torno do seu próprio eixo, movendo as rodas em sentidos opostos. Além disso, várias combinações de velocidades e direcções de rotação em cada roda permitem ao robô uma infinidade de movimentos.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.4\textwidth]{Futaba_S3003}\\
  \caption{Servo Futaba\textsuperscript{\scriptsize{\textregistered}} S3003.}\label{fig:S3003}
\end{figure}

Os servos usados, como anteriormente já foi referido, foram os S3003 da Futaba\textsuperscript{\scriptsize{\textregistered}}. Estes servos estão preparados para uma amplitude de movimentos de 90$^{\circ}$ para cada lado do ponto central, pelo que, para permitir uma rotação contínua, foi necessário alterar o hardware dos servos, descrito no capítulo anterior.

Cada servo é controlado pelo microcontrolador através de um sinal PW (\textit{Pulse-Width}), que é abordado na secção de ``Protocolos de comunicação e comando'' (\ref{seq:Protocol_command}). Devido à alteração realizada para a rotação contínua dos servos, para que estes rodem numa direcção à velocidade máxima, basta enviar o sinal que corresponderia à movimentação deste para a posição máxima dessa direcção. Variando o sinal de comando para uma posição duma direcção, varia-se a velocidade de rotação do servo.

\subsection{Memória EEPROM externa}

Para que, um robô autónomo orientado para aprendizagem, possa ser desligado, sem contudo perder a informação que adquiriu durante a sua aprendizagem, necessita de um espaço para guardar dados, relativos à aprendizagem, que não se alterem com a ausência de alimentação eléctrica. Um destes tipos de armazenamento de dados é a EEPROM (\textit{Electrically-Erasable Programmable Read-Only Memory}), um tipo de memória não-volátil que permite que os dados armazenados não sejam apagados quando a alimentação eléctrica é interrompida. Houve a necessidade da implementação de uma unidade de EEPROM externa, uma vez que a dimensão deste tipo de memória disponível nos microcontroladores é insuficiente (1024 \textit{bits} para a família da série PIC18 e 4096 \textit{bits} para a família dsPIC), para a quantidade de dados relativos à aprendizagem que são necessários armazenar, mesmo para os métodos de aprendizagem mais simples.


\begin{figure}[!h]
  \centering
  \subfloat[]{
      \includegraphics[width=0.25\textwidth]{24LC1025}
      \label{fig:24LC1025_picture}}
  \hfill
  \subfloat[]{
      \includegraphics[width=0.7\textwidth]{24LC1025_pinout}
      \label{fig:24LC1025_pinout}}
  \caption{Unidade de EEPROM de interface série 24LC1025 da Microchip. (a) Fotografia do 24LC1025; (b) \textit{Pinout} do 24LC1025}\label{fig:24LC1025}
\end{figure}

O dispositivo de armazenamento de memória EEPROM implementado foi o 24LC1025 da Microchip com 1 Mbit de memória, como já foi referido na secção \ref{seq:Projecto_Electronico}. O microcontrolador acede a este dispositivo, escrevendo e lendo dados em posições específicas da memória disponível, através da comunicação por I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}, que é descrita na secção de ``Protocolos de comunicação e comando'' (\ref{seq:Protocol_command}). A memória deste dispositivo está agrupada em páginas de 128 \textit{bytes}, cada \textit{byte} é composto por oito \textit{bits}, ao qual está associado um endereço único que vai de 00000h a 1FFFFh. É possível escrever um \textit{byte} de cada vez ou uma página de \textit{bytes}. Quanto à leitura dos dados, é possível ler um \textit{byte} ou uma leitura sequencial de \textit{bytes}. Este dispositivo tem dois pinos que, ligando cada um ao V$_{CC}$ ou à massa, configuram o endereço I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}} do dispositivo, o que permite a utilização de um máximo de quatro destes dispositivos na mesma interface I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}.  Além disso, tem ainda um pino de protecção de dados que, estando conectado ao V$_{CC}$, não permite operações de gravação, sendo apenas permitido operações de leitura.

Embora este dispositivo seja de maior capacidade de memória EEPROM apresenta face a outros dispositivos disponíveis no mercado, ele pode ser permutado por outro dispositivo de memória EEPROM, desde que a interface de comunicação seja I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}. Para o caso de ser necessário mais capacidade de armazenamento de dados, embora na placa de circuito principal do SALbot apenas seja possível fixar uma unidade EEPROM externa, existe uma porta de expansão I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}, que permite instalar até um máximo de quatro dispositivos similares no mesmo bus I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}.

\subsection{XBee}

Como já foi referido, a comunicação sem fios, entre o SALbot e o computador, fica a cargo dos módulos XBee. Mais precisamente os módulos XB24-AWI-001, que são módulos com uma antena de fio metálico, que comunicam através do protocolo \textit{wireless standard} IEEE 802.15.4.

Estes módulos possuem uma interface série, a partir da qual, é possível enviar e receber dados relativos à comunicação sem fios. Assim, no SALbot, o microcontrolador está ligado por porta série ao XBee e, na placa de interface de comunicação, o XBee está ligado por porta série a um MAX232 que transforma os sinais para o protocolo RS232. Isto é, tal como já foi referido, quando o robô envia dados para o computador o microcontrolador envia os dados pela porta série para o XBee. Este envia os dados pelo protocolo IEEE 802.15.4 para outro XBee, o qual os envia para o MAX3232 que, por sua vez, transforma os sinais para serem enviados para o computador através do protocolo RS232. Essa ligação por porta série consiste em dois pinos o TX e o RX. O TX é o pino de transmissão de dados e o RX é o pino de recepção de dados.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.5\textwidth]{XBee}\\
  \caption{Módulo XBee XB24-AWI-001 da Digi\textsuperscript{\scriptsize{\textregistered}}.}\label{fig:XBee}
\end{figure}

Os módulos XBee utilizados têm um alcance máximo de 30 m em espaços urbanos ou fechados, e de 90 m para espaços abertos com uma taxa de transferência de 250 kbps. A gama de taxa de transferência de dados pela interface série vai dos 1200 bps até aos 250 kbps, sendo aceites taxas de \textit{baud rate} não estandardizadas. A comunicação sem fios é feita através do protocolo IEEE 802.15.4, operando na gama de frequências de 2.4 GHz, num dos 16 canais previstos para este protocolo nesta gama de frequências. A transmissão de dados sem fios é feita com uma potência de 1 mW, ou 0 dBm, e a sensibilidade de recepção de dados é de -92 dBm.\cite{XBee_manual}

\pagebreak

Como os módulos XBee operam a 3.3 V, foi necessário implementar, na placa de circuito auxiliar, dispositivos para converter os sinais lógicos de 3.3 V para 5 V e de 5 V para 3.3 V da porta série. A conversão dos sinais lógicos de 3.3 V para 5 V é garantida por um MOSFET (Metal Oxide Semiconductor Field Effect Transistor) BSS138, enquanto que a conversão dos sinais lógicos de 5 V para 3.3 V é garantida por um divisor resistivo de duas resistências de 10 k$\Omega$.

A configuração dos módulos XBee pode ser feita através de comandos ``AT'' ou através de um programa disponibilizado pela Digi\textsuperscript{\scriptsize{\textregistered}}, o X-CTU, onde, através de uma interface gráfica, é possível configurar todos os parâmetros de qualquer módulo XBee. Na medida em que, a comunicação sem fios é realizada em modo transparente, apenas é necessário configurar alguns parâmetros dos módulos XBee para que estes possam comunicar entre si. Basicamente, é necessário configurar os parâmetros CH (canais), ID (PAN ID), DH (Endereço de destino mais significativo), DL (Endereço de destino menos significativo), SC (canais procurados) e BD (\textit{Baud Rate}). O parâmetro CH não é mais do que um dos canais, disponíveis pelo protocolo IEEE 802.15.4 para a gama de frequências de 2.4 GHz, usado para a comunicação sem fios entre os módulos XBee. O parâmetro ID consiste na designação da PAN (\textit{Personal Area Network}) ID, isto é, o identificador da rede, que pode ser entre 0 a 0xFFFF. Caso o valor do parâmetro seja 0xFFFF, o envio de dados é feito em \textit{broadcast} para todas as PAN.
O parâmetro DH e DL correspondem ao endereço de 64-\textit{bit} do dispositivo de destino, sendo DH os 32 \textit{bits} mais significativos e DL os 32 \textit{bits} menos significativos do endereço de destino. Se o valor de DH for 0 e DL for menor do que 0xFFFF, a transmissão de dados é feita usando o endereço de 16-\textit{bit}. Se DH for 0 e DL 0xFFF, a transmissão de dados é feita em \textit{broadcast} para a PAN. O parâmetro SC não é mais do que uma máscara de \textit{bits} para se configurar quais os canais, disponíveis pelo protocolo IEEE 802.15.4 para a gama de frequências de 2.4 GHz, nos quais, o módulo XBee pode procurar outros dispositivos.

Por fim, o parâmetro BD corresponde à taxa de transferência de dados da porta série, em que os valores de 0 a 7 correspondem às taxas de transferência de dados estandardizadas de 1200 bps a 115.2 kbps e os valores de 0x80 a 0x3D090 são usados para taxas de transferência de dados não estandardizadas até 250 kbps.\cite{XBee_manual}

Embora os módulos XBee apenas sejam utilizados para a comunicação entre os robôs e o computador, estes podem ser programados para fazerem mais do que isso. Os módulos XBee, além dos pinos de porta série, alimentação e massa, possuem ainda oito entradas e saídas digitais, das quais seis podem ser configuradas como entradas analógicas, um pino exclusivo para entrada digital, outro pino exclusivo para saída digital e duas de PWM. Tudo isto possibilita o controlo e aquisição de dados de dispositivos remotamente sem a necessidade de um microcontrolador ou quaisquer outros dispositivos de controlo.

Os módulos XBee implementados, quer na placa de circuito auxiliar dos SALbot, quer na placa de interface de comunicação, podem ser permutados por outros módulos XBee, inclusive pelos XBee-PRO ou XBee com o protocolo ZigBee quer da série 1 quer da série 2. No entanto, os XBee da série 2 não podem comunicar com os da série 1, nem mesmo os módulos com o protocolo ZigBee. Da mesma forma que os módulos com o protocolo ZigBee da série 1, também os módulos da série 2 necessitam que um dos módulos de uma rede seja configurado como coordenador. Apesar das diferenças dos módulos XBee da série 1 para a série 2, só é necessário alterar o código do microcontrolador no caso de se pretender usar o modo API (\textit{Application Programming Interface}) em vez do modo transparente.

Os módulos XBee-PRO são semelhantes aos outros módulos XBee, no entanto os XBee-PRO possuem um alcance máximo de 90 m em espaços urbanos ou fechados e 1.6 km para espaços abertos. A potencia máxima de transmissão de dados é de 63 mW, ou 18 dBm, e a sensibilidade de recepção de dados é de -100 dBm. Outra diferença é que os XBee-PRO não utilizam os últimos quatro canais disponíveis pelo protocolo IEEE 802.15.4 para a gama de frequências de 2.4 GHz.\cite{XBee_manual}

No entanto, uma vez que os SALbot foram projectados para a realização de testes e ensaios de algoritmos de aprendizagem em ambientes laboratoriais, não existe uma necessidade significativa da implementação de módulos XBee-PRO, já que os módulos implementados possuem um alcance de transmissão de dados mais do que suficiente para o efeito.

\section{Protocolos de comunicação e comando}
\label{seq:Protocol_command}

Nesta secção são descritos os protocolos de comunicação, do SALbot com o computador e do microcontrolador com o dispositivo de EEPROM externo, e o protocolo de comando dos servos.

\subsection{Sinal PW de comando dos servomotores}
\label{seq:Servo_PW}

Os servos, como já foi referido, são comandados através de um sinal PW enviado pelo microcontrolador. Os servos implementados foram concebidos para se moverem para uma determinada posição angular. Essa posição angular é dada através de um sinal PW. Os sinais PW usados nos servos, normalmente, têm uma frequência de 50 Hz, isto é, um pulso é gerado a cada 20 ms. A largura de cada pulso indica a posição angular para a qual se deseja que o servo se desloque.

No caso do S3003, como é possível ver na figura \ref{fig:Servo_PW}, para um pulso com uma largura de 320$\ \mu$s, o servo posiciona-se a -90$^{\circ}$; para um pulso de 2300$\ \mu$s, o servo posiciona-se a 90$^{\circ}$; e para um pulso de 1320$\ \mu$s, o servo mantêm-se na posição central.\cite{Embedded_robotics}\cite{Futaba_S3003}

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.9\textwidth]{Servo_PW}\\
  \caption{Sinal PW do servo S3003 da Futaba\textsuperscript{\scriptsize{\textregistered}}.}\label{fig:Servo_PW}
\end{figure}

No entanto, após a alteração efectuada nos servos para poderem rodar continuamente, o controlador do servo tem a informação de que o servo está sempre posicionado na posição central. Pelo que, ao enviarmos um sinal PW para comandar o servo para a posição de -90$^{\circ}$, este vai tentar posicionar-se nessa posição, mas como o controlo interno indica sempre a posição central, o servo continua a rodar. Assim, para rodarmos o servo no sentido horário basta enviar um sinal PW com um pulso entre 1321$\ \mu$s e 2300$\ \mu$s, em que a velocidade aumenta quanto maior for a largura do pulso. Para rodarmos o servo no sentido anti-horário deve enviar-se um sinal PW com um pulso entre 1319$\ \mu$s e 320$\ \mu$s, em que a velocidade aumenta quanto menor for a largura do pulso.

\subsection{Comunicação I$^2$C\textsuperscript{\scriptsize{\texttrademark}} com o dispositivo de EEPROM externo}

A comunicação entre o microcontrolador e o dispositivo de EEPROM externo é realizada através de uma interface I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}. A comunicação por I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}} usa um barramento de duas ligações, o SDA (\textit{Serial Data}) e o SCL (\textit{Serial Clock}). A ligação SDA é bidireccional e é utilizada para o enviar e receber dados e endereços de um dispositivo, em \textit{bytes} de oito \textit{bits}, enquanto que a ligação SCL é utilizada para sincronizar a transferência de dados entre os dispositivos.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.9\textwidth]{I2C_NEW}\\
  \caption{Composição da sequência de transferência de dados no I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}.}\label{fig:I2C_data}
\end{figure}

A interface de comunicação I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}} requer que a comunicação seja controlada por um dispositivo \textit{Master}, que, neste caso, é o microcontrolador. É o \textit{Master} que gera os impulsos na linha SCL, controla o acesso ao barramento e gera as condições de \textit{Start} e \textit{Stop}. Os outros dispositivos ligados ao mesmo barramento I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}} são designados de \textit{Slave}. Qualquer dispositivo, tanto o \textit{Master} como um \textit{Slave}, pode ser transmissor (enviam dados) ou receptor (recebem dados).

No I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}, a transferência de dados do transmissor para o receptor só deve ser iniciada quando o barramento estiver desocupado, isto é, quando ambas as linhas de SDA e SCL permanecem no nível lógico 1 (à tensão de V$_{CC}$). Todos os comandos devem iniciar com uma condição de \textit{Start}, que corresponde a uma transição do nível lógico 1 para 0 na linha SDA enquanto a linha SCL permanece no nível lógico 1. E todos os comandos devem terminar com uma condição de \textit{Stop}, que é dada por uma transição do nível lógico 0 para 1 na linha SDA enquanto a linha SCL permanece no nível lógico 1. No final de recepção de cada \textit{byte} o dispositivo receptor deve gerar uma condição de \textit{Acknowledge}, e o \textit{Master} deve gerar um impulso extra na linha SCL para o \textit{bit} de \textit{Acknowledge}. A condição de \textit{Acknowledge} acontece quando o dispositivo receptor coloca a linha SDA no nível lógico 1 e está estabilizado durante o período de nível lógico 1 relativo ao impulso extra gerado na linha SCL.\cite{24LC1025}

\subsubsection{Endereçamento dos dispositivos}

Em todos os comandos, o primeiro \textit{byte} a enviar, após a condição de \textit{Start}, é o \textit{byte} de controlo. Como se pode verificar na figura \ref{fig:I2C_addr}, o \textit{byte} de controlo é composto por quatro \textit{bits} com o código de controlo, um \textit{bit} relativo à selecção do bloco de memória, dois \textit{bits} de selecção do dispositivo e um \textit{bit} que indica se o tipo de operação é de escrita ou leitura. O código de controlo para os dispositivos 24LC1025 é ``1010'', em binário.

Uma vez que o 24LC1025 divide a memória em dois blocos de 512 kb, o \textit{bit} de selecção de bloco indica qual o bloco de memória se pretende aceder. Basicamente, o \textit{bit} de selecção do bloco pode ser tratado como o 16º \textit{bit} de endereço de memória. Os \textit{bits} de selecção do dispositivo correspondem ao endereço do dispositivo, com o qual se pretende comunicar. O \textit{bit} que indica o tipo de operação é 0 para operações de escrita e 1 para operações de leitura.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.9\textwidth]{I2C_endereçamento}\\
  \caption{Composição da sequência de \textit{bits} do endereçamento de uma mensagem por I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}.}\label{fig:I2C_addr}
\end{figure}

 Depois do \textit{byte} de controlo é enviado o endereço da memória à qual se pretende aceder. O endereço da memória é dividido em dois \textit{bytes}. O \textit{byte} menos significativo contém os oito primeiros \textit{bits} do endereço e o \textit{byte} mais significativo os últimos oito \textit{bits}.

\subsubsection{Operações de escrita}

É possível realizar dois tipos de operações de escrita no 24LC1025: a escrita de dados numa posição da memória e a escrita sequencial de dados em cada posição da memória numa página de 128 \textit{bytes}.

Na operação de escrita de um \textit{byte}, a mensagem é iniciada com a condição de \textit{Start}, seguido do \textit{byte} de comando, no qual o \textit{bit} de tipo de comando deve assumir o valor lógico 0. Seguidamente, após a recepção do \textit{Acknowledge} do receptor, são enviados os \textit{bytes} de endereço, primeiro o mais significativo e depois, após a recepção do \textit{Acknowledge} do receptor, o menos significativo. Por fim, após a recepção de um novo \textit{Acknowledge} do receptor, é enviado o \textit{byte} que será gravado na memória do 24LC1025 e a mensagem é finalizada com uma condição de \textit{Stop}.

A mensagem da operação de escrita de uma página de 128 \textit{bytes} é realizada quase da mesma forma que a operação de escrita de um \textit{byte}. A diferença é que os \textit{bytes} do endereço enviados correspondem ao primeiro endereço, a partir do qual, se pretende escrever e, em vez da condição de stop no final do envio do \textit{byte} de dados, são enviados sequencialmente \textit{bytes} de dados, até um máximo de 127 \textit{bytes} adicionais, e só depois é finalizada a mensagem com a condição de \textit{Stop}. O 24LC1025 auto-incrementa uma posição do \textit{byte} menos significativo do endereço à medida que mais \textit{bytes} de dados são recebidos. Se a quantidade de dados enviados implicar que o \textit{byte} de endereço menos significativo ultrapasse o valor 128, o \textit{byte} do endereço volta ao início da página e escreve os dados restantes por cima dos valores que se encontravam anteriormente nessas posições de memória.

\subsubsection{Operações de leitura}

Existem três tipos de operações de leitura: a leitura do endereço actual, a leitura de um endereço específico e a leitura sequencial.

A operação de leitura do endereço actual é iniciada com o envio de um \textit{byte} de controlo após a condição de \textit{Start}; porém, o \textit{bit} de tipo de comando, ao contrário do que acontece nas operações de escrita, deve assumir o valor lógico 1. Após o envio do \textit{byte} de controlo, o 24LC1025 envia um \textit{Acknowledge} e, em seguida, o \textit{byte} de dados do endereço de memória actual, o \textit{Master} passa o envio de um \textit{Acknowledge}, mas gera uma condição de \textit{Stop} no final da leitura. O dispositivo 24LC1025 possui um contador de endereços que contém o endereço da posição da última memória lida. Assim, o endereço da posição de memória da próxima leitura será o endereço seguinte da última leitura.

A operação de leitura de um endereço específico é iniciada enviando um \textit{byte} de controlo após a condição de \textit{Start}, com o \textit{bit} de tipo de operação a 0. Após a recepção de um \textit{Acknowledge} do receptor, são enviados os dois \textit{bytes} do endereço de memória que se pretende ler, enviando primeiramente o \textit{byte} mais significativo e depois, após a recepção de um \textit{Acknowledge}, o \textit{byte} menos significativo. Seguidamente, é enviado novamente o \textit{byte} de controlo antecedido de uma condição de \textit{Start}, mas, desta vez, o \textit{bit} de tipo de operação deve assumir o valor lógico 1. Depois o 24LC1025 envia um \textit{Acknowledge} e, em seguida, o \textit{byte} de dados, correspondente ao endereço de memória que foi enviado. Por fim, à semelhança da operação de leitura do endereço actual, o \textit{Master} não envia um \textit{Acknowledge} e finaliza a mensagem com uma condição de \textit{Stop}.

A operação de leitura sequencial é idêntica à operação de leitura de um endereço específico. No entanto após 24LC1025 enviar o \textit{byte} de dados relativo ao endereço enviado, é enviado um \textit{Acknowledge} para cada leitura sequencial desejada e que é seguido do envio do \textit{byte} de dados do endereço seguinte pelo 24LC1025. Quando todas as leituras desejadas forem efectuadas o \textit{Master} passa o envio do \textit{Acknowledge} e envia uma condição de \textit{Stop}.

\subsection{Protocolo de comunicação entre o SALbot e o PC}

Uma vez que a comunicação, através dos módulos XBee, entre os SALbot e o computador, é realizada em modo transparente, existe a possibilidade de os SALbot receberem hipotéticas mensagens vindas de outros dispositivos \textit{wireless} os quais poderiam interferir com o funcionamento normal dos robôs. Assim, houve a necessidade de implementar um protocolo que só fosse descodificado pelos SALbot ou pelo programa de interface no computador.

O protocolo foi concebido por forma a que fosse possível o envio de mensagens com comprimento variável, até um máximo de quinze \textit{bytes}, tendo em conta a possibilidade da perda de informações pelo meio da mensagem, já que as comunicações \textit{wireless} são permeáveis a interferências externas. Para permitir o comprimento dinâmico da mensagem foi criado um campo que contém a informação da dimensão da mensagem. E, para evitar a leitura de mensagens com erros, foi criado um campo na mensagem permite validar a mensagem recebida.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_generico}\\
  \caption{Topologia da mensagem de comunicação entre o SALbot e o computador.}\label{fig:Protocolo_generico}
\end{figure}

\pagebreak

A mensagem, como é visível na figura \ref{fig:Protocolo_generico}, é constituída por quatro secções: o \textit{byte} de início, um \textit{byte} com o comprimento e tipo, a mensagem propriamente dita e um \textit{byte} de verificação (ou \textit{checksum}).

O \textit{byte} de início depende do robô que envia ou recebe mensagens. Este \textit{byte}, para o SALbot1, tem o valor 255 decimal e ,para o SALbot2, tem o valor 254 decimal. O segundo \textit{byte} contém o valor do comprimento da mensagem, na parte mais significativa, e o tipo de mensagem, na parte menos significativa. Este comprimento corresponde ao número de \textit{bytes} da mensagem propriamente dita, isto é, o número de \textit{bytes} entre este \textit{byte} e o \textit{byte} de verificação. Depois dos \textit{bytes} da mensagem propriamente dita, existe um \textit{byte} de verificação que, basicamente, permite que a mensagem seja validada por quem a recebeu.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_Byte_check}\\
  \caption{Descrição gráfica do \textit{byte} de verificação.}\label{fig:Protocolo_byte_check}
\end{figure}

Na figura \ref{fig:Protocolo_byte_check} pode visualizar-se como funciona o \textit{byte} de verificação. Independentemente do número de \textit{bytes}, pelo qual é constituída a mensagem, este \textit{byte} corresponde à operação sequenciada de XORs (``ou'' exclusivos); ou seja, faz-se a operação XOR do primeiro \textit{byte} com o segundo, depois efectua-se a mesma operação do resultado da anterior com o terceiro \textit{byte} e assim sucessivamente até ao último \textit{byte}.

É através deste \textit{byte} que, quer o programa de interface, quer o programa do SALbot, validam as mensagens recebidas pela porta série.

\subsubsection{Mensagem de modo de operação}

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_op_mode_req_msg}\\
  \caption{Mensagem de alteração do modo de operação do SALbot.}\label{fig:Protocolo_op_mode}
\end{figure}

\pagebreak

A mensagem de modo de operação (figura \ref{fig:Protocolo_op_mode}) é enviada pelo programa de interface, para poder comandar o modo de operação do programa do SALbot. A mensagem é constituída apenas por um \textit{byte}, que corresponde ao modo de operação que o programa do SALbot deve tomar: Autónomo, Manual, Inicialização da Aprendizagem ou Aprendizagem.

\subsubsection{Mensagem de Início/Paragem}

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_start_stop_msg}\\
  \caption{Mensagem de Início/Paragem do SALbot.}\label{fig:Protocolo_start_stop}
\end{figure}

Quando o SALbot é (re)iniciado, o programa entra no modo Idle (não realiza qualquer operação a não ser a verificação de mensagens recebidas). A mensagem de início/paragem (figura \ref{fig:Protocolo_start_stop}) é usada para o utilizador iniciar o programa do SALbot a fim deste iniciar o modo de execução (por defeito é o modo Manual). No entanto, sempre que o utilizador desejar, pode enviar uma mensagem para colocar o programa do SALbot no modo \textit{Idle} (enviando o \textit{Stop}).

Esta mensagem é constituída por um \textit{byte} que indica se é para iniciar ou para parar, independentemente do modo de operação do SALbot.

\subsubsection{Mensagem de pedido de dados}

No modo manual, o SALbot quando recebe uma mensagem deste tipo, vai enviar o tipo de dados pedidos. Estes dados podem ser os valores das distâncias dos sensores de distância, o estado dos sensores de contacto, ou os valores da tabela de aprendizagem. Constituída por um \textit{byte}, a mensagem representa o tipo de dados a receber(figura \ref{fig:Protocolo_req_cmd}).

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_req_cmd_msg}\\
  \caption{Mensagem de pedido de dados.}\label{fig:Protocolo_req_cmd}
\end{figure}

Embora este tipo de mensagem seja normalmente para pedir dados ao SALbot a partir de uma interface num computador remoto, também é possível instruir o SALbot a apagar a sua tabela de aprendizagem.

\subsubsection{Mensagem de envio do estado dos sensores de distância}

Nesta mensagem, são enviados os dados relativos aos sensores de distância por infra-vermelhos e ultra-sons. Como é possível verificar na figura \ref{fig:Protocolo_sens_dist}, são enviados os valores das distâncias dos sensores de distância em dois \textit{bytes} por cada sensor: o primeiro \textit{byte} com o valor mais significativo e o segundo com o valor menos significativo. Como os valores lidos pelas portas analógicas do microcontrolador são de dez \textit{bits} de resolução, nos \textit{bytes} mais significativos dos valores das distâncias, os últimos seis \textit{bits} são ignorados.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_sensores_dist_msg}\\
  \caption{Mensagem de envio do estado dos sensores de distância.}\label{fig:Protocolo_sens_dist}
\end{figure}

\subsubsection{Mensagem de envio do estado dos sensores de contacto}

Uma vez que, os sensores de contacto só têm dois estados (ON e OFF) e estão dispostos por oito zonas de contacto distintas, basta um \textit{byte} para representar o estado de todos os sensores de contacto, em que cada \textit{bit} corresponde ao estado de um sensor. A ordem dos sensores de contacto no \textit{byte} enviado (figura \ref{fig:Protocolo_bumper}) corresponde ao \textit{byte} da porta do microcontrolador (PORTD), onde estão implementados os sensores de contacto.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_bumper_msg}\\
  \caption{Mensagem de envio do estado dos sensores de contacto.}\label{fig:Protocolo_bumper}
\end{figure}

\subsubsection{Mensagem de envio de um elemento da tabela de aprendizagem}

Esta mensagem foi concebida para possibilitar ao SALbot transferir tabelas de aprendizagem para um computador remoto e vice-versa. Assim é possível descarregar tabelas de aprendizagem do SALbot para um computador remoto, para serem analisadas ou simplesmente serem guardadas e posteriormente poderem ser carregadas para o SALbot.

Em cada mensagem apenas pode enviar-se quinze \textit{bytes} de dados e, mesmo que se pudesse enviar os \textit{bytes} todos da tabela numa só mensagem, tratando-se de uma mensagem muito comprida a enviar por uma comunicação sem fios, a probabilidade da transferência de dados ser interrompida ou corrompida seria grande. Por essas razões, em cada mensagem é enviado apenas um valor de uma posição da tabela de aprendizagem.

Neste tipo de mensagem, como se pode verificar na figura \ref{fig:Protocolo_Q_msg}, são enviados três \textit{bytes}. Os dois primeiros são relativos ao endereço da posição na tabela de aprendizagem, sendo o primeiro \textit{byte} o mais significativo do endereço e o segundo o menos significativo. O terceiro \textit{byte} enviado corresponde ao valor da tabela do respectivo endereço enviado.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_Q_msg}\\
  \caption{Mensagem de envio de um elemento da tabela de aprendizagem.}\label{fig:Protocolo_Q_msg}
\end{figure}

Para que a linha de comunicações não seja ocupada durante muito tempo com o envio dos valores da tabela de aprendizagem, os valores nulos da tabela de aprendizagem não são enviados.

\subsubsection{Mensagem de envio do progresso de aprendizagem}

Uma das métricas, possíveis para avaliar a aprendizagem em questão, consiste em medir o número de colisões de um robô, em função do número de iterações do algoritmo de aprendizagem. Esta mensagem (figura \ref{fig:Protocolo_learn_progress}), permite ao SALbot enviar dados relativos à progressão da aprendizagem, enviando o número da iteração e o número de colisões, desde o início da aprendizagem.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_learn_progress_msg}\\
  \caption{Mensagem de envio do progresso de aprendizagem.}\label{fig:Protocolo_learn_progress}
\end{figure}

Além disso, é também enviado o parâmetro $\varepsilon$ do algoritmo de aprendizagem SARSA. Dado que o parâmetro $\varepsilon$ representa um número racional entre 0 e 1, este deve ser definido no programa do microcontrolador como um \verb+float+. No entanto, o formato \verb+float+ do microcontrolador não é o mesmo de um computador, enquanto o do microcontrolador corresponde a 24 \textit{bits}, no computador corresponde normalmente a 32 \textit{bits}. Assim, por forma a evitar a conversão de um formato para o outro, o valor enviado na mensagem corresponde a cem vezes o valor de $\varepsilon$, sob a forma de um \verb+unsigned int+ (16 \textit{bits}).

\subsubsection{Mensagem de envio da acção executada}

Esta mensagem foi concebida para que seja possível identificar na interface do computador remoto a acção executada por cada SALbot. Nesta mensagem (figura \ref{fig:Protocolo_acção}) é enviado apenas o número correspondente da acção executada pelo SALbot.


\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Protocolo_SALbot_action_msg}\\
  \caption{Mensagem de envio da acção executada pelo SALbot.}\label{fig:Protocolo_acção}
\end{figure}

\section{Software}

\subsection{Algoritmo de aprendizagem}
\label{seq:Learning_algorithm}

Os dois os SALbot foram programados com o mesmo software, que foi desenvolvido para testar e avaliar o desempenho dos robôs com um algoritmo básico de aprendizagem. O algoritmo de aprendizagem implementado foi o SARSA (\textit{State-Action-Reward-State-Action}), que pode ser visto mais pormenorizadamente no anexo \ref{seq:SARSA}. Muito resumidamente, o SARSA (equação \ref{eq:SARSA2}) é um algoritmo de aprendizagem \textit{model-free}, muito idêntico ao \textit{Q-learning} (equação \ref{eq:q_learning2}), sendo que, a maior diferença entre eles, reside no facto de o SARSA ser um método de aprendizagem \textit{on-policy}, enquanto o \textit{Q-learning} é um método de aprendizagem \textit{off-policy}. Ou seja, enquanto no \textit{Q-learning} é estimado o valor máximo de $Q$ do próximo par de estado-acção para o cálculo do valor de $Q$ actual, no SARSA, em vez disso, para o cálculo do valor de $Q$ é usado o valor de $Q$ do próximo par estado-acção após a escolha da próxima acção, usando a mesma política que determinou a acção actual, no estado actual. Nas fórmulas \ref{eq:q_learning2} e \ref{eq:SARSA2}: $a$ corresponde a uma acção; $s$ corresponde a um estado; $r$ é a recompensa; $\alpha$ é uma constante entre $[0,1]$ designada por coeficiente de aprendizagem ou \textit{learning rate}; e $\gamma$ é o factor de desconto, também um valor entre $[0,1]$.

\begin{equation} \label{eq:q_learning2}
\mathit{ Q(s_{t} , a_{t}) = Q(s_{t} , a_{t}) + \alpha \Big[r_{t + 1} + \gamma \max_{a} Q(s_{t + 1} , a) - Q(s_{t} , a_{t})\Big] }
\end{equation}

\begin{equation} \label{eq:SARSA2}
\mathit{ Q(s_{t} , a_{t}) \leftarrow Q(s_{t} , a_{t}) + \alpha \Big[r_{t} + \gamma Q(s_{t + 1} , a_{t + 1}) - Q(s_{t} , a_{t})\Big] }
\end{equation}

Para o tipo de aprendizagem pretendido, para testar o SALbot, foi necessário adequar o algoritmo ao robô. Ou seja, uma vez que o objectivo é fazer o robô circular por um ambiente sem colidir, o robô não tem um estado terminal e cada passo corresponde a um episódio. Utilizaram-se os parâmetros de aprendizagem mais comuns para este tipo de algoritmo: $\varepsilon = 0.5 ; \alpha = 0.5 ; \gamma = 0.3$. Em que $\varepsilon$ (factor de exploração) corresponde à probabilidade de escolher uma acção aleatória.

\subsection{Acções e estados}

Foi necessário, ainda, discretizar as acções e estados possíveis para o SALbot. Tendo em consideração o objectivo da aprendizagem (percorrer um ambiente sem colidir), foram consideradas seis acções distintas: andar em frente (acção 0); curvar para a direita (acção 1); curvar para a esquerda (acção 2); rodar 90$^{\circ}$ para a direita (acção 3); rodar 90$^{\circ}$ para a esquerda (acção 4) e andar para trás (acção 5). As acções foram configuradas em passos de duração, que variam consoante a acção. Esses passos de duração correspondem ao envio do sinal PW $n$ vezes.

Quanto aos estados, cada estado é definido consoante as medições dos sensores de distância e contacto. Foram definidos quatro níveis de distância para os sensores de distância por infra-vermelhos laterais e frontal, e três níveis de distância para os sensores de distância por infra-vermelhos traseiro e ultra-sons frontal. Nos sensores de contacto, utilizaram-se quatro \textit{bits} em que cada \textit{bit} corresponde a uma zonas distinta: frente, lateral esquerda, lateral direita e traseira; a que correspondem 16 estados diferentes. Assim obtemos $4\times4\times4\times3\times3\times16 = 9216$ estados possíveis. Embora a maioria dos estados previstos seja muito improvável de acontecer, como por exemplo o SALbot colidir nos quatro lados e estar longe de um objecto de todos os lados, os estados têm de ser contemplados, caso contrário estaríamos, de certa forma, a indicar ao robô que nunca iria aprender aqueles estados. Para que a combinação dos sensores corresponda a um estado, concebeu-se uma função (equação \ref{eq:states}) que combina os estados de cada sensor num estado único.
\begin{center}
    \begin{equation} \label{eq:states}
    \mathit{Estado = a + A b + A B c + A B \Gamma d + A B \Gamma \Delta e + A B \Gamma \Delta E f}
    \end{equation}

    %\caption{} \label{tab:state_comb_def}
    \begin{tabular}{|c|c|c|}
      \hline
      % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
      Sensor & Nível & Número de combinações \\
      \hline
      pára-choques & a & $A$ \\
      sensor de ultra-sons frontal & b & $B$ \\
      sensor de infra-vermelhos frontal & c & $\Gamma$ \\
      sensor de infra-vermelhos traseiro & d & $\Delta$ \\
      sensor de infra-vermelhos lateral esquerdo & e & $E$ \\
      sensor de infra-vermelhos lateral direito & f & $Z$ \\
      \hline
    \end{tabular}
\end{center}

Para o SALbot receber uma recompensa pela acção executada existe uma função que calcula a recompensa. A recompensa depende se o SALbot colidiu ou não, caso ocorra uma colisão a recompensa é de $-10$ por cada sensor de contacto activado. Se não existir nenhuma colisão, a recompensa é a soma das recompensas para cada sensor, ou seja, cada sensor possui uma recompensa para cada nível:

\begin{center}
    %\caption{Recompensa para cada nível dos sensores de distância.} \label{tab:sens_levels_reward}
    \begin{tabular}{|c||c|c|c|c|c|}
      \hline
       & sensor de & sensor de & sensor de & sensor de & sensor de \\
      Nível & ultra-sons & infra-vermelhos & infra-vermelhos & infra-vermelhos & infra-vermelhos \\
       & frontal & frontal & traseiro & lateral esquerdo & lateral direito \\
      \hline
      0 & $+2$ & $+4$ & $+3$ & $0$ & $0$ \\
      1 & $+1$ & $+3$ & $+2$ & $+2$ & $+2$ \\
      2 & $0$ & $+1$ & $-3$ & $-1$ & $-1$ \\
      3 & $-$ & $-3$ & $-$ & $-3$ & $-3$ \\
      \hline
    \end{tabular}
\end{center}

A recompensa total é a soma da recompensa do nível de cada sensor.

\begin{figure}[!h]
    \centering
    \includegraphics[width=.5\textwidth]{SALbot_state_rep}\\
    \caption{Representação dos níveis dos sensores de distância.}\label{fig:SALbot_dist_level_rep}
\end{figure}

Os níveis de cada sensor de distância (representados na figura \ref{fig:SALbot_dist_level_rep}) foram definidos tendo em conta as acções previstas (figura \ref{fig:SALbot_actions}) e as limitações dos sensores. Os níveis máximos correspondem a objectos mais próximos e os níveis mínimos objectos mais distantes. Foram retirados os valores lidos dos sensores de distância por infra-vermelhos para a situação em que o robô se encontra com obstáculos encostados ao pára-choques para definir o nível máximo. Isto foi feito porque os sensores se encontram a menos de 30 mm da face dos pára-choques e eles não podem detectar obstáculos a distâncias menores de 30 mm.

%Para os sensores de distância por infra-vermelhos traseiro e frontal mediram-se os valores destes para uma distância de 100 mm a um obstáculo para definir os níveis mínimo e intermédio respectivamente. Visto que a acção de andar para a frente e para trás permitem ao SALbot percorrer uma distância de 100 mm.
%
%Para os níveis intermédios dos sensores de distância por infra-vermelhos laterais, mediram-se os valores destes para obstáculos a uma distância para a qual o SALbot executando a acção de curvar para o lado do sensor a medir o obstáculo se encontra-se encostado ao pára-choques.
%
%Para os níveis mínimos dos sensores de distância por infra-vermelhos laterais e frontal mediram-se os valores para um obstáculo a uma distância de 200 mm.
%
%No caso do sensor de distância por ultra-sons, o nível máximo foi definido para o valor que representa a distância de 150 mm, uma vez que o sensor envia sempre este valor para objectos abaixo desta distância

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{SALbot_actions}\\
  \caption{Representação das várias acções do SALbot.}\label{fig:SALbot_actions}
\end{figure}

Os níveis médios dos sensores de distância por infra-vermelhos laterais e frontal, bem como o nível mínimo do sensor traseiro, foram definidos pelos valores retirados dos sensores para a detecção de obstáculos tangentes ao círculo, que corresponde à rotação do SALbot, e paralelos aos lados do robô. Para a definição dos níveis mínimos dos sensores de distância por infra-vermelhos laterais e frontal, mediram-se os valores retirados destes para a detecção de obstáculos a uma distância de: 190 mm para a frente e 160 mm para os lados.

No caso do sensor de distância por ultra-sons, o nível máximo foi definido para o valor que representa a distância de 150 mm, uma vez que o sensor envia sempre este valor para objectos abaixo desta distância. O nível mínimo foi definido para uma distância aproximada a 300 mm.

Assim, os níveis dos sensores foram definidos para a seguinte gama de valores:

\begin{center}
    %\caption{Definição de cada nível dos sensores de distância.} \label{tab:sens_level_def}
    \begin{tabular}{|c||c|c|c|c|c|}
      \hline
       & sensor de & sensor de & sensor de & sensor de & sensor de \\
      Nível & ultra-sons & infra-vermelhos & infra-vermelhos & infra-vermelhos & infra-vermelhos \\
       & frontal & frontal & traseiro & lateral esquerdo & lateral direito \\
      \hline
      0 & $\geq 24$ & $< 240$ & $< 390$ & $< 200$ & $< 200$ \\
      1 & $[12,24[ $ & $[240,390[$ & $[390,400[$ & $[200,350[$ & $[200,355[$ \\
      2 & $\geq 24$ & $[390,400[$ & $\geq 400$ & $[350,450[$ & $[355,460[$ \\
      3 & $-$ & $\geq 400$ & $-$ & $\geq 450$ & $\geq 460$ \\
      \hline
    \end{tabular}
\end{center}

O SALbot guarda o valor de $Q$ de cada par de estado-acção numa tabela designada de tabela de aprendizagem (tabela \ref{tab:learning_table_example}). Nessa tabela, as acções estão dispostas ao longo das colunas e os estados ao longo das linhas. Embora se fale de uma tabela de aprendizagem, o SALbot guarda os valores em endereços da EEPROM externa. Surgiu assim a necessidade de transformar as duas dimensões da tabela numa dimensão a que corresponde um endereço. Semelhantemente ao que é feito para a definição de estado, multiplica-se o valor do estado pelo número de acções e somando depois o valor da acção, obtendo-se assim um endereço único a que corresponde um valor de $Q$ para um determinado par de estado-acção.

\begin{table}[!h]
    \begin{center}
    \caption{Tabela de aprendizagem do SALbot.}
    \label{tab:learning_table_example}
    \begin{tabular}{|c|*{2}{c|} c c *{2}{c|}}
    \hline
    \backslashbox{Estado}{Acção} & $a_{0}$ & $a_{1}$ & $\cdots$ & $a_{i}$ & $\cdots$ & $a_{5}$ \tnhl %\\ \cline{1-3} \cline{7-7}
    $s_{0}$ & $Q(s_{0},a_{0})$ & $Q(s_{0},a_{1})$ & $\cdots$ & $Q(s_{0},a_{i})$ & $\cdots$ & $Q(s_{0},a_{5})$ \tnhl %\\ \cline{1-3} \cline{7-7}
    $s_{1}$ & $Q(s_{1},a_{0})$ & $Q(s_{1},a_{1})$ & $\cdots$ & $Q(s_{1},a_{i})$ & $\cdots$ & $Q(s_{1},a_{5})$ \tnhl
    $\vdots$ & $\vdots$ & $\vdots$ & $\ddots$ & $\vdots$ &  & $\vdots$ \\
    $s_{j}$ & $\cdots$ & $\cdots$ & $\cdots$ & $Q(s_{j},a_{i})$ &  & $\vdots$ \\
    $\vdots$ & $\vdots$ & $\vdots$ &  &  & $\ddots$ & $\vdots$ \tnhl
    $s_{9215}$ & $Q(s_{9215},a_{0})$ & $Q(s_{9215},a_{1})$ & $\cdots$ & $\cdots$ & $\cdots$ & $Q(s_{9215},a_{5})$ \\
    \hline
    \end{tabular}
    \end{center}
\end{table}

\subsection{Gerador de números aleatórios}

Para o método de aprendizagem implementado, é necessário gerar números aleatórios: para escolher acções aleatórias; e para escolher entre procurar na tabela de aprendizagem a acção, a que corresponde o maior valor de $Q$ para o estado actual, ou gerar uma acção aleatória.

Uma vez que o microcontrolador não possui um contador de tempo real e para evitar usar uma função pseudo-aleatória (que devolve valores aleatórios com uma sequência predefinida), usou-se uma média dos valores lidos dos sensores de distância, assim que o SALbot é iniciado, para usar como ``semente'' da função aleatória. Assim, com essa ``semente'' a função pseudo-aleatória gera valores aleatórios com uma sequência que depende do valor da ``semente''. Isto é, para ``sementes'' diferentes a sequência de números aleatórios é completamente diferente.

\begin{figure}[!h]
    \centering
    \subfloat[]{
        \includegraphics[width=0.375\textwidth]{1000_rand_actions}
        \label{fig:SALbot_1000_rand_actions}}
\hspace{0.05\textwidth}
    \subfloat[]{
        \includegraphics[width=0.375\textwidth]{10000_rand_actions}
        \label{fig:SALbot_10000_rand_actions}}
    \caption{Geração de: (a) 1000 acções aleatórias; (b) 10000 acções aleatórias.}
    \label{figs:SALbot_rand_actions}
\end{figure}

Analisando a figura \ref{figs:SALbot_rand_actions}, é possível verificar que as percentagens das acções escolhidas aleatoriamente são muito semelhantes entre elas. Isto é, a probabilidade de escolher uma determinada acção é igual para todas.

\subsection{Modos de funcionamento}

A aprendizagem começa pelo estado de Inicialização da Aprendizagem (figura \ref{fig:SALbot_software_SARSA_init}). Nesse estado, primeiro são inicializados os parâmetros e valores de aprendizagem, depois o robô verifica o estado em que se encontra, e escolhe aleatoriamente uma acção; no final, o modo de operação do SALbot é automaticamente alterado para Aprendizagem. Na inicialização dos parâmetros e valores de aprendizagem, primeiro são repostos os parâmetros $\varepsilon$, $\alpha$ e $\gamma$, a contagem do número de iterações e de colisões é colocada a zero e a tabela de aprendizagem é apagada e colocada a zeros. Não é possível colocar o SALbot no modo de Aprendizagem sem que este tenha passado anteriormente pelo estado de Inicialização da Aprendizagem.

\looseness-1Já no modo de Aprendizagem (figura \ref{fig:SALbot_software_learn_step}), é iniciado um ciclo que só termina quando o SALbot mudar de modo de operação. Nesse ciclo o SALbot começa por executar a acção previamente escolhida, verifica o estado após a execução da acção, calcula o valor da recompensa pela acção executada, escolhe uma nova acção (aleatória ou a acção com maior valor de $Q$ para o estado em que se encontra), calcula o valor de $Q$ para o par de estado-acção anterior e volta ao início do ciclo.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.8\textwidth]{Software}\\
  \caption{Fluxograma da rotina \textit{Main}.}\label{fig:SALbot_software_main}
\end{figure}

Foram definidos cinco estados de operação diferentes para o SALbot: o \textit{Idle}, Autónomo, Manual, Inicialização da Aprendizagem e Aprendizagem. Estes estados de operação correspondem a diferentes modos de execução do SALbot. O estado \textit{Idle} faz com que o robô fique em repouso e apenas verifique se recebeu algum comando. No estado Autónomo, o robô executa acções perante os estados em que se encontra, procurando na tabela de aprendizagem a acção que maior valor tem para o estado em que o robô se encontra. O modo de Inicialização da Aprendizagem apenas tem a finalidade de inicializar os parâmetros de aprendizagem para iniciar uma nova aprendizagem. Após a execução das tarefas associadas ao modo de Inicialização da Aprendizagem, o estado do SALbot é automaticamente mudado para Aprendizagem. Enquanto o robô se mantiver no estado de Aprendizagem são gerados episódios de aprendizagem.

A figura \ref{fig:SALbot_software_main} mostra o fluxograma da rotina \textit{Main} do SALbot, onde é possível verificar as funções de cada estado.


\begin{figure}[!h]
    \centering
    \subfloat[]{
        \includegraphics[width=0.2\textwidth]{software_SALbot_init}
        \label{fig:SALbot_software_SALbot_init}}
\hspace{0.15\textwidth}
    \subfloat[]{
        \includegraphics[width=0.2\textwidth]{software_SARSA_init}
        \label{fig:SALbot_software_SARSA_init}}
    \caption{Fluxograma das rotinas: (a) Inicialização do SALbot; (b) Inicialização da Aprendizagem.}
    \label{figs:SALbot_software_inits}
\end{figure}

%\begin{figure}[!h]
%  \centering
%  \includegraphics[width=0.5\textwidth]{Software_Inits}\\
%  \caption{Fluxograma das rotinas: Inicialização do SALbot e Inicialização da Aprendizagem.}\label{fig:SALbot_software_inits}
%\end{figure}

A inicialização do SALbot e da aprendizagem (figura \ref{figs:SALbot_software_inits}) são rotinas que configuram e parametrizam funções e variáveis.

Na inicialização do SALbot, são configuradas as portas, digitais e analógicas, do microcontrolador, a porta série, o temporizador, utilizado para controlar os sinais PW que comandam os servos, e os parâmetros da comunicação I$^{2}$C\textsuperscript{\scriptsize{\texttrademark}}.

A rotina de inicialização da aprendizagem serve para anular a tabela de aprendizagem, repor os parâmetros de aprendizagem nos valores originais e iniciar uma aprendizagem, lendo o estado actual do robô e escolhendo uma acção aleatória.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.5\textwidth]{Software_Learn_step}\\
  \caption{Fluxograma da rotina de Aprendizagem.}\label{fig:SALbot_software_learn_step}
\end{figure}

No episódio de aprendizagem (figura \ref{fig:SALbot_software_learn_step}) é executado uma iteração do algoritmo SARSA. Para que seja possível ao SALbot sair do modo de aprendizagem, ou executar outras tarefas, após a execução da acção, o SALbot vai verificar se existem dados recebidos pela porta série. Após o processamento das mensagens, ou caso não existam mensagens, é continuada a iteração do algoritmo de aprendizagem.

\looseness-1A rotina de processamento de mensagens (figura \ref{fig:SALbot_software_msg}), verifica se os dados recebidos pela porta série correspondem a uma mensagem válida, segundo o protocolo implementado para a comunicação entre os robôs e a interface no computador. Depois, caso seja recebido um comando, este é executado.

\begin{figure}[!h]
  \centering
  \includegraphics[width=0.7\textwidth]{Software_Msg}\\
  \caption{Fluxograma da rotina de Processamento de mensagens.}\label{fig:SALbot_software_msg}
\end{figure}

Porém, como já foi referido anteriormente, se o SALbot estiver no modo Manual, não é verificada a validade da mensagem, segundo o protocolo implementado. Apenas é verificado se foi recebido um comando e, caso seja recebido, este é executado.

%\newpage
\clearpage

\section{Interface no PC}

A interface gráfica (figuras \ref{fig:SALbot_Com1} e \ref{fig:SALbot_Com2}) no computador remoto foi concebida com o fim de se poder comandar e monitorar os dois SALbot. Através da interface, é possível escolher o modo de execução de cada um dos SALbot. No modo Manual, é possível pedir dados dos sensores de distância e de contacto ao SALbot, bem como carregar e descarregar tabelas de aprendizagem do robô. Em qualquer modo, é possível abrir e guardar ficheiros relativos à progressão de aprendizagem (gráfico) e tabela de aprendizagem. Estes ficheiros são do tipo csv (\textit{comma separated values}) para que seja possível visioná-los e interpretá-los num programa de folhas de cálculo, já que a interface não mostra a tabela de aprendizagem.

%\begin{figure}[ht]
%    \centering
%    \subfloat[Secção de monitorização dos sensores e de comando do modo de operação do SALbot2.]{
%        \includegraphics[width=0.68\textwidth]{SALbot_Com_interface1}
%        \label{fig:SALbot_Com1}}
%\hfill
%    \subfloat[Secção de monitorização e comando da aprendizagem do SALbot1.]{
%        \includegraphics[width=0.68\textwidth]{SALbot_Com_interface2}
%        \label{fig:SALbot_Com2}}
%    \caption{Interface gráfica no computador remoto.}
%    \label{figs:SALbot_Com}
%\end{figure}

Na interface existem dois ambientes: o do SALbot1 e SALbot2; dentro de cada um desse ambientes existem mais dois: Sensores e Aprendizagem. No ambiente Sensores de cada um dos SALbot é possível monitorar as distâncias, valores e nível dos sensores de distância, o estado do pára-choques o tipo de movimento do robô e ainda mudar o modo de operação do robô para Manual, Autónomo ou \textit{Idle}. Os modos de Inicialização de Aprendizagem e Aprendizagem, apenas podem ser escolhidos no ambiente Aprendizagem. Nesse ambiente, também é possível monitorar o progresso de aprendizagem, bem como as operações relativas aos dados da aprendizagem do robô já descritas, como carregar e descarregar a tabela de aprendizagem do SALbot.

\begin{figure}[ht]
    \centering
    \includegraphics[width=0.68\textwidth]{SALbot_Com_interface1}
    \caption{Secção, da interface gráfica, de monitorização dos sensores e de comando do modo de operação do SALbot2.}
    \label{fig:SALbot_Com1}
\end{figure}

\begin{figure}[ht]
    \centering
    \includegraphics[width=0.68\textwidth]{SALbot_Com_interface2}
    \caption{Secção, da interface gráfica, de monitorização e comando da aprendizagem do SALbot1.}
    \label{fig:SALbot_Com2}
\end{figure} 