DAMI-M1 v1.3.0

Nos testes de locomoção que fiz com a v1.2.0 do DAMI-M1 fiquei insatisfeito com os resultados. O movimento é claramente mais rectilineo, e o arranque não produz grandes desvios de orientação. Mas acho que ainda pode e deve ser melhorado. Saber como é que devo proceder é  a grande questão.

Para descobrir uma solução terei adoptar uma abordagem sistemática com a introdução de pequenas melhorias seguida de teste para avaliar os resultados.

Os procedimentos necessários são exequiveis com a ligação do robot por cabo ao pc, conforme efectuei com a versão anterior do DAMI-M1, mas queria faze-lo sem estar ligado ao computador por fios e para isso optei por colocar um Banana pi no robot e usa-lo para efectuar as pequenas modificações do programa e obter os resultados dos sensores e controlos por rede.

Esta necessidade enquadra-se numa ideia mais alargada de controlo e monitorização remota do robot que espero chegar ao traçado do mapa do ambiente com a localização do robot no ecran do meu computador.

No processo pensei em usar o programa Processing3, que serve entre outras coisas para traçar gráficos cientificos e tem um cliente tcp, assim como um server tcp. Mas como é habito, nada é facil, e apesar de conseguir traçar uns pontos numa janela com base nos dados recebidos por tcp atravez de um sofware simples de servidor em python no banana pi, apercebi-me que teria que passar algum tempo a tentar comprender melhor o funcionamento o Processing3.

Face ás dificuldades acabei por usar o Banana pi para gerar um ficheiro com os dados da sessão e disponibilizar os ficheiros numa partilha de rede, e os graficos continuam a ser feitos por excel com base neles.

O processo funciona, mas no entanto terei que analisar as diferenças que existem entre o comportamento do erro relativamente ao setPoint da velocidade nos graficos mais abaixo para perceber se as diferenças são geradas pela menor frequencia de amostragem deste metodo, face ao que usa o monitor serie do IDE.

Acima, o grafico que está no fim do artigo a apresentar a v1.2.0 do DAMI-M1, abaixo o grafico que está no fim  deste artigo.

Como se pode observar, as linhas rosa no primeiro gráfico não tem tanta volatilidade, ou seja o erro face ao setPoint da velocidade é mais contido.

A serie 1, azul é o setPoint da velocidade, a Serie 2 o erro dos pulsos face a esse setPoint, e a Serie 3 é o erro de face ao setPoint da direcção (0).

Portanto  diria que está aberta uma nova area de desenvolvimento do DAMI, a sua monitorização remota.

Hardware

O DAMI-M1 teve algumas alterações e hardware novo nesta versão é o seguinte:

  • Interruptor para a alimentação dos motores
  • Banana pi M1
  • Arduino Nano168 trocado por um Nano 328p
  • IMU 10dof waveshare
  • Power Pack 6800 mA / 2.1 A
  • Uma breadboard micro para fazer as ligações I2C

Segue uma breve descrição das alterações efectuadas e dos problemas surgidos.

Instalação do Banana Pi

O banana pi, montado na sua caixa, foi instalado na parte inferior da plataforma superior do DAMI, de forma a que as várias saidas, excepto as do video composto e do som, ficassem acessiveis facilmente.

Banana pi, bateria e IMU montados na parte inferior da plataforma

Como o pi foi montado em parte do espaço ocupado anteriormente pela bateria, esta foi colocada mais a frente, tambem fixa na parte inferior da plataforma superior, por um suporte de plastico com 4 parafusos compridos. Esse plastico foi também aproveitado para fixar o IMU de 10DOF da Waveshare.

Inicialmente pensei ligar o Pi usando a mesma bateria que alimenta todos os componentes. Mas as coisas correram mal, e acabei por voltar a solução do power pack que já tinha testado no meu primeiro robot.

Para isso fiz uma pequena placa adicional com um regulador de tensão de 5V, um divisor de tensão de 13V para 5V, (leitura de carga da bateria), outro divisor de tensão de 5V para 3.3 (para ligar o TX do arduino ao RX do pi), e ainda saida para um sensor de corrente, e por ultimo uma saida para alimentação da BARD, e uma entrada  à qual a o cabo da bateria se liga directamenta.

Placa adicional de alimentação

Nesta configuração, o robot nao necessitava da instalação do power pack para alimentar o pi, e portanto a plataforma superior não tinha ficado tão alta.

Mas quando fui testar a placa a alimentar o pi, ele ia abaixo pouco depois de arrancar e por vezes não arrancava. Na altura não suspeitei do cabo, mas mais tarde, já depois de tudo montado, quando tentei ligar o power pack a uma breadboard com o mesmo cabo, o pi não funcionou na mesma.

Cabo de ligação ao pi

Mas directamente do power pack com outro cabo funciona. O cabo tem uma coisa, deve ser uma especie de filtro; não sei. Na foto está visivel. Suspeito que seja isso que  não permite o fluxo da intensidade de corrente necessária a estabilidade do pi.

Independentemente do que falhou, acabei por colocar o power pack, e em vez da placa descrita acima, coloquei uma pequena placa com um divisor de tensão de 5V para 3.3V para ligar o RX do pi ao TX do arduino, assim como a terra de ambos.

Divisor de voltagem entre o RX do banana pi é o TX do arduino

No final surgiu um problema de interferencia da ligação serie por software com o controlo do servo, que foi resolvido pela ligação do servo ao arduino que não tem a ligação serie.

Mais tarde devo voltar a esta questão da alimentação do Pi, eventualmente mantendo o power pack, que num teste alimentou o pi durante 5:30h, e usar os 5V da placa adicional para alimentar os servos, ou pura e simplesmente esquecer o power pack, e diminuir a altura do robot.

Instalação do Power Pack 6800 mA / 2.1 A

O power pack está instalado na parte superior da plataforma inferior, por baixo do banana pi, e fixo entre três suportes plásticos.

A sua orientação permite que o conector de entrada (carregar) e saida, ligação ao pi, fiquem disponiveis nas laterais do robot.

Na parte de trás existe o orificio onde está um parafuso que impede o deslize do power pack para traz.

Power pack e suporte fixado a parte superior do chassi

A sua instalação fez aumentar a altura do robot, já que o espaço necessário aumentou.  Para isso tive que substituir os quatro parafusos M3 de 70 mm por uns bocados de varões de roscado M3 com cerca de 85mm cada um.

Visão frontal ainda sem os componentes montados no topo

Instalação do IMU 10DOF da Waveshare

A instalação fisica do componente foi efectuada na placa de plastico usada para fixar a bateria à parte inferior da plataforma. Encontra-se localizada mais ou menos no centro do eixo das rodas. Está relativamente plana, com o eixo do y a apontar para a frente.

Como as bibliotecas para este IMU têm todas requisitos de memória bastante elevados, tornou-se necessário substituir o Arduinio nano 168 por um nano 328P, que tem o dobro da memória.

Como a BARD não contempla nenhum conjunto de pinos SDA e SCL para ligações I2C, e existem mais componentes a comunicar por I2C, recorri temporariamente uma bread board micro (azul), visivel na foto, que não está fixa a lado algum.

 

Visão superior do robot já com todas as novas peças montadas

Por ultimo, efectuei a ligação do SDA e SCL dos dois arduinos, do IMU e do sensor de distancia VL53L1X  á breadboard.

Estava completa a nova versão do hardware do DAMI-M1, pensada para ter um microcontrolador dedicado à locomoção, outro à colecta de dados dos sensores, ambos ligados por I2C, e o ultimo destes, o master, ligado por porta serie a um microcomputador de uso geral o banana pi.

Software

O software teve que acompanhar estas modificações, e por isso cada arduino tem o seu próprio programa adequado ás  suas tarefas.

Os dois arduinos já estavam montados, usei o robot para fazer a avaliaçao dos sensores de distancia laser que tenho,  mas não comunicavam entre eles.

Utilização do I2C

A comunicação entre os arduinos é efectuada por I2C, sendo o arduino responsavel pelos sensores o master, e o arduino da locomoção o slave.

A comunicação de dados por I2C tem caracteristicas próprias nomeadamente os seus limites. Só transmite bytes e um limite de 32 bytes por comunicação.

Pelo que percebi, para passar dados numéricos de por I2C existem duas formas, strings e bytes.

Optei por comunicar os dados como bytes, acho que é mais economico do ponto de vista da memória e do processamento, pois não é necessário fazer grandes conversões.

De resto a estrutura da comunicação utilizada foi a integração de quatro exemplos (master/slave/reader/writer) existentes da  biblioteca wire do arduino IDE.

A biblioteca escolhida para ambos foi a Wire. Mais tarde posso equacionar opções mais económicas do ponto de vista da memória para a substituir.

Utilização da porta serie

Para além da comunicação entre arduinos e com os sensores, toda ela efectuada por I2C, foi necessário contemplar uma comunicação minima por porta serie com o banana pi.

Esta parte do software foi também elaborada com base no exemplo existente no IDE.

Bibliotecas para acesso e controlo dos sensores e motores

Para aceder aos dados do sensores e para controlar o servo são usadas bibliotecas.

O uso de bibliotecas como a do IMU implica o uso de parte significativa da memória disponivel, quer para o programa quer para as variaveis.

No caso do Arduino slave, o rascunho usa 13650 bytes (44%) do espaço de armazenamento do programa, e as variáveis globais usam 746 bytes (36%) de memória dinâmica. O loop time esta predominantemente nos 0 e 1 ms por vezes 2ms.

No caso do Arduino master, o rascunho usa 26790 bytes (87%) do espaço de armazenamento do programa, e as variáveis globais usam 1661 bytes (81%) de memória dinâmica. O loop time esta em cerca de 31ms.

Neste ultimo caso já está a dar o aviso de eventual falta de memoria.

Arduinos Nano

dami_m1_master_sensor_mod1_v2

/*
*
* DAMI-M1
*
* master-sensor-mod1-vx
*
* LIBRARIES
* SoftwareSerial (pi serial connection)
* Wire (Arduino I2C Master)
* SparkFun VL53L1X 4M Laser Distance Sensor
* Waveshare 10DOF IMU
* – SparkFun MPU-9250 9-DOF IMU
* – Adafruit BMP280 Library
*
*/

dami_m1_slave_motion_mod1_v2

/*
*
* DAMI-M1
*
* slave-motion-mod1-vx
*
* Shared PIDs for speed and steering
* Adaptative steering pidKs for start + under move above error limit
* Speed Change (step 1 pulse until target)
* – increase: step 1 pulse until target (wait period on start)
* – decrease: distance to decrease speed (Torricelli equation)
*
* LIBRARIES
* Servo (sg90)
* Wire (Arduino I2C slave)
* PID_v1
*

Banana pi

#!/usr/bin/python

import serial
ser = serial.Serial('/dev/ttyS0',115200)

import time
timestr = time.strftime("%Y%m%d-%H%M%S")

file1 = open("/files/smb/datalogs/damilog1-"+timestr+".txt","w")
file2 = open("/files/smb/datalogs/damilog2-"+timestr+".txt","w")
while True:
read_serial=ser.readline()
file1.write(read_serial);
read_serial = read_serial.replace('\n', '')
serialReadings = read_serial.split("\t")
# 0 bodyEncoderLeftTotalPulses
# 1 bodyEncoderRightTotalPulses
# 2 bodySpeedPidSetPoint
# 3 bodySpeedPidInput
# 4 bodySpeedPidOutput
# 5 bodySteeringPidInput
# 6 bodySteeringPidOutput
# 7 bodyMoveDistanceRemain
# 8 heading2D
# 9 heading3D
# 10 yaw
# 11 pitch
# 12 roll
file2.write(serialReadings[2] + " " + serialReadings[3] + " " + serialReadings[5] + '\n');
print serialReadings[2] + " " + serialReadings[3] + " " + serialReadings[5]
#print read_serial

 

Resultados

O objectivo a alcançar com o Banana pi era conseguir tracar um gráfico em tempo real usando o Processing3, para analisar o comportamento do robot sem a influência dos fios.

Não fui muito bem sucedido o Processing3 é complicado e apesar de ter conseguido obter os dados e fazer o plot, o resultado ficou aquém do esperado, pelo que resolvi usar o Excel e importar ficheiros gerados pelo script phyton exibido acima.

O plot exibido abaixo refere se ao vídeo exibido logo abaixo.

Este é o vídeo relativo ao plot acima

Entretanto também fiz outro vídeo do mesmo trajecto, mas sem recolha de dados.

 

 

Coisas por fazer

  • Fazer com que o codigo comando 0, numa sequencia de comandos signifique o fim do conjunto de comandos e o reinicio da sequencia (mod1v3)
  • Modificar o type do elemento cmd da estrutura bodyMoveCmdType, de int para byte (mod1v3)
  • Fazer com que sejam passadas 16 variaveis por loop do master em vez das 8 actuais (mod1v3)
  • Flexibilizar o codigo i2c do master para poder trabalhar com varios slaves arduino (mod1v3)
  • Corrigir um bug no controlo de desaceleração, impedindo que reduza antes de fazer metade do percurso (mod1v3)
  • Aplicar a equação de torricelli no calculo da velocidade maxima. Resolver em ordem da velocidade final.  (mod1v5)
  • Fazer com que o movimento em curso seja interrompido, suspenso, e alterado.
  • Fazer o carregamento de uma sequencia de movimentos no slave a partir do master
  • Fazer a implementação de coeficientes adaptativos no pid da velocidade (mod1v3)
  • Reescrever os pids adaptativos de forma mais coerente com 3 niveis de coeficentes e ter uma variavel de controlo indice (mod1v4)
  • Continuar a estudar e a aperfeiçoar o controlo dos motores no movimento retilineo
  • O slave actualizar a sua posição num espaço bidimensional com 3 graus de liberdade (x, y, a) medidos a partir da origem inicial da sessão (0,0, 0), em que o eixo dos x é coincidente com o eixo das rodas e o do y seu perpendicular no centro do eixo, isto face à orientação inicial da sessão, e  o eixo do a varia entre 0 e 359. com origem em 0 igual á orientação inicial da sessão
  • Com o duplo objectivo de mitigar os limites de memória e dimuir o tempo do loop no arduino responsavel pela comunicação, estudar a implementação de um terceiro arduino a funcionar como segundo master, encarregue das comunicaçoes entre os arduinos e o pi. Enquadrar também no estudo o uso de um mega.
  • Experimentar um novo cabo no pi, e voltar a experimentar o circuito adicional de alimentação.

Reformular a BARD, de modo a incluir:

  • um novo arduino
  • conectores macho no pinos analogicos dos arduinos
  • conectores para vários dispositivos I2C
  • jumpers na alimentação dos arduinos
  • regulador de tensão de 6V para os motores
  • regulador de tensão de 3.3V
  • conectores de alimntação 5V e 3.3V para vários dispositivos

end