An update on our inverted pendulum project. The rotary encoder we used are great. They're accurate, easy, and we can read them quickly. We'd like to make a double pendulum, though. That would mean another encoder for the joint, but we don't know an easy way to make that work. We thought a vision system could free us from the wires necessary for the encoders. Phil wrote some notes on his blog.
Early on in this project, we used a webcam to try to track the colorful stickers attached to pole. It worked, but it was finicky. We've found a far better way. We bought some retroreflective tape and an IR light source source. Then, we ripped apart our PS Eye camera and removed the IR filter inside. We had to file down the lens holder base to bring the focus back to the right range.
With the IR filter removed, the camera can see the illuminated tape very easily.
We used some bash commands called from our Python script to turn down the exposure, gain, etc.
command = "v4l2-ctl -d 1 -c white_balance_automatic=0 -c auto_exposure=1 -c gain_automatic=0" output = subprocess.call(command, shell=True) command = "v4l2-ctl -d 1 -c exposure=0 -c gain=0" output = subprocess.call(command, shell=True)
The result was a nearly binary image. As you can see in the video below, it's basically perfect. We used some simple OpenCV code to threshold, make contours, and fit a red rectangle around the contours.
ret, frame = cap.read() imgray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE , cv2.CHAIN_APPROX_SIMPLE) rect = cv2.minAreaRect(contours) box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(thresh,[box],0,(0,0,255),2)
Here's a link to the Git commit.