Filter: software, code, computer science, tech, life, robotics
I recently came across photographing some close-ups of several iPhone/iPad Apps we developed at Nerves. Fore some reason, I had forgotten how wonderful our back-lit LED displays are. Isn't it amazing that these screens work for countless hours with hardly any visible error.
Below are some impressions of our photo-shoot.
I was recently interviewed for a documentary film about life in the digital age. Below are some excerpts which might be of interest.
What aspects fascinate you in the digital worlds in which you live in? Which opportunities do they offer?
Since I was a young child I was completely fascinated by electronics. My parents were always afraid to leave a calculator or such lying around, because they knew that if I found it I would surely take it apart, inspecting all the insides thoroughly. When I finally got my first computer at age 10, I discovered the internet, which instantly became my new passion. I was absolutely captivated by the idea that I could publish something online which would be instantaneously reachable from all corners of the globe! Today we take it for granted, but 15 years ago this was groundbreaking in the way we communicate with each other as well as with whom we communicate to. The digital world has progressed, where now I am always connected in some manner to multiple services spread across the globe which provide information in a constant stream. To me, the digital world is an (almost) unlimited resource, where information is easily obtainable. If I want to know who ruled England during the 18th century, I only need to grab my phone and type “18th century king england” into Google. Before the digital revolution, gaining this knowledge was considerably harder. This is what fascinates me: the wealth of obtainable knowledge. That's why I co-founded NERVES, where we develop digital services and applications and constantly try to redefine how we communicate digitally.
Could you say that the digitalization of technology has changed your life? How?
Yes, definitely. Probably the most astounding change is the way I interact with people. I'm sure I spend more time interacting with most people through a digital service, such as E-Mail, SMS, Networking, et cetera, than actually talking with them in person. This has both positive and negative effects and my daily life. In some senses I feel more productive (it's faster to Twitter a birthday party than call everyone), but at the same time I also feel much more disconnected from many people, especially in the professional world. I grew up in Africa, Asia, Middle East, Europe, and America, so I have many friends spread out all over the globe. Since the widespread use of the internet and social networks, I now have daily contact with all these friends again. So there are definitely positive benefits from the obsessive digital revolution.
How does your social circle react to your active digital life?
My curiosity makes me a typical early adopter. Most people react well to that, showing a similar interest in much of my digital life, just at a different (lower) level. My family have all slowly joined in on the digital world. We now commonly communicate with Skype and SMS. Even my mother has a Facebook profile now, and tries to promote her art on the internet. My deeper passion with computer science is not understood well by the people around me, neither are they interested. I mostly keep that to myself and a handful of fellow nerds.
One of the greatest lacking features in Adobe Flash is the ability to stretch the timeline. I find this an unbelievable missing feature. I assume the reason it is missing is because of the technical questions that arise when stretching the timeline: mainly that which has to do with rounding errors. Because flash is keyframe oriented, rounding errors can become sorely visible when performing stretch operations. A difficult problem to solve universally. However, in many cases these errors can be ignored. Below is my JSFL script which will stretch the selected frames on the timeline by any given factor.
//
// Stretch Timeline Flash Extension Command
// v2
//
// This extension will automatically stretch the selected frames
// to the given factor of the currently selected timeline.
//
// Compatible with Adobe Flash CS3/CS4.
//
// Based on Reineir Feijen's Flash Extensions. Contributions by Nitin Malik.
//
// Copyright 2011 Dan Krusi, Nerves
// dan.krusi@nerves.ch | www.nerves.ch
//
// Init
var valid = true;
var factor = 1.0;
// Sanity check and factor input
if (fl.getDocumentDOM() == null || fl.getDocumentDOM().getTimeline() == null) {
alert("No timeline is selected!");
} else {
var ret = prompt("Stretch Timeline by a factor. For example, 0.8 would speed up the timeline while 1.4 would slow it down...\n ");
if(ret != null) {
factor = parseFloat(ret);
if (isNaN(factor)) {
alert("The factor '"+ret+"' is not valid!");
} else {
// Rock n Roll!
stretchTimeline(fl.getDocumentDOM().getTimeline(),factor);
}
}
}
// Strech the timeline
function stretchTimeline(timeline_obj, factor) {
// Init
var tl = timeline_obj;
//cleanSelection(tl)
var sel = tl.getSelectedFrames().concat([]);
// Loop selection
for (var i=0;i<sel.length;i+=3) {
var splices = [];
var changed = 0;
var frameCount = tl.layers[ sel[i] ].frameCount;
// Nitin Malik: If startFrame is on empty frame
// Based on fact empty frames can only come after all frames on the layer
if( sel[i+1] > frameCount ) {
sel[i+1] = frameCount;
}
// Nitin Malik: If endFrame is on empty frame
if( sel[i+2] > frameCount ) {
sel[i+2] = frameCount;
}
tl.setSelectedFrames([sel[i],sel[i+1],sel[i+2]]);
// Calculate splices
for (var j=sel[i+1];j<sel[i+2]+1;j++) {
if (j==sel[i+2] || (tl.layers[sel[i]].frames[j] && j==tl.layers[sel[i]].frames[j].startFrame)) {//only keyframes and last frame
var goal = sel[i+1]+Math.round((j-sel[i+1])*factor);
if (factor>=1) {
var df = goal-(j+changed);
var at = j-1+changed;
} else {
var df = (j-changed)-goal;
var at = j-changed;
}
if(df>0) {
splices.push([at, df]);
changed += df;
}
}
}
// Insert/remove necessary frames
if (factor>=1) {
for (var j=0;j<splices.length;j++) {
tl.insertFrames(splices[j][1], false, splices[j][0]);
}
} else {
for (var j=0;j<splices.length;j++) {
tl.removeFrames(splices[j][0]-splices[j][1], splices[j][0]);
}
}
}
}
Download: StretchTimeline_v2.jsfl
Update: Thanks to Nitin Malik (blog.nitinmalik.com) for contributing some changes to handling empty frames.
Tags: code
Developing software for OS X and iPhone OS requires a significant amount of time spent in the OS X operating system. While OS X is really nice and user friendly, there are many little things which annoy me to a point of insanity. These annoyances mostly have to do with the inability to tweak and change user-interface behavior, which is limitless in the world of Linux/Gnome.
Using multiple workspaces, or virtual desktops, fixes a large part of the window-mayhem problem in OS X. But, it also results in some unwanted side-effects. For example, one of the most annoying nuances is the way the Finder behaves when clicking the blue Finder icon. If a Finder window is already open on any workspace (which is always true), that Finder window will be recycled, and the desktop view changed to that workspace. Typically I just want a new Finder window to do a specific task related to that workspace, and then close it again. I can right-click the Finder icon and select "New Finder Window", which does this, but this extra click is too silly for me. Getting a new Finder window should be really fast as it's a common task.
This is where my New Finder application comes handy. New Finder guarantees the ability to open a new Finder window, without the hassles of recycling already opened Finders or having Expose jump to a different desktop. It works best by placing the New Finder application right next to the Finder icon:
It even comes with it's own Preference Pane for setting the default Finder location:
Binary Installer Download: NewFinder-1.0.zip (OS X)
Source Download: NewFinder-1.0-source.zip (OS X)
Tags: software
Everybody that knows me knows my fascination for robotics. Recently, I have been fixated by the idea of a soft-bodied mobile robot - more precisely, a teddy bear stuffed with electronics and a small brain. You see, I believe that simplicity is key to jump starting the robotic revolution. Instead of mimicking every human joint using mechanical devices to build a humanoid, I find it much more effective and efficient to look into design techniques which yield similar results but by a heavily reduced complexity factor. This is why I am stuffing a teddy bear with a simple skeleton made up of six moving parts. For the last few nights I have spent some time realizing my design for a robotic teddy bear. After a few hours of work the teddy is already stuffed with all the necessary electronics and I have created my first prototype.
Below some impressions:
Tags: computer science, tech, robotics
For all those interested, below is a copy of the introduction in my Bachelor Thesis...
What happened to the robotic revolution? Looking back at old technology and mechanics magazines from the 1950's, one cannot help but muse at the wild expectations people had regarding the future of robots. Often portrayed was a bizarre mix of people and machines, living together in a society with the robot as man's new best friend. Some went to the extent to predict a new race of slaves which would serve mankind by the 1960’s – as did the 1957 Mechanix Illustrated article You’ll own Slaves by 1965 (Binder, 1957). The predictions from last century are far from reality. Not only has the progression of the robot been much slower than expected, traversing a very subtle path, but also its role in society has been completely redefined from the original conceptions. Instead of serving us breakfast in the morning, cleaning our living space during the day, and taking our hat and coat from us when we return in the evening, as depicted in the 1940 film Leave It To Roll-Oh (Handy, 1940), robots have found their birthplace in the factory. There they toil away all day, and sometimes night, performing mundane routine tasks over and over. Looking at such a machine, with its precise movements and repetitive activities, its hard edges and vacuous appearance; it has little resemblance of ourselves. Is not the robot supposed to be mankind’s birth-child?
The robotic revolution has not yet undergone in the scale and realm so many thought it would. What then has kept it? Does the robot just need more time to develop and grow, or is our concept of the robot fundamentally flawed? A long standing problem in the field of robotics is the perception of the environment. To us humans, this is a trivial task. We see, hear, and touch our environment around us, combining these senses to form a somewhat indescribable organic perception of the world (Thorpe, Clatz, Duggins, Gowdy, MacLachlan, & Ryan, 2001). It is here, at one of the most essential parts of our defining quality, where the robot has stumbled. The ability to perceive the environment and comprehend its implications is the first step in actively being a part of it. Only then can a robot take it’s prematurely crowned role of being mankind’s helper. For thousands of years we have tried to understand our perceptions, starting with primitive cave drawings and slowly mastering perception with realistic paintings. However, teaching robots to understand perception has proven very difficult, even though a robot can easily imitate its environment through the form of radar, sonar, lidar, or visual images.
After forty years of dedicated efforts on a global scale, robots still have trouble recognizing our face, they move carefully through our world with a slow pace, and are shy to interact. They just barely have learned how to walk (Webb, 2001). In many ways, the robot is still a toddler – unable but eager to explore the world. However, they are growing faster and faster. Each year we are introduced to new robots that are superior in perception and mobility. Each year new robots join our daily lives in some fashion or another. Our question remains; when will we be able to christen this century as the Century of Robotics?
Tags: computer science, tech, robotics
God Bless Qt/Trolltech/Nokia for their very excellent cross-platform framework, but sometimes, even I admit it can be a pain (despite my deep love and passion for it). My latest pain is with the static builds of Qt version 4.5.0/4.5.1. I have spent a considerable amount of time getting this build environment to work on a fresh Ubuntu installation. Below you will find the instructions to make yourself your very own static build...
Step 1: Download and install Qt:
Download Qt from Trolltech (http://www.qtsoftware.com/downloads). Choose the "Complete Development Environment". Once downloaded, install it using sudo.
chmod chmod u+x qt-sdk-linux-x86-opensource-2009.02.bin
sudo ./qt-sdk-linux-x86-opensource-2009.02.bin
Step 3: Get all the required libs:
sudo apt-get install g++
sudo apt-get install libx11-dev
sudo apt-get install libxinerama-dev
sudo apt-get install libxrandr-dev
sudo apt-get install libxrender-dev
sudo apt-get install libxcursor-dev
sudo apt-get install libfontconfig-dev
sudo apt-get install libsm-dev
sudo apt-get install libgtk2.0-dev
sudo apt-get install xorg-dev
Of course, you could also do "sudo apt-get install libqt4-dev", which would get you version 4.4.3 (as of 29.05.2009), but I prefer not to install this version alongside...
Step 2: Configure and compile Qt:
cd /opt/qtsdk-2009.02-static/qt
sudo ./configure -release -static -nomake tools -nomake examples -nomake demos -nomake docs -nomake translations -fast
sudo make sub-src
sudo make install
Tags: computer science
To better understand complex numbers and how their various functions work, I implemented a templated operator-overloaded C++ class which represents a complex number (complex.h, see below).
typedef ComplexT<double> Complex;
Complex c1(1.0,-1.5); // real=1, imag.=-1.5
Complex c2(M_PI,0);
Complex c3 = (c1 + c2)*2.0;
Complex c4 = (c3 / c2) * c1;
Complex c5 = sqrt(exp(c3)); // sqrt( e^c3 )
Complex c6 = pow(c1,4); // c1^4
double abs = c6.abs(); // radius polar notation
double arg = c6.arg(); // angle polar notation
To test my class, I also implemented a GUI which features an input plane on the left with the output on the right, and various functions to apply to the output. The input can also be changed from the classical colored grid lines, to other inputs such as a radial grid or an image.
Download Binaries for Windows, Linux, OSX and Full Sorce Code: ComplexNumbers-1.1-win-linux-osx-source.tar.gz
Tags: code, computer science
Really? Is IBM going to buy Sun? Ah, that would be so nice. Just imagine the fire it would like underneath Microsofts bum! Such a acquisition would create a beautiful new edge in the a-little-bit-lazy computer software industry today.
Tags: software
What is the point?! I am annoyed by the Cisco group passwords every time when I want to create a VPN tunnel to my University's network. Everyone knows how to decrypt these things so why even bother include them encrypted in the profiles? Everytime I have to digup my piece of C-code, edit the line pwd="xxxxxx", compile, and run. I think the ubuntu network manager should include the decrypter in a future release (seriously, who would complain? Cisco?).
To spite this all and make my life easier in the future, I will post the passwords for the HSR network below (I especially like the remote password):
GroupName=wireless
GroupPwd=luft1#buss
enc_GroupPwd=F026D73ACF95F63F8AB33BCDFF21F266DBF2FDCE409C9AC9210022D1ADC7FB12F845E51FB5C46F7C9D21A59F8E7B7E2072EF7EA9CC03CD12
GroupName=hsrremote
GroupPwd=hsrremote
enc_GroupPwd=28B87A7F9A37772E3F2C44EBBC8051DBF1A8A2B24212DB2AB4A729323E7BB74909D31E3A6BF887BC02C4A7EF6D6007A17E8467E3A68FCB48
If you are interested, this excellent algo (using libgcrypt) by Maurice Massar (HAL-9000) will decrypt the Cisco group passwords:
// ct is binary, resp is ascii
int c_decrypt(char *ct, int len, char **resp, char *reslenp)
{
const char *h1 = ct;
const char *h4 = ct + 20;
const char *enc = ct + 40;
char ht[20], h2[20], h3[20], key[24];
const char *iv = h1;
char *res;
gcry_cipher_hd_t ctx;
int reslen;
if (len < 48)
return 0;
len -= 40;
memcpy(ht, h1, 20);
ht[19]++;
gcry_md_hash_buffer(GCRY_MD_SHA1, h2, ht, 20);
ht[19] += 2;
gcry_md_hash_buffer(GCRY_MD_SHA1, h3, ht, 20);
memcpy(key, h2, 20);
memcpy(key+20, h3, 4);
/* who cares about parity anyway? */
gcry_md_hash_buffer(GCRY_MD_SHA1, ht, enc, len);
if (memcmp(h4, ht, 20) != 0)
return -1;
res = malloc(len);
if (res == NULL)
return -1;
gcry_cipher_open(&ctx, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
gcry_cipher_setkey(ctx, key, 24);
gcry_cipher_setiv(ctx, iv, 8);
gcry_cipher_decrypt(ctx, (unsigned char *)res, len, (unsigned char *)enc, len);
gcry_cipher_close(ctx);
reslen = len - res[len-1];
res[reslen] = '\0';
if (resp)
*resp = res;
if (reslenp)
*reslenp = reslen;
return 0;
}
Tags: computer science
« Previous Page 2 of 9 Next »