Archive for November, 2012


boost is the secret of my energy!

One of the bigger advantages of python is ostensibly its ability to wrap C/C++ code and expose its functionality to normal python code. I was attempting to do exactly that recently, and got pretty frustrated at my inability to use boost::python to get my trajectory follower PID code library exposed to my python code so that I could write scripts for calibrating the ARDrone in the mocap lab since my tracking and plotting are done in python.
Right off the blocks, when I tried defining the simplest boost::python class out of my PIDController class with only the constructor, I kept receiving this compilation error of the compiler not being able to find the copy constructor definition. This was odd, since I had clearly declared only my parameterized constructor, and I had no clue where the copy consstructor was coming from. (The error message said something about boost::reference_ptr)
Turns out that by default boost::python expects your class to be copyable (i.e. it has a copy constructor and can be referenced by value), and so you need to clearly specify if the class is not meant to be copyable by adding a boost::noncopyable tag to your boost::python _class template declaration.

This done, I then realized that my code used tf::Vector3 and tf::Matrix3x3, and I would need to build a wrapper to convert the python provided numpy array to these types. I also needed to convert the list of waypoints from a numpy array to a vector of floats, as required in the library. Also, since my trajectory follower library also creates a ROS node, and needs to broadcast and receive tf data, I needed to initialise ROS using ros::init() before creating an object of my PIDController class, since it declared a ros::NodeHandle(), which requires a ros::init() already declared.

Thus, I created a Wrapper class with the sole member being a pointer object of PIDController. My constructor takes in the default arguments, calls ros::init(), and then allocates a new PIDController object to my pointer. I have another function that accepts a numpy array as a boost::python::numeric::array, figures out the length of the array using boost::python::extract and then uses it again to extract values and then push it to the PIDController instance.

To be able to import the generated module, I had to add my library path to PYTHONPATH, and in my CMakeLists I added python to the rosbuild_link_boost definition. Note that the name of the module and the generated library file should match exactly. Also, in order to get boost::python to understand that I was sending in a numpy ndarray, I had to declare so in my BOOST_PYTHON_MODULE.

BOOST_PYTHON_MODULE(libfollow_trajectory)

{
boost::python::numeric::array::set_module_and_type( "numpy", "ndarray");
class_<PidControllerWrapper, boost::noncopyable>("PidController", init<float, float, float, float, float, float, float, float>() );

}
Whew, and that’s it! It sure was longer and more complicated than I expected, but it works like a charm!

Also, working in mocap is fun! The ARDrone, however, is quite annoying. It drifts, ever so much. Here is an example of a series of plots I calculated while the controller tried to follow a parabolic curve. Funnily enough, you can see that the drone actually always drifts to the left of where it thinks it is. One of the reasons why I conducted this test was to determine if this behaviour was repeatable, and if so, then to take into account this drift, and use an iterative learning controller to understand what new trajectory to provide in order to get the drone to follow the intended path (which, in this case would be some trajectory to the right of the provided trajectory)
Image

Also, we are getting an arducopter! Can’t wait to get my hands on it! :D

Advertisements

The slashdot experience

So we managed to get the BIRD MURI video and page ‘slashdotted’ last week. I set up Google Analytics and got some fun stats, that Drew thought would be interesting to disseminate.
tl;dr

  • Web page and youtube get almost equal number of hits ~3K
  • Web page: 93% left before 10 seconds, Video: Average video view retention 1:24.
  • Retention percentage through the initial systems explanation and the the first 43 seconds of the video is > 90%.
  • Conclusions –

a. People prefer youtube videos to web page views

b. Video is much more effective at disseminating information and engaging a prospective audience.

c. Assume a much more global viewership than you normally would

d. 1:30 seems like a good length for a demo video.

In case you haven’t seen the video, here it is

Also, have a look at the slashdot post Some of the comments are fun :)

Raw stats

Since Thursday, 3,039 unique people visited the site, and only 54.62% from the US. The city with the most visitors from was London (1.9%). The next biggest viewerships were from Canada (8.9%), UK (6.3%) and Australia (5%)
Browsers – Chrome (45.9%), Firefox(34%), Safari(!)(10%)
OS – Windows (55%), Mac (19%), Linux (18.2%), iOS(4.4%)
The flip side : 93% people left before 10 seconds.
Also, I checked the youtube stats, which are much better.
We got 3,234 views, With an average view duration of 1:24 minutes (which is 72% of the video duration) (The flight video ends at 1:32 at 80% absolute retention)
Also, retention percentage through the initial systems explanation and the the first 43 seconds of the video is > 90%.
Which probably implies that the video is much more effective at disseminating information and engaging prospective audience.

Extract, color, wait and pickle

So, today I wanted to extract a copy of our ardrone 2.0 package from our repository as a separate hg repository, with all its history imported. A little bit of searching helped me get to the solution
a. Enable the convert extension for mercurial by adding the following lines to ~/.hgrc
[extensions]
hgext.convert=

b. Create a map file which would instruct hg on how to extract the subfolder
include cpp/bird_ros_pkgs/ardrone2
rename cpp/bird_ros_pkgs/ardrone2 .

the first line specifies the relative path of the folder I want to extract from the path of the repo. The next line redirects the contents of that folder to the root of the new repo (. refers to the root of the new repo)
c. Run the hg convert utility!
hg convert --filemap ~/map.txt ~/bird_repo ~/ardrone2_repo/

And that’s it!

Also, miscellaneous notes from October

1. Do not try to use colorgcc with ROS on ubuntu. It is a living nightmare. The issue lies in trying to symlink gcc and g++ to colorgcc and prepending the path to the symlinks to the PATH environment variable. However, many packages don’t really structure themselves well, and don’t seem to traverse through the PATH well. So, although for normal code colorgcc was working, it failed miserably for instance for my ardrone2 package, which uses custom (horrid cascading) makefiles.

2. The thesis theme for wordpress is pretty neat. Using the PHP hooks allows you a great amount of flexibility. Also, whenever using thesis, add the thesis_hooks plugin. It serves as a handy guide to view all the customisable hooks for versions before 2.0.

3. When working with tf, always waitForTransform()s before starting execution based on the transforms. Not doing so results in annoying exceptions. Also, rospy automatically spawns off threads for Subscribe and Publish. Keep that in mind, and use locks whenever necessary. Pickling does not work for objects with locks in them, so design classes that serve purely as data storage and pickle them through accessor classes that lock access to the instance.

4. In Simulink never run differentiation directly on a sensor input. Ideally, use a low pass filter, but for a quick estimation use a transfer function using the laplacian s/(1+2*pi*f*s). Also, try and replace algebraic loops involving differentiation with integration.

5. In Latex, to include multiple figures on the same line with their own captions (just like in my brand new SoP :D) use the subcaption package. Then include images like so
\begin{figure}[h]
\centering
\subcaptionbox*{\footnotesize{}}{\includegraphics[width = 0.30\linewidth, trim=[left] [top] [right] [bottom], clip]{[path_to_image]}}~
\subcaptionbox*{\footnotesize{}}{\includegraphics[width = 0.30\linewidth, trim=[left] [top] [right] [bottom], clip]{[path_to_image]}}~
...
\end{figure}

The ~ at the end specifies single unit space that Latex is not allowed to break a line at. I used 0.3 times the linewidth since I had three pictures in there.