Arquivo de Dezembro, 2012

Serial Port com IronPython

Na continuação desta série de pequenos tutoriais sobre IronPython veremos como usar a porta série para comunicar com um micro controlador.

O framework “.NET” possui uma classe “SerialPort” que possui todas as funções necessárias para usar este periférico. É apenas necessário inicializar o periférico e ler o seu buffer.

O código seguinte inicializa a porta (neste caso a COM5) para uma velocidade de 9600bps, sem paridade, 8 bits de dados e 1 stop bit. O programa fica em execução mostrando a cada 10 segundos o numero de mensagens já recebido.

Cada vez que o programa recebe o caracter “\n” (newline), lança um evento de “DataReceived” que será processado por uma função definida pelo programado e é automaticamente chamada em resposta ao evento. Neste caso a função criada é a “ondata”.

import clr, time
clr.AddReference('System')

contador=0

def ondata(sender, event):
    global contador
    print("Recebeu")
    string=sender.ReadLine()
    print(string)
    contador=contador+1

from System.IO.Ports import SerialPort, Parity, StopBits

serialPort = SerialPort("COM5", 9600, Parity.None , 8, StopBits.One)
serialPort.NewLine="\n"
serialPort.DataReceived+=ondata

serialPort.Open()

while True:
   time.sleep(10) # delays for 10 seconds
   print("Ja contei "+str(contador)+" mensagens recebidas")

serialPort.Close()

É necessário adicionar uma referencia para a assembly “System” que contem o namespace “System.IO.Ports”.

import clr, time
clr.AddReference('System')

contador=0

O namespace “System.IO.Ports” contem a classe “SerialPort” e pode ser importada (juntamente com outras propriedades) através de:

from System.IO.Ports import SerialPort, Parity, StopBits

É necessário instanciar a classe “SerialPort” usando neste caso um construtor que permite definir logo o nome da porta, a velocidade, entre outros. Define-se qual o caracter de paragem, o ‘\n’ e qual a função a ser chamada quando este é recebido, neste caso a função “ondata”. Por fim abre-se a porta para que fique activa:

serialPort = SerialPort("COM5", 9600, Parity.None , 8, StopBits.One)
serialPort.NewLine="\n"
serialPort.DataReceived+=ondata

serialPort.Open()

O programa fica agora “preso” num loop infinito estando a “dormir” durante 10 segundos e de seguida “acorda” e mostra o numero de mensagens já recebido. O numero de mensagens recebido é incrementado cada vez que há um evento “DataReceived” e é automaticamente chamada a funcao “ondata”.

while True:
time.sleep(10) # delays for 10 seconds
print("Ja contei "+str(contador)+" mensagens recebidas")

Falta analisar a funcao que processa o evento. Esta função, utiliza a variavel global “contador” e incrementa-o de cada vez que é chamada.

Um dos argumentos de uma função que processe eventos é o “sender” e este argumento é uma referência para a instância que criou o evento, neste caso, a porta serie. Para ler o que foi recebido na porta usamos o método “ReadLine” associado à referência “sender”.

def ondata(sender, event):
    global contador
    print("Recebeu")
    string=sender.ReadLine()
    print(string)
    contador=contador+1

GUI com IronPython

Na continuação do artigo anterior que mostrava como criar e executar um script em IronPython, iremos agora ver como pode ser criado um GUI (Graphical User Interface) utilizando Python e os componentes do “.NET”.

O GUI que pretendemos construir é constituido por uma janela (Form), uma caixa de texto (TextBox) e tem o seguinte aspecto:

gui

A Microsoft agrupa “funcionalidades” (classes) em “NameSpaces” e “Assemblies”. Os “NameSpaces” são usados para organizar de forma lógica classes que estejam de alguma forma relacionada, têm também como objectivo evitar conflitos entre classes provenientes de várias fontes. As “Assemblies” são código compilado, tipicamente um ficheiro DLL e podem conter vários “NameSpaces”.

Windows Forms (WinForms) é o nome dado à API (Application Programming Interface) de interface gráfica usada nas aplicações. Esta API proporciona o acesso a elementos nativos do interface do Windows como janelas, botões, caixas de texto, labels entre muitos outros. O “.NET” possui um namespace chamado “System.Windows.Forms” que iremos usar para importar para a nossa aplicação a janela e a caixa de texto.

Na documentação online disponível na MSDN (Microsoft Developer Network) pode ver-se quais as classes que pertencem ao namespace “System.Windows.Forms” em http://msdn.microsoft.com/en-us/library/k50ex0x9.aspx. Pesquisando um pouco é fácil de encontrar dentro deste namespace a class “Form” em http://msdn.microsoft.com/en-us/library/system.windows.forms.form.aspx e a class “TextBox” em http://msdn.microsoft.com/en-us/library/system.windows.forms.textbox.aspx

O código necessário para gerar esta aplicação pode ser escrito utilizando o Notepad++ e é o que se segue:

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')

from System.Windows.Forms import Application, Form, TextBox
from System.Drawing import Point

form = Form()
form.Text = 'Exemplo GUI'

#http://msdn.microsoft.com/en-us/library/system.windows.forms.textbox.aspx
#http://msdn.microsoft.com/en-us/library/a19tt6sk.aspx

posicao=Point(20,30)

texto=TextBox()
texto.Location=posicao
texto.Text='Hello World'

form.Controls.Add(texto)

Application.Run(form)

Para que um programa possa usar uma assembly/namespace, é necessário adicionar explicitamente uma referência para este. Para adicionar referências usa-se o módulo CLR e para usar o módulo CLR é necessário importá-lo. É precisamente isso que faz a primeira linha de código:

import clr

As referencias são adicionadas através do método “AddReference”. Para este programa vamos adicionar duas referências para os namespaces “System.Windows.Forms” e “System.Drawing”:

clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')

Destes namespaces vamos importar a class “Application” a “Form” e a “TextBox” bem como a estrutura “Point” para tal usamos o seguinte:

from System.Windows.Forms import Application, Form, TextBox
from System.Drawing import Point

Agora que o nosso código já tem acesso a estas classes vamos instanciar (criar um objecto de um tipo) uma janela (form):

form = Form()
form.Text = 'Exemplo GUI'

O código acima também mostra como aceder e alterar a propriedade Text (Nome da janela) através do operador “.”.

De seguida vamos criar (instanciar) uma caixa de texto. O código seguinte também inicializa uma estrutura do tipo “Point” para escolhermos as coordenadas da caixa de texto em relação à janela e altera o texto para “Hello World”.

texto=TextBox()
posicao=Point(20,30)
texto.Location=posicao
texto.Text='Hello World'

As ultimas duas linhas adicionam a caixa de texto à janela e executam a aplicação:

form.Controls.Add(texto)

Application.Run(form)

Para executarmos o nosso programa assumindo que lhe chamámos “gui.py” podemos (na consola) chamar a aplicação da seguinte forma:

ipy gui.py

esta forma é mais correcta para fazer debug da aplicação.

Quanto tudo funcionar correctamente podemos executar a aplicação (através de um atalho por exemplo) com o comando:

ipyw gui.py

Usando o “ipyw” em vez do “ipy” a aplicação não vai abrir uma janela da consola quando se executa.

Python + .NET = IronPython

Introdução:

Python é uma linguagem de programação de alto nível multi plataforma (Windows, Linux, MAC),  interpretada (os programas em Python são muitas vezes chamados scripts) e orientada a objectos. A linguagem foi projectada com a filosofia de diminuir o esforço do programador bem como da  legibilidade do código. Combina uma sintaxe concisa e recursos poderosos através da sua biblioteca padrão e de módulos e frameworks desenvolvidos por terceiros. A distribuição padrão é conhecida como CPython, é desenvolvida em “C” e pode-se encontrar em http://www.python.org/.

Microsoft .NET é uma iniciativa da Microsoft, que visa uma plataforma única para desenvolvimento e execução de sistemas e aplicações. Com uma ideia semelhante à plataforma Java, o programador deixa de escrever código para um sistema ou dispositivo específico, e passa a escrever para a plataforma .NET. Esta plataforma é executada sobre uma Common Language Runtime – CLR  (Ambiente de Execução Independente de Linguagem) interagindo com um Conjunto de Bibliotecas Unificadas (framework).

Actualmente o .NET suporta um conjunto de Linguagens de Programação através do seu IDE, o Microsoft Visual Studio ou Visual Studio Express (gratuito mas com algumas funções limitadas), entre elas encontram-se o Visual Basic, o Visual C++ e  o C#.

IronPython é uma implementação de Python escrita integralmente em C# utilizando o .NET (em oposição ao CPython escrito em C) e permite aos utilizadores de Python o uso da estrutura .NET e todas as funcionalidades compatíveis, tornando Python outra linguagem do .NET ao lado do Visual Basic ou do C#. O IronPython pode ser descarregado em http://ironpython.net/

Instalação:

Para poder usar o IronPython é necessário fazer o download do installer na página oficial em: http://ironpython.net/ (versão mais actual à data deste artigo 2.7.3).

De seguida executa-se o “installer” e seguem-se os passos normais na instalação de um programa. Findado o processo de instalação é necessário adicionar ao “System Path” (variável de sistema que especifica um conjunto de directorias contendo os executáveis de diversos programas) a  directoria de instalação do IronPython de forma a que este seja reconhecido em qualquer lado.

Nas “Definições Avançadas de Sistema” escolher o separador “Avançadas” e a opção “Variáveis de Ambiente”:

systemvars

De seguida escolher:

systemvars2

Na janela que aparece navega-se até ao fim do texto e adiciona-se um “;” seguido da directoria de instalação do IronPython, no meu caso:

systemvars3

Teste:

Para confirmar que tudo está a funcionar correctamente abram uma janela da consola (DOS) e escrevam “ipy” seguido de “enter”. Deverão obter o seguinte resultado:

ipy

A consola deverá  mostrar a versão do IronPython usada e ficar com o cursor a piscar a seguir a “>>>” . Este é o modo interactivo e permite testar todos os comandos e funções do IronPython (o CPython também tem um modo equivalente).

Podemos criar um programa “Hello World”, para tal escreva na consola:

print('Hello World')

Deverá obter algo do género:
helloPara sair do modo interactivo e voltar à consola, basta escrever o comando “quit()” seguido de “enter”:

quit()

Escrever Scripts:

Podem-se criar ficheiros com código dentro e depois executá-los sem que para isso necessitemos de usar o modo interactivo da consola. Para isso podemos usar um programa como o Notepad++ disponivel em http://notepad-plus-plus.org/. O exemplo anterior ficaria:

scriptpy

No Notepad++ pode-se escolher qual a linguagem de programação de forma a que ele faça o “highlight” do código de forma correcta. De seguida é necessário guardar o ficheiro na localização e com o nome pretendido através de “File-> Save As”:

saveas

Como anteriormente tinha sido escolhido a linguagem de programação o Notepad++ sabe que é um ficheiro com código Python e vai adicionar automaticamente a extensão “.py” ao ficheiro. Neste exemplo o nome do ficheiro vai ser “helloworld.py”.

Para executar o nosso script voltamos à consola e navegamos até à directoria onde guardámos o script e escrevemos:

ipy helloworld.py

O resultado deverá ser:
exec
No próximo tutorial avançaremos para a utilização de componentes .NET e ambiente gráfico.

Dissertação de Mestrado

Durante a minha dissertação de mestrado trabalhei com a temática dos veículos eléctricos e autónomos.

dissertacao

Esta dissertação teve como objectivo o desenvolvimento de um controlador para o sistema de direcção de um veículo autónomo.

Várias pessoas trabalharam neste projecto, tais como:

Marco Silva (PhD Student), Fernando Moita (PhD Student), Professor  Doutor Urbano Nunes, Cristiano Premebida (PhD), Luís Garrote (PhD Student), Pedro Reis, Hugo Faria entre outros.

CAD para Gcode

De forma a poder maquinar uma peça utilizando uma CNC é necessário converter o desenho 3D em algo que o controlador da CNC entenda. As CNCs têm a sua própria linguagem conhecida como “Código G” (G Code em inglês), assim, é necessário algo que converta o desenho em código G.

cad2gcode

Como o esquema anterior demonstra, o workflow de cortar uma peça utilizando a CNC começa com o desenho da mesma num software CAD como o Autocad, Freecad, Solidworks, CamBam (limitado), entre outros.

De seguida o desenho passa por um software CAM como o Mastercam, Sprutcam ou o CamBam onde são escolhidas as opções de maquinagem como o tipo de passagens, o tipo fresa  e informações como diâmetro, velocidade de corte e número de passagens e altura de segurança. É também o software CAM que vai gerar o ficheiro com o código G.

Por fim o ficheiro contendo código G é importado pelo controlador da CNC como o MACH3, o EMC2 Linux, ou um controlador físico como Fanuc ou Heidenhain responsável por controlar a máquina.

Muitas das peças são apenas um contorno 2D com uma profundidade. Este tipo de peças é conhecido como 2.5D e é sobre elas que este tutorial incide usando o CamBam (versão gratuita) http://www.brusselsprout.org/cambam/download.htm

Assumindo que desejamos maquinar uma peça 2.5D (definida por um contorno 2D e por uma altura, regra geral a do próprio material) em PVC expandido de 10mm de espessura como a seguinte :

peca

Por convenção, o topo da peça tem cota (eixo dos Zs)  igual a zero, esta será negativa quando a fresa está a cortar (encontra-se dentro do material) e positiva quando está a viajar entre pontos sem cortar (altura de segurança).

Usando o desenho CAD (por exemplo com o SolidWorks) devemos guardar uma versão com a extensão “DXF” e vamos abri-la no CAMBAM usando a opção “File->Open”:

cambam

Convém verificar se as unidades no CamBam são coincidentes com as usadas no controlador. Na imagem anterior é possível ver o contorno da peça.

Para este exemplo vamos usar PVC expandido de 10mm de espessura e uma fresa de 3mm de diâmetro com duas laminas em hélice.

fresapvc

Clicando em qualquer dos contornos este ficará realçado a vermelho e usando o “control (ctrl)” podemos seleccionar mais que um contorno.

cambam25d

Com estes contornos seleccionados iremos agora escolher o tipo de operação a efectuar sobre eles e seguidamente o diâmetro da fresa, se queremos cortar por dentro ou por fora do contorno, a profundidade de corte, o numero de passagens, a velocidade de avanço e a altura de segurança.

Dos menus iremos escolher “CAM->2.5D Profile” e o CamBam abrirá um menu do lado esquerdo com diversas opções como se encontra na figura seguinte:

cambamopcoes

As opções mais importantes são:

Nome do campo Descrição do Campo Valor para o exemplo
DepthIncrement É este valor que define quanto é que a fresa vai penetrar no material a cada passagem que faz. 3 [mm]
FinalDepthIncrement Define qual o incremento de penetração da fresa a fazer na ultima passagem. Utiliza-se este campo no caso em que o “DepthIncrement” escolhido não dê número de passagens certo, por exemplo se for escolhido um valor de “DepthIncrement” de 3mm e a espessura a cortar seja de 10mm. Neste iriam ser feitas três passagens com incremento de 3mm e utilizando o “FinalDepthIncrement” igual a 1mm para completar os 10mm. No caso em que o numero de passagens dê certo este campo pode ser igual a zero. 1 [mm]
StockSurface Este valor determina a altura da peça. Por convenção é igual a zero. 0 [mm]
TargetDepth Define qual a profundidade pretendida a ser atingida pela fresa. Por convenção fresa corta quando a cota é Zero. Assim sendo este valor aparece negativo, no nosso exemplo será = a -10mm (espessura do PVC) -10 [mm]
CutFeedrate Define a velocidade de avanço (em mm/min) enquanto a fresa está a cortar. Este valor depende do tipo de material, da fresa e CNC usada, é necessária alguma experiência/testes para descobrir qual o que se adequa melhor. 300 [mm/min]
PlungeFeedrate Define a velocidade de penetração (em mm/min) da fresa no material. 250 [mm/min]
ClearancePlane Define qual a altura a que a fresa pode movimentar-se em segurança de um sitio para o outro sem embater na peça a maquinar. 5 [mm]
InsideOutside Define se desejamos que a fresa corte por dentro ou por fora do contorno. Inside
ToolDiameter Define o diametro da fresa que vai ser utilizada para cortar. 3 [mm]
ToolNumber Define qual o numero que desejamos atribuir a uma determinada fresa. Caso durante o trabalho apenas se use uma fresa não é necessário usar este campo e pode-se usar o valor default de zero. 0

De seguida selecciona-se o contorno exterior e volta-se a repetir o procedimento mostrado acima tendo atenção que no campo “InsideOutside” deve-se alterar para “Outside”.

cambamopcoes2

Terminadas as operações pode-se verificar se tudo está conforme desejado clicando com o botão do lado direito do rato em cima de “Machining” e escolher a oção “cambamgentool

Os caminhos onde a fresa passará aparecem agora junto com a peça. Utilizando a tecla “Alt” juntamente com o botão esquerdo do rato pode-se visualizar a peça e os percursos da fresa a 3D.cambam3D

Usando a tecla “Alt” e fazendo duplo clic em cima da peça faz o reset para a vista normal de visualização.

Para terminar resta gerar o código G, para isso basta clicar com o botão direito em cima de “Machining” e escolher a opção “Create GCode File” e salvar normalmente o arquivo onde se desejar como noutras aplicações.

Os ficheiros neste exemplo podem ser descarregados aqui.

MySQL com IronPython

Brevemente!