N-link compound pendulum simulation

For our Mechanical Dynamics final project, a friend and I decided to generalize the equations for compound pendulums to write a simulation program that could generate animations for n-link compound pendulums with user specified lengths, masses, angular displacement and velocities. We originally wanted to write a full blown physics engine, but quickly realized that two weeks was not enough time to do something of that scale, haha.

First things first, a demonstration! The following is an simulation of a 5 link compound pendulum:

Read our final report for a more formal/comprehensive explanation of the process!
Download the code!

[Read more…]

PseudOS — A baremetal RaspPi OS

Now that I’ve got a bit of time, I thought I’d do a debrief of a couple of cool projects that I’ve worked on this past year. First up, PseudOS, a baremetal Raspberry PI OS that I wrote with some friends for our Software Systems final project.

(We were really sleep deprived when making the final video, apologies for any strange noises we make.)

It doesn’t look really amazing, because we didn’t really implement any OS features other than UART and a basic calculator program. However, we did do this all baremetal. What is baremetal, you ask? Well, it means that the code we wrote interacted with the RaspPi at the hardware level. We modified an Assembly boot file to give us control over the hardware registers, and wrote a kernel in C to provide the actual OS functionality. This website was an amazing resource for us through the whole process.

[Read more…]

Installing OpenCV for C++ and Python

Copying the instructions from my awesome robotics professor Paul Ruvolo from here so I don’t lose these steps:

To install OpenCV, go ahead and type each of these steps into your terminal window. Note that the “make” step will take forever, so go grab some popcorn or tea once you get there.

$ cd /tmp
$ wget https://github.com/Itseez/opencv/archive/2.4.11.zip
$ unzip 2.4.11.zip
$ cd opencv-2.4.11
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=RELEASE \
-DBUILD_PYTHON_SUPPORT=ON \
-DWITH_XINE=ON \
-DWITH_OPENGL=ON \
-DWITH_TBB=ON \
-DBUILD_EXAMPLES=ON \
-DBUILD_NEW_PYTHON_SUPPORT=ON \
-DWITH_V4L=ON \
-DOPENCV_EXTRA_MODULES_PATH=./modules
$ make -j2
$ sudo make install

In a nutshell, we download OpenCV 2.4 to the temporary folder, build it, make with two CPU cores, then install.Β It seems like those cmake parameters are actually pretty important to get stuff working!

-Sophie

Basic Color Tracking with OpenCV

OpenCV is a fantastic library for use in everything computer vision. It has pretty good documentation and support, as well as being completely open source. Here’s an introduction to implementing a basic OpenCV program, which we’ll use to track a red circle.

A complete version of the code is at the end of this post.

To start our OpenCV code, we need access to an image.

import cv2

def main():
  cap = cv2.VideoCapture(0)
  while True:
    ret, frame = cap.read()
    cv2.imshow("camera", frame)
    c = cv2.waitKey(1)

if __name__ == '__main__':
  main()

We open a connection to the webcam at index 0 (this number changes if you have multiple camera devices on your system) returning the image to the frame variable that we’ve set from before. We use imshow to show the frame to the screen, then pause for a second for the image to display. Run the code, and you should see a window with your webcam input pop up on the screen.

cv_1

Cool! So we have a frame for our OpenCV script to work with. Now, in image processing, we have to treat images as an array of numbers. In our case, the camera returns a 640×480 array of pixels with values from (0,0,0) to (255,255,255)–RGB color space. We’ll want to convert the RGB image into HSV for color filtering.

Typically, we visualize RGB(right) as a cube and HSV(left) as a cone.

RGB visualization HSV visualization

Note that RBG combines intensity and color. However, HSV separates the intensity of the color from the hue, which means we can simply filter one channel of the HSV image to get the color we want. Super useful!

**Note that OpenCV orders the channels as BRG instead of RGB**

Let’s convert the image to HSV, then filter for red.

import cv2
import cv2.cv as cv
import numpy as np

def main():
	cap = cv2.VideoCapture(0)
	while True:
		ret, frame = cap.read()

		hsv_image = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
		red_image = cv2.inRange(hsv_image, (0,50,50), (8,170,200))
		cv2.imshow("camera", frame)
		cv2.imshow("red image", red_image)
		c = cv2.waitKey(1)

if __name__ == '__main__':
	main()

cv_2

Woah! So cool right!? Note that there’s a bit of red from my face, as well as my my little red friend in the background is highlighted as well. However, the majority of the filtered image is around the red pokeball. As a brief aside: The reason why color filtering isn’t the best way do object recognition is that color changes drastically with the lighting conditions. (Remember the blue/black, gold/white dress scandal earlier this year? Hahaha). To change the color that the code will filter for, change the value inside the cv2.inRange function.

With the red image filtered out now, we can do some basic shape detection to find where our ball is. The function can use for this is HoughCircles. The method behind circle detection is rather complex, but we can treat it like a black box for now and just run the code over our image.

import cv2
import cv2.cv as cv
import numpy as np

def main():
	cap = cv2.VideoCapture(0)
	while True:
		ret, frame = cap.read()

		hsv_image = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
		red_image = cv2.inRange(hsv_image, (0,50,50), (8,170,200))

		circles = cv2.HoughCircles(red_image, cv.CV_HOUGH_GRADIENT,1,20,
		param1=50,param2=30,minRadius=0,maxRadius=0)

		if circles != None:
			circles = np.uint16(np.around(circles))
			for i in circles[0,:]:
				# draw the outer circle
				cv2.circle(frame,(i[0],i[1]),i[2],(0,255,0),2)
				# draw the center of the circle
				cv2.circle(frame,(i[0],i[1]),2,(0,0,255),3)

		cv2.imshow("camera", frame)
		cv2.imshow("red image", red_image)
		c = cv2.waitKey(1)

if __name__ == '__main__':
	main()

The result is a function that can largely find red circular objects in a scene.

cv_3A caveat:
This is a crazy basic implementation of color filtering + HoughCircles. As a result, this code only filters for a limited range of red colors, then runs the hough algorithm with fairly loose parameters over the resulting image. Due to this, this code is inflexible in different lightning conditions and is unreliable for the circle detected output. There are several ways to do object detection/color filtering, the intracacies of which I’ll cover another day. πŸ™‚

Adding new packages directly to python path

As an aside:

When installing libraries for python not through pip install, it’s a good idea to note that the “import” command from python imports from the Python/2.x/site-packages directory. For things like homebrew, you can tell Python where to look for the package by creating symlinks.

For example, when I was trying to link OpenCV installed from Homebrew into my Python path:

cd /Library/Python/2.7/site-packages
ln -s /usr/local/Cellar/opencv/2.4.9/lib/python2.7/site-packages/cv.py cv.py
ln -s /usr/local/Cellar/opencv/2.4.9/lib/python2.7/site-packages/cv.py cv.py

-Sophie

Automatically updating your website with Git and git-hooks

*This process works with sites hosted on NearlyFreeSpeech.net. I’m not sure how well it’ll work on other hosts, though I assume the process should be similar.

I was jealous of all of my friends with their pretty websites, so I decided that I would go ahead and build my own. Looking into all the options out there, I decided that I’d host my site on NearlyFreeSpeech.net(NFS) because it was cheapest (literally $0.01 a day!), and gave me the most control over my site.

After buying the “justsophie.com” domain, I had nice little space on the internet where I could make myself cozy. I just had to populate it! Typically, updating a site requires one to SSH or FTP assets to the server, which is really annoying if you make lots of changes. And because I’m lazy, I decided to automate this process by using Git hooks. (Laziness FTW :D)

What we have to do is create an empty Git repo on your website with a post-receive hook that will take the updated files and put them in the public facing folder! I’m assuming you know how push/pull, commits, etc work in Git. Let me know if you don’t!

On your computer:
We’ll need to create a new git folder for all the assets of our website. Go on and create a new repo on Github and clone it to your local computer. I’m just going to use this website as an example.

git clone https://github.com/srli/Pomelo

All set for now, let’s go set up the stuff on NFS.
[Read more…]

Installing Kinect drivers on Ubuntu 14.04 and ROS Indigo

The XBox Kinect is a surprisingly great sensor that is also really cheap. The combination of the two factors makes it a great sensor to use in Robotics research as an interface for human robot interaction. However, it’s a bit difficult to interface with due to the complicated install process, so this post will walk through the steps of installing OpenNI dependencies for use on ROS Indigo and Ubuntu 14.04.

Unfortunately, NiTE is now proprietary software, so I hope you’ve either found a cached version of it elsewhere, or have found a replacement gesture recognition suite. If so, let me know too please! πŸ˜€

[Read more…]

Useful Code Snippets

Even as a super awesome engineer, there are still basic things that I always forget. Like 1+1… or whether it’s cos(0)=1 or sin(0)=1. That’s why it’s so useful to have a cheatsheet at all times!

Anyhow, here are some things I have to search Google for waaaay too often:

Converting MOV to GIF:

ffmpeg -i home_anim3.mov -vf scale=560:560/a -pix_fmt rgb24 -r 20 -f gif - | gifsicle --optimize=3 --delay=5 > home_anim3.gif

Got this from here.


Markdown:
Great Markdown cheatsheet


Viewing ROS image topics:

rosrun image_view disparity_view image:=/camera/depth_registered/disparity
or
rosrun image_view image_view image:=/camera/rgb/image_color


Copying file from local to server via SSH:

scp /path/to/source-file user@host:/path/to/destination-folder/

More commands found here.


Opening ROS serial node (defaults to port /dev/ttyUSB0):

rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0

[Read more…]