Este artigo é sobre a exploração do projecto genérico para controlo de braços robóticos em ROS com o nome NTBD, cujo o exemplo de implementação é feico com o eezybotarm mk2, e que está descrito no seguinte endereço:
https://hotblackrobotics.github.io/en/blog/2018/01/17/ntbd-guide-part-I/
Para além desta descrição existe também um repositório no github com o software usado na implementação do controlo do braço robótico eezybotarm mk2 no ROS e que está disponível nos seguintes endereços (o segundo é o meu fork)
- https://github.com/HotBlackRobotics/ntbd
- https://github.com/inaciose/ntbd
A exploração do software neste repositório será feita de dois modos:
- Numa primeira fase em conformidade com o procedimento descrito no artigo principal, onde se recorre ao um container do docker pré preparado pelo autor do projecto.
- Numa segunda fase será abordado de forma nativa de modo a compreender melhor o funcionamento de cada um dos pacotes.
- Numa terceira fase, irei alterar o hardware de controlo dos servos passando a usar uma placa de geração de sinais PWM com interface i2c baseada no chip PCA9685.
As duas primeiras fases partilham o mesmo hardware descrito no projecto ntbd, ainda sem o modulo PCA9865.
Hardware de controlo do braço robótico
Para além de um braço robótico adequado, o projecto ntbd usa como exemplo o eezibotarm mk2, mas pode ser aplicado noutros braços robóticos como por exemplo o eezibotarm mk1. é necessário o seguinte hardware:
- Um micro-controlador. O controlo dos servos pode ser efectuado por um micro-controlador, como por exemplo o ATMEGA 328p. Seguindo o projecto ntbd, será usado um Arduino Mega 2560.
- Um computador com linux capaz de correr o docker e o ROS. Pode ser um PC x86 ou Raspberry Pi. Na segunda fase o computador tem de ter o ROS instalado.
As ligações entre o arduino e os servos são as seguintes:
- Servo 1 sinal (amarelo) > Arduino pino 2
- Servo 2 sinal (amarelo) >Arduino pino 3
- Servo 3 sinal (amarelo) > Arduino pino 4
- Servo 4 sinal (amarelo) > Arduino pino 5
Podem ser usados outros pinos, desde que seja capazes de produzir um sinal PWM, mas para isso é necessário alterar o firmware.
Os servos devem ter alimentação externa. Não esquecer de partilhar a terra.
A ligação entre o computador e o Arduino é efectuada por uma interface USB.
Firmware de controlo do braço robótico
Microcontrolador tem que estar a correr um programa desenhado para o efeito.
No firmware original do ntbd, a integração no ROS é efectuda pelo recurso às bibiotecas rosserial, e para gerar o sinal PWM adequado é usada a biblioteca Servo.
O programa é bastante simples, mas o procedimento para a compilação é mais elaborado, e está descrito no seguinte artigo:
NTBD Robot Arm Arduino Firmware
Numa fase posterior será usado um modulo PCA9685, pelo que o firmware terá de ser alterado para o novo hardware.
Exploração do NTBD com Docker Containers
O autor do projecto NTBD preparou dois docker containers com os pacotes para o ROS para serem usados no projecto ntbd docker.
- O container o ntbd_base, contém os pacotes globais (ntbd_core e ntbd_msgs);
- O container ntbd_manipulator, contém o software especifico para o braço robótico. Neste caso o eezybotarm mk2.
Para além do software nos docker containers é ainda necessário proceder à preparação de um micro controlador, um Arduino Mega, com o firmware referido acima.
Para saber mais sobre o assunto consultar:
Explorar o eezyBotArm mk2 com NTBD Docker Container.
Exploração do NTBD sem docker
Exploração do software existente no repositório do ntbd no github de forma proceder á sua execução fora do docker.
Na base do repositório existem duas pastas. A pasta ntdb_base tem dois pacotes para o ROS que funcionam independentemente o braço robótico que está a ser explorado. Além desses dois pacotes tem ainda um ficheiro de configuração para o nginx. A pasta ntbd_manipulator tem o software especifico para um braço robótico, no caso o eezybotarm mk2, e o software para ser executado no webserver.
Para além dos pacotes do ros, e o software web, o respositório tem também o sketch para o arduino que subscreve o tópico motors do tipo Motors_Array, via rosserial.
ntbd_core
Existente dentro da pasta ntbd_base, é um pacote genérico que se encarrega do movimento dos servos com os seguintes com os seguinte scripts:
- motors_limiter, publica o tópico motors, e subscreve o motors_nolim;
- path_planner, publica o tópico desired_position, e subscreve o desired_position_nointerp;
- position_limiter, publica o tópico desired_position_nointerp, e subscreve o desired_position_nolim;
ntdb_msgs
Existente dentro da pasta ntbd_base, é um pacote genérico que contém a definição das mensagens do tipo Motors_Array
urdf_manipulator
Existente dentro da pasta ntbd_manipulator, é um pacote especifico para braço robótico, e tem as pastas de config, launch, meshes e urdf.
Este pacote esta dentro de uma pasta que a refere como abstrata.
Também na pasta ntbd_manipulator, e fora de qualquer pacote do ROS, estão os seguintes ficheiros:
- fk, publica o tópico actual_position, e subscreve o motors
- ik, publica o tópico motors_nogripper, e subscreve o desired_position
- motors_values, publica o tópico motors_nolim, e subscreve os tópicos: gripper_value e motors_nogripper
- physical_2_visual, publica o tópico joint_states, e subscreve o motors
Também de fora de qualquer pacote do ROS está o ficheiro NTBD_launch.launch.
Todos estes ficheiros tem de ser copiados para dentro de um pacote do ROS para poderem ser executados. Se usarmos o ficheiro launch NTBD_launch.launch, sem modificações, todos os ficheiros tem de ser copiados para o pacote ntbd_core.
O ficheiro NTBD_launch.launch tem um erro, pois refere o ficheiro siBOT_noEE.urdf na pasta robots, quando ele está na pasta urdf.
O projecto implica a instalação de alguns pacotes do sistema e do ROS caso não estejam previamente instalado com os seguintes comandos:
sudo apt install nginx sudo apt install ros-melodic-rosbridge-server sudo apt install ros-melodic-rosbridge-suite sudo apt install ros-melodic-tf2-web-republisher
Por último, já depois de ter copiado os scripts e o launch para o sitio certo, ter configurado o nginx, colocado o conteúdo da pasta web na pasta apropriada, e ter efectuado algumas alterações ao ficheiro launch efectuei a primeira tentativa de executar o ntbd fora do docker com o seguinte comando:
roslaunch manipulator_urdf NTBD_launch.launch
Com os pacotes do ntdb em execução é necessário apontar navegador para o endereço seguinte:
http://localhost
Mas as coisas não funcionaram pois, não visualizo o braço no interface web, conforme acontece quando se usa a versão do docker, e quando tento executar o interface web de controlo do braço dá-me sempre este erro:
2020-04-12 22:12:16+0100 [-] failing WebSocket opening handshake (‘missing port in HTTP Host header ‘localhost’ and server runs on non-standard port 9090 (wss = False)’)
2020-04-12 22:12:16+0100 [-] dropping connection to peer tcp4:127.0.0.1:33722 with abort=False: missing port in HTTP Host header ‘localhost’ and server runs on non-standard port 9090 (wss = False)
Nos seguintes links recolhi alguma informação sobre o assunto mas não consegui resolver o problema:
https://github.com/crossbario/autobahn-python/issues/775
https://github.com/RobotWebTools/rosbridge_suite/issues/467
Após analisar o index.html descobri que o interface fica funcional se alterar a linha 186 para o seguinte:
url : ‘ws://’+ window.location.hostname + ‘:9090’
Após este teste bem sucedido irei preparar dois pacotes ROS adequados a exploração dos braços eezybotarm mk1 e mk2 fora do docker.
Tópicos dos nodes usados pelo ntbd
- /actual_position (pub: FK)
- /client_count (pub: rosbridge_websocket)
- /connected_clients (pub: rosbridge_websocket)
- /desired_position (pub: path_planner; sub: IK)
- /desired_position_nointerp (pub: position_limiter; sub: path_planner)
- /desired_position_nolim (pub: rosbridge_websocket; sub: position_limiter);
- /diagnostics (pub: init_serial_node)
- /gripper_value (pub: rosbridge_websocket; sub: motors_values)
- /joint_states (pub: joint_state_publisher_gui, physical_2_visual; sub: robot_state_publisher)
- /motors (pub: motors_limiter; sub: FK, physical_2_visual, init_serial_node)
- /motors_nogripper (pub: IK; sub: motors_values)
- /motors_nolim (pub: motors_values; sub: motors_limiter)
- /tf (pub: robot_state_publisher; sub: tf2_web_republisher)
- /tf2_web_republisher/cancel (pub: rosbridge_websocket; sub: tf2_web_republisher)
- /tf2_web_republisher/feedback (pub: tf2_web_republisher; sub: /rosbridge_websocket)
- /tf2_web_republisher/goal(pub: rosbridge_websocket; sub: tf2_web_republisher)
- /tf2_web_republisher/result (pub: tf2_web_republisher; sub: /rosbridge_websocket)
- /tf2_web_republisher/status(pub: tf2_web_republisher; sub: /rosbridge_websocket)
- /tf_static (pub: robot_state_publisher; sub: tf2_web_republisher)