AtCore é um acrônimo para Atelier Core. O AtCore é uma biblioteca de comunicação
entre o computador e a impressora 3D que está licenciado sob uma licença Open Source. A partir desta biblioteca é possível conectar qualquer tipo de interface que seja compatível ao AtCore para o controle e gerenciamento de uma impressora 3D. Definimos a estrutura simplificada do AtCore na figura19 a seguir:
Figura 19 – Diagrama de Classe do AtCore Simplificado (Omitindo Métodos)
Nas próximas seções descreveremos as classes do AtCore.
5.4
Classe SerialLayer
A classe SerialLayer é responsável por toda a comunicação serial entre a impressora e o host. Por si só é uma classe bem simples, onde baseada na biblioteca QSerialPort1
do Qt, toda a questão de diferença de sistemas e portas que são usadas na conexão, principalmente nos sistemas Unix e Windows, são abstraídas por essa biblioteca, fazendo com que nossa única preocupação seja enviar, receber comandos e tratar eventuais erros que possam acontecer.
Para compatibilidade binária, que é a portabilidade de programas executáveis de uma plataforma ou versão para outra,usamos uma estrutura chamada d-pointer, que
5.5. Classe Temperature 41
segundo a definição encontrada na Wiki do Qt informa que a implementação e os detalhes
da biblioteca podem ser escondidos dos usuários e as mudanças na implementação podem ser feitas sem quebrar a compatibilidade binária2, ou seja, encapsulamos a biblioteca, fazendo
com que com a evolução do AtCore e suas versões, as versões futuras não quebrem as anteriores, evitando assim uma recompilação da aplicação. A compatibilidade binária pode ser quebrada quando alguma mudança na biblioteca força a recompilação da aplicação. Por isso todas as classes possuem uma estrutura privada que somente através desse ponteiro que os atributos e métodos serão acessados, evitando que novas versões do AtCore quebrem as anteriores. Nesta classe que somente o AtCore pode acessar, definimos variáveis que lidam com o que é enviado e retornado pela impressora através da porta serial, e que posteriormente podem ser transferida para camadas de interface ou não.
5.5
Classe Temperature
A classe Temperature foi criada para lidar com a aferição de temperaturas da cama e extrusores da impressora 3D. A classe analisa os retornos das strings de temperatura através de expressões regulares, e então armazena esses valores em variáveis que são posteriormente acessadas pela interface gráfica.
A seguir mostramos exemplos de tipos de strings retornadas pela impressora:
ok T:46.2 /215.0 B:34.1 /215.0 T0:46.2 /215.0 @:127 B@:127 P:31.7 A:32.1 ok T:135.7 /160.0 B:57.9 /160.0 T0:135.7 /160.0 @:127 B@:127
ok B:49.06 /55 T:64.78 /215
Por isso tratar cada temperatura, foi necessário, já que pelo menos os formatos B: para cama e T: para extrusores são padrões, mas a sua ordem e formatos de string não são. Neste momento o código se encontra limitado ao tratamento de somente uma temperatura de origem do extrusor, já que não possuímos acesso a impressoras 3D que possuem mais de um extrusor para efetuar testes e adaptações apropriados.
5.6
IFirmware e Plugins
A classe IFirmware é abtrata e deriva de uma interface, onde a partir dela esten- demos as outras classes que são os plugins do AtCore. Para criar plugins seguimos as definições da documentação do Qt para a criação dos mesmos. Isso implicou na criação da classe IFirmware, e nos plugins que herdam da mesma, além de usar o QPluginLoader para fazer o carregamento destes plugins na aplicação principal3. Como dizemos na Seção
3.1, são vários os firmwares para impressoras 3D e pelas variações que eles possuem
2 https://wiki.qt.io/D-Pointer
42 Capítulo 5. Atelier Printer Host
criamos uma estrutura de plugins baseadas nesta classe que trata as especificidades de cada firmware. Por ser uma interface, a maioria de seus métodos são métodos virtuais que são implementados nas respectivas classes de plugin. Cada classe possui uma macro, ’Q_DECLARE_INTERFACE’, que a define como interface para o Qt meta-object system,
que reconhece a mesma.
A partir disso criamos os plugins. Até o momento da escrita desse trabilho são sete plugins criados a partir dos firmwares que são open-source, incluindo o firmware GRBL, que é a base de onde a Impressão 3D foi construída.
Para que estes plugins sejam carregados, temos um método que realiza uma análise para descobrir o caminho onde os plugins foram instalados. A partir do início da conexão, temos um segundo método que analisa automaticamente qual o plugin instalado na impressora 3D e a partir dessa análise realizar o carregamento do plugin definido. O usuário também possui a escolha de pré-configurar qual o firmware que sua impressora possui, e no caso da conexão o sistema pula a parte de detecção automática.
Como mencionado, para fazer o carregamento do plugin é necessário usar a classe
QPluginLoader4. A partir do sucesso dessa operação, a impressora estará devidamente
conectada e podemos usá-la normalmente.
Uma das vantagens de usarmos o Qt é o uso de signals e slots. Esta ferramenta é possível graças ao Qt meta-object system, que já mencionamos anteriormente. Um sinal é disparado quando um evento particular ocorre, e a este sinal temos conectado uma função, que ao receber o sinal executa os procedimentos. Segundo a documentação do Qt, todas as classes que herdam de QObject podem conter sinais e slots5. Segue a definição oficial:
“Todas as classes que herdam o QObject ou uma de suas subclasses (por exemplo, QWidget) podem conter sinais e slots. Sinais são emitidos por objetos quando eles mudam seu estado de uma maneira que pode ser interessante para outros objetos. Isso é tudo que o objeto faz para se comunicar. Não sabe nem se importa se alguma coisa está recebendo os sinais que emite. Esse é um verdadeiro encapsulamento de informações e garante que o objeto possa ser usado como um componente de software.”
Um sinal é emitido a partir da palavra chave emit. Para conectar e desconectar uma função a um signal usamos as palavras chaves connect e disconnect.
Listing 5.1 – Exemplo de um connect
c o n n e c t(d- >serial, &S e r i a l L a y e r::r e c e i v e d C o m m a n d, this, &A t C o r e:: f i n d F i r m w a r e) ;
4 http://doc.qt.io/qt-5/qpluginloader.html 5 http://doc.qt.io/qt-5/signalsandslots.html
5.7. PrintThread 43
Listing 5.2 – Exemplo de um disconnect
d i s c o n n e c t(f i r m w a r e P l u g i n() , \&I F i r m w a r e::r e a d y F o r C o m m a n d, this, \&A t C o r e::p r o c e s s Q u e u e) ;
5.7
PrintThread
A classe PrintThread como o próprio nome traz é uma thread para realizar a impressão de um arquivo G-Code. Isso torna o processo de impressão um processo a parte da aplicação principal do sistema evitando que o mesmo fique congelado e sem controle da impressora 3D.
No exemplo de código5.3, vemos de forma simplificada como o processo de impressão ocorre. Temos uma estrutura de repetição, onde enquanto o arquivo não terminar de ser lido, processamos cada linha, até o fim do arquivo ser atingido.
Listing 5.3 – Exemplo simplificado do processo de impressão
v o i d P r i n t T h r e a d::p r o c e s s J o b() { if (d- >g c o d e s t r e a m- >a t E n d() ) { e n d P r i n t() ; } n e x t L i n e() ; w h i l e (d- >c l i n e.i s E m p t y() && !d- >g c o d e s t r e a m- >a t E n d() ) { n e x t L i n e() ; } if (!d- >c l i n e.i s E m p t y() && d- >core- >s t a t e() != A t C o r e::P A U S E) { e m i t n e x t C o m m a n d(d- >c l i n e) ; } }
5.7.1
Injeção de Comando
Dentro da classe PrintThread possuímos uma ferramenta que realiza uma injeção de comando. A ideia desta função é que o usuário em vez de ter um retrabalho de fatiar um modelo em 3D para fazer uma pequena alteração, como adicionar uma pausa ou inserir alguma mensagem, pode usar dos métodos de injeção de comando e as definições contidas no AtCore e adicionar esses comandos no arquivo, onde ao realizar a análise da linha lida no arquivo, se a linha começar com um gatilho que definimos como ";-", o processo de realizar a injeção de comando é iniciado e o comando injetado na lista de comandos enviados a impressora.
44 Capítulo 5. Atelier Printer Host
Gatilhos de injeção de comandos suportados até o momento:
;- Pause: G91, G0 Z1, G90, G1 X0 Y195
;- Message: Show this message (limited chars depends on machine maybe) ;- Pause: G91, G0 Z1, G90, G1 X0 Y195
;- Extruder Temperature:160,0,true (set temp of extruder 0 to 160 and wait) ;- Bed Temperature: 80,true (set bed temp to 80 and wait.)
;- Fan Speed: 100, 0 (set fan 0 to 100 ) ;- Print Speed: 50 (set print speed to 50) ;- Flow Rate: 50 (set flow rate to 50)
;- Message: Show this message (limited chars depends on machine maybe) ;- Command: G28
5.8. Atelier 45
5.8
Atelier
Atelier é a interface de usuário que foi construída e que usa o AtCore para gerenciar as impressoras 3D. Através de pesquisas e recomendações de usuários, percebemos que era necessário o desenvolvimento de uma interface simples e prática que atendesse as seguintes demandas:
1. Atenda aos usuários desktop; 2. Atenda aos usuários mobile;
3. Atenda aos usuários de embarcados.
Note que são experiências diferentes e ambientes dependendo do público-alvo. Neste traba- lho elaboramos uma interface que atende aos usuários de embarcados, e também funciona no desktop. Graças ao uso do Qt, não temos uma preocupação de compatibilidade multi- plataforma, já que qualquer aplicação Qt é compatível com todas as plataformas6. Nosso verdadeiro desafio é elaborar uma interface que seja adaptável a todos esses ambientes.
A princípio desenvolvemos um MVP - Minimum Viable Product com as ferramentas básicas para controle de uma impressora 3D, que neste caso são ferramentas da qual o
AtCore já possui o suporte. Com a ajuda do KDE Visual Design Group, que é um grupo
de trabalho dentro da comunidade do KDE, voltado ao design de aplicações, elaboramos uma primeira versão do que poderia vir a ser a nova interface, que é possível conferir na figura 20 a seguir.
46 Capítulo 5. Atelier Printer Host Figura 20 – A telier Mo ckup