====== Trabalho Prático 3: Controle ====== ===== 1. Proposta ===== No trabalho anterior foram introduzidos conceitos de sensoriamento e tratamento de dados. Agora a idéia é desenvolver técnicas que nos permitam ajustar o robô para exibir comportamentos bem determinados em situações mais complexas. Diferente da atividade anterior, onde as variações de parâmetros eram contornadas por alterações nos sensores ou na forma como os dados eram coletados, agora teremos de trabalhar em lógicas melhores para interpretar as informações captadas e tomar decisões. De forma resumida, as atividades propostas neste trabalho foram: * Adicionar um sensor opto-reflexivo à montagem e usar suas medidas em um algoritmo que faça o robô "seguir paredes"; * Comparar algumas soluções propostas no livro, como o uso de curvas "suaves" (ambos os motores permanecem acionados), "abrutas" (apenas um motor permanece ligado durante a curva) e algoritmos de três estados. * Fazer a montagem proposta na seção 5.2, para controle de posição usando sensores de interrupção de feixe com medição em quadratura. Implementar controladores de posição do tipo P e PD e compará-los; * Adicionar sensores de interrupção de feixe ao robô, e implementar um controle de posição das rodas, de modo que o sistema possa descrever linhas retas de comprimento pré-definido; * Implementar o algoritmo "wave-front" discutido em sala. Este deverá permitir a definição do alvo e obstáculos de forma dinâmica. Dada a natureza do algoritmo, será necessário também implementar funções que permitam ao robô fazer giros de noventa graus com precisão. ===== 2. Planejamento Inicial ===== O nome deste item foi mantido apenas por tradição, visto que não houve planejamento na execução deste trabalho. Consequentemente, as propostas não foram implementadas e não possuíamos nada concreto no dia da apresentação. O futuro do grupo ainda é incerto, mas não entraremos mais a fundo nestes problemas. O fato é que não apresentamos o trabalho três, e se participarmos da competição teremos tarefas extras a fazer. Isto porque, além de preparar a avaliação prévia, será necessário implementar as funcionalidades desenvolvidas neste trabalho, pois estas serão muito úteis no evento em questão. Nestas condições, o presente relatório foi elaborado apenas para discutir os algoritmos para controle e "wall follow", pois foram os únicos items das atividades propostas que implementamos. Destacamos ainda que nenhum deles foi testados no robô, e também não foram atribuídos alguns valores associados a dados dos sensores (como os valores da histerese do sensor ótico, ou os ganhos de velocidade, que dependeriam da resolução dos encoders). Estes foram indicados como "????" nos códigos em anexo. Caso estes valores fossem ajustados, os algoritmos estariam prontos para teste. ===== 3. Algoritmos desenvolvidos ===== Foram escritos códigos para todas as funcionalidades solicitadas nos itens 2 e 3 do enunciado do trabalho, que correspondem aos exercícios do livro-texto sobre "wall follow" e controle. Destacamos que foi escrito um algoritmo para cada funcionalidade citada, portanto ainda faltou criar um programa que permitisse ao usuário selecionar qual funcionalidade deseja usar. Cada arquivo abaixo possui comentários ao longo de todo o código, alguns explicam detalhes do programa e outros falam sobre a lógica implementada de forma geral. Assim, as soluções são auto-contidas, portanto acrescentaremos aqui apenas algumas diretrizes gerais sobre cada arquivo. ==== 3.1 Algoritmos "Wall Follow" ==== Esta atividade consistia em uma lista de exercícios do livro. No primeiro deles, deveríamos alterar um algoritmo-exemplo, de modo a introduzir uma janela de histerese no sistema. Uma de nossas decisões de projeto foi implementar curvas "suaves", isto é, para o robô virar mantemos os dois motores acionados no mesmo sentido, mas com potências diferentes. Desta forma o robô avança enquanto vira, melhorando a distância percorrida por unidade de tempo. Esta abordagem também reduz erros por ultrapassagem da referência (overshoot), pois como a variação de distância entre o robô e a parede é mais lenta, o sistema tem mais tempo para detectar se a referência foi atingida e reagir adequadamente. Outra característica do nosso algoritmo é permitir calibrar previamente a distância que deve ser mantida e a duração do percurso. O código completo pode ser visto no arquivo 1 da seção de documentação. A segunda atividade desta seção consistia em comparar implementações usando curva abrupta e curva suave quando o robô estivesse seguindo uma parede com quinas. Como o objeto de comparação era o tipo de curva, decidimos usar o exemplo do livro ao invés do nosso algoritmo de três estados. Desta forma não há uma rotina de avanço em linha reta, portanto o robô sempre estará fazendo curva para um dos lados, o que tornará mais evidente as diferenças que queremos visualizar. Apesar dos dois algoritmos serem bem semelhantes (a diferença é apenas na potência aplicada aos motores durante as curvas), disponibilizamos ambos na seção de documentação (arquivos 2 e 3). A atividade 3 deste item consistia em avaliar os resultados do algoritmo de três estados em paredes com quinas, e como já citado, não foi implementada. A atividade 4 consistia em alterar o algoritmo de três estados, de modo que a curva se tornasse mais acentuada quanto maior fosse o erro entre a distância medida e a desejada. Isto caracteriza um controlador do tipo P, e foi esta a solução que adotamos. Uma propriedade interessante deste novo algoritmo é que não precisamos mais de uma função de fazer curva para cada lado. Como o erro é sempre "referência - sinal medido", temos informação sobre a magnitude do erro (dada pelo módulo), e de sua direção (dada pelo sinal algébrico). Em nossa implementação, durante uma curva, ambos os motores recebem uma potência somada a uma constante arbitrária multiplicada pelo erro. Esta constante possui o mesmo modulo para ambos os motores, mas em um deles ela é positiva e no outro é negativa. Assim, o que define qual motor recebe um aumento e qual recebe redução de potência é o sinal do erro. A implementação destas idéias pode ser vista no arquivo 4 da seção de documentação. Outro ponto interessante é que, da forma como está implementada a função de curvas deste item, poderíamos ter suprimido a função de andar em linha reta, pois enquanto o robô mantiver a distância desejada em relação à parede, o erro será nulo, fazendo com que os dois motores recebam a mesma potência. No entanto pretendíamos testar esta idéia depois que a primeira vesão do algoritmo já estivesse funcionando, coisa que nunca aconteceu. ==== 3.2 Algoritmos para Controle de Posição==== Para este item deveriamos fazer dois exercicios da seção sobre controle PD do livro. No primeiro deles deveriamos realizar a montagem indicada e alterar um algoritmo-exemplo para implementar um controle de posição PD. Além disso deveríamos sintonizá-lo e descrever o método que usamos para achar os valores de ganho adequados. Não há realmente muito o que discutir sobre a solução de programação adotada, visto que consistia apenas em alterações simples em relação ao que o livro apresentava. O ponto interessante deste item seria a avaliação dos resultados e a determinação dos ganhos, mas não chegamos a executar esta parte. De qualquer forma, apresentamos o código implementado no item 5 da seção de documentação. A segunda atividade deste item consistia em montar shaft-encoders nas rodas do robô e implementar uma rotina que fizesse o sistema andar em linha reta por distâncias pré-definidas. Como o controle do item anterior era baseado na contagem de um shaft-encoder, muitas idéias foram aproveitadas para esta atividade. A diferença é que agora, além de cuidar do controle de posição de cada roda, também devemos manter algum sincronismo entre elas. Nossa solução foi implementar para cada roda um controlador PD semelhante ao do item anterior, porém acrescentamos um termo de acoplamento em ambos, sendo este proporcional à diferença entre as contagens dos encoders. Além disto, nosso robô pode receber a distância a ser percorrida como parâmetro, medida em contagens do encoder (pretendiamos mapear este parâmetro para centímetros após os testes). Os valores permitidos vão de 0 a 9999, porém acreditamos que o robô não irá se mover, ou não se comportará bem para valores muito baixos. O algoritmo implementado está no item 6 da seção de documentação. Os shaft-encoders já estavam montados no robô desde o trabalho 1, mas usavam uma lógica de controle bastante rudimentar. Infelizmente não chegamos a testar esta implementação para podermos comparar os desempenhos. ===== Conclusões e Propostas de Melhorias ===== Esta é mais uma seção do relatório que foi mantida por tradição. O trabalho não foi concluído, e dentre o que foi feito, nada foi testado em ambiente real. Portanto não há resultados dos quais tirar conclusões, e as propostas de melhorias são tão numerosas quanto óbvias. Após esta ocorrência lamentável, o grupo ainda precisa se reunir para decidir o que será feito a partir de agora, afinal ainda temos a competição para tentar nos redimir. ===== Documentação ===== 1: {{:cursos:introrobotica:2010-2:grupo07:wall_follow_3_state.pdf|}} 2: {{:cursos:introrobotica:2010-2:grupo07:wall_follow_curva_abrupta.pdf|}} 3: {{:cursos:introrobotica:2010-2:grupo07:wall_follow_curva_suave.pdf|}} 4: {{:cursos:introrobotica:2010-2:grupo07:wall_follow_proporcional.pdf|}} 5: {{:cursos:introrobotica:2010-2:grupo07:controle_pd_geartrain.pdf|}} 6: {{:cursos:introrobotica:2010-2:grupo07:controle_pd_robo.pdf|}}