Criando arquivos de launch
Tendo visto como os arquivos de launch podem ser usados, estamos prontos para pensar como criá-los para nosso uso.
Sumário
Onde colocar arquivos de launch
Assim como todos os outros arquivos ROS, cada arquivo de launch deve estar associado a um pacote específico. O esquema de nomeação serve para dar nomes aos arquivos de launch, terminando com .launch
. O lugar mais simples para armazenar os arquivos de launch é diretamente no diretório de pacotes. Quando estiver procurando por arquivos de launch, o roslaunch
também buscará por subdiretórios de cada diretório de pacote. Alguns pacotes, incluindo vários do núcleo de pacotes ROS, utilizam este recurso ao organizar os arquivos de launch dentro de um subdiretório próprio, usualmente chamado launch
.
Ingredientes Básicos
Os arquivos de launch mais simples consistem de um elemento raíz contendo diversos elementos node
.
Inserind o o elemento raíz
Arquivos de launch são documentos XML, e cada documento XML deve ter exatamente um elemento raíz. Para os arquivos de launch do ROS, cada elemento raíz é definido por um par de etiquetas launch
:
<launch>
...
</launch>
Todos os outros elementos de cada arquivo de launch devem ser inclusos entre estas etiquetas.
Nós de launching
O coração de qualquer arquivo de launch é a coleção de elementos nós, que nomeia um único nó a ser executado. Um elemento nó se parece com:
<node
pkg="package-name"
type="executable-name"
name="node-name"
/>
⚠️ A barra final próxima ao fim da etiqueta do nó é importante e fácil de ser esquecida. Ela indica que nenhuma etiqueta de fechamento (“
</node>
”) está por vir, e que cada elementonode
está completo. Parsers do tipo XML são necessários para sermos rigorosos com esse tipo de coisa. Se você omitir essa barra, esteja preparado para erros do tipo:Invalid roslaunch XML syntax: mismatched tag
You can also also write the closing tag explicitly:
node pkg="..." type="..." name="..."></node>
Na verdade, esta etiqueta de fechamento é necessária se o nó tem filhos, tais como
remap
ou elementosparam
. Estes elementos são introduzidos nas seções 6.4 and 7.4, respectivamente.
Um elemento node
tem três atributos necessários:
- Os atributos
pkg
etype
identificam qual programa ROS deve ser executado para iniciar este nó.
Estes são os mesmos que os dois argumentos de linha de comando dorosrun
, especificando o nome do pacote e o nome do executável, respectivamente. - O atributo
name
designa um nome para o nó. Isso sobrescreve qualquer nome que o nó normalmente atribuiria a si mesmo na sua chamada doros::init
.
⏩ Esse ato de sobrescrever elimina a informação quanto ao nome provida ao
ros::init
, incluindo qualquer outra requisição que o nó possa ter feito para um nome anônimo. (Veja a Section 5.4.) Para utilizar um nome anônimo de dentro de um arquivo launch, use uma substituiçãoanon
para o atributo do nome, do tipo:name="$(anon base_name)"
Note, no entanto, que múltiplos usos do mesmo nome base gerarão o mesmo nome anônimo. Isto significa que (a) podemos nos referir àquele nome em outras partes do arquivo de launch, mas (b) devemos ser cuidadosos ao utilizar diferentes nomes base para cada nó que desejamos tornar anônimos.
Encontrando arquivos de log de um nó
Uma diferença importante entre o roslaunch
e a execução individual de cada nó utilizando o rosrun
é que, por padrão, as saídas padrão dos nós executados são redirecionadas para um arquivo de log, não aparecendo no console1. O nome do arquivo de log é:
∼/.ros/log/run_id/node_name-number-stdout.log
O run_id
é um identificador único gerado quando o master é iniciado. Os números nestes arquivos são pequenos inteiros que numeram os nós. Por exemplo, executar o arquivo de launch na Lista 6.1 envia a saída padrão de dois dos seus nós para um arquivo de log com os seguintes nomes:
turtlesim-1-stdout.log
telep_key-3-stdout.log
Estes arquivos de log podem ser visualizados por meio de um editor de texto à sua escolha.
Direcionando saídas para o console
Para sobrescrever esse comportamento para um único nó, use o atributo output
no seu elemento node
:
output="screen"
Nós iniciados com esse atributo exibirão a sua saída padrão em tela ao invés de exibir nos arquivos de log discutidos acima. Esse exemplo usa o esse atributo para o nó subpose
, o que explica porque as mensagens INFO
desse nó aparecem no console. Isso também explica porque esse nó não está presente na lista de arquivos de log acima.
Além do atributo output
, que afeta somente um único nó, nós podemos forçar o roslaunch
mostrar a saída de todos os seus nós, utilizando a opção de linha de comando --screen
:
roslaunch --screen package-name launch-file-name
⚠️ Se um programa, quando iniciado a partir do
roslaunch
, não produz a saída que você espera, deve-se verificar se aquele nó tem o atributooutput="screen"
habilitado.
Solicitando respawning
Após iniciar todos os nós requisitados, o roslaunch
monitora cada um deles, rastreando aqueles que permanecem ativos. Para cada nó, podemos solicitar o roslaunch
que reinicie quando estiver finalizado, ao utilizar o atributo respawn
:
respawn="true"
Isso pode ser útil, por exemplo, para nós que podem finalizar prematuramente, devido a falhas de software, problemas de hardware, ou outras razões.
O atributo respawn
não é realmente necessário no nosso exemplo—Todos os três programas são bastante confiáveis—mas nós incluímos para o turtlesim_node
de modo a ilustrar como o respawning funciona. Se você fechar a janela do turtlesim
, o nó correspondente será finalizado. O ROS rapidamente nota isso e, já que aquele nó está marcado como um nó de respawn
, um novo nó turtlesim
, com sua janela correspondente, aparece para substituir o anterior.
Solicitando nós
Uma alternativa ao respawn
é declarar que um nó é required
:
required="true"
Quando um nó do tipo required
termina, o roslaunch
responde finalizando todos os outros nós ativos, finalizando ele mesmo. Este tipo de comportamento pode ser útil, por exemplo, para nós que (a) são tão importantes que, se falharem, a sessão por completo deve ser abandonada, e (b) não podem ser normalmente reiniciados pelo atributo respawn
.
O exemplo usa o atributo requerido para o nó turtle_teleop_key
. Se você fechar a janela na qual o nó de teleoperação está rodando, o roslaunch
finalizará os outros dois nós e sairá.
⚠️ Devido ao conflito entre os significados entre eles, o
roslaunch
reclamará se você definir ambos os atributosrespawn
erequired
para um único nó.
Executando nós nas suas próprias janelas
Uma desvantagem em potencial ao utilizar o roslaunch
, comparado à nossa técnica original de utilizar o rosrun
em um terminal em separado para cada nó, é que todos os nós compartilham o mesmo terminal. Isto é administrável (e muitas vezes útil) para nós que simplesmente geram mensagens de log, e não aceitam entradas do console. Para nós que dependem de entradas do console, como é o caso do turtle_teleop_key
, pode ser preferível manter os terminais separados.
Felizmente, o roslaunch
provê uma maneira limpa de obter isso, utilizando o atributo launchprefix
de um elemento de nó:
launch-prefix="command-prefix"
A ideia é que o roslaunch
inserirá o dado pré-fixo no começo da linha de comando que ele constrói internamente na execução do nó em questão. No example.launch
, utilizamos este atributo para o nó de teleoperação:
launch-prefix="xterm -e"
Por conta deste atributo, esse elemento de nó é aproximadamente equivalemnte a este comando:
xterm -e rosrun turtlesim turtle_teleop_key
Como você deve saber, o comando xterm
inicia uma simples janela terminal. O argumento -e
diz ao xterm
para executar o restante da sua linha de comando (nesse caso, rosrun turtlesim turtle_teleop_key
) dentro de si mesmo, no lugar de um novo shell interativo. O resultado é que o turtle_teleop_key
, um programa estritamente baseado em texto, aparece dentro de uma janela gráfica.
⏩ O atributo
launch-prefix
, naturalmente, não é limitao aoxterm
. Ele também pode ser útil na
depuração (viagdb
ouvalgrind
), ou para diminuir o nível de prioridade de um processo (vianice
).
1 Na versão atual do roslaunch
, saídas de erros padrão—notavelmente incluindo as saídas de console de ERROR-
e FATAL-level
mensagens de log—aparecem no console, ao invés de estarem presentes nos arquivos de log. Entretanto, um comentário no código fonte do roslaunch
enfatiza que este comportamento pode ser modificado no futuro.