Grupo 8 - 404! Esse grupo não existe!
Trabalho Prático 2
Introdução
A locomoção é uma característica inerente à maioria dos seres vivos. Por isso, um mecanismo capaz de simular esse atributo é muito interessante em aplicações na robótica. Um robô capaz de navegar em um rio para localização de objetos, resgate ou até mesmo realizar tarefas em altas profundidades é uma aplicação muito significativa, por exemplo, para empresas petrolíferas e para a marinha. Outra forma de explorar a locomoção é através de veículos aéreos não tripulados, como os drones, que estão presentes em indústrias, no exército e, inclusive, como mecanismo de entrega de encomendas da Amazon. Além disso, há ainda os robôs baseados em locomoção terrestre, que vão desde veículos autônomos movidos a rodas até a imitação de passos de seres humanos (como o Asimo, da Honda) e animais (como o Big Dog, da Boston Dynamics).
Comparando-se os robôs de base fixa com os robôs de base móvel, é possível perceber benefícios decorrentes da base móvel. Além de aumentar o espaço de trabalho, as aplicações se estendem a diversos ambientes. Um braço robótico com base fixa, por exemplo, tem um espaço de trabalho limitado aos graus de liberdade, aos graus de atuação e aos limites de juntas relacionados ao manipulador, isto é, ele se encontra confinado em uma certa área do mundo. Existe, portanto, um ganho no espaço de trabalho ao adicionar-se uma base móvel ao robô: um robô terrestre, por exemplo, ganha três graus de liberdade; um robô capaz de voar ganha seis graus de liberdade; e um robô aquático pode ganhar seis ou três graus de liberdade, dependendo de sua capacidade ou não de submergir, respectivamente.
Ao se considerar uma base móvel, além dos benefícios, existem algumas restrições ligadas ao tipo de rodas utilizadas. A tração diferencial, que é o foco do trabalho, possui restrições não-holonômicas e, por isso, não é capaz de gerar velocidades em qualquer direção instantaneamente. Apesar das restrições, essa base é interessante para tarefas simples, como seguimento de trajetória, que é um dos pontos que este trabalho aborda: trajetória em linha reta, em forma de quadrado e triangular.
Outro aspecto a se explorar com a adição da base móvel é a interação com o ambiente, que se dá através de sensores e atuadores. Os atuadores, no caso deste trabalho, acionam as rodas diferenciais, e o sensor LDR detecta as intensidades das cores, a fim de realizar tarefas específicas.
O desenvolvimento de um robô móvel com tração diferencial e equipado com um sensor LDR é o objetivo central deste trabalho.
Especificações das tarefas
Tarefa de Locomoção
A tarefa de locomoção foi dividida em três trajetórias:
. Seguimento de linha reta;
. Seguimento de um quadrado; e
. Seguimento de um triângulo.
Tarefa de Identificação de Cor
A tarefa de identificação, da mesma forma, foi dividida em três partes:
. Montagem do sensor LDR e do LED;
. Calibragem do sensor; e
. Identificação da cor.
Multitarefa e tomada de decisão
A tarefa é dividida em duas partes:
. Identificação do cubo e tomada de decisão dependendo da cor do bloco; e
. Interrupção de todas as tarefas se o robô não identificar nenhum bloco.
Menu
Todas as tarefas devem ser acionadas facilmente pelo Menu
Especificações do robô
O robô é uma miniaturização de um caminhão e está montado sobre duas rodas fixas atuadas de forma independente. Tais rodas possuem seus eixos alinhados de maneira a possibilitar o movimento das rodas sem limitações relacionadas ao desbalanceamento dos eixos. Para o acionamento das rodas fixas houve uma redução de 3:25 em cada roda. Uma roda de suporte (roll on) foi adicionada a fim de garantir o funcionamento correto do robô. Os motorem foram acionados com 30% de potência. Para a aquisição de dados, um LED de três cores (RGB) foi conectado a resistores - 151 ohm para o led vermelho e 82 ohm para o verde e o azul (estes valores foram calculados considerando-se a especificação de corrente do fabricante, 20 mA, e a tensão de saída das portas utilizadas, 5V), e, posteriormente, à Handy Board nas portas de digital outputs. O LDR foi isolado do LED utilizando-se fita isolante e foi conectado na porta de analog input. Uma estrutura foi construída a fim de posicionar tanto o LED quanto o LDR. Uma estrutura adicional foi desenvolvida para restringir a distância de detecção dos blocos.
Acima podemos ver o teste das caixas e a estrutura do robô
Acima podemos ver o teste da tração e da roda final escolhida, além das caixas de engrenagens para as rodas
Desenvolvimento da lógica do código
O algoritmo criado para a execução das tarefas descritas acima envolve, de maneira simplificada, as seguintes partes: menu, fragmentos de trajetórias, calibração, identificação de cor, detecção de bloco e a interação das funções com a multitarefa.
Menu
O menu foi criado como uma chamada para uma função de controle que direciona as chamadas para as tarefas a serem realizadas. Um laço 'while' em loop infinito (while(1){…}) mantêm o menu sempre em execução, sendo que após a execução de qualquer uma das tarefas chamadas na função de menu principal, a função retorna para o 'main' onde é chamada novamente. Isso permite que o robô esteja sempre em um estado de prontidão para a execução das tarefas definidas. Para fazer a seleção de tarefas dentro do menu foi criada uma outra função que controla uma variável ligada ao acionamento (pressionar e então soltar) o botão de STOP. Essa função é chamada em uma 'thread' separada, e cada vez acionada é encerrada e reiniciada. O menu principal então, faz a chamada para a função de contagem de cliques em STOP e então espera (utilizando dois loops while) o acionamento do botão START para, considerando o valor da variável ligada ao botão STOP, fazer a chamada da função selecionada.
Fragmentos de trajetórias
A função responsável pelo acionamento do motor é a mesma do trabalho prático 1, runMotor(numMotor,potencia,tempo), que tem funcionamento intuitivo. Para a descrição das trajetórias foram calibrados empiricamente tempos para que o robô percorresse uma reta de 30cm e um ângulo de 90º que são os necessários para executar as mesmas e foram criadas duas funções que eram responsáveis por mandar o robô andar para frente - runStraight() -, fazendo com que a potência fosse positiva para ambos os motores, e uma função que fazia o robô virar- turnAround() -, atribuindo potências com sinais invertidos. A função para locomoverReta() simplesmente acionava runStraight() com potências positivas e negativas no tempo necessário para as retas serem percorridas. A função para locomverTriangulo() acionavam runStraight() para o primeiro cateto, turnAround() com o tempo necessário para um ângulo de 90º, runStraight() para o segundo cateto, turnAround() para o ângulo maior com um offset ajustando o tempo, runStraight() para a hipotenusa com um offset para ajustar o valor levemente maior que os catetos e finalmente turnAround() com um ângulo complementar ao anterior. A função locomoverQuadrado() simplesmente alternava entre runStraight() e turnAround() nas vezes necessárias para percorrer os lados do quadrado.

Aqui podemos verificar a caixa opaca construída para proteger os sensores das luzes externas, importante tanto para a calibração quanto para a consequente identificação de cores
Calibração
O algoritmo de calibração das cores consiste na criação de uma matriz 5×4. Cada linha da matriz representa uma cor de bloco: a primeira corresponde ao bloco vermelho, a segunda ao verde, a terceira ao azul, a quarta ao amarelo e a quinta ao preto. Cada coluna corresponde a uma média de 10 leituras do LDR: a primeira sob a incidência do led vermelho, a segunda sob o verde, a terceira sob o azul e a quarta sob nenhum led.
Identificação de cor
O algoritmo de identificação das cores foi baseado no método de mínimos quadrados. Ao ser acionado, cria-se um vetor 1×4 para o bloco a ser identificado, sendo as medidas das colunas valores tal qual descrito no algoritmo de calibração (uma média pra cada led incidindo isoladamente e uma média sem led). Após, o algoritmo compara os valores das colunas do vetor com os valores das colunas de cada linha da matriz de calibração, ou seja, os valores do bloco a ser identificado são comparados com os valores dos blocos calibrados. A comparação feita é o quadrado da diferença entre as medidas. Os valores desses quadrados são somados para uma mesma linha, e, por fim, decide-se que a cor do bloco não identificado é a mesma daquele bloco cuja comparação resultou em uma mínima soma de quadrados.
Detecção de bloco
O algoritmo para a detecção é capaz de saber quando há um bloco na frente do robô em movimento, fazendo-o parar para realizar a identificação. Para que o robô saiba quando há um bloco em sua frente, é necessária a utilização de um parâmetro de parada. O cálculo desse parâmetro envolve os valores da 4ª coluna (sem incidência de led) da matriz de calibração. O algoritmo consite em verficar o menor valor da quarta coluna, aplicar um índice de correção de 10% para menos (ou seja, o parâmetro utilizado corresponde a 90% do menor valor da 4ª coluna da matriz de calibração), e fazer o LDR ler dados durante o movimento até que o valor lido seja maior que o parâmetro ( o valor deve ser maior que o parâmetro porque, na nossa montagem, o LDR retorna valores mais próximos de 255 para ambientes escuros e mais próximos de 0 para ambientes claros).
Interação Multitarefa
A função Multitarefa foi interpretada intuitivamente como recursiva para o grupo, porem a Handyboard não suportou essa implementação. Para isso foi criada uma função auxiliar que ficava num loop com uma variável booleana de check, se uma das execuções da multitarefa(como encontrar bloco desconhecido/verde ou andar 10 segundos sem achar bloco) a função retornava 1 para a bool e essa terminava o loop. Basicamente os motores eram acionados por 10segundos e se o LDR detectasse uma interferência muito grande do ambiente, os motores eram desligados, o cubo era identificado e os procedimentos similares aos de trajetoria eram acionados para realizar a tarefa necessária.
Problemas encontrados
. Tamanho do robô foi modificado inúmeras vezes devido às reduções diferentes que foram testadas e à posição da plataforma da Handy Board;
. A roda de suporte (roll-on) não apresentou rolagem eficiente;
. Uma roda castor foi implementada, entretanto ela não possuiu a robustez necessária para suportar a Handy Board;
. Houve problemas com a identificação de cores devido à estrutura de restrição de distância;
. A intensidade luminosa do ambiente afetou a detecção dos blocos;
. Os blocos utilizados para a calibração não eram consistentes (havia muitas partes descascadas);
. O nível de bateria da Handboard alterou as trajetórias.
. O HandyBoard não lida bem com funções recursivas e portanto teve de ser criada uma lógica especial para tratar o algoritmo multitarefa que era intuitivamente recursivo.
. Variáveis globais são as únicas utilizaveis no projeto e isso gerou muita confusão com funções que chamavam outras e usavam as mesmas variáveis, foram necessárias criar variáveis com múltiplos nomes para as mesmas funções sem que houvesse interferência no funcionamento correto.
. Os motores não apresentavam potências iguais e para isso foi criada uma variável offset para ajustar o tempo em que ambos precisavam ficar ligados para que a distância percorrida fosse igual.
Outros Vídeos

