Visualizando as mensagens de protocolo
Sumário
Até agora, falamos um pouco sobre como criar mensagens de protocolo (mensagens de log), mas muito pouco sobre para onde essas mensagens realmente vão. Na realidade, existem três destinos diferentes para mensagens de protocolo: cada mensagem de log pode aparecer como saída no console, como uma mensagem no tópico de rosout
e como uma entrada em um arquivo de log. Vamos ver como usar cada um deles.
Console
Primeiramente, e de forma mais visível, as mensagens de protocolo são enviadas para o console. Especificamente, as mensagens DEBUG
e INFO
são impressas na saída padrão, onde as mensagens de WARN
, ERROR
, e FATAL
são enviadas para o padrão de erro.
⏩ Aqui, a diferença entre a saída padrão e o erro é basicamente irrelevante, a não ser que você deseje redirecionar um ou ambos os fluxos para um arquivo ou canal, que por sua vez causa algumas complicações. A técnica usual de redirecionamento de arquivo
command > file
redireciona a saída padrão, mas não o erro. Para englobar todos as mensagens de protocolo para o mesmo arquivo, ao invés disso use algo assim:
command &> file
Todavia, tenha cuidado pois as diferenças na forma como esses dois fluxos são armazenados no buffer pode fazer com que as mensagens apareçam fora de ordem - com as mensagens
DEBUG
eINFO
aparecendo mais tarde do que o esperado - no resultado. Você pode forçar as mensagens em sua ordem natural usando o comandostdbuf
para convencer a saída padrão a usar um buffer de linha:stdbuf -oL command &> file
Finalmente, perceba que o ROS insere códigos de cores ANSI - que parecem para humanos e para software que não os entende, algo como:
ˆ [[0m
- em sua saída, mesmo se a saída não estiver sendo direcionada a um terminal. Para visualizar um arquivo contendo esses tipos de códigos, tente um comando como este:less -r file
Formatando as mensagens de console
Você pode ajustar o formato usado para imprimir mensagens de protocolo no console definindo a variável de ambiente ROSCONSOLE_FORMAT
. Essa variável normalmente contém um ou mais nomes de campo, cada um denotado por um cifrão e chaves, mostrando onde os dados da mensagem de protocolo devem ser inseridos. O formato padrão é equivalente a:
[${severity}] [${time}]: ${message}
Esse formato é, provavelmente, adequado para a maioria dos usso, porém existem outros campos que ele pode ser útil:
- Para inserir detalhes sobre a localização do código-fonte a partir do qual a mensagem foi gerada, use alguma combinação dos campos
$ {file}
,$ {line}
e$ {function}
. - Para inserir o nome do nó que gerou a mensagem de protocolo, use o campo
$ {node}
A ferramenta
roslaunch
(que será apresentada no Capítulo 6) não afunila, por padrão, a saída padrão e o erro padrão dos nós que ela inicia para seus próprios fluxos de saída. Para ver a saída de um nóroslaunched
, você deve usar explicitamente o atributooutput =" screen "
, ou forçar todos os nós a ter este atributo--screen
com o parâmetro de linha de comando pararoslaunch
.
Mensagem no rosout
Além de aparecer no console, cada mensagem de protocolo também é publicada no tópico /rosout
. O tipo de mensagem deste tópico é rosgraph_msgs/Log
. A Lista 4.6 mostra os campos neste tipo de dados, que inclui o nível de gravidade, a própria mensagem e alguns outros metadados associados.
Lista 4.6
Campos no tipo de mensagem rosgraph_msgs/Log
.
byte DEBUG=1<p>
byte INFO=2
byte WARN=4
byte ERROR=8
byte FATAL=16
std_msgs / Header header
uint32 seq
time stamp
string frame_id
byte level
string name
string msg
string file
string function
uint32 line
string[ ] topics<p>
Você provavelmente notou que as informações em cada uma dessas mensagens são bastante semelhantes aos detalhes na saída do console discutida acima. A utilidade primária do tópico /rosout
, em comparação com a saída do console, é que ele inclui, em um único fluxo, uma mensagens de log de todos os nós do sistema. Todas essas mensagens de log aparecem em /rosout
, independentemente de onde, quando ou como seus nós foram iniciados, ou mesmo em qual computador eles estão rodando.
Como /rosout
é apenas um tópico comum, você pode, é claro, usar
rostopic echo /rosout
para ver a mensagem diretamente. Se você insistir, pode até escrever um programa de próprio para /rosout e exibir ou processar a mensagem da maneira que você preferir. Porém, a maneira mais simples de ver as mensagens /rosout é dada usando esse comando:
rqt_console
A Figura 4.2 mostra a GUI resultante. Ele mostra mensagens de protocolo de todos os nós, um por linha, junto com opções para ocultar ou destacar mensagens com base em vários tipos de filtros. A própria GUI não deve precisar de nenhuma explicação extra.
Figura 4.2: A interface para o rqt_console
.
⏩ A descrição de
rqt_console
acima não é totalmente verdadeira. Na verdade,rqt_console
subscreve/rosout_agg
ao invés de/rosout
. Aqui está o gráfico verdadeiro, quando nosso exemplo de contagem e de uma instância derqt_console
estão em execução:
O sufixo
_agg
se refere ao fato de que as mensagens são agregadas pelo nórosout
. Cada mensagem publicada no tópico/rosout
é ecoada no tópico/rosout_agg
pelo nórosout
. A razão para essa aparente redundância é para reduzir a sobrecarga do debugging. Como cada relacionamento editor-assinante leva a uma conexão de rede direta entre os dois nós, assinar/rosout
(para o qual cada nó é um editor) pode ser custoso em sistemas com muitos nós, especialmente quando esses nós geram muitas mensagens de protocolo. A ideia é que o nórosout
será o único assinante de/rosout
e o único editor em/rosout_agg
. Então, as ferramentas de dubug podem acessar o fluxo completo de mensagens de protocolo, sem criar trabalho extra para cada nó no sistema, inscrevendo-se em/rosout_agg
.Além disso, os pacotes ROS para alguns robôs, incluindo o PR2 e o TurtleBot, usam o mesmo padrão para mensagens de diagnóstico, que são originalmente publicadas em um tópico chamado
/diagnostics
e ecoadas por um nó agregador em outro tópico chamado/diagnostics_agg
.
Arquivos de Protocolo
O terceiro e último destino para mensagens de log é um arquivo de log gerado pelo nó rosout
. Como parte de sua função de retorno de chamada para o tópico /rosout
, este nó grava uma linha em um arquivo com um nome como este:
∼/.ros/log/run_id/rosout.log
Este arquivo de log rosout.log
é um arquivo de texto simples. Ele pode ser visualizado com ferramentas de linha de comando como less
, head
ou tail
, ou com seu editor de texto favorito. O run_id
é um identificador universalmente único (UUID) que é gerado - com base no endereço MAC do hardware do seu computador e na hora atual - quando o mestre é iniciado. Aqui está um exemplo de run_id
:
57aa1860-d765-11e2-a830-f0def1e189cc
O uso desse tipo de identificador exclusivo torna possível distinguir protocolos de sessões ROS separadas.
Encontrando o ID de execução
Existem pelo menos duas maneiras fáceis de aprender o run_id
da sessão atual.
- Você pode examinar a saída gerada pelo
roscore
. Perto do final desta saída, você verá uma linha parecida a esta.setting /run_id to run_id>
- Você pode pedir ao mestre o
run_id
atual, usando um comando como este:rosparam get /run_id
Isso funciona porque o run_id
é armazenado no servidor de parâmetros. Mais detalhes sobre os parâmetros estão no capítulo 7.
Fazendo o check-in e limpando arquivos de protocolo
Esses arquivos de log se acumulam com o passar do tempo, o que pode ser problemático se você usar o ROS por certo tempo em um sistema que tem limitações significativas (devido a uma cota de conta ou a limites de hardware) no espaço de disco. Tanto o roscore
quanto o roslaunch
executam verificações para monitorar o tamanho dos protocolos existentes e avisam quando eles excedem 1GB, mas nenhum deles toma medidas para reduzir o tamanho. Você pode usar este comando para ver a quantidade de espaço em disco na conta do usuário atual consumido por protocolos ROS:
rosclean check
Se os protocolos estão consumindo muito espaço em disco, você pode remover todos os protocolos existentes usando este comando:
rosclean purge
Você pode, também, se preferir, excluir os arquivos de log manualmente.