Monday, 30 December 2013

Mechanism animation with PyQtGraph

Linux isn't only FreeCAD.

I have always wanted to create animated mechanisms using python and a plot library. Not only the mechanisms, but a small program that could be used without typing a word of code at all (a personal project).
I found matplotlib very similar to matlab, but not very well suited to create a graphical interface with it. 
But yesterday I tried PyQtGraph and was amazed with how easy is to create dialog boxes and very complex plots, plus people says is faster than matplotlib. 
The con has been a step learning curve.

The install was easy downloading the deb package from the site and using gdebi. I did not need anything extra to get it working.

Slider-Crank Mechanism

Once installed PyQtGraph, open a terminal (ctrl+alt+t) and type "python" (without quotes), then copy-paste this code:


import math
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui

window=pg.plot(title="Crank-Slider Mechanism")


i=0

def update():  
  global i
  x1=[0,math.cos(i),2+math.cos(i)]
  y1=[0,math.sin(i),0]
  
  if(i<360):
    i+=0.003
  else:
    i=0
    
  window.plot(x1,y1,clear=True)

time=QtCore.QTimer()

time.timeout.connect(update)
time.start(0.1) 

  
A window like this should appear in your screen with a slider-crank mechanism moving inside.


Step by Step

To create a plot window:

window=pg.plot(title="Crank-Slider Mechanism")

"window" is the variable where we save the plot window, pg is the name we give to the imported pyqtgraph library and the part inside brackets gives name to the plot window.

The function "update()" plots the mechanism advancing one step every time is called. The crank angle (i) is increased until it reaches 360º, then i resets to 0.

x1 and y1 are x and y point values at every step. This is no the "formal" way of doing this things, but is easy and fast.  If someone wants to dig more, crank is 1 unit long and crank to slider bar is 2 units long.

window.plot(x1,y1,clear=True)

It plots x,y data inside "window" and with the parameter "clear" it erases previous plot before plotting the new one.

The timer events is the most obscure part of the script, what I think it does is:

time=QtCore.QTimer()  # Creates a timer

time.timeout.connect(update) # Executes a function when time is up

time.start(0.1) # Starts timer and counts to 0.1 milliseconds


And this is all I have learnt of pyqtgraph at the moment, next step could be something like dialog boxes that modify bar dimensions.  

Hope you could see the mechanism moving, if not, comment something. (If you liked it, you can comment too ;) )

bye!