Sunday 13 July 2014

Inverse Kinematics: Part 2

On to part two of exploring inverse kinematics! This time I think I will add two additional degrees of freedom to the arm and calculate the inverse kinematics. 

$l_1$ - Length of the first link
$l_2$ - Length of the second link
$l_3$ - Length of the third link
$\theta_0$ - The angle of the base drum.
$\theta_1$ - The angle of the first link from the ground
$\theta_2$ - The angle of the second link w.r.t the first
$\theta_3$ - The angle of the third link w.r.t the second

First let's ignore the third link and consider the two links plus the rotating base. This extension is relatively simple to handle. If the value of $\theta_0$ is found then the problem can again be reduced to a planar 2D problem which already has a nice solution.

It's easy to see that:
$\theta_0 = atan2(z, x)$

Once this is found, then we can find the absolute distance in the x-z plane $d = \sqrt{x^2 + z^2}$. Then the inverse kinematics for the two links can be found by replacing $x$ with $d$ in all the equations.

Now it's time to add the third link into the equations. This third link is special. It's not really an additional degree of freedom. Two links and a rotating base are all that's needed to reach any point in 3D space. So why the third link? Imagine that there was a gripper attached to the third link. This gripper grabs a glass of water. If that third link were not there, this gripper would tilt with the angle of the second link and whatever liquid is in the glass would spill all over the place. This third link in the arm will adjust its angle to the second link so that it maintains a constant angle from the ground plane. Now if the arm is holding a glass of water and moving around, the glass will always be pointed in the right direction. It won't tilt and spill its contents all over the place. Let the constant angle between the third link and the ground be $\phi$ degrees. Applying this constraint we get: $\theta_3 = \theta_1 - \theta_2 - \phi$.

So all we need to do is subtract the vector of the third link from the target coordinates, apply the 2-link plus base inverse kinematics on this coordinates and then calculate phi using the value of $\theta_1$ and $\theta_2$ that we get from those calculations.

I've implemented all this in the invkin4() function in this python script.

I'll post a processing simulation of this soon. I'm still fiddling around with the P3D. I haven't got used to it yet.

EDIT: Go here to see a processing simulation of the inverse kinematics script. :D

Interlude: The Electric Kettle Conundrum


So I decided to start using an electric kettle to prepare myself some coffee from this semester onwards. I naively thought that this was a simple matter of unpacking the electric kettle that I had stored away in my cupboard for the last two years, boiling some water in it and getting delicious, steaming coffee. Life is rarely that simple.

I first plugged the kettle into a spike buster that I have in my room. In about five minutes I hear a electric whizzle and see a quick burst of electric white sparks coming from my spike buster. Oops. I blew a fuse. I checked the electrical rating of my kettle. It was rated for 13A and 250V. I checked the fuse of the spike buster. It was rated for 13A and 250V. I guess I was driving the poor instrument at it's limit! Brushing aside the problem of getting a new fuse for the spike buster, I decided to see if it was possible to run the kettle directly off the wall socket.

But just before I connected the kettle and turned it on, I paused for a second. The memory of the white sparks was still fresh in my mind. So I decided to figure out whether the wall socket that I had in my room was capable of delivering the 250V 13A that the kettle required before I plugged it in and possible caused a fire that burned the whole building down.

So I started researching on plugs. Boring? Absolutely not! It turns out that engineers are very systematic creatures that draw up standards for pretty much everything under the sun. So I started hunting for the standards for electrical plugs in India. After a bit of googling I found that there are three standard types of plugs used for wall sockets in India; Types C, D, and M.

Type C
Type M
Type D
Since I wasn't too interested in the Type C plug (I didn't have any in my room) I pulled up some specs on the plugs. I lifted all this stuff directly from this website.

[The Type D plug] has three round prongs that form a triangle. It is a 5A plug. The central earth pin is 20.6 mm long and has a diameter of 7.1 mm. The 5.1 mm line and neutral pins are 14.9 mm long, on centres spaced 19.1 mm apart. The centre-to-centre distance between the grounding pin and the middle of the imaginary line connecting the two power pins is 22.2 mm. Type M, which has larger pins and is rated at 15 amps, is used alongside type D for larger appliances in India, Sri Lanka, Nepal and Pakistan. Some sockets can take both type M and type D plugs.
Although type D is now almost exclusively used in India and Nepal, it can still occasionally be found in hotels in the UK. It should be noted that tourists should not attempt to connect anything to a BS 546 round-pin outlet found in the UK as it is likely to be on a circuit that has a special purpose: e.g. for providing direct current (DC) or for plugging in lamps that are controlled by a light switch or a dimmer.
Type D plugs are among the most dangerous ones in the world: the prongs are not insulated (i.e. the pin shanks do not have a black covering towards the plug body like type C, G, I, L or N plugs), which means that if a type D plug is pulled halfway out, its prongs are still connected to the socket! Little children run the risk of electrocuting themselves when pulling such a plug out and putting their fingers around it. Type D outlets are not recessed into the wall, so they do not provide any protection from touching the live pins either.
http://www.worldstandards.eu/electricity/plugs-and-sockets/d/ 

[The Type M plug] the Indian type D plug, but its pins are much larger. Type M is a 15 amp plug, which has three round prongs that form a triangle. The central earth pin is 28.6 mm long and has a diameter of 8.7 mm. The 7.1 mm line and neutral pins are 18.6 mm long, on centres spaced 25.4 mm apart. The centre-to-centre distance between the grounding pin and the middle of the imaginary line connecting the two power pins is 28.6 mm. 
http://www.worldstandards.eu/electricity/plugs-and-sockets/m/ 

So I got out my ruler and decided to go ahead and measure my wall socket to see which plug type it was. First I measured the holes. My earth pin had a diameter of 8.7 mm and my live and neutral pins had a diameter of 7.1 mm. I thought that was it! I'd determined that my plug was of Type M! But there was a little unexpected twist! I then measured the spacing between the centres of the live and neutral pins just for fun and found that it was 19.1 mm! This thoroughly confused me. Here was a wall socket that had the pin diameters of a Type M socket but had the pin spacings of a Type D socket! I was unsure what to do! What I wanted to know was the current rating of the wall socket. If the socket had the current rating of Type M then it can supply up to 15A and I can safely run my kettle from it. However, if the socket had the current rating of Type D then it could only supply 5A and I would risk setting something on fire.

So I dived back into the internet and dug deeper. The Bureau of Indian Standards (BIS) is the organization that keeps track of the standards for all the stuff in India and I found that the code for the electrical plug standards is "IS1293". Weird.
So I dug up the pdf of that standard and started reading through it. After skimming through the material at high speed I found what I was looking for on page 83 of that document. The page had actual measurements of the wall sockets. They did not have a plug type with the weird combination of measurements that I measured. So I decided to think about it a bit. Obviously, Type M plugs which are 25.4 mm apart won't fit into this socket that I have even if the pin diameter matches. Since the socket pin spacing was 19.1 mm I assume/deduce that it was not meant to supply power to devices with Type M plugs. So from that page on the standards, this wall socket that I have must either supply 6A or 10A. Since both those values are below the rated 13A for my electric kettle, I think that I should not use it at the moment. I think I'll ask some people in the college about the actual current ratings of the plugs in my room but for now, no kettle.

TL;DR: Dammit! I can't use my kettle!

Friday 11 July 2014

Inverse Kinematics for 2DOF Arm

When I first came across the problem of inverse kinematics I thought - quite naively - that it would be a simple matter to find a solution to the problem because the forward kinematics problem was so simple to solve. I decided to start out with a 2 link arm and see if I could work out the solution on my own from scratch without having any initial knowledge about inverse kinematics. After filling pages and pages with calculations that didn't quite seem to be going anywhere I realized why it was such a difficult problem. 

Of course a 2 link arm had a complete close form solution. After a bit of online research I found the solution. However, the solution for arms with more than 2 degrees of freedom turns out to be not so simple. It requires using numerical methods to slowly converge on a solution. This approach doesn't solve everything either. There's still the problem of choosing the right set of angles because there are often multiple solutions for a particular location of the end of the arm and some of these solutions are invalid because they are outside the range of motion of the motors at the joints of the arm.

I've decided to slowly familiarize myself with all the different ways of finding inverse kinematics solutions. I think I'll make blogposts each with a higher degree of freedom and eventually I'll talk about the solution for the 6DOF arm. Why stop at 6? Because it turns out that in 3D space, you don't need more than 6DOF to reach a particular location/orientation. Any more than that and your arm becomes redundant. 3DOF for location in space plus 3DOF for orientation in space are all we need from an arm.

So in this post I'll talk about the solution to 2 link robotic arm. And this arm will have hinge type joints only. I think that the technical term used is "revolute joint".

A 2 link planar robotic arm looks like this:



The forward kinematics equations for this arrangement are simple enough.
$x = l_1 cos(\theta_1) + l_2 cos(\theta_1 + \theta_2)$
$y = l_1 sin(\theta_1) + l_2 sin(\theta_1 + \theta_2)$

The inverse kinematics equations are quite monstrous. The full derivation is given in this fantastic pdf. I'll just write down the final equations here.

Given a value of x and y, the inverse kinematics equations are:
Let
$k_1 = l_1 + l_2 cos(\theta_2)$
$k_2 = l_2 sin(\theta_2)$
$\gamma = atan2(k_2, k_1)$

$\theta_2 = atan2(\sqrt{1 - (\frac{x^2 + y^2 - l_1^2 - l_2^2}{2l_1 l_2})^2}, \frac{x^2 + y^2 - l_1^2 - l_2^2}{2l_1 l_2})$
$\theta_1 = atan2(y, x) - \gamma$

I wrote a simple python script to calculate the values of theta. You can get the code here. The invkin2() function calculates the values of $\theta_1$ and $\theta_2$ for an arm with 2 links.

It was a bit difficult to test the code this way though. Can't see if I'm right or wrong in most cases. So I wrote this processing sketch to visualize the calculations so I can easily verify their correctness.

You can view the processing simulation here: http://rationalash.github.io/invkin/


Friday 4 July 2014

Completed Task 1!

I've completed task 1 of the Eudyptula Challenge! I know that's not really something to be excited about since it was a very basic task but I'm still excited! I've got a mail with details of task 2. This is getting more interesting.

I've read online that most people are getting stuck with task 6. I wonder what that task is. Hmmm...

I think starting this challenge was a brilliant idea. I'm learning way more than in any of the classes I've ever taken. Learning through solving a set of incrementally difficult practical challenge is the best thing ever!

The task recommends that I try out all the code with a regular system and not a virtual machine but I think I'm a bit too inexperienced to work with my regular laptop. If I somehow mess up the kernel and brick my laptop It's a huge loss. I can't afford to be without my laptop for extended periods of time at the moment. So after weighing the risks I think I'll just stick to running Ubuntu 14.04 in virtualbox.


Vritualbox is actually really handy when it comes to stuff like this. I even used that system to test out and become used to the i3 window manager before installing it on my main system. If anyone is thinking of trying out a new window manager it might be a good idea to use it in a virtual machine and tweaking all the config files in that before transferring it to your actual system.

So on to task 2!

Thursday 3 July 2014

Switching to the i3 Window Manager

I've been thinking about switching to tiling window managers ever since I discovered the awesome tiling features of Emacs. But there were a lot of things that kept me bound to a desktop environment like Gnome. The network manager was the biggest thing. Since I use a mobile internet connection more often than WiFi I regularly had to use the network manager app in Ubuntu to configure and edit these connections (They're a bit temperamental). But after a while my curiosity got the best of me and I finally decided to give it a go.

My initial choice was the awesome window manager. I picked it because it seemed popular and a lot of people on Linux forums were recommending it. Despite all the praise people seemed to have for it, I didn't quite like it. I'd spend ages trying to get all the windows in exactly the order and tiling configuration I wanted and even then it was a bit tricky to navigate. There was also the fact that I needed to learn the Lua programming language to configure it. 

Then I came across the i3 window manager. I went to YouTube and watched a couple of videos of people trying it out and was reasonably impressed with the degree of flexibility it offered. I liked the tree based structure they used to implement their containers and loved the way I could open new tiled windows in any orientation I wanted by using a simple keyboard shortcut. I found that I preferred it to the weird interface that awesome provided.

So now that I was stuck with i3, I needed to tackle the huge challenge of getting all the monitoring programs working inside it. I use a laptop that is quite prone to overheating. So I needed a temperature monitoring program to update the CPU's current temperature to a bar that's visible across all workspaces. I needed to know the current temperature of the system with a quick glance. I also needed the network manager applet and a Guake terminal running. Also, the default font that i3 uses looks really ugly. So I needed to figure out how to change that as well. i3 doesn't require you to know some weird obscure programming language like Lua to configure it. It used simple text files for configuration! 

Once I had the basic stuff configured I needed to tackle the biggest annoyance with simple window managers - no simple interface for suspend, lock, shutdown and logout. Ok logout is simple. I just need to press Mod4+Shift+e to exit the window manager but suspending the laptop and locking its screen were a bit tricky.

After hours of googling I found a really neat script online which handled everything. It even had a neat pyGtk GUI. I downloaded the script, modified a little bit to suit my needs and bound it to Mod4+Esc. And there's this really neat program called xautolock which puts the computer to sleep when I don't use it for a while. 

I've uploaded all my config files to my github account here: https://github.com/RationalAsh/configs

So finally here's how my laptop looks now:


It was a bit of a pain to fiddle around with config files for hours to get all the basic functionality up and running but I quite like the freedom it gives me to make my desktop look however I want it to look! :D