Tag Archives: python

Linear Delta Robot Inverse Kinematics Software Prototype

My previous post was showing off the initial OpenSCAD model of a liner delta robot project I’ve started. I’ve been interested in building a delta robot in some time but have been put off by the inverse kinematics, thinking it would be an absolute nightmare to figure out. Turns out it’s surprisingly simple for vertical linear delta robots and I’ve written a quick Python+PyGame GUI to work out the required Z positions for the 3 corners of the robot.

Liner Delta Robot Inverse Kinematics Software

The blue bars on the left show the required Z positions to reach the XY co-ordinate shown by the diagram in the center of the screen. The grey bar next to the individual Z positions shows the total Z height for the head of the delta robot. The dark grey crosses in the center region show the possible locations reached by the robot.
Setting the delta robots head XY position is done by clicking on a location. The Z height can be set by scrolling the mouse wheel.

For the time being I’m going to stick with pygame for the GUI components, I’m quite liking the minimal look. I may at a later date port it over to using QT.

Ultimately the goal is to use this software for testing the inverse kinematics model, as well as for debugging the delta robot during construction by implementing an interface to directly control the robot via USB. At a later date G-Code interpretation may be added.

This first version of the software is not in a fit state to release. Once I’ve cleaned up the code I’ll stick it up on GitHub under a GPL license.

Advertisements

Introducing undleBundle!

Tired of looking up the commands to compress/uncompress files via the command line in Ubuntu? Don’t know your -zcvf’s from your -zxvf’s? Then undleBundle may be just your cup of tea!
undleBundle is a python script which wraps a bunch of command line compression/decompressions tools together in simple interface with sensible defaults. Want to make a tar.gz? simple, just run:

bundle filename.txt

want to uncompress your file?

undle filename.tar.gz

want to select a specific compression type to use? (assuming you have the correct tools installed it currently supports tar.gz, rar, zip, tar and 7z, but adding new types is a breeze) Use the -t switch (only used in bundle, undle will automatically determine filetype for decompression)

bundle -t zip filename.txt

want to also select a new filename for the created file? Also simple!(see, a pattern is emerging) use the -f switch:

bundle -t zip -f fancy_new_filename.zip filename.txt

And that’s it, that’s all there is to undleBundle.

Python – OpenCV IplImage To PyQt QImage

This is a quick post which will hopefully save someone some time. I spent far too long trying to figure this out.
If you’re using Qt and OpenCV with python and want to show an opencv iplimage within a Qt Widget here’s a quick hack to convert the iplimage to a qimage.


class IplQImage(QtGui.QImage):
"""A class for converting iplimages to qimages"""

     def __init__(self,iplimage):
         #Rough-n-ready but it works dammit
         alpha = cv.CreateMat(iplimage.height,iplimage.width, cv.CV_8UC1)
         cv.Rectangle(alpha,(0,0),(iplimage.width,iplimage.height),cv.ScalarAll(255),-1)
         rgba = cv.CreateMat(iplimage.height,iplimage.width, cv.CV_8UC4)
         cv.Set(rgba, (1,2,3,4))
         cv.MixChannels([iplimage, alpha],[rgba], [
         (0, 0), # rgba[0] -> bgr[2]
         (1, 1), # rgba[1] -> bgr[1]
         (2, 2), # rgba[2] -> bgr[0]
         (3, 3) # rgba[3] -> alpha[0]
         ])
         self.__imagedata = rgba.tostring()
         super(IplQImage,self).__init__(self.__imagedata, iplimage.width,iplimage.height, QtGui.QImage.Format_RGB32)

All in all it’s fairly straight forward, an example case is something like the following:


#Create a 3 channel RGB iplimage (could be from a webcam ect.)
iplimage = cv.CreateMat(iplimage.height,iplimage.width, cv.CV_8UC3)
#Turn it into a qimage
qimage = IplQImage(iplimage)

It works by sub-classing QImage and overloading the constructor with a new one that accepts an IplImage, this then has an extra alapha channel added (to make it compatible with the QImage pixel packing) and finally the __init__ method of the superclass (QImage) is called with the data from the iplimage passed into it as a string.

The important part is:


self.__imagedata = rgba.tostring()

This keeps a reference to the image data so it doesn’t go out of scope when the __init__ returns. (the QImage constructor that accepts image data doesn’t keep a local reference to the data, so you have to make sure it isn’t lost.[at least i think that’s right])

“Clothed all in the morning you know by the river” – A Lite Introduction to Markov Chains and Nonsense

(Poorly written and badly structured Python code for this blog post can be found here, this makes quite a fun and quick project if you’re trying to learn a new language)

Imagine reading the following half of a sentence in a sherlock holmes novel:

"My name is Sherlock".....

What is the probability the next word will be “Holmes”? Well, thanks to project gutenberg who host public domain e-books, and the wonders of “find” in nearly any text editing software, we can see that that collection of words appears exactly twice in all of the Sherlock Holmes books, and more importantly for us, 100% of the time it appears it will be followed by the word “Holmes.”

Now lets look at the following fragment of that previous sentence:

"name is"

We can probably assume the range of words that are likely to follow this fragment within the books is greater than just "Sherlock",and with a bit of tedious searching, we can find exactly what words appear and the number of times that they do.

From this table of figures it is now possible to derive a series of probabilties, so that now when you read the fragment "name is" in a Sherlock Holmes novel you can thoughtfully pause before reading the next word and take an informed guess at what it will be.

What if we now take the pair of words:

"My name"

What is the range of words that could follow that fragment within the books? Or even better, what if we take the entirety of the Sherlock Holmes novels, split it all down into consecutive pairs of words and, for every pair, calculate the probabilites for the next word? What we’d have would be a model we could use to predict the next word for any given pair of words within the books of Sherlock Holmes.

Lets abstract this idea a bit:

We have a model of a system, which given a state of the system, we can use to predict the next state.

In our case the “system” is the books, the “state” is a pair of words, and the “model” is a massive list of all the pairs of words in the books with a corresponding table for every pair showing the possible following words (the “next state”). An important thing to note is the predictions are based purely on the current state, no previous states are considered.

Pretty cool eh? but what to do with it? Well, there’s probably some pretty interesting analysis/classification problems this could help with, but I’m just going to use it to make nonsense sentences.

To make nonsense we first pick a random pair of consecutive words from our book as a starting point. We then look at all the possible following words in our model and roll a virtual weighted die to determine what the next word should be. We then take the 2nd word from out first pair and our new word, form them into a new pair and find the possible words that could follow this new pair….and so on.

The result of this can be quite interesting, sentences can seem to have a structure and a semblance of meaning, yet still make no sense. This is due in part to some pairs of words having very few possible words following them (for example "is Sherlock"), while other pairs of words have many possible words that could follow them (for example "it is").

Where can we go from here? Well, there are a number of possible options, instead of using whole words, why not use letters to make nonsense words? Change the number of consecutive words used to create the model and see what happens (my guess is you’ll reach a point where trying to get a random sentence will result in just reciting parts of the book word for word), how about feeding two different books into the model instead of just one? (feeding Sherlock Holmes and the Wizard of Oz in results in some pretty weird sentences that seem to “flow” between Oz and Sherlock).

Robot Arms, Chaotic Python, and London

So I’ve moved down to London, which is kind of like Manchester except the buses smell slightly better. In a hostel at the moment with a 1Mb connection and a single router for the whole place so internet is somewhat intermittent.

While i’m without tools, building materials, and internetty distractions I’ve finally decided to learn some python, which, i have to say, is starting to grow on me quite a lot. It’s like programming is fun again rather than just a tool to get stuff done with. So without further ado here is my first python program. It uses pyglet (which is awesome) to plot the points of this equation: x_next = x*r*(1-x)

#! /usr/bin/env python

from pyglet.gl import *
from pyglet.graphics import *
from pyglet.window import key

class HelloWorldWindow(pyglet.window.Window):

    def __init__(self):
         super(HelloWorldWindow, self).__init__()
         self.param = 2.8
         self.start_val = .34
         self.y_vals =[0]
         self.create_chaos()
         self.label = pyglet.text.Label('PgUp/PgDown-Starting Value Up/Down-Lambda Value')

     def on_draw(self):
         glClear(GL_COLOR_BUFFER_BIT)
         glLoadIdentity()
         for count in range(0,800):
             pyglet.graphics.draw(1, pyglet.gl.GL_POINTS,('v2i', (count, int(self.y_vals[count]*200))))
         self.label.draw()

     def create_chaos(self):
         self.y_vals =[self.start_val]
         r = self.param
         for x in range(0,800):
             self.y_vals.append(self.y_vals[x]*r*(1-self.y_vals[x]))

     def on_key_press(self, symbol, modifiers):
         if symbol == key.UP:
             print ['Lambda: ', self.param]
             self.param += 0.05
             if self.param >= 4:
                 self.param = 4
         elif symbol == key.DOWN:
             self.param -= 0.05
             print ['Lambda: ', self.param]
         elif symbol == key.PAGEUP:
             self.start_val += 0.05
             if self.start_val > 1:
                 self.start_val =1
             print ['Lambda: ', self.start_val]
         elif symbol== key.PAGEDOWN:
             self.start_val -= 0.05
             if self.start_val < 0:
                 self.start_val =0
             print ['Lambda: ', self.start_val]
         self.create_chaos()

if __name__ == '__main__':
     window = HelloWorldWindow()
     pyglet.app.run()

PgUp/PgDown adjust the starting value of x while the up/down keys adjust the value of r.

The equation is from the book Chaos by James Gleick and demonstrates a chaotic system (keep pressing up and see how the system becomes stable in multiple states before turning chaotic).

The system stable in one state


The system stable in multiple states


Things getting chaotic

I really can’t describe it as eloquently and simply as the book, which i highly recommend reading.

In other exciting news i bought a hydraulic robot arm from a car boot sale for a mere 40 pounds!

My good friend lon who helped me transport the arm to my parents (hello lon! Your probably the only one whos gonna read this 😉 )


Me attending to the arm

Kind of frustrating not being able to play with it being in London an all, but with my new found python&pyglet skillz i’m gonna try and write some inverse kinematics code to control it when i finally do get my hands on it. If i get some free time/ internet i’ll post some details about it.