On the ROS calibration procedure, when we click the commit button, the node write a file to the ~/.ros/camera_info, with the name of the camera.
As far as i know today we may control the name of the camera adding the following code (need to check)
<param name="camera_name" value="vx800_camera" />
Depois de o ficheiro estar gravado, podemos fazer uma cópia do ficheiro para um pacote do ROS, de modo a que o possamos usar mais tarde, e ao mesmo tempo não correr o risco de perder o ficheiro por sobreposição de um ficheiro de calibração de outra camera com o mesmo nome.
Para isso deveremos acrescentar as seguintes linhas ao ficheiro launch que usamos para lançar o node com o driver da usb_cam.
Ultimamente tenho usado mais o gazebo para simular os robots e os diversos ambientes em que eles podem actuar.
A utilização que tenho feito do gazebo tem sido essencialmente orientada para o desenvolvimento de soluções para a viatura robótica do automec que será usada para competir nas provas de condução autónoma no Festival Nacional de Robótica.
Ao captarem a realidade as cameras introduzem distorção na representação que é feita. Essa distorção torna-se bastante visível quando se usa quadros de xadrez nas tomadas de imagem.
Apesar de ter lido que no gazebo a camera está pré calibrada e que não necessita de ser calibrada[1] pelo processo usado em cameras reais, uma investigação breve sobre IPM (Inverse Perspective Mapping), deixou claro que a utilização do quadro de xadrez é um elemento essencial para encontrar os parâmetros da transformação, e que todos os processos descritos incluíam a fase de calibração da camera, pela que a reprodução deste processo no gazebo torna-se importante.
Além disso também podemos definir os parâmetros intrínsecos no xml que define a camera [2].
Após uma pesquisa na web encontrei o pacote calibration_gazebo que após experimentar verifiquei que funcionava bem num dos exemplos que tinha integrado, mas que quando aplicado ao ambiente simulado usado no projecto do automec não funcionava.
Como alternativa usei apenas ficheiro sdf que define o quadro de xadrez, integrando-no pacote que define o ambiente de simulação.
Desta forma o quadro de xadrez fica disponível para inserção no ambiente simulado recorrendo a facilidade de drag and drop do gazebo.
Para o efeito cria-se uma pasta chamada chessboard, dentro da pasta models do pacote que define o ambiente simulado, no caso do automec (simulation_environment)
De seguida, copia-se os seguintes ficheiros para dentro da pasta criada. O ficheiro xacro serve apenas para gerar o ficheiro sdf, caso desejemos que o xadrez tenha outras características, como por exemplo quadrados de tamanho diferente.
Para colocar o quadro de xadrez no ambiente simulado basta arrastar a sua designação para a posição adequada (em frente da camera). Roda-lo de forma aos quadrados ficarem voltados para a camera. Durante o procedimento de calibragem, devemos desloca-lo e roda-lo até ficar disponível o botão Calibrate .
O seguinte comando dá inicio ao processo de calibragem. Nesse comando há que substituir o nome do tópico e da camera pelos correctos
Quando este comando é executado aparece uma janela onde fica visível a imagem captada pela camera, e quando é caso disso a indicação dos vertices identificados pelo programa.
Alem de 3 botões desligados (calibrate, save e commit) que se activam quando o programa capturar uma serie de imagem do quadro de xadrez com os vertices identificados.
Vai ser necessário identificar esses vertices algumas vezes, de vários angulos e distancias, sendo que é exibida na consola uma linha com os dados adquiridos em cada posição e orientação considerada.
Quando estiver activo, deve-se clicar no botão Calibrate, surgindo na consola os parâmetros de calibragem calculados recolhidos.
Posteriormente clicar no botão save para guardar um ficheiro de arquivo (/tmp/calibrationdata.tar.gz) com as várias imagens consideradas no processo de calibragem, e dois ficheiros com os parâmetros para calibrar a camera (ost.txt e ost.yaml)
Quando se clica no botão commit, é criado um ficheiro camera.yaml na seguinte pasta: ~/.ros/camera_info
O conteúdo do ficheiro criado nesta pasta é igual ao do ficheiro ost.yaml, e contêm os parâmetros de calibração da camera.
Este é o relato da experiência de utilização do pacote calibration_gazebo que está disponível no seguinte repositório:
https://github.com/oKermorgant/calibration_gazebo
Na primeira execução reparei que este pacote depende do pacote slide_publisher. Esta dependência pode ser satisfeita com o seguinte comando
sudo apt install ros-noetic-slider-publisher
Também está disponível no seguinte repositório
https://github.com/oKermorgant/slider_publisher
O erro que denuncia a dependência é o seguinte
Resource not found: slider_publisher
O comando que faz o spawn do quadro de xadrez para a calibração da camera é o seguinte:
roslaunch calibration_gazebo landmark.launch
Este comando pressupõe que o ambiente simulado já esteja em execução, pelo que no caso do projecto do automec será necessário executar por exemplo o seguinte comando:
No entanto na experiência efectuada o quadro de xadrez não apareceu.
Segundo a descrição do pacote o programa tentará identificar o link da camera (o primeiro a ter a palavra camera) e a fazer o spawn do quadro de xadrez á sua frente, caso não encontre o quadro aparece numa posição fixa.
O pacote contem os launch files que permite lançar dois ambientes simulados para testar o seu funcionamento.
roslaunch calibration_gazebo perspective.launch
roslaunch calibration_gazebo fisheye.launch
A execução do primeiro, seguido do comando para lançar o quadro, permitiu verificar que o quadro aparece em frente da camera.
Numa tentativa de identificar o que estava a acontecer, foi efectuada uma correcção do launch file de modo a poder observar as mensagens geradas pelo node.
No caso do do ambiente exemplo pré configurado no pacote 0 resultado na consola foi o seguinte:
process[calibration_gazebo/landmark_bridge-2]: started with pid [404599]
False
False
Found camera link at camera::camera_link
[INFO] [1632494079.717182, 0.000000]: Loading model XML from file /home/inaciose/catkin_ws/src/calibration_gazebo/sdf/landmark.sdf
[INFO] [1632494079.735229, 0.000000]: Waiting for service /gazebo/spawn_sdf_model
[INFO] [1632494079.743581, 16.158000]: Calling service /gazebo/spawn_sdf_model
[INFO] [1632494080.021423, 16.313000]: Spawn status: SpawnModel: Successfully spawned entity
Ficando o processo de calibração disponível conforme a imagem acima
No caso do ambiente simulado do projecto do automec o quadro de xadrez nunca aparece no ecrã e surgem as seguintes mensagens de erro.
process[calibration_gazebo/landmark_bridge-2]: started with pid [415518]
False
(...)
False
Could not find camera link, spawning landmark at (0,0,0.5)
[INFO] [1632494966.819862, 0.000000]: Loading model XML from file /home/inaciose/catkin_ws/src/calibration_gazebo/sdf/landmark.sdf
[INFO] [1632494966.824028, 24.350000]: Waiting for service /gazebo/spawn_sdf_model
Como após algumas pesquisas e verificações não consegui colocar o paccote a funcionar no ambiente de simulação usado no projecto do automec, passei para outra abordagem.
A nova abordagem foi usar apenas ficheiro sdf que define o quadro de xadrez, integrando-no pacote que define o ambiente de simulação.
Video da base para carro robot com direção ackermann
Numa primeira fase imaginei um robot com direção ackermann com um diferencial traseiro e um motor dc disposto de forma longitudinal relativamente ao chassis.
Para isso comprei no aliexpress um conjunto de peças que implementam uma direção ackermann, e um diferencial traseiro.
Numa impressora 3D fiz uns adaptadores (com rolamento) para as rodas da frente, e uns suportes de eixo (com rolamento) a aplicar com os eixos traseiros.
The new hardware version have the ESP8266 replaced by an ESP32, and new modules. An IMX219 camera, an IMU MPU6050, a smal OLED screen, connection available to a GPS (with basic software already tested on a breadboard), and an 3.3V power supply by an LM317T.
After some successfully preliminar tests, i try to free drive it to my living room, but i lost the robot control because the bad WiFi coverage.
After that event all my rosserial connections ended on error. See the terminal output bellow.
[INFO] [1630082983.539943]: Setup subscriber on pub_vel [std_msgs/Int16]
[WARN] [1630082997.385001]: Last read step: data checksum
[WARN] [1630082997.389949]: Run loop error: [Errno 104] Connection reset by peer
[INFO] [1630082997.395216]: Removing subscriber: pub_dir
[INFO] [1630082997.405242]: Removing subscriber: pub_vel
[INFO] [1630082997.413336]: Removing subscriber: cmd_vel
[INFO] [1630082997.421426]: Shutting down
[INFO] [1630082997.425133]: All done
Traceback (most recent call last):
File "/opt/ros/melodic/lib/rosserial_python/serial_node.py", line 73, in <module>
server.listen()
File "/opt/ros/melodic/lib/python2.7/dist-packages/rosserial_python/SerialClient.py", line 253, in listen
self.startSerialClient()
File "/opt/ros/melodic/lib/python2.7/dist-packages/rosserial_python/SerialClient.py", line 259, in startSerialClient
client.run()
File "/opt/ros/melodic/lib/python2.7/dist-packages/rosserial_python/SerialClient.py", line 556, in run
self.port.flushOutput()
AttributeError: RosSerialServer instance has no attribute 'flushOutput'
Today, the first connection, is successfully and stable. I believe that the yesterday issues are due to the wifi connections.
My home have a WiFi extender. The extender have the _EXT suffix on the ssid. If the main ssid is myssid, the extender have myssid_EXT.
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
The software required to explore the kinect xbox 360 in ROS must be compiled from sources.
First we need to build the libfreenect (no ros package) from sources, and only after that can build the freenect_stack (ros package) also from the sources.
We also need to install the ros package rgbd-launch with the following command
sudo apt-get install ros-noetic-rgbd-launch
build libfreenect
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git-core cmake freeglut3-dev pkg-config build-essential libxmu-dev libxi-dev libusb-1.0-0-dev
cd ~/src
git clone git://github.com/OpenKinect/libfreenect.git
cd libfreenect
mkdir build
cd build
cmake -L ..
make
sudo make install
sudo ldconfig /usr/local/lib64/
build freenect_stack
cd ~/catkin_ws/src
git clone https://github.com/ros-drivers/freenect_stack.git
cd ..
catkin_make
The kinect xbox 360 output topics can be visualized on rviz with the following displays:
Image
Camera
Pointcloud2
DeepCloud
In the ‘Global Options’ set the ‘Fixed Frame’ to ‘camera_link’.
The last two displays have configurations to give colors to points, superimposition of outputs, etc.
Not all topics produce visible output.
Error building freenect_stack
-- Checking for module 'libfreenect'
-- No package 'libfreenect' found
CMake Error at /usr/share/cmake-3.16/Modules/FindPkgConfig.cmake:463 (message):
A required package was not found
Solution: build libfreenect before
Error building freenect_stack
Resource not found: rgbd_launch
ROS path [0]=/opt/ros/noetic/share/ros
ROS path [1]=/home/inaciose/catkin_ws/src
ROS path [2]=/opt/ros/noetic/share
The traceback for the exception was written to the log file
Esta página reúne alguma informação recolhida na minha pesquisa e experiências com os dispositivo de localização GPS uBlox neo 6M e neo M8N no ROS.
As experiências foram efectuadas num ESP32 de 38 pinos, com a ligação serial no RX2 e TX2, e alimentação de 3.3V.
A exploração das informações recolhidas do GPS foi efectuada com a biblioteca tinygpsplus.
http://arduiniana.org/libraries/tinygpsplus/
A programação necessária foi efectuada no vscode com o platformio.
NMEA sentences
As informações go GPS são obtidas com base em fluxos de texto cujas linhas começam com as seguintes sequências de caracteres e cada uma delas agrupa informações especificas.
$GPRMC
$GPVTG
$GPGGA
$GPGSA
$GPGSV
$GPGLL
No caso do neo6M verifiquei que existem 3 linhas seguidas da $GPGSV
Estas mensagens fazem parte do grupo das sensor_msgs e incluem, para além da longitude, latitude e altitude, informações do tipo NavSatStatus (que contẽm informaçoes sobre os satélites)
Este tipo de mensagens contêm menos informações que as do tipo GPSFix.
Estas mensagens fazem parte do grupo das gps_common, definidas no pacote com o mesmo nome e incluem mais informações que as mensagens do tipo NavSatFix, também incluem informações do tipo GPSStatus (que contẽm informaçoes sobre os satélites)
Algumas particularidades na publicação da mensagem GPSFix
Devido ao limite do buffer do rosserial, o numero de satélites visíveis sobre os quais é publicada informação está limitado a 8 . Neste momento não estão a ser seleccionados todos os satélites em uso, o limite é por ordem no array.
A mensagem de erro na consola do ROS é a seguinte:
[ERROR] [1631463315.015253]: Message from device dropped: message larger than buffer.
Pelo que percebi, os satélites são aqueles cujo SNR é zero.
Outra particularidade é como preencher campos de mensagens ros que são arrays variáveis.
Segundo as informações no ros wiki (http://wiki.ros.org/msg) os arrais de inteiros são preenchidos com variáveis do tipo std::vector<T>, mas no rosserial este tipo não está disponível.
Para contornar este problema devemos, fazer com que o campo aponte para um array pré declarado, e posteriormente atribuir o numero de itens no array a um campo não documentado (msg.campo_lenght) na definição do tipo da msg do ros.
int array[MAX_ITENS];
(put values in the array)
gps_status_msg.satellite_visible_prn = array;
gps_status_msg.satellite_visible_prn_length = array_item_count;
GPSFix – Informações não preenchidas ou por confirmar
# Direction (degrees from north)
float64 track – gps.course.deg() ??? is from north?
# Vertical speed (meters/second)
float64 climb
# Device orientation (units in degrees)
float64 pitch
float64 roll
float64 dip
# Total (positional-temporal) dilution of precision
float64 gdop
# Temporal dilution of precision
float64 tdop
# Uncertainty of measurement, 95% confidence
all err_ and covariance information
GPSStatus – Informações não preenchidas
# Satellites used in solution
int32[] satellite_used_prn # PRN identifiers
uint16 motion_source # Source for speed, climb and track
uint16 orientation_source # Source for device orientation
uint16 position_source # Source for position