Welcome to Robot Dialogs. This is a place where I will record my progress, mistakes, errors, failures, lessons learned and hopefully occasional success in my designs and implementations of robots and other technical endeavors. I will try to make it as educational, informative and entertaining as I can...

Wednesday, December 16, 2009

My Favorite (Obscure) Code

I don't really have time during the holidays to be working on robots. Celebrations and family gatherings aside I have to start focusing on getting my masters thesis finished (I'll post about this later when I get more done and I may need your help). To fill the void between now and my next physical computing/robot project I've decided to go back and document some of the projects I was lucky enough to work on when I was still taking classes and had access to a real machine shop :( . But those posts will come over time, hopefully when I get access to a better camera. For today I've got a post for the code monkeys.

The code (stripped of meaningful names/comments see full below):
public static double [][] getX(double radius ){
   LinkedList<double> x = new LinkedList<double>();
   for(double a = 30; a<=330;a+=10 ){
     x.add(new double []{radius*Math.cos(a*Math.PI/180), radius*Math.sin(a*Math.PI/180)});
   }
   x.add(new double []{0,0});
   return x.toArray(new double[x.size()][]);
}
public static double [][] getY(double radius )
   LinkedList<double> y = new LinkedList<double>();
   for(double a = 0; a<=180;a+=10 ){
     y.add(new double []{radius*Math.cos(a*Math.PI/180), radius*Math.sin(a*Math.PI/180)});
   }
   boolean toggle = true;
   for(double a = -radius; a<radius*((double)6/5);a+=radius*((double)1/5)){
     y.add(new double []{a,(toggle ? -radius : -radius*((double)2/3))});
     toggle = !toggle;
   }
   return y.toArray(new double[y.size()][]);
}
Okay so that's pretty obscure right? You could figure it out if you drew each two element array as if they were x,y points. Don't waste your time unless you like obscure code. Just scroll on down. (And yeah I know this isn't exactly perfect or even "good" code...it was done quickly).

Step back in time to May 2009. I'm taking a class called Robot Motion Planning mostly a high level independent work/"research something and present it" type course. I was hoping to learn more in depth about kinematics but the course ended up diverging from that so I picked a topic involving Rapidly-exploring Random Trees (RRTs). These beauties are used to find motion paths in complex environments for robots (both mobile robots, robot articulators (arms)) and can even extended to path planning for just about any object. Now there's a whole slew of algorithmic and mathematical stuff to know and dive into (computing C-spaces, obstacle collision detection algorithms, multi-dimensional spaces). But lets not worry about all that.

The research I did isn't really original (I don't think a least) but it was pretty interesting to work on. I took RRTs to the next level by computing (in near real-time) paths for multiple robots using multi-threaded programming techniques (in JAVA). I've included the full source at the bottom, but it's not well documented or tested so use at your own risk.

So what does the code actually do? Well It generates x,y coordinates for the "robot's" graphic in the simulation. Not getting it? Take another look at the real code.

The actual code snippet:
public static double [][] getPackMan(double radius ){
   LinkedList<double> packman = new LinkedList<double>();
   for(double a = 30; a<=330;a+=10 ){
     packman.add(new double []{radius*Math.cos(a*Math.PI/180), radius*Math.sin(a*Math.PI/180)});
   }
   packman.add(new double []{0,0});
   return packman.toArray(new double[packman.size()][]);
}
public static double [][] getGhost(double radius )
   LinkedList<double> ghost = new LinkedList<double>();
   for(double a = 0; a<=180;a+=10 ){
     ghost.add(new double []{radius*Math.cos(a*Math.PI/180), radius*Math.sin(a*Math.PI/180)});
   }
   boolean toggle = true;
   for(double a = -radius; a<radius*((double)6/5);a+=radius*((double)1/5)){
     ghost.add(new double []{a,(toggle ? -radius : -radius*((double)2/3))});
     toggle = !toggle;
   }
   return ghost.toArray(new double[ghost.size()][]);
}

Yeah that's right baby, PackMan in 5 lines and only one loop. And ghosts in 8 lines. This made my day when I got it finished. I'm sure there are ways to get it even smaller, but this is 'as is' from the project...



The presentation for the research culminated in some nifty videos. Double click on them (takes you to YouTube) and watch them in HD to actually see...

Gather

Scatter

Wander


The code is here: RRT.jar (This is a runnable jar containing the source. Use "java -jar RRT.jar" to run. Works best on a quad core...)

Here is the presentation: Real-Time Crowd Path Planning with RRTs.pdf (It's fairly sparse. I believe in the "if you can't talk about it without reading from the slides then you don't know shit" approach.)

Holy crap it's such a huge pain in the ass to embed code in Blogger. Argh.

No comments:

Post a Comment